

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 教學課程：傳送 Amazon SNS 通知
<a name="iot-sns-rule"></a>

本教學課程示範如何建立 AWS IoT 規則，將 MQTT 訊息資料傳送至 Amazon SNS 主題，以做為 SMS 文字訊息傳送。

在本教學課程中，您會建立一個規則，在溫度超過規則中所設定的值時，將訊息資料從天氣感應器傳送至 Amazon SNS 主題的所有訂閱者。該規則會在回報的溫度超過規則設定值時進行偵測，然後建立新的訊息承載資料，其中僅包含裝置 ID、回報的溫度及超過的溫度限制。該規則會將新訊息承載作為 JSON 文件傳送至 SNS 主題，其會通知 SNS 主題的所有訂閱者。

**您會在本教學課程中學到什麼：**
+ 如何建立及測試 Amazon SNS 通知
+ 如何從 AWS IoT 規則呼叫 Amazon SNS 通知
+ 如何在規則查詢陳述式中使用簡單的 SQL 查詢和函數
+ 如何使用 MQTT 用戶端測試 AWS IoT 規則

此教學課程約需 30 分鐘方能完成。

**Topics**
+ [步驟 1：建立傳送簡訊的 Amazon SNS 主題](#iot-sns-rule-create-sns-topic)
+ [步驟 2：建立 AWS IoT 規則以傳送文字訊息](#iot-sns-rule-create-rule)
+ [步驟 3：測試 AWS IoT 規則和 Amazon SNS 通知](#iot-sns-rule-test-rule)
+ [步驟 4：檢閱結果及後續步驟](#iot-sns-rule-review-results)

**開始本教學課程之前，請確定您有：**
+ 

**[設定 AWS 帳戶](setting-up.md)**  
您需要 AWS 帳戶 和 AWS IoT 主控台才能完成本教學課程。
+ 

**檢閱 [使用 MQTT 用戶端檢視 AWS IoT MQTT 訊息](view-mqtt-messages.md)**  
請確定您可使用 MQTT 用戶端來訂閱並發佈至主題。您會使用 MQTT 用戶端，在此程序中測試您的新規則。
+ 

**檢閱 [Amazon Simple Notification Service](https://docs.aws.amazon.com//sns/latest/dg/welcome.html)**  
若您未曾使用過 Amazon SNS，請查閱[設定 Amazon SNS 的存取](https://docs.aws.amazon.com//sns/latest/dg/sns-setting-up.html)。如果您已完成其他 AWS IoT 教學課程，則應該已正確設定您的 AWS 帳戶 。

## 步驟 1：建立傳送簡訊的 Amazon SNS 主題
<a name="iot-sns-rule-create-sns-topic"></a>

此程序說明如何建立天氣感應器可以傳送訊息資料的 Amazon SNS 主題。然後，Amazon SNS 主題會透過簡訊通知所有訂閱者超過溫度限制。

**若要建立一個傳送 SMS 簡訊的 Amazon SNS 主題**

1. **建立一個 Amazon SNS 主題。**

   1. 登入 [Amazon SNS 主控台](https://console.aws.amazon.com//sns/home)。

   1. 在左側導覽窗格中，選擇 **Topics** (主題)。

   1. 在 **Topics** (主題) 頁面上，選擇 **Create new topic** (建立新主題)。

   1. 於 **Details** (詳細資訊) 中，選擇 **Standard** (標準) 類型。依預設，主控台會建立一個 FIFO 主題。

   1. 於 **Name** (名稱) 中，輸入 SNS 主題名稱。針對本教學，輸入 **high\_temp\_notice**。

   1. 向下捲動到頁面底部，並選擇 **Create topic** (建立主題)。

      主控台會開啟新主題的 **Details** (詳細資訊) 頁面。

1. **建立 Amazon SNS 訂閱。**
**注意**  
您在此訂閱中使用的電話號碼可能會因您將在本教學課程中傳送訊息而產生簡訊費用。

   1. 於 **high\_temp\_notice** 主題詳細資訊頁面中，選擇 **Create subscription** (建立訂閱)。

   1. 於**Create subscription** (建立訂閱) 的 **Details** (詳細資訊) 區段下，在 **Protocol** (通訊協定) 清單中選擇 **SMS**。

   1. 於 **Endpoint** (端點) 中，輸入可接收簡訊的電話號碼。請務必將其輸入，使其以 `+` 開頭，包含國碼和地區碼，且不包含任何其他標點符號字元。

   1. 選擇**建立訂閱**。

1. **測試 Amazon SNS 通知。**

   1. 於 [Amazon SNS 主控台](https://console.aws.amazon.com//sns/home)的左側導覽窗格中，選擇 **Topics** (主題)。

   1. 若要開啟主題的詳細資料頁面，請於 **Topics** (主題) 的主題清單中，選擇 **high\_temp\_notice**。

   1. 如要開啟 **Publish message to topic** (將訊息發佈至主題) 頁面，請於 **high\_temp\_notice** 詳細資訊頁面中，選擇 **Publish message** (發佈訊息)。

   1. 在 **Publish message to topic** (將訊息發佈至主題) 的 **Message body** (訊息內文) 區段下，在 **Message body to send to the endpoint** (要傳送至端點的訊息內文) 中，輸入簡短訊息。

   1. 捲動到頁面底部，並選擇 **Publish message** (發佈訊息)。

   1. 在您先前建立訂閱時所使用的手機號碼上，確認已收到訊息。

   若您並未收到測試訊息，請再次檢查電話號碼及手機設定。

   請確保您可從 [Amazon SNS 主控台](https://console.aws.amazon.com//sns/home) 發佈測試訊息，然後再繼續教學課程。

## 步驟 2：建立 AWS IoT 規則以傳送文字訊息
<a name="iot-sns-rule-create-rule"></a>

您將在本教學課程中建立的 AWS IoT 規則會訂閱 `device/{{device_id}}/data` MQTT 主題，其中 `{{device_id}}`是傳送訊息的裝置 ID。主題篩選條件會將這些主題描述為 `device/+/data`，其中 `+` 為與兩個正斜線字元間之任何字串相符的萬用字元。此規則也會測試訊息裝載中的 `temperature` 欄位值。

當規則收到來自相符主題的訊息時，其會採用來自主題名稱的 `{{device_id}}`、來自訊息承載的 `temperature` 值、及為其測試的限制新增一個常數值，並將這些值做為 JSON 文件傳送至 Amazon SNS 通知主題。

 例如，來自天氣感應器裝置編號 32 的 MQTT 訊息會使用 `device/32/data` 主題，並具有看起來如下的訊息承載：

```
{
  "temperature": 38,
  "humidity": 80,
  "barometer": 1013,
  "wind": {
    "velocity": 22,
    "bearing": 255
  }
}
```

規則的規則查詢陳述式採用訊息承載的 `temperature` 值、主題名稱的 `{{device_id}}`，並新增常數 `max_temperature` 值，以將看起來像這樣的訊息承載傳送至 Amazon SNS 主題：

```
{
  "device_id": "32",
  "reported_temperature": 38,
  "max_temperature": 30
}
```

**建立 AWS IoT 規則以偵測超額溫度值，並建立要傳送至 Amazon SNS 主題的資料**

1. 開啟 [AWS IoT 主控台的**規則**中樞](https://console.aws.amazon.com//iot/home#/rulehub)。

1. 若此為您的第一個規則，請選擇 **Create** (建立) 或 **Create a rule** (建立規則)。

1. 在 **Create a rule** (建立規則) 中：

   1. 在 **Name** (名稱) 中，輸入 **temp\_limit\_notify**。

      請記住，規則名稱在您的 AWS 帳戶 和 區域中必須是唯一的，而且不能有任何空格。我們在此名稱中使用底線字元來分隔規則名稱中的字詞。

   1. 在 **Description** (說明) 中，說明規則。

      有意義的說明可讓您更容易記住此規則的作用及您建立規則的原因。說明可依所需而定，因此請盡可能詳細說明。

1. 在 **Create a rule** (建立規則) 的 **Rule query statement** (規則查詢陳述式) 中：

   1.  在**使用 SQL 版本**中，選取 **2016-03-23**。

   1. 在 **Rule query statement** (規則查詢陳述式) 編輯方塊中輸入陳述式：

      ```
      SELECT topic(2) as device_id, 
          temperature as reported_temperature, 
          30 as max_temperature 
        FROM 'device/+/data' 
        WHERE temperature > 30
      ```

      本陳述式：
      + 聆聽主題與 `device/+/data` 主題篩選條件相符及 `temperature` 值大於 30 的 MQTT 訊息。
      + 從主題字串中選取第二個元素，並將其指定給 `device_id` 欄位。
      + 從訊息承載選取值 `temperature` 欄位，並將其指派給 `reported_temperature` 欄位。
      + 建立常數值 `30` 來表示限制值，並將其指定給 `max_temperature` 欄位。

1. 若要開啟此規則的規則動作清單，請於 **Set one or more actions** (設定一個或多個動作) 中，選擇 **Add action** (新增動作)。

1. 在 **Select an action** (選取動作) 中，選擇 **Send a message as an SNS push notification** (傳送 SNS 推送通知形式的訊息)。

1. 若要開啟所選取動作的組態頁面，請在動作清單底部選擇 **Configure action** (設定動作)。

1. 於 **Configure action** (設定動作)：

   1. 於 **SNS target** (SNS 目標) 中，選擇 **Select** (選取)，找出您名為 **high\_temp\_notice** 的 SNS 主題，然後選擇 **Select** (選取)。

   1. 在 **Message format** (訊息格式) 中，選擇 **RAW**。

   1. 在**選擇或建立角色以授予執行此動作的 AWS IoT 存取權**中，選擇**建立角色**。

   1. 在 **Create a new role** (建立新角色) 的 **Name** (名稱) 中，輸入新角色的唯一名稱。在本教學課程中，使用 **sns\_rule\_role**。

   1. 選擇 **Create Role** (建立角色)。

   若您要重複此教學課程或重複使用現有的角色，請先選擇 **Update role** (更新角色)，再繼續進行。此會更新角色的政策文件，以使用 SNS 目標。

1. 選擇 **Add action** (新增動作)，並返回 **Create a rule** (建立規則) 頁面。

   在新動作的圖標中，**Send a message as an SNS push notification** (以 SNS 推送通知形式傳送訊息)，您可看到規則呼叫的 SNS 主題。

   這是您將新增至此規則的唯一規則動作。

1. 如要建立並完成此步驟，請於 **Create a rule** (建立規則) 中，向下捲動至底部，然後選擇 **Create rule** (建立規則)。

## 步驟 3：測試 AWS IoT 規則和 Amazon SNS 通知
<a name="iot-sns-rule-test-rule"></a>

若要測試新規則，您將使用 MQTT 用戶端來發佈和訂閱此規則所使用的 MQTT 訊息。

在新視窗的 [AWS IoT 主控台中開啟 MQTT 用戶端](https://console.aws.amazon.com//iot/home#/test)。這可讓您編輯規則，而不會遺失 MQTT 用戶端的組態。如果您讓 MQTT 用戶端前往主控台中的另一個頁面，其不會保留任何訂閱或訊息記錄。

**如要使用 MQTT 用戶端來測試您的規則。**

1. 在 AWS IoT 主控台的 [MQTT 用戶端](https://console.aws.amazon.com//iot/home#/test) 中，訂閱輸入主題，在此案例中為 `device/+/data`。

   1. 在 MQTT 用戶端中的 **Subscriptions** (訂閱) 下選擇 **Subscribe to a topic** (訂閱主題)。

   1. 在 **Subscription topic** (訂閱主題) 中，輸入輸入主題篩選條件 **device/\+/data** 的主題 。

   1. 將剩下的欄位保留為其預設設定。

   1. 請選擇 **Subscribe to topic** (訂閱主題)。

      在 **Subscriptions** (訂閱) 欄中，**Publish to a topic** (發佈到主題) 之下，**device/\+/data** 隨即顯示。

1. 使用特定裝置 ID **device/32/data**，將訊息發佈至輸入主題。您無法發佈至包含萬用字元的 MQTT 主題。

   1. 在 MQTT 用戶端中的 **Subscriptions** (訂閱) 下選擇 **Publish to topic** (發佈至主題)。

   1. 在 **Publish** (發佈) 欄位中輸入輸入主題名稱 **device/32/data**。

   1. 複製此處顯示的範例資料，並在主題名稱下方的編輯方塊中貼上範例資料。

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. 選擇 **Publish to topic** (發佈至主題)，發佈您的 MQTT 訊息。

1. 確認簡訊已傳送。

   1. 在 MQTT 用戶端中 **Subscriptions** (訂閱) 下，您先前訂閱的主題旁會有一個綠點。

      該綠點表示自上次查看後，已收到一個或多個新訊息。

   1. 於 **Subscriptions** (訂閱) 下，選擇 **device/\+/data**，來檢查訊息承載是否與您剛剛發佈的內容相符，如下所示：

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. 檢查您用來訂閱 SNS 主題的手機，並確認訊息承載內容如下所示：

      ```
      {"device_id":"32","reported_temperature":38,"max_temperature":30}
      ```

      請注意，`device_id` 值是個帶有引號的字串，而 `temperature` 值是個數字。這是因為 [https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic) 函數從輸入訊息的主題名稱中提取字串，而 `temperature` 值會使用輸入訊息承載的數值。

      若要將 `device_id` 值設為數值，請將規則查詢陳述式中的 `topic(2)` 替換為：

      ```
      cast(topic(2) AS DECIMAL)
      ```

      請注意，將 `topic(2)` 值轉換為數值，`DECIMAL` 值僅適用於該部分主題僅包含數字字元時。

1. 請嘗試傳送溫度不超過限制的 MQTT 訊息。

   1. 在 MQTT 用戶端中的 **Subscriptions** (訂閱) 下選擇 **Publish to topic** (發佈至主題)。

   1. 在 **Publish** (發佈) 欄位中輸入輸入主題名稱 **device/33/data**。

   1. 複製此處顯示的範例資料，並在主題名稱下方的編輯方塊中貼上範例資料。

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. 若要傳送 MQTT 訊息，請選擇 **Publish to topic** (發佈至主題)。

   您應該能看到您在 **device/\+/data** 訂閱中傳送的訊息。不過，因溫度值低於規則查詢陳述式中的最高溫度，所以您不應收到簡訊。

   若您並未看到正確的行為，請查看疑難排解提示。

### 疑難排解 SNS 訊息規則
<a name="iot-sns-rule-trouble"></a>

若您並未看到預期的結果，請查看以下事項。
+ 

**您收到錯誤的橫幅**  
若在您發佈輸入訊息時出現錯誤，請先更正該錯誤。下列步驟可協助您修正該錯誤。
+ 

**您並未在 MQTT 用戶端中看到輸入訊息**  
每次您將輸入訊息發佈至 `device/22/data` 主題中，若您依程序中所述訂閱了 `device/+/data` 主題篩選條件，則該訊息應會顯示於 MQTT 用戶端中。

**要檢查的事項**
  + 

**檢查您訂閱的主題篩選條件**  
若您依程序中所述訂閱了輸入訊息主題，則每次發佈輸入訊息時都應該會看到其複本。

    若您並未訊息，請檢查您訂閱的主題名稱，並將其與所發佈的主題進行比較。主題名稱區分大小寫，且您訂閱的主題必須與所發佈訊息承載的主題相同。
  + 

**檢查訊息發佈功能**  
在 MQTT 用戶端中的 **Subscriptions** (訂閱) 下，選擇 **device/\+/data**，檢查發佈訊息的主題，然後選擇 **Publish to topic** (發佈至主題)。您應該會在訊息清單中出現主題下方的編輯方塊中看到訊息承載。
+ 

**您並未收到 SMS 訊息：**  
若要讓您的規則運作，其必須具有授權其接收訊息和傳送 SNS 通知的正確政策，且必須接收訊息。

**要檢查的事項**
  + 

**檢查 MQTT 用戶端 AWS 區域 的 和您建立的規則**  
您正在執行 MQTT 用戶端的主控台必須與您建立的規則處於相同的 AWS 區域。
  + 

**檢查訊息承載中的溫度值是否超過測試閾值**  
若溫度值小於或等於 30 (如規則查詢陳述式中所定義)，則規則將不會執行其任何動作。
  + 

**檢查規則查詢陳述式中的輸入訊息主題**  
若要讓規則運作，其必須收到一則訊息，其主題名稱與規則查詢陳述式之 FROM 子句中的主題篩選條件相符。

    檢查規則查詢陳述式中主題篩選條件的拼字與 MQTT 用戶端中主題的拼字。主題名稱區分大小寫，且郵件的主題必須與規則查詢陳述式中的主題篩選條件相符。
  + 

**檢查輸入訊息承載的內容**  
若要讓規則運作，其必須在 SELECT 陳述式中宣告的訊息承載中尋找資料欄位。

    檢查規則查詢陳述式中 `temperature` 欄位的拼字與 MQTT 用戶端中訊息承載的拼字。欄位名稱區分大小寫，規則查詢陳述式中的 `temperature` 欄位必須與訊息承載中的 `temperature` 欄位相符。

    請確定訊息承載中的 JSON 文件格式正確。若 JSON 有任何錯誤，例如缺少逗號，則規則將無法進行讀取。
  + 

**檢查規則動作中重新發佈的訊息主題**  
Republish (重新發佈) 規則動作發佈新訊息的主題必須與您在 MQTT 用戶端中訂閱的主題相符。

    開啟您建立於主控台中的規則，並檢查規則動作重新發佈訊息的主題。
  + 

**檢查規則所使用的角色**  
規則動作必須具有接收原始主題及發佈新主題的權限。

    授權規則接收訊息資料的政策並加以重新發佈為所使用的主題所特定的。若變更用於重新發佈訊息資料的主題，則必須更新規則動作的角色，來更新其政策以與目前主題相符。

    若您懷疑這會是問題，請編輯 Republish (重新發佈) 規則動作並建立新角色。規則動作建立的新角色會收到執行這些動作所需的授權。

## 步驟 4：檢閱結果及後續步驟
<a name="iot-sns-rule-review-results"></a>

**於本教學課程中：**
+ 您已建立並測試了 Amazon SNS 通知主題和訂閱。
+ 您在規則查詢陳述式中使用了一個簡單的 SQL 查詢和函數，可為您的通知建立一個新訊息。
+ 您已建立 AWS IoT 規則來傳送使用自訂訊息承載的 Amazon SNS 通知。
+ 您使用 MQTT 用戶端來測試 AWS IoT 規則。

**後續步驟**  
使用此規則傳送一些簡訊之後，請嘗試使用其來查看教學課程的某些層面如何影響訊息，及訊息傳送的時間。此處有幾種簡單的入門方式。
+ 變更輸入訊息主題中的 {{device\_id}}，並觀察簡訊內容中的影響。
+ 變更規則查詢陳述式中所選取的欄位，並觀察簡訊內容中的影響。
+ 變更規則查詢陳述式中的測試，以測試最低溫度，而非最高溫度。請記得變更 `max_temperature` 的名稱！
+ 新增重新發佈規則動作，以於傳送 SNS 通知時傳送 MQTT 訊息。
+ 請嘗試本系列中的下一個教學課程，並了解如何進行 [教學課程：將裝置資料儲存在 DynamoDB 表格中](iot-ddb-rule.md)。