薬を飲むまで飲んだか聞いてくるLINE botアプリを作ってみた[中編]
こんにちは、リサリサです。以下の続きです。
①Push機能を作る
作るもの
①Push機能:この機能のスタートになる機能です。
構成はこんな感じです。
①EventBrigeから起動
②メッセージを送る対象のユーザーをSSMのパラメーターストアから取得
③対象がまだ今日薬を飲んでいないか、DynamoDBを見て確認
④飲んでいなければメッセージをプッシュ
という機能を作ります。
Lambdaの枠を作成
line-bot-medical-pushを作成します。
さっき作ったレイヤーを追加。
環境変数に、以下を追加。前編で控えた「チャンネルアクセストークン」を設定します。
メッセージプッシュのサンプルコードを試してみる
line-bot-sdkを使ったサンプルコードのテストをしてみます。
リファレンスはここにあります。
TEXTメッセージ
LINEへのメッセージのpushは以下のようにするみたいです。
line_bot_api = LineBotApi(channel_access_token=チャンネルアクセストークン) line_bot_api.push_message(あなたのユーザーID, TextSendMessage(text='Hello World!'))
試しに書いてみる
import json import os from linebot import (LineBotApi, WebhookHandler) from linebot.models import (MessageEvent, TextMessage, TextSendMessage) from linebot.exceptions import (LineBotApiError, InvalidSignatureError) def lambda_handler(event, context): user_id = 'U20985f92f155b8d6211c4ce99c6c59dd' line_bot_api = LineBotApi(channel_access_token=チャンネルアクセストークン) line_bot_api.push_message(あなたのユーザーID, TextSendMessage(text='Hello World!')) return { 'statusCode': 200, 'body': json.dumps('ok', ensure_ascii=False) }
テスト
ボタン付きのメッセージ
今回は、ボタン付きのメッセージを送信したいので、以下のようになるみたいです。
line_bot_api = LineBotApi(channel_access_token=チャンネルアクセストークン) buttons_template_message = TemplateSendMessage( alt_text='Buttons template', template=ButtonsTemplate( title='Menu', text='Please select', actions=[ PostbackAction( label='postback', display_text='postback text', data='action=buy&itemid=1' ) ] ) ) line_bot_api.push_message(あなたのユーザーID, buttons_template_message)
試しに書いてみる
line_bot_api = LineBotApi(channel_access_token=チャンネルアクセストークン) buttons_template_message = TemplateSendMessage( alt_text='Buttons template', template=ButtonsTemplate( title='Menu', text='Please select', actions=[ PostbackAction( label='postback', display_text='postback text', data='action=buy&itemid=1' ) ] ) ) line_bot_api.push_message(あなたのユーザーID, buttons_template_message)
テスト
Lambdaのコードを作成
本編のコードを書きます。
import json import datetime import os import traceback import boto3 from linebot import (LineBotApi, WebhookHandler) from linebot.models import (MessageEvent, TextMessage, TextSendMessage,TemplateSendMessage,PostbackAction,ButtonsTemplate) from linebot.exceptions import (LineBotApiError, InvalidSignatureError) def getDynamoKey(user_id,date): """ DynamoDBからデータを取得 """ dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('line-bot-medical') get_item = table.get_item( Key={ "user_id": user_id ,"date": date } ) if 'Item' not in get_item: item = '' else: item = get_item['Item'] print(item) return item def get_parameters(param_key): """ パラメーターストアから値を取得 """ ssm = boto3.client('ssm', region_name='ap-northeast-1') response = ssm.get_parameters( Names=[ param_key, ], WithDecryption=True ) return response['Parameters'][0]['Value'] def lambda_handler(event, context): try: print(event) today = (datetime.datetime.utcnow() + datetime.timedelta(hours=9)).strftime('%Y/%m/%d') #送信先のユーザーを取得 if 'user_id' in event: # テスト時はeventから送信先のユーザーを取得 users = [event['user_id']] else: # メッセージをを送る対象のユーザーをSSMのパラメーターストアから取得 users = json.loads(get_parameters('line-bot-medical-push-users')) for user in users: # 対象がまだ今日薬を飲んでいないか、DynamoDBを見て確認 status_data = getDynamoKey(user,today) if 'status' in status_data: status = status_data['status'] else: status = '' if status != 'ok': # 飲んでいなければメッセージをプッシュ buttons_template_message = TemplateSendMessage( alt_text='お薬飲んだ?', template=ButtonsTemplate( title=today, text='お薬飲んだ?', actions=[ PostbackAction( label='飲んだよ', display_text='飲んだよ', data=f"date={today}&status=ok" ), PostbackAction( label='後で飲むよ', display_text='後で飲むよ', data=f"date={today}&status=ng" ) ] ) ) #メッセージ送信 line_bot_api = LineBotApi(channel_access_token=os.environ['ACCESS_TOKEN']) line_bot_api.push_message(user, buttons_template_message) return { 'statusCode': 200, 'body': json.dumps('ok', ensure_ascii=False) } except: traceback.print_exc() return { 'statusCode': 500, 'body': json.dumps('err', ensure_ascii=False) }
トリガーを設定
夜にだけ飲むお薬なので、19時から23時の間1時間置きに動かします。
テスト
いい感じです。
次はこの後のリアクションに対する応答機能を作ります。
後編へ続く
すみません…続きは後編へ…