はじめに
サービスを運用する際に問い合わせフォームに新たな問い合わせが行われたら通知してくれる機能が欲しいことは実際の運用でよくあるケースだと思われます。
また、できればアプリ側の責任にせずDB周辺でその機能を完結させ情シスなどが管理しやすい形にしたいところです。
SupabaseではEdge Functionsを利用することでデータベースに新たなデータが追加されたことをトリガーにしてSlack通知を送ることができます。実際にやってみましょう。
Slack Appの作成
Slack APIにアクセスしましょう。
その後ヘッダーのYour Appを押し、次の画面でCreate an App
をクリックします。
次の画面ではFrom Scratch
を押しましょう。
アプリ名とSlackのワークスペースをそれぞれ設定します。
Incoming Webhookの設定
アプリの作成ができたら、Incoming Webhook
をONにします。
下のほうにあるAdd new Webhook to Workspace
をクリックし、投稿先のチャンネルを指定します。
連携ができたかどうか確認するために下記のコマンドをたたいてみましょう。
curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' ${webhook url}
Slackに通知が届いたので、ちゃんと接続ができているようです。
Edge Functionsの開発
次にEdge Functionsを開発しましょう。
適当なプロジェクトフォルダを作成します。
supabase init
supabase start
その後、functionの作成を行います。
supabase functions new slack-notify
ファイルの内容を編集します。
// Follow this setup guide to integrate the Deno language server with your editor:
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
// Setup type definitions for built-in Supabase Runtime APIs
import "jsr:@supabase/functions-js/edge-runtime.d.ts";
console.log("Hello from Functions!");
const SLACK_WEBHOOK_URL = Deno.env.get("SLACK_WEBHOOK_URL") || "ローカルのt機はここにwebhookのURLを入れる";
Deno.serve(async (req) => {
const payload = await req.json();
const { record } = payload;
// Slackに送信するメッセージを作成
const message = {
text:
`新しい問い合わせが届きました:\n名前: ${record.name}\nメール: ${record.email}\n内容: ${record.message}`,
};
// Slack Incoming Webhookを使用して通知を送信
const response = await fetch(SLACK_WEBHOOK_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(message),
});
if (response.ok) {
return new Response(JSON.stringify({ success: true }), {
headers: { "Content-Type": "application/json" },
status: 200,
});
} else {
return new Response(JSON.stringify({ success: false }), {
headers: { "Content-Type": "application/json" },
status: 500,
});
}
});
/* To invoke locally:
1. Run `supabase start` (see: https://supabase.com/docs/reference/cli/supabase-start)
2. Make an HTTP request:
curl -i --location --request POST 'http://127.0.0.1:54321/functions/v1/slack-notify' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \
--header 'Content-Type: application/json' \
--data '{"type":"INSERT","table":"inquiries","record":{"id":1,"name":"テスト太郎","email":"test@example.com","message":"これはテストメッセージです。"}}'
*/
functionをローカルで起動し、実際に動いているか下記で確認しましょう。
supabase functions serve
curl -i --location --request POST 'http://127.0.0.1:54321/functions/v1/slack-notify' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0' \
--header 'Content-Type: application/json' \
--data '{"type":"INSERT","table":"inquiries","record":{"id":1,"name":"テスト太郎","email":"test@example.com","message":"これはテストメッセージです。"}}'
通知が送られたらOKです。
デプロイ
Supabaseプロジェクトとリンクさせます。
supabase link --project-ref ${プロジェクトID}
WebhookのURLを環境変数として利用できるようにコマンドで送信します。
npx supabase secrets set SLACK_WEBHOOK_URL=${Slack Appから取得したWebhook URL}
デプロイします。
supabase functions deploy
Supabaseのトリガー設定
SQL Editorで下記を実行しましょう。
CREATE EXTENSION IF NOT EXISTS http WITH SCHEMA extensions;
CREATE OR REPLACE FUNCTION notify_new_contact()
RETURNS TRIGGER AS $$
DECLARE
result json;
BEGIN
SELECT status, content::json INTO result
FROM http((
'POST',
'https://${プロジェクトID}.supabase.co/functions/v1/slack-notify',
ARRAY[
http_header('Authorization', 'Bearer ${anon key}'),
http_header('Content-Type', 'application/json')
],
'application/json',
jsonb_build_object('record', row_to_json(NEW))::text
)::http_request);
-- レスポンスのログを記録(オプション)
RAISE NOTICE 'HTTP Response: %', result;
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- トリガーの作成
CREATE TRIGGER new_contact_notification
AFTER INSERT ON contact
FOR EACH ROW
EXECUTE FUNCTION notify_new_contact();
通知の確認
ここまでで通知の仕組みは作成できました。
実際にcontactテーブルにデータが挿入されたときにSlackに通知が来るか確認してみましょう。
こんな感じで適当に入力して試してみます。
送信すると少したってSlackに通知が来ました!
参考資料
ローカルでのEdge Functioinsの作成方法:https://supabase.com/docs/guides/functions/quickstart
ローカル開発環境のデプロイ方法:https://supabase.com/docs/guides/functions/deploy
Slack APIのドキュメント:https://api.slack.com/docs
今回のgitリポジトリ:https://github.com/TodoONada/supabase-slack-notify