Send Email Hook
Use a custom email provider to send authentication messages
The Send Email Hook runs before an email is sent and allows for flexibility around email sending. You can use this hook to configure a back-up email provider or add internationalization to your emails.
Email sending behavior
Email sending depends on two settings: Email Provider and Auth Hook status.
Email Provider | Auth Hook | Result |
---|---|---|
Enabled | Enabled | Auth Hook handles email sending (SMTP not used) |
Enabled | Disabled | SMTP handles email sending (custom if configured, default otherwise) |
Disabled | Enabled | Email Signups Disabled |
Disabled | Disabled | Email Signups Disabled |
Inputs
Field | Type | Description |
---|---|---|
user | User | The user attempting to sign in. |
email | object | Metadata specific to the email sending process. Includes the OTP and token_hash . |
_49{_49 "user": {_49 "id": "8484b834-f29e-4af2-bf42-80644d154f76",_49 "aud": "authenticated",_49 "role": "authenticated",_49 "email": "valid.email@supabase.io",_49 "phone": "",_49 "app_metadata": {_49 "provider": "email",_49 "providers": ["email"]_49 },_49 "user_metadata": {_49 "email": "valid.email@supabase.io",_49 "email_verified": false,_49 "phone_verified": false,_49 "sub": "8484b834-f29e-4af2-bf42-80644d154f76"_49 },_49 "identities": [_49 {_49 "identity_id": "bc26d70b-517d-4826-bce4-413a5ff257e7",_49 "id": "8484b834-f29e-4af2-bf42-80644d154f76",_49 "user_id": "8484b834-f29e-4af2-bf42-80644d154f76",_49 "identity_data": {_49 "email": "valid.email@supabase.io",_49 "email_verified": false,_49 "phone_verified": false,_49 "sub": "8484b834-f29e-4af2-bf42-80644d154f76"_49 },_49 "provider": "email",_49 "last_sign_in_at": "2024-05-14T12:56:33.824231484Z",_49 "created_at": "2024-05-14T12:56:33.824261Z",_49 "updated_at": "2024-05-14T12:56:33.824261Z",_49 "email": "valid.email@supabase.io"_49 }_49 ],_49 "created_at": "2024-05-14T12:56:33.821567Z",_49 "updated_at": "2024-05-14T12:56:33.825595Z",_49 "is_anonymous": false_49 },_49 "email_data": {_49 "token": "305805",_49 "token_hash": "7d5b7b1964cf5d388340a7f04f1dbb5eeb6c7b52ef8270e1737a58d0",_49 "redirect_to": "http://localhost:3000/",_49 "email_action_type": "signup",_49 "site_url": "http://localhost:9999",_49 "token_new": "",_49 "token_hash_new": ""_49 }_49}
Outputs
- No outputs are required. An empty response with a status code of 200 is taken as a successful response.
You can configure Resend as the custom email provider through the "Send Email" hook. This allows you to take advantage of Resend's developer-friendly APIs to send emails and leverage React Email for managing your email templates. For a more advanced React Email tutorial, refer to this guide.
If you want to send emails through the Supabase Resend integration, which uses Resend's SMTP server, check out this integration instead.
Create a .env
file with the following environment variables:
_10RESEND_API_KEY=your_resend_api_key_10SEND_EMAIL_HOOK_SECRET=<base64_secret>
You can generate the secret in the Auth Hooks section of the Supabase dashboard. Make sure to remove the v1,whsec_
prefix!
Set the secrets in your Supabase project:
_10supabase secrets set --env-file .env
Create a new edge function:
_10supabase functions new send-email
Add the following code to your edge function:
_61import { Webhook } from "https://esm.sh/standardwebhooks@1.0.0";_61import { Resend } from "npm:resend";_61_61const resend = new Resend(Deno.env.get("RESEND_API_KEY") as string);_61const hookSecret = Deno.env.get("SEND_EMAIL_HOOK_SECRET") as string;_61_61Deno.serve(async (req) => {_61 if (req.method !== "POST") {_61 return new Response("not allowed", { status: 400 });_61 }_61_61 const payload = await req.text();_61 const headers = Object.fromEntries(req.headers);_61 const wh = new Webhook(hookSecret);_61 try {_61 const { user, email_data } = wh.verify(payload, headers) as {_61 user: {_61 email: string;_61 };_61 email_data: {_61 token: string;_61 token_hash: string;_61 redirect_to: string;_61 email_action_type: string;_61 site_url: string;_61 token_new: string;_61 token_hash_new: string;_61 };_61 };_61_61 const { error } = await resend.emails.send({_61 from: "welcome <onboarding@example.com>",_61 to: [user.email],_61 subject: "Welcome to my site!",_61 text: `Confirm you signup with this code: ${email_data.token}`,_61 });_61 if (error) {_61 throw error;_61 }_61 } catch (error) {_61 return new Response(_61 JSON.stringify({_61 error: {_61 http_code: error.code,_61 message: error.message,_61 },_61 }),_61 {_61 status: 401,_61 headers: { "Content-Type": "application/json" },_61 },_61 );_61 }_61_61 const responseHeaders = new Headers();_61 responseHeaders.set("Content-Type", "application/json");_61 return new Response(JSON.stringify({}), {_61 status: 200,_61 headers: responseHeaders,_61 });_61});
Deploy your edge function and configure it as a hook:
_10supabase functions deploy send-email --no-verify-jwt