# Receive an inbound SMS

When someone sends a text message to your Twilio number, Twilio can invoke a **webhook** that you've created to determine what reply to send back using **[TwiML](/docs/messaging/twiml)**. This page provides examples of Functions that can serve as the webhook for your Twilio number.

A Function that responds to webhook requests will receive details about the incoming message as properties on the `event` parameter. These include the incoming number (`event.From`), the recipient number (`event.To`), and the text body of the message (`event.Body`). Other relevant data include the number of media sent and geographic metadata about the phone numbers involved. You can view a full list of potential values at [Twilio Request to your Webhook URL](/docs/messaging/guides/webhook-request).

After a Function is invoked by an inbound SMS, you can take any number of actions. The following examples can serve as a starting point for your implementation.

## Create and host a Function

Before you run any of the examples on this page, create a Function and paste the example code into it. You can create a Function in the Twilio Console or by using the [Serverless Toolkit](/docs/labs/serverless-toolkit).

## Console

If you prefer a UI-driven approach, complete these steps in the Twilio Console:

1. Log in to the [Twilio Console](https://1console.twilio.com) and navigate to **Develop > Functions & Assets**. If you're using the *legacy* Console, open the [**Functions** tab](https://www.twilio.com/console/functions/overview).
2. Functions are contained within **Services**. Click **[Create Service](https://www.twilio.com/console/functions/overview/services)** to create a new **[Service](/docs/serverless/functions-assets/functions/create-service)**.
3. Click **Add +** and select **Add Function** from the dropdown.
4. The Console creates a new [protected](/docs/serverless/functions-assets/visibility) Function that you can rename. The filename becomes the URL path of the Function.
5. Copy one of the example code snippets from this page and paste the code into your newly created Function. You can switch examples by using the dropdown menu in the code rail.
6. Click **Save**.
7. Click **Deploy All** to build and deploy the Function. After deployment, you can access your Function at `https://<service-name>-<random-characters>-<optional-domain-suffix>.twil.io/<function-path>`\
   For example: `test-function-3548.twil.io/hello-world`.

## Serverless Toolkit

The [Serverless Toolkit](/docs/labs/serverless-toolkit) lets you develop locally, deploy projects, and perform other tasks through the [Twilio CLI](/docs/twilio-cli/quickstart).

1. From the CLI, run `twilio serverless:init <YOUR-SERVICE-NAME> --empty` to bootstrap your local environment.
2. Go to your new project directory using `cd <YOUR-SERVICE-NAME>`.
3. In the `/functions` directory, create a JavaScript file whose name reflects the purpose of the Function. For example, `sms-reply.protected.js` for a [protected](/docs/serverless/functions-assets/visibility) Function intended to handle incoming SMS.
4. Add the code example of your choice to the file and save it. Note that a Function can only export a single handler. You need to create separate files to run or deploy multiple examples at once.

After you save the Function code, you can test it locally (and optionally tunnel requests to it using a tool like [ngrok](https://ngrok.com/)), or deploy it.

### Run your Function in local development

Run `twilio serverless:start` from your CLI to start the project locally. The Function(s) in your project are accessible from `http://localhost:3000/sms-reply`

* If you want to test a Function as a [Twilio webhook](/docs/usage/webhooks/getting-started-twilio-webhooks), run: `twilio phone-numbers:update <your Twilio phone number> --sms-url "http://localhost:3000/sms-reply"`\
  This automatically generates an ngrok tunnel from Twilio to your locally running Function, so you can start sending texts to it. You can apply the same process but with the `voice-url` flag instead to test with [Twilio Voice](/docs/voice).
* If your code does *not* connect to Twilio Voice or Messages as a webhook, start your dev server and start an ngrok tunnel in the same command with the `ngrok` flag. For example: `twilio serverless:start --ngrok=""`

### Deploy your Function

To deploy your Function and have access to live url(s), run `twilio serverless:deploy` from your CLI. This deploys your Function(s) to Twilio under a development Environment by default, where they can be accessed from:

`https://<service-name>-<random-characters>-dev.twil.io/<function-path>`

For example: `https://incoming-sms-examples-3421-dev.twil.io/sms-reply`

You can now invoke your Function with HTTP requests, configure it as the [webhook](/docs/usage/webhooks/getting-started-twilio-webhooks) for a Twilio phone number, call it from a Twilio Studio [**Run Function** Widget](/docs/studio/widget-library/run-function), and more.

## Set a Function as a webhook

For your Function to react to incoming SMS or voice calls, it must be set as a [webhook](/docs/usage/webhooks) for your Twilio number. There are a variety of methods to set a Function as a webhook:

![Setting a Function as a Messaging webhook using the webhook dropdown option.](https://docs-resources.prod.twilio.com/bf4eae4ac40fe7d47003a93bca295d5c232e0b372358e73ceff931fee3ccdc4f.png)

## Respond with a static message

For the simplest example, you can reply to the incoming SMS with a hard-coded message. To do so, you can create a new `MessagingResponse` and declare the intended message contents. Once your message content has been set, you can return the generated TwiML by passing it to the `callback` function as shown and signaling a successful end to the Function.

```js title="Respond to an inbound SMS"
exports.handler = (context, event, callback) => {
  // Create a new messaging response object
  const twiml = new Twilio.twiml.MessagingResponse();
  // Use any of the Node.js SDK methods, such as `message`, to compose a response
  twiml.message('Hello, World!');
  // Return the TwiML as the second argument to `callback`
  // This will render the response as XML in reply to the webhook request
  return callback(null, twiml);
};
```

## Respond dynamically to an inbound SMS

Because you can access the incoming message text from `event.Body`, you can tailor the response based on that text. For example, you could respond with "Hello, there!" to an incoming message that includes the text "hello". You could say "Goodbye" to any message including "bye". You can have a fallback response if neither of those conditions is met.

```js title="Dynamically respond to an inbound SMS"
exports.handler = (context, event, callback) => {
  // Create a new messaging response object
  const twiml = new Twilio.twiml.MessagingResponse();

  // Access the incoming text content from `event.Body`
  const incomingMessage = event.Body.toLowerCase();

  // Use any of the Node.js SDK methods, such as `message`, to compose a response
  if (incomingMessage.includes('hello')) {
    twiml.message('Hello, there!');
  } else if (incomingMessage.includes('bye')) {
    twiml.message('Goodbye!');
  } else {
    twiml.message('Not sure what you meant! Please say hello or bye!');
  }

  // Return the TwiML as the second argument to `callback`
  // This will render the response as XML in reply to the webhook request
  return callback(null, twiml);
};
```

## Forward an inbound SMS

Another example uses additional `event` properties to forward SMS messages from your Twilio phone number to your personal phone. Use this approach when you don't want to share your personal number, such as when selling an item online or interacting with unknown contacts.

This Function will accept an incoming SMS and generate a TwiML response that contains the number that sent the message followed by the contents of the SMS. Because the `to` property of the TwiML is set to your personal phone number, this message will be forwarded to you instead of creating a response directly to the sender.

For a detailed example, see [SMS Forwarding and Responding Using Twilio and JavaScript](https://www.twilio.com/blog/sms-forwarding-and-responding-using-twilio-and-javascript).

```js title="Forward an inbound SMS"
const MY_NUMBER = "+15095550100";

exports.handler = (context, event, callback) => {
  // Create a new messaging response object
  const twiml = new Twilio.twiml.MessagingResponse();
  // Use any of the Node.js SDK methods, such as `message`, to compose a response
  // Access incoming text information like the from number and contents off of `event`
  // Note: providing a `to` parameter like so will forward this text instead of responding to the sender
  twiml.message({ to: MY_NUMBER }, `${event.From}: ${event.Body}`);
  // Return the TwiML as the second argument to `callback`
  // This will render the response as XML in reply to the webhook request
  return callback(null, twiml);
};
```

> \[!NOTE]
>
> This example hard-codes your personal number in the Function for convenience. For a more secure approach, consider setting `MY_NUMBER` as an **[Environment Variable](/docs/serverless/functions-assets/functions/variables)** in the Functions UI instead. It could then be referenced in your code as `context.MY_NUMBER`, as shown in the following example.

```js title="Forward an inbound SMS" description="Using an environment variable to store sensitive data"
exports.handler = (context, event, callback) => {
  // Create a new messaging response object
  const twiml = new Twilio.twiml.MessagingResponse();
  // Use any of the Node.js SDK methods, such as `message`, to compose a response
  // Access incoming text information like the from number and contents off of `event`
  // Access environment variables and other runtime data from `context`
  twiml.message({ to: context.MY_NUMBER }, `${event.From}: ${event.Body}`);
  // Return the TwiML as the second argument to `callback`
  // This will render the response as XML in reply to the webhook request
  return callback(null, twiml);
};
```

## Respond with MMS media from an HTTP request

All the Function examples so far are fully synchronous and only rely on data from the inbound message. Functions can also request data from other services by using modern [async/await syntax](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await).

For example, a Function can fetch an online resource (such as an image of a Shiba Inu) and reply with an MMS that includes the image.

```js title="Respond to an inbound SMS with an asynchronously generated MMS"
const axios = require('axios');

// Note that the function must be `async` to enable the use of the `await` keyword
exports.handler = async (context, event, callback) => {
  // Create a new messaging response object
  const twiml = new Twilio.twiml.MessagingResponse();

  // You can do anything in a Function, including making async requests for data
  const response = await axios
    .get('https://dog.ceo/api/breed/shiba/images/random')
    .catch((error) => {
      // Be sure to handle any async errors, and return them in a callback to end
      // Function execution if it makes sense for your application logic
      console.error(error);
      return callback(error);
    });

  const imageUrl = response.data.message;

  // Use any of the Node.js SDK methods, such as `message`, to compose a response
  // In this case we're also including the doge image as a media attachment
  // Note: access incoming text details such as the from number on `event`
  twiml
    .message(`Hello, ${event.From}! Enjoy this doge!`)
    .media(imageUrl);

  // Return the TwiML as the second argument to `callback`
  // This will render the response as XML in reply to the webhook request
  return callback(null, twiml);
};
```

> \[!WARNING]
>
> To use an npm module such as `axios` to create HTTP requests, you will need to add it as a [Dependency](/docs/serverless/functions-assets/functions/dependencies).
