chore: update to import_map and serve.

This commit is contained in:
thorwebdev committed 2023-02-17 14:09:27 +08:00
1 parent ae3e1b89ac
commit 5bd05e4099
38 files changed
+177 -136

No files matched your search

+9 -12
View File
@@ -6,23 +6,17 @@
## Example Functions
The function examples are located in [`./supabase/functions`](./supabase/functions):
- [`browser-with-cors`](./supabase/functions/browser-with-cors/index.ts): Handle CORS headers for function invocations from browser environments.
- [`select-from-table-with-auth-rls`](./supabase/functions/select-from-table-with-auth-rls/index.ts): Retrieve data from an authenticated user via RLS.
- [`send-email-smtp`](./supabase/functions/send-email-smtp/index.ts): Send an email using SMTP credentials.
- [`stripe-webhooks`](./supabase/functions/stripe-webhooks/index.ts): Handle Stripe Webhooks.
- [`telegram-bot`](./supabase/functions/telegram-bot/index.ts): Webhook handler for Telegram bots using [grammY](https://grammy.dev/).
We're constantly adding new Function Examples, [check our docs](https://supabase.com/docs/guides/functions#examples) for a complete list!
## Develop locally
- Run `supabase start` (make sure your Docker daemon is running.)
- Run `mv ./supabase/.env.local.example ./supabase/.env.local` to rename the local `.env` file.
- Set the required variables to run the desired edge functions in the `.env.local` file.
- Run `supabase functions serve your-function-name --env-file ./supabase/.env.local`
- Run `cp ./supabase/.env.local.example ./supabase/.env.local` to create your local `.env` file.
- Set the required variables for the corresponding edge functions in the `.env.local` file.
- Run `supabase functions serve --env-file ./supabase/.env.local --no-verify-jwt`
- Run the CURL command in the example function, or use the [invoke method](https://supabase.com/docs/reference/javascript/invoke) on the Supabase client or use the test client [app](./app/).
## Test
## Test Client
This example includes a create-react-app in the [`./app/`](./app/) directory which you can use as a sort of postman to make test requests both locally and to your deployed functions.
@@ -45,10 +39,13 @@ Note: when testing locally, the select dropdown doesn't have any effect, and inv
- Link your project
- Within your project root run `supabase link --project-ref your-project-ref`
- Set up your secrets
- Run `supabase secrets set --env-file ./supabase/.env.local` to set the environment variables.
(This is assuming your local and production secrets are the same. The recommended way is to create a separate `.env` file for storing production secrets, and then use it to set the environment variables while deploying.)
- You can run `supabase secrets list` to check that it worked and also to see what other env vars are set by default.
- Deploy the function
- Within your project root run `supabase functions deploy your-function-name`
- In your [`./app/.env`](./app/.env) file remove the `SUPA_FUNCTION_LOCALHOST` variable and restart your Expo app.
@@ -18,6 +18,7 @@
"node_modules/": true,
"app/": true,
"supabase/functions/": true
}
},
"deno.importMap": "./supabase/functions/import_map.json"
}
}
@@ -1,3 +1,18 @@
# cloudflare-turnstile
CLOUDFLARE_TURNSTILE_SECRET_KEY=your_secret_key
# discord-bot
DISCORD_PUBLIC_KEY=
# location
IPINFO_TOKEN="your https://ipinfo.io token"
# postgres-on-the-edge
DATABASE_URL=
# puppeteer
PUPPETEER_BROWSERLESS_IO_TOKEN=
# send-email-smtp
SMTP_HOSTNAME="your.hostname.com"
SMTP_PORT="2587"
@@ -5,10 +20,14 @@ SMTP_USERNAME="your_username"
SMTP_PASSWORD="your_password"
SMTP_FROM="no-reply@example.com"
# stripe-webhooks
STRIPE_API_KEY="<YOUR API KEY HERE>"
STRIPE_WEBHOOK_SIGNING_SECRET="<YOUR WEBHOOK SIGNING HERE>"
# telegram-bot
TELEGRAM_BOT_TOKEN="get it from https://t.me/BotFather"
FUNCTION_SECRET="random secret"
# stripe-webhooks
STRIPE_API_KEY="<YOUR API KEY HERE>"
STRIPE_WEBHOOK_SIGNING_SECRET="<YOUR WEBHOOK SIGNING HERE>"
# upstash-redis-counter
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
@@ -1,5 +1,5 @@
{
"deno.enable": true,
"deno.lint": true,
"deno.unstable": true
"deno.unstable": true,
"deno.importMap": "./import_map.json"
}
@@ -2,7 +2,7 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
import { serve } from 'std/server'
import { corsHeaders } from '../_shared/cors.ts'
console.log(`Function "browser-with-cors" up and running!`)
@@ -2,6 +2,10 @@
Turnstile is Cloudflare's CAPTCHA alternative: https://developers.cloudflare.com/turnstile/get-started/
## Watch the Video Tutorial
[![video tutorial](https://img.youtube.com/vi/OwW0znboh60/0.jpg)](https://www.youtube.com/watch?v=OwW0znboh60)
## Setup
- Follow these steps to set up a new site: https://developers.cloudflare.com/turnstile/get-started/
@@ -2,7 +2,7 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
import { serve } from 'std/server'
import { corsHeaders } from '../_shared/cors.ts'
console.log(`Function "cloudflare-turnstile" up and running!`)
@@ -55,7 +55,7 @@ serve(async (req) => {
})
// To invoke:
// curl -i --location --request POST 'http://localhost:54321/functions/v1/' \
// curl -i --location --request POST 'http://localhost:54321/functions/v1/cloudflare-turnstile' \
// --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \
// --header 'Content-Type: application/json' \
// --data '{"token":"cf-turnstile-response"}'
@@ -5,6 +5,10 @@
- https://deno.com/deploy/docs/tutorial-discord-slash
- https://discord.com/developers/docs/interactions/application-commands#slash-commands
## Watch the Video Tutorial
[![video tutorial](https://img.youtube.com/vi/J24Bvo_m7DM/0.jpg)](https://www.youtube.com/watch?v=J24Bvo_m7DM)
## Create an application on Discord Developer Portal
1. Go to [https://discord.com/developers/applications](https://discord.com/developers/applications) (login using your discord account if required).
@@ -59,6 +63,6 @@ Open Discord, type `/Promise` and press **Enter**.
## Run locally
```bash
supabase functions serve discord-bot --no-verify-jwt --env-file ./supabase/functions/discord-bot/.env
supabase functions serve discord-bot --no-verify-jwt --env-file ./supabase/.env.local
ngrok http 54321
```
@@ -5,10 +5,10 @@
// Sift is a small routing library that abstracts away details like starting a
// listener on a port, and provides a simple function (serve) that has an API
// to invoke a function for a specific path.
import { json, serve, validateRequest } from 'https://deno.land/x/sift@0.6.0/mod.ts'
import { json, serve, validateRequest } from 'sift'
// TweetNaCl is a cryptography library that we use to verify requests
// from Discord.
import nacl from 'https://cdn.skypack.dev/tweetnacl@v1.0.3?dts'
import nacl from 'nacl'
enum DiscordCommandType {
Ping = 1,
@@ -1,8 +1,8 @@
// This example shows how to use Edge Functions to read incoming multipart/form-data request,
// and write files to Supabase Storage and other fields to a database table.
import { Application, Router } from 'https://deno.land/x/oak/mod.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
import { Application } from 'oak'
import { createClient } from '@supabase/supabase-js'
const MB = 1024 * 1024
@@ -25,9 +25,9 @@ app.use(async (ctx) => {
const supabaseClient = createClient(
// Supabase API URL - env var exported by default.
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_URL')!,
// Supabase API ANON KEY - env var exported by default.
Deno.env.get('SUPABASE_ANON_KEY') ?? ''
Deno.env.get('SUPABASE_ANON_KEY')!
)
//upload image to Storage
@@ -15,9 +15,11 @@ Good luck trying to GET a T-Shirt!
### Serve this function locally
```bash
supabase functions serve --no-verify-jwt get-tshirt-competition
supabase functions serve --no-verify-jwt
```
Navigate to http://localhost:54321/functions/v1/get-tshirt-competition?email=testr@test.de&twitter=thorwebdev&size=2XL&answer=20
### Deploy this function
```bash
@@ -2,8 +2,8 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
import { serve } from 'std/server'
import { createClient } from '@supabase/supabase-js'
import { corsHeaders } from '../_shared/cors.ts'
console.log(`Function "get-tshirt-competition" up and running!`)
@@ -2,23 +2,18 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from "https://deno.land/std@0.131.0/http/server.ts";
import { serve } from 'std/server'
console.log("Hello from Functions!");
console.log('Hello from Functions!')
serve(async (req) => {
const { name } = await req.json();
serve((_req) => {
const data = {
message: `I was deployed via GitHub Actions!`,
};
}
return new Response(JSON.stringify(data), {
headers: { "Content-Type": "application/json" },
});
});
headers: { 'Content-Type': 'application/json' },
})
})
// To invoke:
// curl -i --location --request POST 'http://localhost:54321/functions/v1/' \
// --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24ifQ.625_WdcF3KHqz5amU0x2X5WWHP-OEs_4qj0ssLNHzTs' \
// --header 'Content-Type: application/json' \
// --data '{"name":"Functions"}'
// To invoke: http://localhost:54321/functions/v1/github-action-deploy
@@ -0,0 +1,18 @@
{
"imports": {
"denomailer": "https://deno.land/x/denomailer@0.12.0/mod.ts",
"nacl": "https://cdn.skypack.dev/tweetnacl@v1.0.3?dts",
"oak": "https://deno.land/x/oak@v11.1.0/mod.ts",
"og_edge": "https://deno.land/x/og_edge@0.0.4/mod.ts",
"grammy": "https://deno.land/x/grammy@v1.8.3/mod.ts",
"react": "https://esm.sh/react@18.2.0",
"std/server": "https://deno.land/std@0.177.0/http/server.ts",
"stripe": "https://esm.sh/stripe@11.1.0?target=deno",
"sift": "https://deno.land/x/sift@0.6.0/mod.ts",
"@supabase/supabase-js": "https://esm.sh/@supabase/supabase-js@2.7.1",
"postgres": "https://deno.land/x/postgres@v0.14.2/mod.ts",
"puppeteer": "https://deno.land/x/puppeteer@16.2.0/mod.ts",
"React": "https://esm.sh/react@18.2.0?deno-std=0.177.0",
"upstash_redis": "https://deno.land/x/upstash_redis@v1.19.3/mod.ts"
}
}
@@ -4,6 +4,14 @@ This example shows how you can get user location based on the IP provided in X-F
You will need to signup for an account in https://ipinfo.io and provide it as `IPINFO_TOKEN` environment variable ([learn how to set environment variables to your functions](https://supabase.com/docs/guides/functions#secrets-and-environment-variables)).
## Develop locally
```bash
supabase functions serve --env-file ./supabase/.env.local --no-verify-jwt
```
Navigate to http://localhost:54321/functions/v1/location
## Deploy
```bash
@@ -2,20 +2,29 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from "https://deno.land/std@0.131.0/http/server.ts"
import { serve } from 'std/server'
function ips(req: Request) {
return req.headers.get("x-forwarded-for")?.split(/\s*,\s*/);
return req.headers.get('x-forwarded-for')?.split(/\s*,\s*/)
}
serve(async (req) => {
const clientIps = ips(req) || [''];
const res = await fetch(`https://ipinfo.io/${clientIps[0]}?token=${Deno.env.get('IPINFO_TOKEN')}`, {
headers: { 'Content-Type': 'application/json'}});
const { city, country } = await res.json();
return new Response(
JSON.stringify(`You're accessing from ${city}, ${country}`),
{ headers: { "Content-Type": "application/json" } },
const clientIps = ips(req) || ['']
const res = await fetch(
`https://ipinfo.io/${clientIps[0]}?token=${Deno.env.get('IPINFO_TOKEN')}`,
{
headers: { 'Content-Type': 'application/json' },
}
)
if (res.ok) {
const { city, country } = await res.json()
return new Response(JSON.stringify(`You're accessing from ${city}, ${country}`), {
headers: { 'Content-Type': 'application/json' },
})
} else {
return new Response(await res.text(), {
status: 400,
})
}
})
@@ -5,7 +5,7 @@ This example shows how you can write functions using Oak server middleware (http
## Run locally
```bash
supabase functions serve oak-server
supabase functions serve --no-verify-jwt
```
Use cURL or Postman to make a POST request to http://localhost:54321/functions/v1/oak-server.
@@ -20,5 +20,5 @@ Use cURL or Postman to make a POST request to http://localhost:54321/functions/v
## Deploy
```bash
supabase functions deploy oak-server
supabase functions deploy oak-server --no-verify-jwt
```
@@ -1,4 +1,4 @@
import { Application, Router } from 'https://deno.land/x/oak/mod.ts'
import { Application, Router } from 'oak'
const router = new Router()
router
@@ -9,7 +9,7 @@ Generate Open Graph images with Deno and Supabase Edge Functions and cache the g
## Run locally
```bash
supabase functions serve og-image-with-storage-cdn --no-verify-jwt
supabase functions serve --no-verify-jwt
```
Navigate to http://localhost:54321/functions/v1/og-image-with-storage-cdn?ticketNumber=3524&username=thorwebdev&name=Thor%20%E9%9B%B7%E7%A5%9E%20Schaeff
@@ -1,6 +1,6 @@
import React from 'https://esm.sh/react@18.2.0?deno-std=0.140.0'
import { ImageResponse } from 'https://deno.land/x/og_edge@0.0.4/mod.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
import React from 'React'
import { ImageResponse } from 'og_edge'
import { createClient } from '@supabase/supabase-js'
import { corsHeaders } from '../_shared/cors.ts'
const STORAGE_URL = 'https://obuldanrptloktxcffvn.supabase.co/storage/v1/object/public/images/lw6'
@@ -213,7 +213,7 @@ export async function handler(req: Request) {
})
if (error) throw error
return generatedImage
return await fetch(`${STORAGE_URL}/tickets/${username}.png?v=3`)
} catch (error) {
return new Response(JSON.stringify({ error: error.message }), {
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
@@ -2,7 +2,7 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from 'https://deno.land/std@0.140.0/http/server.ts'
import { serve } from 'std/server'
import { handler } from './handler.tsx'
@@ -8,7 +8,7 @@ Generate Open Graph images with Deno and Supabase Edge Functions, no framework n
## Run locally
```bash
supabase functions serve opengraph --no-verify-jwt
supabase functions serve --no-verify-jwt
```
Navigate to http://localhost:54321/functions/v1/opengraph
@@ -1,5 +1,5 @@
import React from 'https://esm.sh/react@18.2.0?deno-std=0.140.0'
import { ImageResponse } from 'https://deno.land/x/og_edge@0.0.4/mod.ts'
import React from 'React'
import { ImageResponse } from 'og_edge'
export function handler(req: Request) {
return new ImageResponse(
@@ -2,7 +2,7 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from 'https://deno.land/std@0.140.0/http/server.ts'
import { serve } from 'std/server'
import { handler } from './handler.tsx'
@@ -1,5 +1,5 @@
import * as postgres from 'https://deno.land/x/postgres@v0.14.2/mod.ts'
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
import * as postgres from 'postgres'
import { serve } from 'std/server'
// Get the connection string from the environment variable "DATABASE_URL"
const databaseUrl = Deno.env.get('DATABASE_URL')!
@@ -4,6 +4,14 @@ This example shows how you can use Puppeteer and a headless-browser to generate
Since Edge Functions cannot run a Headless Browser instance due to resource constraints, you will need to use a hosted browser service like https://browserless.io.
## Develop locally
```bash
supabase functions serve --env-file ./supabase/.env.local --no-verify-jwt
```
Navigate to http://localhost:54321/functions/v1/puppeteer
## Deploy
```bash
@@ -1,11 +1,14 @@
import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
import puppeteer from 'https://deno.land/x/puppeteer@16.2.0/mod.ts'
import { serve } from 'std/server'
import puppeteer from 'puppeteer'
serve(async (req) => {
try {
console.log(`wss://chrome.browserless.io?token=${Deno.env.get('PUPPETEER_BROWSERLESS_IO_KEY')}`)
// Visit browserless.io to get your free API token
const browser = await puppeteer.connect({
browserWSEndpoint: 'wss://chrome.browserless.io?token=YOUR_API_TOKEN',
browserWSEndpoint: `wss://chrome.browserless.io?token=${Deno.env.get(
'PUPPETEER_BROWSERLESS_IO_KEY'
)}`,
})
const page = await browser.newPage()
@@ -17,7 +20,7 @@ serve(async (req) => {
return new Response(screenshot, { headers: { 'Content-Type': 'image/png' } })
} catch (e) {
console.error(e)
return new Response(JSON.stringify(`Error occurred when generating the screenshot`), {
return new Response(JSON.stringify({ error: e.message }), {
headers: { 'Content-Type': 'application/json' },
status: 500,
})
@@ -2,8 +2,8 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
import { serve } from 'std/server'
import { createClient } from '@supabase/supabase-js'
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
@@ -2,8 +2,8 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
import { createClient, SupabaseClient } from 'https://esm.sh/@supabase/supabase-js@2'
import { serve } from 'std/server'
import { createClient, SupabaseClient } from '@supabase/supabase-js'
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
@@ -2,8 +2,8 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
import { serve } from 'std/server'
import { createClient } from '@supabase/supabase-js'
import { corsHeaders } from '../_shared/cors.ts'
console.log(`Function "select-from-table-with-auth-rls" up and running!`)
@@ -13,4 +13,4 @@ Note: `SMTP_PORT` must be a port other than `25`, `465`, and `587` as Deno Deplo
## Test locally
- `cp ./supabase/.env.local.example ./supabase/.env.local`
- `supabase functions serve send-email-smtp --env-file ./supabase/.env.local`
- `supabase functions serve --env-file ./supabase/.env.local`
@@ -2,14 +2,14 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from 'https://deno.land/std@0.131.0/http/server.ts'
import { SmtpClient } from 'https://deno.land/x/denomailer@0.12.0/mod.ts'
import { serve } from 'std/server'
import { SmtpClient } from 'denomailer'
const smtp = new SmtpClient()
console.log(`Function "send-email-smtp" up and running!`)
serve(async (req) => {
serve(async (_req) => {
await smtp.connect({
hostname: Deno.env.get('SMTP_HOSTNAME')!,
port: Number(Deno.env.get('SMTP_PORT')!),
@@ -24,7 +24,7 @@ serve(async (req) => {
subject: `Hello from Supabase Edge Functions`,
content: `Hello Functions \o/`,
})
} catch (error: any) {
} catch (error) {
return new Response(error.message, { status: 500 })
}
@@ -41,7 +41,7 @@ serve(async (req) => {
})
// To invoke:
// curl -i --location --request POST 'http://localhost:54321/functions/v1/' \
// curl -i --location --request POST 'http://localhost:54321/functions/v1/send-email-smtp' \
// --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24ifQ.625_WdcF3KHqz5amU0x2X5WWHP-OEs_4qj0ssLNHzTs' \
// --header 'Content-Type: application/json' \
// --data '{"name":"Functions"}'
@@ -9,7 +9,7 @@ Also check out our full Stripe Payments examples for [React Native (Expo)](https
## Test locally
- Terminal 1:
- `supabase functions serve --no-verify-jwt stripe-webhooks --env-file ./supabase/.env.local`
- `supabase functions serve --no-verify-jwt --env-file ./supabase/.env.local`
- Terminal 2:
- `stripe listen --forward-to localhost:54321/functions/v1/`
- Terminal 3 (optional):
@@ -2,20 +2,21 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from 'https://deno.land/std@0.132.0/http/server.ts'
import { serve } from 'std/server'
// esm.sh is used to compile stripe-node to be compatible with ES modules.
import Stripe from 'https://esm.sh/stripe@10.13.0?target=deno&no-check&deno-std=0.132.0'
// Import via bare specifier thanks to the import_map.json file.
import Stripe from 'stripe'
const stripe = Stripe(Deno.env.get('STRIPE_API_KEY'), {
const stripe = new Stripe(Deno.env.get('STRIPE_API_KEY') as string, {
// This is needed to use the Fetch API rather than relying on the Node http
// package.
apiVersion: '2022-11-15',
httpClient: Stripe.createFetchHttpClient(),
})
// This is needed in order to use the Web Crypto API in Deno.
const cryptoProvider = Stripe.createSubtleCryptoProvider()
console.log(`Function "stripe-webhooks" up and running!`)
console.log('Hello from Stripe Webhook!')
serve(async (request) => {
const signature = request.headers.get('Stripe-Signature')
@@ -27,8 +28,8 @@ serve(async (request) => {
try {
receivedEvent = await stripe.webhooks.constructEventAsync(
body,
signature,
Deno.env.get('STRIPE_WEBHOOK_SIGNING_SECRET'),
signature!,
Deno.env.get('STRIPE_WEBHOOK_SIGNING_SECRET')!,
undefined,
cryptoProvider
)
@@ -36,25 +37,5 @@ serve(async (request) => {
return new Response(err.message, { status: 400 })
}
console.log(`🔔 Event received: ${receivedEvent.id}`)
// Secondly, we use this event to query the Stripe API in order to avoid
// handling any forged event. If available, we use the idempotency key.
const requestOptions =
receivedEvent.request && receivedEvent.request.idempotency_key
? {
idempotencyKey: receivedEvent.request.idempotency_key,
}
: {}
let retrievedEvent
try {
retrievedEvent = await stripe.events.retrieve(receivedEvent.id, requestOptions)
} catch (err) {
return new Response(err.message, { status: 400 })
}
return new Response(JSON.stringify({ id: retrievedEvent.id, status: 'ok' }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
})
return new Response(JSON.stringify({ ok: true }), { status: 200 })
})
@@ -2,34 +2,28 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from "https://deno.land/std@0.131.0/http/server.ts"
import { serve } from 'std/server'
console.log(`Function "telegram-bot" up and running!`)
import { Bot, webhookCallback } from "https://deno.land/x/grammy@v1.8.3/mod.ts";
import { Bot, webhookCallback } from 'grammy'
const bot = new Bot(Deno.env.get('TELEGRAM_BOT_TOKEN') || '');
const bot = new Bot(Deno.env.get('TELEGRAM_BOT_TOKEN') || '')
bot.command("start", (ctx) => ctx.reply("Welcome! Up and running."));
bot.command('start', (ctx) => ctx.reply('Welcome! Up and running.'))
bot.command('ping', (ctx) => ctx.reply(`Pong! ${new Date()} ${Date.now()}`))
const handleUpdate = webhookCallback(bot, "std/http");
const handleUpdate = webhookCallback(bot, 'std/http')
serve(async (req) => {
try {
const url = new URL(req.url);
if (url.searchParams.get('secret') !== Deno.env.get('FUNCTION_SECRET'))
const url = new URL(req.url)
if (url.searchParams.get('secret') !== Deno.env.get('FUNCTION_SECRET'))
return new Response('not allowed', { status: 405 })
return await handleUpdate(req);
return await handleUpdate(req)
} catch (err) {
console.error(err);
console.error(err)
}
})
// To invoke:
// curl -i --location --request POST 'http://localhost:54321/functions/v1/' \
// --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24ifQ.625_WdcF3KHqz5amU0x2X5WWHP-OEs_4qj0ssLNHzTs' \
// --header 'Content-Type: application/json' \
// --data '{"name":"Functions"}'
@@ -1,2 +0,0 @@
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
@@ -9,7 +9,7 @@ Create a Redis database using the [Upstash Console](https://console.upstash.com/
Select the `Global` type to minimize the latency from all edge locations. Copy the `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` to your .env file. You'll find them under **Details > REST API > .env**.
```bash
cp supabase/functions/upstash-redis-counter/.env.example supabase/functions/upstash-redis-counter/.env
cp supabase/.env.local.example supabase/.env.local
```
## Run locally
@@ -18,7 +18,7 @@ Make sure you have the latest version of the [Supabase CLI installed](https://su
```bash
supabase start
supabase functions serve upstash-redis-counter --no-verify-jwt --env-file supabase/functions/upstash-redis-counter/.env
supabase functions serve --no-verify-jwt --env-file supabase/.env.local
```
Navigate to http://localhost:54321/functions/v1/upstash-redis-counter.
@@ -27,5 +27,5 @@ Navigate to http://localhost:54321/functions/v1/upstash-redis-counter.
```bash
supabase functions deploy upstash-redis-counter --no-verify-jwt
supabase secrets set --env-file supabase/functions/upstash-redis-counter/.env
supabase secrets set --env-file supabase/.env.local
```
@@ -2,8 +2,8 @@
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
import { serve } from 'https://deno.land/std@0.177.0/http/server.ts'
import { Redis } from 'https://deno.land/x/upstash_redis@v1.19.3/mod.ts'
import { serve } from 'std/server'
import { Redis } from 'upstash_redis'
console.log(`Function "upstash-redis-counter" up and running!`)