この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、リサリサです。以下の続きです。
①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時間置きに動かします。
テスト
いい感じです。
次はこの後のリアクションに対する応答機能を作ります。
後編へ続く
すみません…続きは後編へ…