Skip to content

get-convex/twilio

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Convex Twilio Component

Send and receive SMS messages in your Convex app using Twilio.

Prerequisites

Twilio Phone Number

Create a Twilio account and, if you haven't already, create a Twilio Phone Number.

Note the Phone Number SID of the phone number you'll be using, you'll need it in a moment.

Convex App

You'll need a Convex App to use the component. Follow any of the Convex quickstarts to set one up.

Installation

Install the component package:

npm install @convex-dev/twilio

Create a convex.config.ts file in your app's convex/ folder and install the component by calling use:

// convex/convex.config.js import { defineApp } from "convex/server"; import twilio from "@convex-dev/twilio/convex.config.js"; const app = defineApp(); app.use(twilio); export default app;

Set your API credentials:

npx convex env set TWILIO_ACCOUNT_SID=ACxxxxx npx convex env set TWILIO_AUTH_TOKEN=xxxxx

Instantiate a Twilio Component client in a file in your app's convex/ folder:

// convex/example.ts import Twilio from "@convex-dev/twilio"; import { components } from "./_generated/server.js"; const twilio = twilioClient(components.twilio, { // optionally pass in the default "from" phone number you'll be using // this must be a phone number you've created with Twilio default_from: process.env.TWILIO_PHONE_NUMBER!, }); // export to be used everywhere in your /convex code export default twilio;

Register Twilio webhook handlers by creating an http.ts file in your convex/ folder and use the client you've exported above:

Or, if you already have an http router:

// http.ts import twilio from "./example"; import { httpRouter } from "convex/server"; const http = httpRouter(); twilio.registerRoutes(http); export default http;

This will register two webhook HTTP handlers in your your Convex app's deployment:

  • YOUR_CONVEX_SITE_URL/twilio/message-status - capture and store delivery status of messages you send.
  • YOUR_CONVEX_SITE_URL/twilio/incoming-message - capture and store messages sent to your Twilio phone number.

Note: if you want to route twilio endpoints somewhere else, pass a custom http_prefix

Sending Messages

To send a message use the Convex action sendMessage exposed by the client, for example:

// convex/messages.ts import { v } from "convex/values"; import { internalAction } from "./_generated/server"; import twilio from "./twilio"; export const sendSms = internalAction({ args: { to: v.string(), body: v.string(), }, handler: async (ctx, args) => { return await twilio.sendMessage(ctx, args); }, });

By querying the message (see below) you can check for the status (Twilio Statuses). The component subscribes to status updates and writes the most up-to-date status into the database.

Receiving Messages

To receive messages, you will associate a webhook handler provided by the component with the Twilio phone number you'd like to use. The webhook handler is mounted at

YOUR_CONVEX_SITE_URL/incoming-message 

You can associate it with your Twilio phone number in two ways:

  1. Using the Twilio console in the "Configure" tab of the phone number, under "Messaging Configuration" -> "A messsage comes in" -> "URL".

  2. By calling registerIncomingSmsHandler exposed by the component client, passing it the phone number's SID:

// convex/messages.ts // ... export const registerIncomingSmsHandler = internalAction({ args: {}, handler: async (ctx) => { return await twilio.registerIncomingSmsHandler(ctx, { sid: "YOUR_TWILIO_PHONE_NUMBER_SID", }); }, });

Now, incoming messages will be captured by the component and logged in the messages table.

You can execute your own logic upon receiving an incoming message, by providing a callback when instantiating the Twilio Component client:

// convex/example.ts const twilio = twilioClient(components.twilio, { default_from: process.env.TWILIO_PHONE_NUMBER || "", incomingMessageCallback: async (ctx, message) => { // use ctx here to execute other Convex functions console.log("Incoming message", message); } });

Querying Messages

To list all the mssages, use the list method in your Convex function.

To list all the incoming or outgoing messages, use listIncoming and listOutgoing methods:

// convex/messages.ts // ... export const list = query({ args: {}, handler: async (ctx) => { return await twilio.list(ctx); }, }); export const listIncoming = query({ args: {}, handler: async (ctx) => { return await twilio.listIncoming(ctx); }, }); export const listOutgoing = query({ args: {}, handler: async (ctx) => { return await twilio.listOutgoing(ctx); }, });

To get a single message by its sid, use getMessageBySid:

export const getMessageBySid = query({ args: { sid: v.string(), }, handler: async (ctx, args) => { return await twilio.getMessageBySid(ctx, args); } })

Get messages by the "to" phone number:

export const getMessagesTo = query({ args: { to: v.string(), }, handler: async (ctx, args) => { return await twilio.getMessagesTo(ctx, args); } })

Get messages by the "from" phone number:

export const getMessagesFrom = query({ args: { from: v.string(), }, handler: async (ctx, args) => { return await twilio.getMessagesFrom(ctx, args); } })

You can also get all messages to and from a particular number:

export const getMessagesByCounterparty = query({ args: { from: v.string(), }, handler: async (ctx, args) => { return await twilio.getMessagesByCounterparty(ctx, args); } })

About

Convex component for sending/receiving SMS messages with Twilio

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 5