Method 3) Custom method
This method allows you provide a callback using which you can send emails however you like. The input to the callback will be email template variables, so you can freely design the email as well. Use this method if you are:
- Using a third party email service like Mailchimp.
- You want to do some custom spam protection before sending the email.
- You already have an email sending infrastructure and want to use that.
- NodeJS
- GoLang
- Python
import supertokens from "supertokens-node";
import ThirdPartyPasswordless from "supertokens-node/recipe/thirdpartypasswordless";
import Session from "supertokens-node/recipe/session";
import EmailVerification from "supertokens-node/recipe/emailverification"
supertokens.init({
    appInfo: {
        apiDomain: "...",
        appName: "...",
        websiteDomain: "..."
    },
    recipeList: [
        ThirdPartyPasswordless.init({
            emailDelivery: {
                override: (originalImplementation) => {
                    return {
                        ...originalImplementation,
                        sendEmail: async function (input) {
                            let {
                                codeLifetime, // amount of time the code is alive for (in MS)
                                email,
                                urlWithLinkCode, // magic link
                                userInputCode, // OTP
                            } = input;
                            // TODO: create and send email
                        }
                    }
                }
            },
        }),
        // if email verification is enabled
        EmailVerification.init({
            emailDelivery: {
                override: (originalImplementation) => {
                    return {
                        ...originalImplementation,
                        sendEmail: async function (input) {
                            // TODO: create and send email verification email
                            // Or use the original implementation which calls the default service,
                            // or a service that you may have specified in the emailDelivery object.
                            return originalImplementation.sendEmail(input);
                        }
                    }
                }
            },
        }),
        Session.init()
    ]
});
import (
    "fmt"
    "github.com/supertokens/supertokens-golang/ingredients/emaildelivery"
    "github.com/supertokens/supertokens-golang/recipe/emailverification"
    "github.com/supertokens/supertokens-golang/recipe/emailverification/evmodels"
    "github.com/supertokens/supertokens-golang/recipe/thirdpartypasswordless"
    "github.com/supertokens/supertokens-golang/recipe/thirdpartypasswordless/tplmodels"
    "github.com/supertokens/supertokens-golang/supertokens"
)
func main() {
    supertokens.Init(supertokens.TypeInput{
        RecipeList: []supertokens.Recipe{
            thirdpartypasswordless.Init(tplmodels.TypeInput{
                EmailDelivery: &emaildelivery.TypeInput{
                    Override: func(originalImplementation emaildelivery.EmailDeliveryInterface) emaildelivery.EmailDeliveryInterface {
                        (*originalImplementation.SendEmail) = func(input emaildelivery.EmailType, userContext supertokens.UserContext) error {
                            // amount of time the code is alive for (in MS)
                            codeLifetime := input.PasswordlessLogin.CodeLifetime
                            email := input.PasswordlessLogin.Email
                            // magic link
                            urlWithLinkCode := input.PasswordlessLogin.UrlWithLinkCode
                            // OTP
                            userInputCode := input.PasswordlessLogin.UserInputCode
                            fmt.Println(codeLifetime)
                            fmt.Println(email)
                            fmt.Println(urlWithLinkCode)
                            fmt.Println(userInputCode)
                            // TODO: create and send email
                            return nil
                        }
                        return originalImplementation
                    },
                },
            }),
            // if email verification is enabled
            emailverification.Init(evmodels.TypeInput{
                Mode: evmodels.ModeRequired,
                EmailDelivery: &emaildelivery.TypeInput{
                    Override: func(originalImplementation emaildelivery.EmailDeliveryInterface) emaildelivery.EmailDeliveryInterface {
                        originalSendEmail := *originalImplementation.SendEmail
                        (*originalImplementation.SendEmail) = func(input emaildelivery.EmailType, userContext supertokens.UserContext) error {
                            // TODO: create and email verification email
                            // Or use the original implementation which calls the default service,
                            // or a service that you may have specified in the EmailDelivery object.
                            return originalSendEmail(input, userContext)
                        }
                        return originalImplementation
                    },
                },
            }),
        },
    })
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe.thirdpartypasswordless.types import EmailDeliveryOverrideInput, EmailTemplateVars
from supertokens_python.recipe import thirdpartypasswordless
from typing import Dict, Any
from supertokens_python.ingredients.emaildelivery.types import EmailDeliveryConfig
from supertokens_python.recipe.emailverification.types import EmailDeliveryOverrideInput as EVEmailDeliveryOverrideInput, EmailTemplateVars as EVEmailTemplateVars
from supertokens_python.recipe import emailverification
def custom_email_deliver(original_implementation: EmailDeliveryOverrideInput) -> EmailDeliveryOverrideInput:
    original_send_email = original_implementation.send_email
    async def send_email(template_vars: EmailTemplateVars, user_context: Dict[str, Any]) -> None:
        # TODO: create and send magic link email
        # Or use the original implementation which calls the default service,
        # or a service that you may have specified in the email_delivery object.
        return await original_send_email(template_vars, user_context)
    
    original_implementation.send_email = send_email
    return original_implementation
def custom_emailverification_delivery(original_implementation: EVEmailDeliveryOverrideInput) -> EVEmailDeliveryOverrideInput:
    original_send_email = original_implementation.send_email
    async def send_email(template_vars: EVEmailTemplateVars, user_context: Dict[str, Any]) -> None:
        # TODO: create and send email verification email
        # Or use the original implementation which calls the default service,
        # or a service that you may have specified in the email_delivery object.
        return await original_send_email(template_vars, user_context)
    original_implementation.send_email = send_email
    return original_implementation
init(
    app_info=InputAppInfo(
        api_domain="...", app_name="...", website_domain="..."),
    framework='...',  
    recipe_list=[
         thirdpartypasswordless.init(
            email_delivery=EmailDeliveryConfig(override=custom_email_deliver)
        ),
        # If email verification is enabled
        emailverification.init(
            mode="OPTIONAL",
            email_delivery=EmailDeliveryConfig(override=custom_emailverification_delivery))
    ]
)
If you call the original implementation function for sendEmail, it will use the service that you have configured. If you have not configured any service, it will use the default service.
So using this method, you can for example, have your custom way of sending email verification emails, but use the default or SMTP service to send the passwordless login emails.
important
When using this callback, you must manage sending the email yourself.