Send an SMS with Svelte and Twilio Functions

February 24, 2021
Written by
Reviewed by
Diane Phan
Twilion

sveltesms.png

In this article you’ll learn how to send an SMS from your Svelte app. Because Svelte is a client-side framework, you’ll need to have a backend server that can handle sending the message, otherwise your Twilio credentials would be exposed. For this, you’ll create an API using Twilio Functions.

To demonstrate these concepts, you’ll build a Svelte app with a button. When the button is clicked, a POST request will be made to your API. The API will send a message and then return a response back to your Svelte app.

Prerequisites

In order to follow along with this tutorial, you’ll need these tools and technologies:

Create your API with Twilio Functions

Create a new Function Service

Twilio Functions is a serverless environment that lets you deploy backend services without the overhead of setting up a server. Twilio Functions is especially convenient because it will automatically include your Twilio Account SID and Auth Token as environment variables out of the gate.

In order to create an API with Twilio Functions, you have to first create a Function Service. A Service is a collection of functions and resources that create a cohesive development environment.

To get started, navigate to the Functions section of the Twilio Console. Click the Create Service button, and when prompted, give your service the friendly name “svelte-sms” and then click Next.

This will take you to your new Service’s dashboard, where you can create functions as part of your Service.

Click the Add + button toward the top of the screen, as shown below, and then click Add Function. This will create a new function. Change the path name of your new function to /sms.

Screenshot of Twilio Functions Service Dashboard with Add button circled in red

Write your Function

After a moment, you’ll see a new tab open in the editor on the right side of your screen. This is where you can edit your function. Delete all the boilerplate code inside.

Copy and paste the following code into the editor to create a shell for your function:

exports.handler = async function(context, event, callback) {
};

This creates a new async function with three parameters: context, event, and callback. context is an object that gives you access to the Twilio Node.js helper library. The event object is used to access any request data.

Inside your function, add the following two variables, as shown in the highlighted lines:


exports.handler = async function(context, event, callback) {
  const twilioClient = context.getTwilioClient();
  
  const messageDetails = {
    body: "Ahoy, Svelte developer!",
    to: "+YOUR_PERSONAL_NUMBER",
    from: "+YOUR_TWILIO_NUMBER"
  }
};

In the code above, twilioClient is an instance of the Twilio Node.js REST Client, and messageDetails is an object that includes import details about the SMS message you’re going to send:

  • body is the content of the message
  • to is your personal phone number - be sure to use E.164 formatting
  • from is your Twilio phone number

Be sure to change the placeholder values for both phone numbers in the code above before moving on.

Because your Svelte app is not running on the same domain as your Twilio Function, you’ll need to enable CORS to send a response back to your Svelte app. Beneath the messageDetails variable, inside your function, add the following code:

  const response = new Twilio.Response();
  
  const headers = {
    "Access-Control-Allow-Origin": "http://localhost:5000",
    "Access-Control-Allow-Methods": "GET,PUT,POST,DELETE,OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type",
    "Content-Type": "application/json"
  };
        
  response.setHeaders(headers);

Now you’ll add the code to send your message. Beneath the existing code, still within your function, add the following:

  try {
    const message = await twilioClient.messages.create(messageDetails);
    response.setBody({
      status: `Your message was sent successfully with SID: ${message.sid}`
    });
    return callback(null, response);
  } catch(error) {
    response.setBody({
      status: error
    });
    return callback(response);
  }

This code uses the Twilio Client to send the message and then returns a response with either a success message or an error.

Click the Save button beneath the editor.

Along the left hand menu of your Function Service dashboard, look under the Settings heading for Environment Variables. Click Environment Variables and make sure the checkbox is checked next to the line that says “Add my Twilio Credentials (ACCOUNT_SID) and (AUTH_TOKEN) to ENV”. This will ensure that twilioClient will be initialized correctly with your credentials.

Screenshot showing checked box on environment variables settings screen

Before deploying, click the drop down next to your function’s path name under the Functions heading and select “Public”.

Then, to the right of the drop down, click the three vertical dots and then click Copy URL. This URL is the endpoint you’ll make a POST request to in your Svelte app.

Screenshot showing function service dashboard with vertical dots and drop down menu circled

Store this URL in a handy location for now. It should look like this:

https://svelte-sms-XXXX.twil.io/sms

To finish your API, click Deploy All at the bottom of the screen.

With this approach, your Twilio Function is not secure. That's okay for demonstration purposes, but this is not recommended for any real-life application. If you're using a public Twilio Function, secure it using a passcode or another method. 

Create your Svelte app

Scaffold the app

Now it’s time to switch gears and create your Svelte app. Open up a new terminal window. Run the following commands to clone a basic Svelte app template that you’ll use as a starting point for your app:

npx degit sveltejs/template svelte-sms

Change directory in your new svelte-sms folder, and install the necessary dependencies:

cd svelte-sms
npm install

Add your HTML and CSS

Once that’s done, open the svelte-sms/src folder and look for a file called App.svelte. Open this file in your favorite text editor and delete everything inside. This file will house the code for the only component in your Svelte project, App, which in this case is the button.

In Svelte, you write the HTML, CSS, and JavaScript for your component all in one file.

Copy and paste the following code to create a <button> element and add some styles to it:

<button>Click me to send a message!</button>

<style>
  button {
    background-color: #000000;
    color: white;
  }
</style>

Save your file.

Head to your terminal and run the following command to start your local server:

npm run dev

Once your server starts, visit http:localhost:5000 in your browser to see your app so far.

Screenshot of svelte app running in the browser

Add your JavaScript

Back in App.svelte, add some empty <script> tags above everything you’ve written so far:

<script>

</script>

…

You’ll make your POST request to your API from inside these <script> tags. Grab that URL you saved for your /sms API endpoint (something like https://svelte-sms-XXXX.twil.io/sms); you’ll use it now.

Inside your <script> tags, add the following code:


let status = '';

const handleClick = async () => {
  const response = await fetch('https://svelte-sms-XXXX.twil.io/sms');
  const data = await response.json();
  status = data.status;
}

This code creates a piece of state called status with an initial value of an empty string. This state will be updated after the POST request, and it will be used to display a message to the user letting them know whether the message was sent successfully or not.

This code also creates an async function called handleClick(). This function will be called when the <button> is clicked, and this is where your POST request is made (see highlighted line 4). Be sure to change the URL in the fetch() method to reflect your actual endpoint.

Connect your HTML and JavaScript

With your click handler in place, it’s time to let the <button> element know how to respond when it’s clicked. You do this with Svelte’s on: directive.

Edit your <button> element so it looks like this:

<button on:click={handleClick}>Click me to send a message!</button>

And then, right below your <button> element, add a <div> element for the status state:


<button on:click={handleClick}>Click me to send a message!</button>
<div>{status}</div>

Save your file.

Test your work

Restart your server if needed and head back to your browser. Click the button. In a few moments, you’ll receive an SMS on your personal phone number that says “Ahoy, Svelte developer!”

The UI on your Svelte app will also update to show a success status that includes the SID of the message that was sent:

Screenshot of Svelte app showing success message to user

Conclusion

If you’re going to use Twilio to send an SMS from a JavaScript framework, it’s very important that you create an API in order to protect your Twilio credentials. I hope you enjoyed this demonstration of how you can do that in your Svelte app using Twilio Functions.

If you’re new to Svelte, or want to learn more about it, check out this post comparing the basics of Svelte and React.

Ashley is a JavaScript Editor for the Twilio blog. To work with her and bring your technical stories to Twilio, find her at @ahl389 on Twitter. If you can’t find her there, she’s probably on a patio somewhere having a cup of coffee (or glass of wine, depending on the time).