在 Alexa 技能開發中,資料儲存至關重要。本文說明如何運用 DynamoDB 和 S3 進行資料儲存及管理。DynamoDB 作為 NoSQL 資料函式庫,提供高擴充套件性和低延遲特性,適合儲存鍵值對資料。S3 則適用於儲存大量資料,例如圖片、音訊等。透過請求和回應攔截器,我們可以在技能程式碼執行前後,載入和儲存永續性資料,例如使用者存取次數。永續性屬性可儲存使用者相關資訊,方便在不同會話中存取。S3 儲存桶則可存放媒體檔案,並透過預簽名 URL 讓 Alexa 技能安全地存取這些檔案,無需直接暴露檔案路徑。程式碼範例包含 Python 和 Node.js,示範如何設定 DynamoDB 介面卡、使用永續性屬性、以及產生 S3 預簽名 URL。

5.4 請求和回應攔截器

請求和回應攔截器是在您的技能程式碼被呼叫時執行的。請求攔截器在意圖程式碼執行前執行,而回應攔截器則在程式碼完成後執行。因此,它們可以用來載入和儲存持續性資料,而不是在每個意圖程式碼中載入和儲存。您也可以在攔截器中執行其他動作。

要使用攔截器,您需要在程式碼頂部新增更多的「from」陳述式:

from ask_sdk_core.dispatch_components import AbstractRequestInterceptor
from ask_sdk_core.dispatch_components import AbstractResponseInterceptor

然後,您需要在技能建構器之前新增攔截程式碼:

class LoadPersistenceAttributesRequestInterceptor(AbstractRequestInterceptor):
    def process(self, handler_input):
        # 檢查是否為第一次呼叫技能並初始化預設值
        persistent_attributes = handler_input.attributes_manager.persistent_attributes
        if not persistent_attributes:
            persistent_attributes['visit_counter'] = 1
            logger.info("Create attributes")
        else:
            # 將小數轉換為整數 - AWS SDK DynamoDB 問題
            pass
        return

class SavePersistenceAttributesResponseInterceptor(AbstractResponseInterceptor):
    def process(self, handler_input, response):
        # 儲存持續性屬性之前發送回應給使用者
        handler_input.attributes_manager.save_persistent_attributes()
        return

最後,您需要在技能建構器之後註冊攔截請求和回應程式碼:

sb = SkillBuilder()
sb = CustomSkillBuilder(persistence_adapter=dynamodb_adapter)

# 攔截器
sb.add_global_request_interceptor(LoadPersistenceAttributesRequestInterceptor())
sb.add_global_response_interceptor(SavePersistenceAttributesResponseInterceptor())

這樣就完成了攔截器的設定和註冊。

使用 Alexa 和 Raspberry Pi 開發語音控制 IoT 應用程式

第 5 章:S3 儲存和 DynamoDB 資料函式庫

在開發語音控制 IoT 應用程式時,儲存和管理使用者資料是一個重要的方面。Alexa 提供了兩種儲存選擇:S3 儲存和 DynamoDB 資料函式庫。在本章中,我們將探討如何使用這兩種儲存選擇來儲存和管理使用者資料。

使用 Persistent Attributes 儲存資料

在前面的章節中,我們已經學習瞭如何使用 persistent_attributes 來儲存使用者資料。以下是更新的 LaunchRequestHandler 程式碼:

sb.add_request_handler(LaunchRequestHandler())

我們需要更新程式碼以使用 persistent_attributes 來儲存資料。首先,註解掉以下程式碼:

if not persistent_attributes:
    persistent_attributes['visit_counter'] = 0

以及以下程式碼:

handler_input.attributes_manager.persistent_attributes = persistent_attributes
handler_input.attributes_manager.save_persistent_attributes()

現在,讓我們執行技能並觀察結果。使用者存取次數將被儲存到永續性資料中。

使用 Interceptors 儲存和載入 Session Attributes

我們也可以使用 interceptors 來儲存和載入 session attributes。以下是 Node.js 中的 request 和 response interceptor 程式碼:

const RequestInterceptor = {
  async process(handlerInput) {
    const { attributesManager } = handlerInput;
    let sessionAttributes = attributesManager.getSessionAttributes();
    let persistentAttributes = await attributesManager.getPersistentAttributes();
    sessionAttributes = Object.assign({}, persistentAttributes, sessionAttributes);
    attributesManager.setSessionAttributes(sessionAttributes);
  }
};

const ResponseInterceptor = {
  async process(handlerInput) {
    let { attributesManager, responseBuilder } = handlerInput;
    let sessionAttributes = attributesManager.getSessionAttributes();
    let persistentAttributes = await attributesManager.getPersistentAttributes();
    sessionAttributes = Object.assign({}, persistentAttributes, sessionAttributes);
    attributesManager.setPersistentAttributes(sessionAttributes);
    await attributesManager.savePersistentAttributes();
  }
};

我們需要註冊 interceptors。新增以下程式碼:

const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = Alexa.SkillBuilders.custom()
 .addRequestHandlers(
    LaunchRequestHandler,
    //...
    SessionEndedRequestHandler
  )
 .addInterceptors(RequestInterceptor, ResponseInterceptor);

現在,讓我們執行技能並觀察結果。使用者存取次數將被儲存到永續性資料中,並且可以在不同的會話中被載入。

刪除 Persistent Attributes

如果需要刪除永續性屬性,可以使用以下程式碼:

handler_input.attributes_manager.delete_persistent_attributes();

這將刪除所有永續性屬性。

使用 DynamoDB 和 S3 儲存資料

在 Alexa 的開發過程中,儲存資料是非常重要的一部分。DynamoDB 和 S3 是兩種常用的儲存解決方案。

DynamoDB

DynamoDB 是一種 NoSQL 資料函式庫,使用鍵值對來儲存資料。它提供了高可擴充套件性和低延遲的優點。要使用 DynamoDB,需要先設定 DynamoDbAdapter,然後初始化介面卡,最後新增自訂技能建構器來載入 DynamoDb 介面卡。

以下是使用 DynamoDB 的步驟:

  1. 安裝 DynamoDbAdapter
  2. 初始化 DynamoDbAdapter
  3. 新增自訂技能建構器來載入 DynamoDb 介面卡

DynamoDB 支援 PartiQL 查詢語言,但這超出了本文的範圍。有關更多資訊,可以參考 Amazon 官方檔案。

S3 儲存

S3 是一種物件儲存服務,允許您儲存和擷取大量資料。要使用 S3,需要先建立一個儲存桶,然後上傳您的資料。

以下是使用 S3 的步驟:

  1. 建立一個儲存桶
  2. 上傳您的資料
  3. 取得預簽名 URL 來存取您的資料

S3 提供了 5 GB 的免費儲存空間,20,000 個 GET 請求,2,000 個 PUT、COPY、POST 或 LIST 請求,以及 100 GB 的資料傳輸每月。

存取 S3 儲存的資料

要存取 S3 儲存的資料,可以使用預簽名 URL。預簽名 URL 是一種安全的方式來存取您的資料,而不需要將實際的資料傳輸給使用者。

以下是使用預簽名 URL 的步驟:

  1. 取得預簽名 URL
  2. 使用預簽名 URL 來存取您的資料

範例程式碼

以下是使用 S3 儲存和預簽名 URL 的範例程式碼:

from utils import create_presigned_url
from ask_sdk_model.ui import StandardCard, Image, SimpleCard

my_image_url = create_presigned_url("Media/jba.png")

image_data = {
    "card": {
        "title": 'My picture',
        "text": "me!",
    }
}

card = StandardCard(
    title=image_data["card"]["title"],
    text=image_data["card"]["text"],
    image=Image(
        small_image_url=my_image_url,
    )
)

這個範例程式碼使用預簽名 URL 來存取 S3 儲存的圖片,並使用 StandardCard 來顯示圖片。

從系統架構的視角來看,本章深入探討了 Alexa 技能開發中資料儲存的關鍵技術:DynamoDB 和 S3,以及請求/回應攔截器的應用。 分析比較了 session attributes 和 persistent attributes 的使用方法,並闡述瞭如何利用攔截器有效管理 persistent attributes,避免在每個 intent 中重複讀寫,提升程式碼效率和可維護性。 雖然 DynamoDB 的 PartiQL 查詢功能並未詳述,但明確指出了其進階應用方向,也提供了 S3 預簽名 URL 的實務範例,展現了在安全性與資料存取效率之間的平衡。 預計未來,隨著物聯網應用的普及, serverless 資料函式庫如 DynamoDB 的整合將成為主流,而 S3 作為經濟高效的儲存方案,其重要性也將持續提升。 對於開發語音控制 IoT 應用程式的開發者而言,深入理解並善用這些儲存技術和攔截器機制,將是構建高效能、可擴充套件且安全可靠應用程式的關鍵。 建議開發者根據實際應用場景選擇合適的儲存方案,並充分利用攔截器簡化程式碼邏輯,提升開發效率。