Back to Novu

Twilio SMS Integration with Novu

docs/platform/integrations/sms/twilio.mdx

3.19.015.1 KB
Original Source

You can utilize the Twilio API to communicate with your customers using SMS messaging. Let's look at how you can do that:

Setting up Twilio

<Steps> <Step title="Create a Twilio Account"> 1. Go to [Twilio](https://www.twilio.com/) and create an account, starting with their free trial. 2. You'll be asked to verify your email and your phone number. Get them verified. </Step> <Step title="Get a Twilio Phone Number"> 1. Once verified, you'll get an option to 'get a Twilio phone number' from your Twilio console. 2. Click on it to get your Twilio phone number. <Note> When first using Twilio there should be an option to get a Twilio phone number in the main console. Otherwise, you may have to [Buy](https://console.twilio.com/us1/develop/phone-numbers/manage/search?frameUrl=%2Fconsole%2Fphone-numbers%2Fsearch%3Fx-target-region%3Dus1&currentFrameUrl=%2Fconsole%2Fphone-numbers%2Fsearch%3FisoCountry%3DUS%26searchTerm%3D%26searchFilter%3Dleft%26searchType%3Dnumber%26x-target-region%3Dus1%26__override_layout__%3Dembed%26bifrost%3Dtrue) a number to begin using it. For first-time users, utilize the free number provided. </Note>

For more detailed instructions, follow one of their many Tutorials within their docs.

</Step> <Step title="Understand the Key Components"> Irrespective of the language you use, the process requires:
  1. Account SID and Auth token loaded into the code using secure environment variables
  2. A Twilio client object that takes the SID and Token as variables
  3. A message object containing:
  • Your Twilio phone number
    • The recipient's phone number
    • The SMS message body
</Step> </Steps>

Creating a Twilio integration with Novu

<Steps> <Step title="Connect Twilio to Novu"> 1. Visit the [Integrations Store](https://dashboard.novu.co/integrations) on Novu 2. Click the "Add a provider" button 3. Locate **Twilio** and click on the `Disabled` button and mark it as `Active` 4. Click on the **Connect** button </Step> <Step title="Configure Twilio Credentials"> 1. Go to your [Console](https://console.twilio.com/) on Twilio and access the Account Info section 2. Enter your: - `Account SID` - `Auth Token` - `Twilio Phone Number` - `Data residency region` (optional) — leave as **US (default)** unless your Twilio account uses EU data residency 3. Click on the **Save** button </Step> </Steps>

Multi-region data residency

Twilio supports processing and storing SMS data in specific regions. Novu lets you choose the API region when connecting your Twilio integration.

RegionTwilio regionWhen to use
US (default)US1Existing Twilio accounts and US-based data residency
EU (Ireland)IE1EU data residency for SMS (phone numbers, message bodies, and related personal data processed in Ireland)
<Note> EU data residency requires **IE1-specific credentials** from the Twilio Console and senders configured for the IE1 region. See Twilio's [Messaging API with Twilio Regions](https://www.twilio.com/docs/global-infrastructure/messaging-api-with-twilio-regions) guide for setup details. </Note>

Configure EU data residency

<Steps> <Step title="Create IE1 API credentials"> In the Twilio Console, create API credentials for the **IE1** region. Use those credentials in your Novu Twilio integration instead of your US credentials. </Step> <Step title="Configure senders for IE1"> If you send with phone numbers, set each number's active messaging region to **IE1** in the Twilio Console under **Numbers & Senders**. </Step> <Step title="Select EU in Novu"> When connecting or updating your Twilio integration in Novu, set **Data residency region** to **EU (Ireland)** and save your IE1 credentials. </Step> </Steps>

Sending WhatsApp message

To send WhatsApp messages with Twilio integration, prefix the phone number of the subscriber with whatsapp: as shown below:

<Tabs> <Tab title="Node.js"> ```typescript import { Novu } from '@novu/api';

const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>" });

await novu.trigger({ workflowId: "workflowId", to: { subscriberId: "subscriberId", phone: "whatsapp:+14155238886", }, payload: {}, overrides: { "providers": { "twilio": { "_passthrough": { "body": { "contentSid": "HXb5b62575e6e4ff6129ad7c8efe1f983e", "contentVariables": "{"1":"12/1","2":"3pm"}" } } } } }, });

  </Tab>
  <Tab title="Python">
```python
import os
import novu_py
from novu_py import Novu

with Novu(secret_key=os.getenv("NOVU_SECRET_KEY", "")) as novu:
    novu.trigger(trigger_event_request_dto=novu_py.TriggerEventRequestDto(
        workflow_id="workflowId",
        to={"subscriber_id": "subscriberId", "phone": "whatsapp:+14155238886"},
        payload={},
        overrides={
        "providers": {
                "twilio": {
                        "_passthrough": {
                                "body": {
                                        "contentSid": "HXb5b62575e6e4ff6129ad7c8efe1f983e",
                                        "contentVariables": "{\"1\":\"12/1\",\"2\":\"3pm\"}"
                                }
                        }
                }
        }
},
    ))
</Tab> <Tab title="Go"> ```go import ( "context" "os"
novugo "github.com/novuhq/novu-go"
"github.com/novuhq/novu-go/models/components"

)

s := novugo.New(novugo.WithSecurity(os.Getenv("NOVU_SECRET_KEY")))

res, err := s.Trigger(context.Background(), components.TriggerEventRequestDto{ WorkflowID: "workflowId", To: components.CreateToSubscriberPayloadDto(components.SubscriberPayloadDto{ SubscriberID: "subscriberId", Phone: novugo.String("whatsapp:+14155238886"), }), Payload: map[string]any{}, Overrides: map[string]any{ "providers": { "twilio": { "_passthrough": { "body": { "contentSid": "HXb5b62575e6e4ff6129ad7c8efe1f983e", "contentVariables": "{"1":"12/1","2":"3pm"}" } } } } }, }, nil)

  </Tab>
  <Tab title="PHP">
```php
use novu;
use novu\Models\Components;

$sdk = novu\Novu::builder()->setSecurity('<NOVU_SECRET_KEY>')->build();

$sdk->trigger(
    triggerEventRequestDto: new Components\TriggerEventRequestDto(
        workflowId: 'workflowId',
        to: new Components\SubscriberPayloadDto(subscriberId: 'subscriberId', phone: 'whatsapp:+14155238886'),
        payload: {},
        overrides: {
        "providers": {
                "twilio": {
                        "_passthrough": {
                                "body": {
                                        "contentSid": "HXb5b62575e6e4ff6129ad7c8efe1f983e",
                                        "contentVariables": "{\"1\":\"12/1\",\"2\":\"3pm\"}"
                                }
                        }
                }
        }
},
    ),
);
</Tab> <Tab title=".NET"> ```csharp using Novu; using Novu.Models.Components;

var sdk = new NovuSDK(secretKey: "<NOVU_SECRET_KEY>");

await sdk.TriggerAsync(triggerEventRequestDto: new TriggerEventRequestDto() { WorkflowId = "workflowId", To = To.CreateSubscriberPayloadDto(new SubscriberPayloadDto() { SubscriberId = "subscriberId", Phone = "whatsapp:+14155238886" }), Payload = {}, Overrides = { "providers": { "twilio": { "_passthrough": { "body": { "contentSid": "HXb5b62575e6e4ff6129ad7c8efe1f983e", "contentVariables": "{"1":"12/1","2":"3pm"}" } } } } }, });

  </Tab>
  <Tab title="Java">
```java
import co.novu.Novu;
import co.novu.models.components.*;

Novu novu = Novu.builder().secretKey("<NOVU_SECRET_KEY>").build();

novu.trigger()
    .body(TriggerEventRequestDto.builder()
        .workflowId("workflowId")
        .to(To2.of(SubscriberPayloadDto.builder().subscriberId("subscriberId").phone("whatsapp:+14155238886").build()))
        .payload({})
        .overrides({
        "providers": {
                "twilio": {
                        "_passthrough": {
                                "body": {
                                        "contentSid": "HXb5b62575e6e4ff6129ad7c8efe1f983e",
                                        "contentVariables": "{\"1\":\"12/1\",\"2\":\"3pm\"}"
                                }
                        }
                }
        }
})
        .build())
    .call();
</Tab> <Tab title="cURL"> ```bash curl --location 'https://api.novu.co/v1/events/trigger' \ --header 'Content-Type: application/json' \ --header 'Authorization: ApiKey <NOVU_SECRET_KEY>' \ -d '{ "name": "workflowId", "to": { "subscriberId": "subscriberId", "phone": "whatsapp:+14155238886" }, "payload": {}, "overrides": { "providers": { "twilio": { "_passthrough": { "body": { "contentSid": "HXb5b62575e6e4ff6129ad7c8efe1f983e", "contentVariables": "{\"1\":\"12/1\",\"2\":\"3pm\"}" } } } } } }' ``` </Tab> </Tabs>

Sending WhatsApp template message

To send WhatsApp template messages with Twilio integration, you can use the template field in the overrides object.

<Tabs> <Tab title="Node.js"> ```typescript import { Novu } from "@novu/api";

const novu = new Novu({ secretKey: "<NOVU_SECRET_KEY>", // Required if using EU region // serverURL: "https://eu.api.novu.co", });

await novu.trigger({ workflowId: "workflowId", to: { subscriberId: "subscriberId", phone: "whatsapp:+14155238886", }, payload: {}, overrides: { providers: { twilio: { "_passthrough": { "body": { "contentSid": "HXb5b62575e6e4ff6129ad7c8efe1f983e", "contentVariables": "{"1":"12/1","2":"3pm"}" } } } } } });

  </Tab>
  <Tab title="Python">
```python
import os
import novu_py
from novu_py import Novu

with Novu(secret_key=os.getenv("NOVU_SECRET_KEY", "")) as novu:
    novu.trigger(trigger_event_request_dto=novu_py.TriggerEventRequestDto(
        workflow_id="workflowId",
        to={"subscriber_id": "subscriberId", "phone": "whatsapp:+14155238886"},
        payload={},
        overrides={
            "providers": {
                "twilio": {
                    "_passthrough": {
                        "body": {
                            "contentSid": "HXb5b62575e6e4ff6129ad7c8efe1f983e",
                            "contentVariables": "{\"1\":\"12/1\",\"2\":\"3pm\"}"
                        }
                    }
                }
            }
        },
    ))
</Tab> <Tab title="Go"> ```go import ( "context" "os"
novugo "github.com/novuhq/novu-go"
"github.com/novuhq/novu-go/models/components"

)

s := novugo.New(novugo.WithSecurity(os.Getenv("NOVU_SECRET_KEY")))

res, err := s.Trigger(context.Background(), components.TriggerEventRequestDto{ WorkflowID: "workflowId", To: components.CreateToSubscriberPayloadDto(components.SubscriberPayloadDto{ SubscriberID: "subscriberId", Phone: novugo.String("whatsapp:+14155238886"), }), Payload: map[string]any{}, Overrides: map[string]any{ "providers": map[string]any{ "twilio": map[string]any{ "_passthrough": map[string]any{ "body": map[string]any{ "contentSid": "HXb5b62575e6e4ff6129ad7c8efe1f983e", "contentVariables": "{"1":"12/1","2":"3pm"}", }, }, }, }, }, }, nil)

  </Tab>
  <Tab title="PHP">
```php
use novu;
use novu\Models\Components;

$sdk = novu\Novu::builder()->setSecurity('<NOVU_SECRET_KEY>')->build();

$sdk->trigger(
    triggerEventRequestDto: new Components\TriggerEventRequestDto(
        workflowId: 'workflowId',
        to: new Components\SubscriberPayloadDto(subscriberId: 'subscriberId', phone: 'whatsapp:+14155238886'),
        payload: [],
        overrides: [
            'providers' => [
                'twilio' => [
                    '_passthrough' => [
                        'body' => [
                            'contentSid' => 'HXb5b62575e6e4ff6129ad7c8efe1f983e',
                            'contentVariables' => '{"1":"12/1","2":"3pm"}',
                        ],
                    ],
                ],
            ],
        ],
    ),
);
</Tab> <Tab title=".NET"> ```csharp using Novu; using Novu.Models.Components; using System.Collections.Generic;

var sdk = new NovuSDK(secretKey: "<NOVU_SECRET_KEY>");

await sdk.TriggerAsync(triggerEventRequestDto: new TriggerEventRequestDto() { WorkflowId = "workflowId", To = To.CreateSubscriberPayloadDto(new SubscriberPayloadDto() { SubscriberId = "subscriberId", Phone = "whatsapp:+14155238886" }), Payload = new Dictionary<string, object>(), Overrides = new Overrides() { Providers = new Dictionary<string, Dictionary<string, object>>() { { "twilio", new Dictionary<string, object>() { { "_passthrough", new Dictionary<string, object>() { { "body", new Dictionary<string, object>() { { "contentSid", "HXb5b62575e6e4ff6129ad7c8efe1f983e" }, { "contentVariables", "{"1":"12/1","2":"3pm"}" }, } }, } }, } }, }, }, });

  </Tab>
  <Tab title="Java">
```java
import co.novu.Novu;
import co.novu.models.components.*;
import java.util.Map;

Novu novu = Novu.builder().secretKey("<NOVU_SECRET_KEY>").build();

novu.trigger()
    .body(TriggerEventRequestDto.builder()
        .workflowId("workflowId")
        .to(To2.of(SubscriberPayloadDto.builder().subscriberId("subscriberId").phone("whatsapp:+14155238886").build()))
        .overrides(TriggerEventRequestDtoOverrides.builder()
            .additionalProperties(Map.of("providers", Map.of("twilio", Map.of(
                "_passthrough", Map.of("body", Map.of(
                    "contentSid", "HXb5b62575e6e4ff6129ad7c8efe1f983e",
                    "contentVariables", "{\"1\":\"12/1\",\"2\":\"3pm\"}"
                ))
            ))))
            .build())
        .build())
    .call();
</Tab> <Tab title="cURL"> ```bash curl --location 'https://api.novu.co/v1/events/trigger' \ --header 'Content-Type: application/json' \ --header 'Authorization: ApiKey <NOVU_SECRET_KEY>' \ -d '{ "name": "workflowId", "to": { "subscriberId": "subscriberId", "phone": "whatsapp:+14155238886" }, "payload": {}, "overrides": { "providers": { "twilio": { "_passthrough": { "body": { "contentSid": "HXb5b62575e6e4ff6129ad7c8efe1f983e", "contentVariables": "{\"1\":\"12/1\",\"2\":\"3pm\"}" } } } } } }' ``` </Tab> </Tabs> <Note> Read more about [sending a Message with the Twilio API for WhatsApp](https://www.twilio.com/docs/whatsapp/tutorial). </Note>