メニュー

Expand
Rate this page:

Thanks for rating this page!

We are always striving to improve our documentation quality, and your feedback is valuable to us. How could this documentation serve you better?

Amazon AWS IoT、Lambda、およびAPI Gatewayを使用してESP8266でSMSメッセージに返信する

Ever wish you could send a text to your toaster? After today you'll be well on your way - we're going to show how to receive and reply to SMS or MMS messages with an Espressif ESP8266, Amazon AWS IoT, Lambda, and API Gateway. We'll also look at TwiML, Twilio's markup language, and how Webhooks work with Twilio.

Let's carry on and look at a serverless solution to receiving SMS and MMS messages on a $2 piece of silicon. (The toast part? You'll have to figure that out.)

TwiMLとは何か

TwiML is the Twilio Markup Language, which is just to say that it's an XML document with special tags defined by Twilio to help you build your SMS and voice applications. TwiML is easier shown than explained. Here's some TwiML you might use to respond to an incoming phone call:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say>Thanks for calling!</Say>
</Response>

And here's some TwiML you might use to respond to an incoming SMS message:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Message>We got your message, thank you!</Message>
</Response>

すべてのTwiMLドキュメントはルートの<Response>要素と、その中に含まれるひとつ以上の動詞からなります。 動詞とは、電話をかけてきた人にあいさつする<Say>や、受信メッセージへの返信としてSMSを送信する<Message>といったような、Twilioにおこなってほしいアクションのことです。 TwiMLで実行できることがあまねく網羅されたリファレンスについては、TwiML APIリファレンスを参照してください。

Webhookとは何か

Webhooks are user-defined HTTP callbacks. They are usually triggered by some event, such as receiving an SMS message or an incoming phone call. When that event occurs, Twilio makes an HTTP request (usually a POST or a GET) to the URL configured for the webhook.

To handle a webhook, you only need to build a small web application that can accept the HTTP requests. Almost all server-side programming languages offer some framework for you to do this. Examples across languages include ASP.NET MVC for C#, Servlets and Spark for Java, Express for Node.js, Django and Flask for Python, and Rails and Sinatra for Ruby. PHP has its own web app framework built in, although frameworks like Laravel, Symfony and Yii are also popular.

どのフレームワークや言語を選んだにせよ、WebhookはあらゆるTwilioアプリケーションに対して同様に機能します。 これらはTwilioに与えられたURIに対するリクエストを生成します。 アプリケーションはデータベースの読み書き、他のAPIとの統合、あるいは何らかの演算など、必要とされるあらゆる処理を実行し、それからTwilioに実行してほしい指示をTwiMLのレスポンスとしてTwilioに応答します。

Amazon AWSでサーバーレスに挑戦しよう

This is our fourth guide exploring working with Twilio and Amazon's AWS services. On some of the integration steps, we'll point you to a previous post where we detail the setup. If you just want to skip ahead, you can clone the code behind this article from GitHub.

Here's a preview of this guide's architecture:

  • An ESP8266 communicating with Amazon's AWS IoT
  • Amazon's API Gateway to handle incoming Twilio Webhook requests, passing them to Lambda
  • Lambda will forward legal messages to the ESP8266 on the MQTT topic 'twilio'
  • Responses from the ESP8266 will use the passthrough setup we detailed in our guide on sending MMS and SMS messages from an ESP8266 via AWS IoT and Amazon Lambda
メッセージの送信:

AWS IoT、Lambda、およびESP8266を使用してメッセージを送信する

メッセージの受信:

AWS IoTとLambdaを使用して、TwilioからSMSおよびMMSメッセージを受信する

Amazon AWS IoTをアクティブにする

In our article on sending messages with the ESP8266 and Lambda, we covered the AWS IoT setup in greater detail. If you haven't yet gone through that article, we'd highly suggest you do so first - but we'll give a summary of the steps you'll need to complete.

  1. Add a new ESP8266 'Thing' and 'Type' in AWS IoT
  2. MQTTの「twilio」トピックへのアクセスを許可する新規ポリシーを作成します(このチュートリアルでは「iot:*」を使用しています。
  3. Create a new IAM user with permission to do everything on IoT. Store the credentials to use on the ESP8266.
  4. 作成されたthingの「Interact」タブから、ESP8266上で使用する「Update to this thing shadow」MQTTトピックとHTTPSエンドポイントを取得します。

Also highly suggested: keep a tab open with the Test MQTT Client subscribed to both the shadow update topic and the 'twilio' channel.

Amazon API GatewayでAPIのモックをセットアップする

We're going to use API Gateway to expose a route for Twilio to access. We first went over this process in our receiving and replying to SMS and MMS messages using Amazon Lambda guide.

From the API Gateway console, create a new API with the 'Create API' button. Give it a friendly name and description, then create the API. Follow that up with a new resource 'message' (at '/message'), and create a 'POST' method on message.

For now, select 'Mock' as an 'Integration type' - we'll eventually add a Lambda function, but for now this'll suffice. Leave the API as is (don't deploy it yet) and let's start carving out our Lambda functions.

Exercising the Espressif ESP8266

While you'll be able to follow our MQTT posts without hardware, to complete this guide you'll need an ESP8266. To maximize accessibility, we've targeted the Arduino IDE with this tutorial. While we can't support other setups, we'd love to hear about your successes outside.

ESP8266の基板の選択

No board yet? The Arduino on ESP8266 repository's tested board list is the best place to get started. A tested development board variant is the quickest way to get up and running on the hardware. You can always switch later when you have the MVP working.

We were using the ESP8266 Thing from Sparkfun while crafting this guide. The Sparkfun Thing overloads the DTR pin and may cause trouble with your serial monitor. We've added an option for SoftwareSerial debugging on top of HardwareSerial (or none). Set your preference at the top of the .ino file.

アカウント用のESP8266のセットアップ

You'll need to edit a number of variables at the top of the .ino file before getting started. We covered exactly where to find each of the variables in our article on sending SMS or MMS messages from an ESP8266 with Lambda, but we'll briefly summarize now.

  • Gather credentials for your WiFi ssid and password.
  • AWSキー(IoT権限を持つIAMユーザー用)、AWSシークレット(同一のユーザー)、AWS IoTの地域、およびHTTPSエンドポイントをAWS IoT内のESP8266 Thingの「Interact」セクションから取得します。
  • Change the your_device_number and number_to_text variables to an owned Twilio number and a phone that can receive texts, respectively. Optionally change your_sms_message and optional_image_path to change the message you'll receive at power-on.

Arduinoにライブラリーを追加します。

We're relying on a few libraries for the guide today:

Using Arduino's Library Manager is possible for two of the libraries, but the others must be added manually. For a complete overview of library management on Arduino, see the official documentation.

スルーライブラリーマネージャーを追加する(検索)
  • ArduinoJSON
  • WebSockets
Arduinoに手動で追加する

The easiest way to get these libraries into Arduino is to install directly from the zip file once you download.

これは、Arduino IDE内のZIPライブラリーインストーラーから直接完了できる場合があります。

「Sketch」メニュー -> 「Add ZIP Library」 -> ダウンロードされたZIPファイルを選択します

ZIP LibraryをArduinoに追加する

ダウンロードリンク:

クライアントコードの構築と基板のプログラミング

If you've followed all the steps, programming the board should be as easy as setting the board and serial port of your ESP8266 in the Arduino IDE and clicking 'Upload'. If you have the Test MQTT Client open, watch for a message on the 'twilio' topic to come from your ESP8266 as soon as you turn it on.

ESP8266上でメッセージを受信する

The way the code handles incoming messages is to take a pointer to a function that you define that can handle a MQTT::MessageData reference. MQTT::MessageData is a structure which contains a few things you'll need, including a reference to another struct 'Message'.

struct Message
{
    enum QoS qos;
    bool retained;
    bool dup;
    unsigned short id;
    void *payload;
    size_t payloadlen;
};


struct MessageData
{
    MessageData(MQTTString &aTopicName, struct Message &aMessage)  : message(aMessage), topicName(aTopicName)
    { }

    struct Message &message;
    MQTTString &topicName;
};

We've split our listeners into two functions for the example application, one on the Device Shadow update channel, and the other on the twilio topic. In the twilio callback function, you can see how we shuttle the message body into a C-Style string, and use ArduinoJSON to parse some needed fields. Finally, we reverse the string and send it back out to the twilio MQTT topic, where it'll eventually make its way to your phone.

        
        
        
        
        An example function consuming an incoming message from Twilio and messaging back after reversing the body.

        ESP8266とAmazon AWS IoTを使用してSMSおよびMMS(日本未対応)を受信およびそれに返信する

        An example function consuming an incoming message from Twilio and messaging back after reversing the body.

        Simple, right? That's really all it takes to handle incoming messages on the ESP8266.

        Lambdaにこまごまとした作業をさせる

        We're going to have two Lambda functions in the backend of our application: one for sending messages and one for receiving messages.

        Amazon Lambdaでメッセージを送信する

        The first function we've already described in detail in the sending guide. If you haven't yet done that exercise, we'd suggest visiting now before continuing this guide. It details how to set up AWS IoT to talk to the ESP8266 and how to forward messages from the 'twilio' MQTT topic to Lambda. We'll be using the exact same function to reply to messages, so that will need to be added to Lambda.

        Briefly, here's what you need to do:

        1. Load the code from the 'Lambda Function Send SMS' directory in the GitHub repo into a new Lambda function
        2. LambdaのConfigurationタブで、「Handler」を変更して、「twilio_functions.iot_handler」を指すようにします。
        3. Set up a trigger with the SQL Statement of SELECT * FROM 'twilio' WHERE Type='Outgoing', and in AWS IoT change the SQL version to '2015-10-08'
        4. Enter the environment variables AUTH_TOKEN and ACCOUNT_SID

        Now, JSON messages published to the 'twilio' MQTT topic in AWS IoT will be forwarded to Lambda. In Lambda we do a tiny bit of processing and then use the Twilio Python Helper Library to send SMS and MMS messages.

        Lambdaでメッセージを受信し、空白の本文を返す

        The second aspect is new for this article - we need a Lambda function to receive incoming requests from Twilio.

        On your computer, start a new directory and include the content from the GitHub repository's 'Lambda Function Receive Message' directory inside. Install the Twilio Python Helper Library inside the directory (personally, we used pip install with a target), and zip up the contents of the directory (but not the directory itself!).

        Create a new Lambda function in the same region as the 'Mock' API and choose that API as the trigger to the new function. Under role, select 'Create a New Role From Template', selecting 'AWS IoT Button permissions'. Give that role a descriptive name - we'll need to visit it again after - and create your function.

        Now in Lambda, change to the 'Code' tab, and select 'Upload a .ZIP File' from the 'Code entry type' menu. Upload the zip file you created on your computer, and make sure you are using the Python 2.7 runtime.

        Now in the 'Configuration' tab, change the handler to 'twilio_functions.twilio_webhook_handler'. This is pointing to the twilio_functions.py file you just opened, and telling AWS to call the twilio_webhook_handler() function when triggered.

              
              
              
              
              Demonstrating how to verify incoming Twilio requests and pass messages along to a MQTT topic for consumption by IoT devices.

              LambdaでTwilioのWebhookリクエストを受信する

              Demonstrating how to verify incoming Twilio requests and pass messages along to a MQTT topic for consumption by IoT devices.

              続いて、コード内で求められる4つの環境変数を設定します(こちらもLambdaの「Code」タブ内で行います)。

              • AUTH_TOKEN
              • AWS_TOPIC (「twilio」、括弧を含みません)
              • REQUEST_URL (For now, '' or blank - we'll come back to this)
              • AWS_IOT_REGION

              受信および転送を行うPythonコードを調べる

              このLambdaファンクションでいくつかの興味深い詳細に気がつかれるでしょう。

              まず、TwilioからのメッセージをLambdaでPythonを使用しTwilioから受信するWebhookを検証する記事での解説と同様のやり方で検証しています。

              Next, we check the message body is under 160 characters before we burden the ESP8266 with a new message. (There are a few orders of magnitude more RAM on Lambda than on the ESP8266).

              Finally, we use the in-built boto3 library to post to the 'twilio' MQTT topic in your AWS region.

              LambdaにMQTTトピックへの投稿を許可する

              Remember that role you created in Lambda? If you deployed the API and let Twilio use it as of now, you'd find that Twilio can access your route just fine... but publishing to the 'twilio' MQTT topic is unauthorized. Let's rectify that by applying the proper permissions to your Lambda function's role.

              ご自身の名前のプルダウンの「My Security Credentials」を使用して、IAMに移動します。

              あなたのユーザー名付近のメニューから、Amazon IAMにアクセスします

              In there, click on the 'Roles' link in the left sidebar. Find the role you assigned to this Lambda function and click on it. Next, click on the 'Create Role Policy' button under 'Inline Policies':

              Amazon IAMでインラインポリシーを作成する

              ここで、Lambdaに全トピックへの投稿を許可するインラインポリシーを追加することが必要です。

              {
                  "Version": "2012-10-17",
                  "Statement": [
                      {
                          "Effect": "Allow",
                          "Action": [
                              "iot:Publish"
                          ],
                          "Resource": [
                              "*"
                          ]
                      }
                  ]
              }
              

              With that policy, your Lambda function is authorized to publish to MQTT topics. Unless you turn off the validation steps you won't be able to test it yet - you'll have to wait until our final step, hooking up Twilio, for that.

              Triggering Lambda with API Gateway

              You will want to modify the 'Mock' API we built out earlier. When you linked to it from the Lambda trigger, it should have already added the function as the integration to your API. If it instead created a new resource and method, delete it - under the /message POST resource and method you can add the function directly from inside API Gateway.

              Now we'll need to configure API Gateway now exactly as we did in our receiving and replying to SMS and MMS messages from Lambda article. The full steps are detailed in that post, but here's the summary of what you'll need to do:

              1. In 'Method Request', add the X-Twilio-Signature HTTP Request Header to pass through to Lambda.
              2. In 'Integration Request', remove all Body Mapping Templates and add a new one for application/x-www-form-urlencoded with a template of:
                #set($httpPost = $input.path('$').split("&"))
                {
                "twilioSignature": "$input.params('X-Twilio-Signature')",
                #foreach( $kvPair in $httpPost )
                 #set($kvTokenised = $kvPair.split("="))
                 #if( $kvTokenised.size() > 1 )
                   "$kvTokenised[0]" : "$kvTokenised[1]"#if( $foreach.hasNext ),#end
                 #else
                   "$kvTokenised[0]" : ""#if( $foreach.hasNext ),#end
                 #end
                #end
                }
                
              3. In 'Integration Response', remove existing Body Mapping Templates and add one in HTTP status code 200 for application/xml. Use this two line template:
                #set($inputRoot = $input.path('$')) 
                $inputRoot​
                
              4. 「Method Response」では、HTTPステータス200についてすべての既存のレスポンス本文を削除し、application/xmlに一つ追加します。

              If you did all that, you're ready to deploy! From the 'Action' pulldown menu, 'Deploy API':

              APIギャラリーにAPIを追加する

              You will be asked to choose an existing (or create a new) stage. We called our stage 'prod'... feel free to name it whatever you'd like - just remember what it's called.

              After deploying, you'll get a URL to your new /message route. Copy that exact URL, '/message' and all, into the REQUEST_URL environment variable of your Lambda function. This is also the time to make sure the trigger is enabled on the Lambda side - make sure that the 'prod' stage of the API will trigger your function.

              Keep that URL on your clipboard - you're going to use it one more time.

              TwilioのWebhook URLを構成する

              It's now time to plug Twilio into your Amazon-and-Thing setup. Log into your Twilio Account and go to the console. Click the 'pound sign'/'hashtag' ('#') in the sidebar and navigate to 'Active Numbers'.

              Existing numbers you have will show an icon if SMS and MMS are enabled. You'll need one with both capabilities for the initial ESP8266 application's startup (it sends an MMS). If you'd only likle to exercise SMS sending capabilities, set optional_image_path to an empty string before uploading to your board.

              If you don't yet have a number, Twilio makes your search easy. Select SMS and MMS before you start your search and we'll only return numbers available to purchase that feature both capabilities:

              SMS対応Twilio電話番号を購入する

              Whether you bought your number new or you're recycling, click on the number to use. (Note: this can be different than the number programmed into the ESP8266, you can use any Twilio number you own.)

              In the screen that appears, under 'Messaging' and in 'A Message Comes In', select 'Webhook' and paste the URL from your new API in API Gateway into the text box (highlighted below). Ensure 'HTTP POST' is selected.

              SMS Webhook

              Backup Webhook URLs

              You'll also notice the 'Primary Handler Fails' box. When you go to production, you'll want to add a failover webhook here to catch any issues with your primary webhook Twilio will automatically use the secondary handler if there is a problem with your webhook or we can't reach the primary handler in 15 seconds. See our Availability and Reliability guide for details.

              SMS Your Twilio Number Under 160 Characters!

              It's time to test the whole setup - send a SMS to the Twilio number assigned to the ESP8266. If all goes well, you should see your message sent back to you from the ESP... esrever ni!

              Try texting it "Oozy rat in a sanitary zoo.". Or really, any line from this Weird Al song.

              Make the Thing Your Own

              With that under your belt, you've now got an end to end solution for receiving and replying to SMS and MMS messages with some Amazon serverless AWS solutions. If you combine the sending SMS and MMS messages from the ESP8266 and Lambda post, you'll also have a handle on outgoing messages. Call it "Incoming and outgoing text messages in 64 Kb of RAM". (640Kb really was enough for anyone).

              If you're ready to press on, Add-Ons will often simplify the next steps on your journey to production. Quickly add our partners' convenient powerful services and tools to your application- try it, you'll love the ease of use.

              Please keep us posted on your production journey. We'd love to hear from you on Twitter - let us know what you're building, or what you've built!

              Paul Kamp David Prothero Kat King
              Rate this page:

              ヘルプが必要ですか?

              誰しもが一度は考える「コーディングって難しい」。そんな時は、お問い合わせフォームから質問してください。 または、Stack Overflow でTwilioタグのついた情報から欲しいものを探してみましょう。