となったので、

 

と作成

とできた。

slackのOutgoing Webhooksから受信する

Proxy統合ではなく、Lambda側のインタフェースを決めてしまう

 

/raspberrypi/{proxy+} を作成し、POSTのみ作成

/raspberrypi/speak で呼び出し、speakの場合、音声再生要求を投げる

Lambda関数を作成

実装はシンプル

https://github.com/nilesflow/Slack2RaspberryPi

下記等参考に

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html

query paramaterのtokenの値の検証のみ

tokenの値はコンソール上の環境変数に設定

Lambdaを登録しておく。

 

フォーマットは下記の形式

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format

 

Lambdaオーソライザー

ロールはLambda実行権限含むものを作成しておく

 

クエリパラメータにtokenを設定して認証させたいので、認証でLambdaリクエストオーソライザーを設定。

~検証とURLクエリ文字列パラメータを設定。

リクエストパスのproxyを入力しておく

・作成したLambdaを指定

・プロキシ統合は使わずに、呼び出し側ロジックはAPI Gateway側で吸収

・リクエストパラメータのproxyをマッピング

 

・Content-Type=application/x-www-form-urlencoded で送信される

・それ以外は厳しめに通過禁止に設定しておく

 

・マッピングテンプレートは次の通り

## slackのOutgoing Webhooksから下記の形式で送信される
## token=viK8ruCmEfBjd9u84MOEeTWo
## team_id=T0001
## team_domain=例
## channel_id=C2147483705
## channel_name=テスト
## timestamp=1355517523.000005
## user_id=U2147483697
## user_name=スティーブ
## text=googlebot: 身軽なツバメの対気速度はどのくらい?
## trigger_word=googlebot:

## POSTパラメータの分割(A=x&B=y)
#set($aParams = $input.body.split(“&”))

## path変数の分割
#set($aPaths = $input.params(‘proxy’).split(“/”))

## 出力されるJSONデータの生成
{
##pathの次階層をactionとする
“action” : “$aPaths[0]”,

## 必要なPOSTパラメータのみをマッピング
#foreach( $param in $aParams)
#set($hParam = $param.split(“=”))
#if( $hParam[0] == “text”)
“text” : “$util.urlDecode($hParam[1])”,
#end
#if( $hParam[0] == “user_name”)
“user” : “$util.urlDecode($hParam[1])”,
#end
#end

## カンマ制御のためのダミー
“dummy” : null
}

 

Lambda側で定義される次の変数をマッピングしている

action

text

user

 

・統合レスポンスは200のみ設定

slackへ応答を返すには、200でレスポンスパラメータを返す必要があるため

マッピングテンプレートは次の通り

## for slack Outgoing Webhooks
## 全て200の単一フォーマットで返却
#set ($inputRoot = $input.path(‘$’))

## Lambdaで正常に処理された場合
#if ($input.path(‘$.statusCode’) > 0)

## 200の場合のフォーマット
#if ($input.path(‘$.statusCode’) == 200)
#set ($body = $util.parseJson($input.path(‘$.body’)))
{
“text” : “$body.message”
}

## それ以外の場合のフォーマット
#else ## 200
#set ($body = $util.parseJson($input.path(‘$.body’)))
{
“text” : “$body.error: $body.error_description”
}
#end ## not 200

## 例外等
#else ## statusCode
{
“text” : “$input.path(‘$.errorMessage’)”
}
#end ## not statusCode

Lambdaの応答の次のケース全てを200として返却する

・ステータスコード200:正常

・ステータスコード200以外:異常(Lambda実装コード中で認識したエラー)

・例外等それ以外:異常(Lambda実装コード中以外のエラーも含む)

 

・ゲートウェイのレスポンスで、API Gatewayで検出したエラーのレスポンスフォーマットを定義する

これも、SlackのOutgoing Webhooksのフォーマットに合わせておく。

400, 500も200で返すようにしておく。

 

メソッドレスポンスモデルは不要なのか。

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-method-settings-method-response.html

統合レスポンス、ゲートウェイのレスポンスでまかなえているようだった。

slack → RaspberryPiを実現するため

python3.6で実装

下記を参考に

【AWS Lambdaの基本コードその4】 AWS IoTにメッセージをPublish

事前に作っておいたエンドポイント raspberrypi/speak へ送信

RaspberryPi側でsubscribeできることを確認しておく

 

Lambda応答

return {
‘isBase64Encoded’: False,
‘statusCode’: statusCode,
‘body’: json.dumps(dict),
‘headers’: {
‘Content-Type’: ‘application/json’,
},
}

 

Lambdaの注意点

API Gateway側でプロキシ統合を選んだ場合は、Lambda側で実装しなくてはならない

API Gateway側で吸収するなら、決まった形式で返す必要がある

こことか参考にさせてもらった

https://qiita.com/taknuki/items/dd47d1c6d4190b52df9a#%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9

 

テスト送信しておく

AWS IoT

raspberry pi用のthingsを作成

ダウンロードした証明書とroot証明書を配置、エンドポイントを控えておく

 

Raspberry Pi

AWS IoTのMQTTクライアントを導入。Pahoを使用。

下記にまとめている

https://github.com/nilesflow/AWSIoTSpeaker/blob/master/README.md

 

AWS IoT Device SDK for C 等もあるが、pythonクライアントとした

下記ソースを参考にさせて貰った

MQTT with AWS IoT Platform using Python and Paho

から参照して下記Git Repository

https://github.com/pradeesi/AWS-IoT-with-Python-Paho

 

準備

pip install paho-mqtt

pip install boto3

git clone https://github.com/nilesflow/AWSIoTSpeaker/blob/master/README.md

証明書を配置

vi config.ini

  • AWS IoTのHost、証明書情報を入力
  • トピック名を指定

今回は、raspberrypi/#とした

 

起動(バックグラウンド起動しておく)

python index.py &

 

Amazon polly でテキスト→音声変換し、mp3ファイルをローカルに保存

mp3ファイルを再生

音声ファイルの生成処理は下記を参照

AWS SDK for Python (boto3)でAmazon Pollyの声を使い分けてみる

 

mp3の再生は下記を参考に

第12回「Raspberry Piで音遊び!」

 

コマンドラインからの再生テスト

apt-get install mpg321

mpg321 polly.mp3

 

pythonからの再生は下記を参照

https://qiita.com/Nyanpy/items/cb4ea8dc4dc01fe56918

pygameで再生

 

上記ソースでは、raspberrypi/speak トピックで指定音声を再生するようにしている

AWS IoTのテスト画面からトピックを発行して確認しておく

★アプリレビュー
手順がよくわからなかったのでメモ。

・アプリレビュー
https://developers.facebook.com/apps/1718184088469400/review-status/

・スクリーンショットが必要。
・テストユーザを指定してください。
 という事で、本番アプリのテストユーザを指定
・ただ、本番アプリのテストユーザは、まだpages_messaging自体がないので、本番ページとやり取りできない。
・なので、テストユーザで作成したページを使ってもらう想定。でよいのか?
・アプリレビューでは、本物ページしか選べない。から担当者に伝えるすべがないが。。

レビュー用に本番アプリでテストユーザで作成したページを対応させる手順は以下。
https://developers.facebook.com/bugs/230322797329131/?hc_location=ufi

1) Create test user by toggling the Authorize test users for this app and grant permissions “manage_pages” and “page_messaging”.
2) Use the Edit Button and get an access token for this user (using v2.6). Please save this for later.
3) Use edit button to login as the test user
4) After login, create page as the test user
5) Use the user access token for the test user to get the page access token for this user. You can do this with the following call:
https://graph.facebook.com/v2.6/me/accounts?access_token=

6) Use this page access token to link your Facebook Application with your Page.
https://graph.facebook.com/v2.6/me/subscribed_apps?method=POST&access_token=

7) After you have followed these steps you will receive RTU updates to your Test Page and be able to message your Test User from your Test Page.

最後のこれも必要だった。ページアクセストークンの有効期限が短いので、多分レビュー前に切れてしまう。
GET /oauth/access_token?
grant_type=fb_exchange_token&
client_id={app-id}&
client_secret={app-secret}&
fb_exchange_token={short-lived-token}

・本番アプリ上のページアクセストークンを、上記テストユーザのページのページアクセストークンに変えた。
・で、申請。

で、良いのか。。

★開発環境
https://developers.facebook.com/apps/1718184088469400/dashboard/
メニューから「テストアプリ」が作成できる。

製品を追加で、「Messenger」を追加。
後の設定は同じ。

使い方としては、

本番アプリ – 本番ページ – 自分、他(レビュー後、無制限)
      – テストユーザページ – テストユーザ
テストアプリ – 開発ページ – 自分 ※アプリレビュー無いから、他は、個別に招待した人
– テストユーザページ – テストユーザ

という感じかな。
開発ページに対する、開発アプリの作成は不要。

ELBは各リージョン。

cloudfrontは、バージニア北部のみ。

 

https://elb.nilesflow.net

https://cloudfront.nilesflow.net/

SSL評価はAだったよという話。
https://www.ssllabs.com/ssltest/analyze.html?d=cloudfront.nilesflow.net&latest
https://www.ssllabs.com/ssltest/analyze.html?d=elb.nilesflow.net&latest