0
0

More than 3 years have passed since last update.

GoogleAssistantからWebhookでLineの特定人物へPush通知

Last updated at Posted at 2020-03-08

アンドロイドスマホに搭載のGoogleAssistantもしくはGoogleHome系のアプリを作りました。
サムネイル.png

実際の図

GoogleAssistantで"アイで"と発話すると"hello"と返し、Line側には"アイで"がPUSH通知されます。
1.jpg
2.jpg

そもそも

GoogleAssistant→DialogFlow→LineはIntegrationsで設定すればすぐできますが、
テキストを返すことはできません。
またIntegrationsの方法は自分のLINEへはPUSH通知できますが、特定の人へPUSH通知はできません。

基本、google homeで子供の宿題管理をするの実装手順にてできました。うまくいかなかった箇所を本記事に加えてます。

フロー図

google homeで子供の宿題管理をするからお借りして一部付け加えてます。
フロー図Line改.png

DialogFlow

テストでIntentのパラメータを$anyにしてます。
これで”アイで”と発話すればこのIntentが起動します。
Lambda_error.png

Lambda

なぜLambdaを経由しているのかというと、GASでデプロイしたエンドポイントは、302リダイレクトをしてしまい、DialogflowのWebhookとして使えなかったからです。

一番のハマりポイント

google homeで子供の宿題管理をする通り実行するとLambda関数にて下記エラーが出ます。
Gasistant側.png
該当箇所↓
body = json.dumps(json.loads(event["body"])).encode("utf-8")

ん?event["body"]ってなに?
jsonデータ見ても”request”なんだけど…

色々調べてみると下記に書いてありました。

API Gatewayの「Lambda プロキシ統合の使用」オプションより

結論から言うと、API Gatewayにてプロキシ統合の使用をチェックすればOKです。
APIGate.png

試しにPOSTしてみたところ、Lambdaのeventには以下の値が設定されていました。

hoge.json
{
    resource: '/mook',
    path: '/mook',
    httpMethod: 'POST',
    headers: { Accept: ' application/json' },
    queryStringParameters: { param1: 'value1' },
    pathParameters: null,
    stageVariables: null,
    requestContext: {
        accountId: 'xxxxxxxxxxxx',
        resourceId: 'xxxxxx',
        stage: 'test-invoke-stage',
        requestId: 'test-invoke-request',
        identity: {
            cognitoIdentityPoolId: null,
            accountId: 'xxxxxxxxxxxx',
            cognitoIdentityId: null,
            caller: 'xxxxxxxxxxxx',
            apiKey: 'test-invoke-api-key',
            sourceIp: 'test-invoke-source-ip',
            cognitoAuthenticationType: null,
            cognitoAuthenticationProvider: null,
            userArn: 'arn:aws:iam::xxxxxxxxxxxx:root',
            userAgent: 'Apache-HttpClient/4.5.x (Java/1.8.0_102)',
            user: 'xxxxxxxxxxxx'
        },
        resourcePath: '/mook',
        httpMethod: 'POST',
        apiId: 'xxxxxxxxxx'
    },
    body: '{"Message": "Hello World"}'
}   

API Gatewayがこれまで丸めていたHTTPヘッダーの情報をかなりきちんと得ることができます。

Spreadsheet with GAS

下記GASのコードです

code.gs
// プロパティ取得
const PROPERTIES = PropertiesService.getScriptProperties();

const LINE_CHANNEL_ACCESS_TOKEN = PROPERTIES.getProperty('LINE_CHANNEL_ACCESS_TOKEN');//GLG_test_bot
const USER_ID = PROPERTIES.getProperty('your_USER_ID');

function doPost(e) {
 try {
   let request = JSON.parse(e.postData.getDataAsString());
   let any = request.queryResult.parameters.any
   switch (any) {
     case 'アイ':
       let result = { "fulfillmentText": "hello" };//fulfillmentTextが大事!
       pushMessage(any)
       return returnAsJSON(result);
     default:
       return returnAsJSON({ "fulfillmentText": "ごめんね。よくわからなかったよ" });
   }
 } catch (ex) {
   Logger.log("Error at doPost : %s", ex)
   doc.getBody().appendParagraph(Logger.getLog())
   return returnAsJSON({ "fulfillmentText": "エラーが発生しました。ログで確認できます" });
 }
}

function returnAsJSON(obj) {
 return ContentService.createTextOutput(JSON.stringify(obj)).setMimeType(ContentService.MimeType.JSON);
}

function pushMessage(message) {
 let postData = {
   "to": USER_ID,
   "messages": [{
     "type": "text",
     "text": message,
   }]
 };

 let url = "https://api.line.me/v2/bot/message/push";
 let headers = {
   "Content-Type": "application/json",
   'Authorization': 'Bearer ' + LINE_CHANNEL_ACCESS_TOKEN,
 };

 let options = {
   "method": "post",
   "headers": headers,
   "payload": JSON.stringify(postData)
 };
 let response = UrlFetchApp.fetch(url, options);
}

GASはウェブ公開にてデプロイし、そのあと出てくるURLをLambda側にコピペすればOK

※Lineについて別途設定が必要ですが、特別なことはやっていないので設定等は割愛。
LineBotでググればいくらで出てきます。

あとはDialogFlow側でテストし、AWSのcloudwatchのログなどを見ながら実装する。

今後の展望

GASが使えるのでスプレッドシートと連携して色々できます。

参考:

google homeで子供の宿題管理をする
初めてのサーバーレスアプリケーション開発 ~API GatewayからLambdaを呼び出す~ | Developers.IO

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0