Method 4) Custom method
This method allows you provide a callback using which you can send SMSs however you like. The input to the callback will be SMS template variables, so you can freely create the content of the SMS as well. Use this method if you are:
- Using a third party SMS service that is not Twilio.
- You want to use another delivery methog like Whatsapp or FB Messenger.
- You want to do some custom spam protection before sending the SMS.
- You already have an SMS sending infrastructure and want to use that.
- NodeJS
- GoLang
- Python
- Other Frameworks
Important
For other backend frameworks, you can follow our guide on how to spin up a separate server configured with the SuperTokens backend SDK to authenticate requests and issue session tokens.
import supertokens from "supertokens-node";
import Passwordless from "supertokens-node/recipe/passwordless";
import Session from "supertokens-node/recipe/session";
supertokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
Passwordless.init({
smsDelivery: {
override: (originalImplementation) => {
return {
...originalImplementation,
sendSms: async function ({
codeLifetime, // amount of time the code is alive for (in MS)
phoneNumber,
urlWithLinkCode, // magic link
userInputCode, // OTP
}) {
// TODO: create and send SMS
}
}
}
},
}),
Session.init()
]
});
import (
"fmt"
"github.com/supertokens/supertokens-golang/ingredients/smsdelivery"
"github.com/supertokens/supertokens-golang/recipe/passwordless"
"github.com/supertokens/supertokens-golang/recipe/passwordless/plessmodels"
"github.com/supertokens/supertokens-golang/supertokens"
)
func main() {
supertokens.Init(supertokens.TypeInput{
RecipeList: []supertokens.Recipe{
passwordless.Init(plessmodels.TypeInput{
SmsDelivery: &smsdelivery.TypeInput{
Override: func(originalImplementation smsdelivery.SmsDeliveryInterface) smsdelivery.SmsDeliveryInterface {
(*originalImplementation.SendSms) = func(input smsdelivery.SmsType, userContext supertokens.UserContext) error {
// amount of time the code is alive for (in MS)
codeLifetime := input.PasswordlessLogin.CodeLifetime
phoneNumber := input.PasswordlessLogin.PhoneNumber
// magic link
urlWithLinkCode := input.PasswordlessLogin.UrlWithLinkCode
// OTP
userInputCode := input.PasswordlessLogin.UserInputCode
fmt.Println(codeLifetime)
fmt.Println(phoneNumber)
fmt.Println(urlWithLinkCode)
fmt.Println(userInputCode)
// TODO: create and send SMS
return nil
}
return originalImplementation
},
},
}),
},
})
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe.passwordless.types import SMSDeliveryOverrideInput, SMSTemplateVars
from supertokens_python.recipe import passwordless
from typing import Dict, Any
from supertokens_python.ingredients.smsdelivery.types import SMSDeliveryConfig
def custom_sms_deliver(original_implementation: SMSDeliveryOverrideInput) -> SMSDeliveryOverrideInput:
async def send_sms(template_vars: SMSTemplateVars, user_context: Dict[str, Any]) -> None:
# amount of time the code is alive for (in MS)
_ = template_vars.code_life_time
__ = template_vars.phone_number
___ = template_vars.url_with_link_code # magic link
____ = template_vars.user_input_code # OTP
# TODO: create and send SMS...
original_implementation.send_sms = send_sms
return original_implementation
init(
app_info=InputAppInfo(
api_domain="...", app_name="...", website_domain="..."),
framework='...',
recipe_list=[
passwordless.init(
sms_delivery=SMSDeliveryConfig(override=custom_sms_deliver)
)
]
)
If you call the original implementation function for sendSms
, it will use the service that you have configured. If you have not configured any service, it will use the default service.
important
When using this callback, you must manage sending the SMS yourself.