この記事は呉高専エンジニア勉強会 Advent Calendar 2017 1日目の記事になります。
🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍘🍙🍙🍙🍙
こんにちは、ちゃんゆーです。
趣味の延長で友人とローカルなコミュニティラジオをPodcastで配信しています。
準備をTrelloでタスク管理しながら進めていくなかで、TrelloのカードをLINEで通知してくれたら便利だなーと思ったので、そんなおにぎりくんbotを作って壊した話です。
何を作ったのか
Trelloでカードが移動したらLINEに通知してくれるbot。
おにぎりくんと呼ばれています。
なぜ作ったのか
そもそもなぜLINEなのか
Slack使えば一瞬で作れますというか、ノンプログラミングで設定できますが、いかんせんSlackは特に情報系に疎い学生には敷居が高いのでした。(経験談)
Notificationナニソレ? と言われてひとつづつ使い方教えるのも骨が折れるのです。
そうしてLINEでやり取りして開発やラジオの収録を行うことになったのでした。
IFTTT時代
最初はIFTTT連携してLINE Notifyが教えてくれていました。
でもラグがひどくてつらかったのです。
おにぎりくんの誕生
そこで自作bot製作に踏み切りました。
こうしてTrelloのカードが移動する度におにぎりくんが教えてくれるようになりました。
どうやって作ったのか
僕はPythonしか書けないので、PythonのDjangoでサクッと組みました。
コードはGitHubにあげています。
ざっくりこんな感じになりました。
from django.shortcuts import render
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
import json
import requests
import os
from line.views import push_message
REPLY_ENDPOINT = 'https://api.line.me/v2/bot/message/reply'
ACCESS_TOKEN = os.getenv('LINE_ACCESS_TOKEN')
LINE_USERID = os.getenv('LINE_USERID')
LINE_GROUPID = os.getenv('LINE_GROUPID')
HEADER = {
"Content-Type": "application/json",
"Authorization": "Bearer " + ACCESS_TOKEN
}
def index(request):
return HttpResponse("Hello World")
@csrf_exempt
def callback(request):
try:
action = json.loads(request.body.decode('utf-8'))['action']
from pprint import pprint
pprint(action)
entities = action['display']['entities']
action_type = action['display']['translationKey']
if action_type == 'action_create_card':
list_name = entities['list']['text']
card_name = entities['card']['text']
member_name = entities['memberCreator']['text']
body = f'カード「{card_name}」がリスト「{list_name}」に追加されました。\n追加者:{member_name}'
push_message(LINE_GROUPID, body)
elif action_type == 'action_move_card_from_list_to_list':
after_list_name = entities['listAfter']['text']
before_list_name = entities['listBefore']['text']
card_name = entities['card']['text']
member_name = entities['memberCreator']['text']
body = f'カード「{card_name}」がリスト「{before_list_name}」からリスト「{after_list_name}」に移動されました。\n移動者:{member_name}'
push_message(LINE_GROUPID, body)
except Exception as e:
pass
return HttpResponse("callback")
from django.shortcuts import render
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
import json
import requests
import os
REPLY_ENDPOINT = 'https://api.line.me/v2/bot/message/reply'
PUSH_ENDPOINT = 'https://api.line.me/v2/bot/message/push'
ACCESS_TOKEN = os.getenv('LINE_ACCESS_TOKEN')
HEADER = {
"Content-Type": "application/json",
"Authorization": "Bearer " + ACCESS_TOKEN
}
def index(request):
return HttpResponse("Hello World")
@csrf_exempt
def callback(request):
events = json.loads(request.body.decode('utf-8'))['events']
for event in events:
reply_token = event['replyToken']
if event['type'] == 'message':
if event['message']['type'] == 'text':
if 'debug' in event['message']['text']:
reply = event['message']['text']
reply += get_line_ids(event['source'])
reply_message(reply_token, reply)
elif 'おにぎり' in event['message']['text']:
reply = 'おにぎりくんだよ。呼んだ?'
reply_message(reply_token, reply)
else:
pass
else:
pass
else:
pass
return HttpResponse("callback")
def get_line_ids(source):
reply = ''
if 'userId' in source:
reply += '\nuserId:' + source['userId']
if 'groupId' in source:
reply += '\ngroupId:' + source['groupId']
if 'roomId' in source:
reply += '\nroomId:' + source['roomId']
return reply
def reply_message(reply_token, reply):
reply_body = {
"replyToken":reply_token,
"messages":[
{
"type": "text",
"text": reply
}
]
}
requests.post(REPLY_ENDPOINT, headers=HEADER, data=json.dumps(reply_body))
def push_message(to, message):
push_body = {
"to": to,
"messages":[
{
"type": "text",
"text": message
}
]
}
requests.post(PUSH_ENDPOINT, headers=HEADER, data=json.dumps(push_body))
改良の余地が大いにあるコードたちです。
おにぎりくんの定着
コードを見ての通り、LINEのトーク内で おにぎり
が含まれた発言をすると、おにぎりくんが反応してくれます。
おぎにりはダメでした。
稼働後のおにぎりくん
その後、おにぎりくんは死亡、その後蘇生することで復活し、さらにはゾンビ化した挙句、巨人に取って代わられたのでした。
詳細についてはまた書きますね。
駄文失礼いたしました。