주먹밥 군 탄생, 번영, 죽음

이 기사는 오고전 엔지니어 공부회 Advent Calendar 2017 1일째 기사가 됩니다.

🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍙🍘🍙🍙🍙🍙

안녕하세요, 찬유입니다.

취미의 연장으로 친구와 로컬 커뮤니티 라디오를 Podcast로 전달하고 있습니다.
준비를 Trello로 태스크 관리하면서 진행해 나가는 가운데, Trello의 카드를 LINE으로 통지해 주면 편리하다-라고 생각했기 때문에, 그런 주먹밥 군bot을 만들어 부서진 이야기입니다.

무엇을 만들었는가



Trello로 카드가 이동하면 LINE에 통지해주는 bot.



주먹밥 군이라고합니다.

왜 만들었는가



원래 왜 LINE인가



Slack 사용하면 순식간에 만들 수 있다고 할까, 논프로그래밍으로 설정할 수 있습니다만, 간선 Slack는 특히 정보계에 희소한 학생에게는 문턱이 높았습니다. (경험담)
Notification 나니솔레? 라고 말해 하나씩 사용법 가르치는 것도 뼈가 부러지는 것입니다.

그렇게 LINE에서 교환해 개발이나 라디오의 수록을 실시하게 된 것이었습니다.

IFTTT 시대



처음에는 IFTTT 연계하여 LINE Notify가 가르쳐 주었습니다.



하지만 러그가 심하고 힘들었습니다.

주먹밥 군의 탄생



거기서 자작bot 제작에 밟았습니다.



이렇게 Trello의 카드가 이동할 때마다 주먹밥 군이 가르쳐 주게 되었습니다.

어떻게 만들었는지



나는 파이썬 만 쓸 수 있기 때문에 파이썬의 장고에서 바삭 바삭했습니다.
코드는 GitHub 에 올리고 있습니다.

자꾸 이런 느낌이 되었습니다.

trello/views.py
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")


line/views.py

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의 토크내에서 おにぎり 가 포함된 발언을 하면, 주먹밥 군이 반응해 줍니다.



오기니는 좋지 않았습니다.

가동 후 주먹밥 군



그 후, 주먹밥 군은 사망, 그 후 소생하는 ​​것으로 부활해, 나아가서는 좀비화한 거구, 거인을 대신해 대체된 것이었습니다.
자세한 내용은 다시 씁니다.

낭문 실례했습니다.

좋은 웹페이지 즐겨찾기