LoginSignup
5
7

More than 3 years have passed since last update.

【LINE Messaging API】Pythonで誰かと繋がる BOTを作成

Last updated at Posted at 2019-12-02

ランダムチャット

本Botを友達追加している中で、ランダムにユーザと繋がることができる

流れ

1.「NEXT」を押下することで、誰かと繋がる
image.png

2.「REMOVE」を押下することで、離脱できる(※離脱しない限り、繋がり続ける)
image.png

ソースコード

 randomchat
    |
    |_ config.py
    |
    |_ lineapp.py
    |
    |_ lineapphandl.py
    |
    |_ reply.py
    |
    |_ richmeny.py

ご自身のチャネルを確認して、設定する
チャネルアクセストークン
チャネルシークレット

config.py
# LINE Messaging API
YOUR_CHANNEL_ACCESS_TOKEN = 'チャネルアクセストークン'
YOUR_CHANNEL_SECRET = 'チャネルシークレット'

# messages
NEXT = 'NEXT'
NOTNEXT = 'NO PARTICIPANT'
MATCHED = 'MATCHED'

REMOVE = 'REMOVE'

REMOVED = 'REMOVED'

FAILED = 'FAILED'

1.リッチメニューが存在するかチェックする
 (詳しくは、リッチメニュー作成を見てくください)

2.メッセージを受信すると、TextMessageメソッドが呼ばれる
 (詳しくは、オウム返し BOTを見てください)

lineapp.py
from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import config, lineapphandl, richmenu
import os


app = Flask(__name__)

YOUR_CHANNEL_SECRET = config.YOUR_CHANNEL_SECRET
YOUR_CHANNEL_ACCESS_TOKEN = config.YOUR_CHANNEL_ACCESS_TOKEN

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

# check for existing richmenu
rich_menu_list = line_bot_api.get_rich_menu_list()
if not rich_menu_list:
    result = richmenu.createRichmeu()
    if not result:
        reply.reply_message(event, config.FAILED)

@app.route("/callback", methods=['POST'])
def callback():
    # get X-Line-Signature header value
    signature = request.headers['X-Line-Signature']

    # get request body as text
    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    # handle webhook body
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        print("Invalid signature. Please check your channel access token/channel secret.")
        abort(400)

    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    lineapphandl.TextMessage(event)

if __name__ == '__main__':
    app.run()

<createRichmenuメソッド>

richmenu.py
from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    RichMenu, RichMenuSize, RichMenuArea, RichMenuBounds, MessageAction, PostbackTemplateAction
)
import randomchat.config


def initMenu(line_bot_api):
    result = False
    try:
        # define a new richmenu
        rich_menu_to_create = RichMenu(
            size = RichMenuSize(width=1200, height=405),
            selected = True,
            name = 'richmenu for randomchat',
            chat_bar_text = 'TAP HERE',
            areas=[
                RichMenuArea(
                    bounds=RichMenuBounds(x=0, y=0, width=480, height=405),
                    action=MessageAction(text='REMOVE')
                ),
                RichMenuArea(
                    bounds=RichMenuBounds(x=480, y=0, width=720, height=405),
                    action=MessageAction(text='NEXT')
                )
            ]
        )
        richMenuId = line_bot_api.create_rich_menu(rich_menu=rich_menu_to_create)

        # upload an image for rich menu
        image = 'richmenu.jpg'
        path = '/home/web/randomchat/' + image

        with open(path, 'rb') as f:
            line_bot_api.set_rich_menu_image(richMenuId, "image/jpeg", f)

        # set the default rich menu
        line_bot_api.set_default_rich_menu(richMenuId)

        result = True

    except Exception:
        result = False


    return result

<TextMessageメソッド>
1.ユーザー管理の処理
2.「NEXT」or「REMOVE」or メッセージの処理

lineapphandle.py
from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import config, reply
import random, copy

YOUR_CHANNEL_SECRET = config.YOUR_CHANNEL_SECRET
YOUR_CHANNEL_ACCESS_TOKEN = config.YOUR_CHANNEL_ACCESS_TOKEN

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)

usersList = []
usersDic = {}

def TextMessage(event):
    userId = event.source.user_id
    message = event.message.text

    if not userId in usersList:
        usersList.append(userId)
        if not userId in usersDic.keys():
            usersDic[userId] = {}
            usersDic[userId]['toUserId'] = ''

    toUsersList = copy.copy(usersList)
    toUsersList.remove(userId)


    if message == config.NEXT:
        if not len(toUsersList) == 0:
            num = random.randint(0, int(len(toUsersList)-1))
            usersDic[userId] = toUsersList[num]
            toUserId = toUsersList[num]
            usersDic[toUserId] = userId

            # delete Id form list
            usersList.remove(userId)
            usersList.remove(toUserId)

            # reply
            message = TextSendMessage(text=config.MATCHED)
            reply.reply_message(event, message)
            reply.push_message(toUserId, message)

        else:
            message = TextSendMessage(text=config.NOTNEXT)
            reply.reply_message(event, message)

    elif message == config.REMOVE:
        usersList.remove(userId)
        toUserId = usersDic[userId]
        if userId in usersDic.values():
            pushMessage = TextSendMessage(text=config.REMOVED)
            reply.push_message(toUserId, pushMessage)
            usersDic[toUserId] = ''
        usersDic.pop(userId)

        message = TextSendMessage(text=message)
        reply.reply_message(event, message)

    else:
        if usersDic[userId] == '':
            message = TextSendMessage(text=message)
            reply.reply_message(event, message)

        else:
            toUserId = usersDic[userId]
            message = TextSendMessage(text=message)
            reply.push_message(toUserId, message)

<リプライメソッド>
reply_message: メッセージを送信してきたユーザに送る(詳しくは、を見てください)
push_message: 指定したユーザにメッセージを送る

reply.py
from flask import Flask, request, abort

from linebot import (
    LineBotApi, WebhookHandler
)
from linebot.exceptions import (
    InvalidSignatureError
)
from linebot.models import (
    MessageEvent, TextMessage, TextSendMessage,
)
import config, lineapphandl


YOUR_CHANNEL_SECRET = config.YOUR_CHANNEL_SECRET
YOUR_CHANNEL_ACCESS_TOKEN = config.YOUR_CHANNEL_ACCESS_TOKEN

line_bot_api = LineBotApi(YOUR_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(YOUR_CHANNEL_SECRET)


def reply_message(event, message):
    line_bot_api.reply_message(
        event.reply_token,
        message
    )

def push_message(toUserId, message):
    line_bot_api.push_message(
        toUserId,
        message
    )
5
7
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
5
7