0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

chatwork-webhook→AWS Lambda →Googleスプレッドシートでメッセージを記録する

Last updated at Posted at 2022-11-10

実現したいこと

chatworkの無料アカウントだと過去のメッセージが閲覧できなくなってしまったので、
閲覧期限が過ぎたメッセージを見返すために都度メッセージを記録する処理を作りたい。

はじめに

復習を兼ねて記事にしました。
スプレッドシートウェブアプリとlambdaを併用する意味はあまりないと思います。
lambdaを使いたくなったというのと最初はメッセージの保存先をスプレッドシートにするつもりがなかったので、
結局この形になってしまいました。
特にこだわりがなければスプレッドシートウェブアプリをwebhook urlとして使った方が早いかもしれません。

環境

chatwork webhook
AWS Lambda
AWS API Gateway
python 3.9
Googleスプレッドシート
GAS
Windows 11

実行手順

1 スプレッドシートウェブアプリの作成

[1] GASプロジェクトに以下コードを転記

function doPost(e) {
  const post = e.postData.contents
  const sheet = SpreadsheetApp.getActiveSheet(); 
  const postObj = JSON.parse(post)
  
  const webhook_event = postObj["webhook_event"]
  insertWebhookEvent(sheet, webhook_event)
}

// 対象シートの最終行にwebhook_eventの内容をそのまま転記する関数
// sheet:対象シート webhook_event:chatwork_webhookのbody["webhook_event"]
const insertWebhookEvent = (sheet, webhook_event) => {
  const keys = Object.keys(webhook_event)
  const insertAry2d = keys.map((key) => {
    if (key === "send_time") {
      const sendDateJst = Utilities.formatDate(new Date(webhook_event[key] * 1000), "JST", "yyyy/MM/dd HH:mm:ss");
      return sendDateJst
    }
    return webhook_event[key]
  })
  
  sheet.appendRow(insertAry2d)

}

[2] デプロイする

 右上のデプロイをクリック
 -> 新しいデプロイ
 -> ウェブアプリを選択
 -> 適当な名称を付ける(アクセスできるユーザーは全員)
 -> URLをメモ

2 webhookの編集

[1] webhookの新規作成

※この時のURLはとりあえず、メモしたスプレッドシートウェブアプリのURLを入力

6_webhookの作成画面.png

[2] 作成したwebhookのトークンをメモ

 ※新規作成後、webhook設定IDの下にあります。

3 lambda関数の作成

[1] aws lambdaを開く

 AWS Lambda
 -> 関数
 -> 関数の作成をクリック

[2] lambdaの基本情報の入力

 一から作成
 -> 基本的な情報を入力
 -> 右下、関数の作成をクリック

1_lambdaの設定.png

[3] webhookからリクエストを受け、スプレッドシートウェブアプリにpostする関数の作成

コードソース -> lambda_functionに以下の内容を転記

import os
import base64
import hashlib
import hmac
import json
import requests

def lambda_handler(event, context):
    # webhook編集画面のtoken
    token = os.environ["CHATWORK_API_TOKEN"]
    # リクエストヘッダー内の署名検証に使うための署名文字列
    request_signature = event["headers"]["x-chatworkwebhooksignature"]
    request_body = event["body"]
    
    digest = hmac.new(base64.b64decode(token), request_body.encode("utf-8"), hashlib.sha256).hexdigest()
    expected_signature = base64.b64encode(bytes.fromhex(digest)).decode("utf-8")

    # 署名確認
    if not(request_signature == expected_signature):        
        print("署名エラー")
        return {
            "statusCode": 410,
            "body": "SignatureDoesNotMatch"
        }
        
    url = os.environ["SPREADSHEET_URL"]

    json_item = json.dumps(event)
    j = json.loads(json_item)
    webhook_body = j["body"]
    requests.post(url, data=webhook_body.encode("utf-8"))
    
    return {
        "statusCode": 200
    }

🖊上記のコードの内容
 json_itemまででリクエストされた値の署名検証行っている
 署名検証で許可された場合、スプレッドシートウェブアプリにpostリクエストを行う
 スプレッドシートウェブアプリとwebhook編集画面のtokenは環境変数から取得する

[4] 環境変数の設定

 関数作成画面中央部、設定をクリック
 -> 左一覧から環境変数をクリック
 -> 編集をクリック
 -> キー、値に以下を入力し1個ずつ作成し保存

キー
SPREADSHEET_URL スプレッドシートウェブアプリのURL
CHATWORK_API_TOKEN webhook編集画面のtoken

2_環境変数の設定.png

[5] requestsライブラリが入ったzipフォルダを作成

 ※ lambda環境下ではpip installができないため、一度zipにしてからアップロードする必要がある

 ローカル環境にて以下を実行

mkdir python
cd python
pip install -t ./ requests
cd ../
zip -r requests.zip python/

 ※ 最初に作成するフォルダはpythonという名称である必要がある

🖊参考
AWS Lambdaでレイヤー追加してもエラーが解決しないのはフォルダ名が問題だった

[6] zipフォルダをアップロードする

 lambda ダッシュボード
 -> レイヤー
 -> レイヤーの作成をクリック
 -> 適当な名称を付け、zipをアップロード(他の設定は特に必要ない
 -> 作成したレイヤーのバージョンarnをメモ

3_arnnum取得.png

[7] 作ったlambda関数内でrequestsを使えるようにする

 関数作成画面下部レイヤーからレイヤーの追加をクリック
 -> arnの指定をクリック
 -> メモしたバージョンarnを入力し追加ボタンクリック

4_arnの指定.png

2 ApiGatewayの設定

[1] HTTP APIの構築

 aws ApiGatewayを開く
 -> apiの作成をクリック(過去に使ってないと出ないかも)
 -> HTTP API の構築をクリック

[2] 統合を作成

 統合のプルダウンからlambda
 -> Lambda関数で先ほど作った関数を指定
 -> 適当なapi名を付ける
 -> 次へ

5_統合の作成.png

[3] ルートの設定(ステージはなにもしない)

 メソッドをpostに変更
 -> 次へ
 -> ステージはそのままで次へ

[4] 作成したapi_gatewayのurlをwebhookの編集にて入力

 とりあえず入力しておいた、スプレッドシートウェブアプリのURLを削除してapi_gatewayのurlを入力

以上で特定のメッセージルームでメッセージが飛び交うたびに
スプレッドシートに内容が転記されるようになっているはずです。

おわりに

 最初から記事にするつもりはなかったため、ところどころ抜けがあるかもしれません。
 抜けがあったら申し訳ないです。

 また、lambdaで実装した署名検証をlambda authorizerとして別に作るのも面白そうなので、
 気が向いたら作ってみるのもいいかなと思いました。

参考

チャットワークのwebhookの署名検証をPythonで実装してみた
aws lambda に外部ライブラリをインストールする方法
chatwork to Discord webhookを使ったLambda python
【GAS】チャットワークのメッセージを取り出す関数とメッセージを送る関数

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?