PythonでLINEリッチメニューのテキストに応答してみた

前回作成したリッチメニューのメッセージアクションのテキストに対して、Pythonで応答してみました。

LINEリッチメニュー切り替えを試してみた

Flexmessageで返答と、シナリオ・メッセージで返答を試しました。Flex Messageは、レイアウトをカスタマイズできるメッセージです。

Flexmessageで応答

完成デモ

※ 全画面表示で再生ください。

Flex Message作成

Flex Message Simulator でレイアウトを確認しながら作成できます。サンプルもあるので、便利です!

前回同様、LINEスキマニを題材に、公式HPヘルプページのコンテンツをベースに作成してみました。Flex Message Simulatorで作成し、JSONコードをコピーして、以下、Pythonコードで使用します。

Pythonコード

公式のサンプルボットコードをベースに、@handler.add(MessageEvent, message=TextMessage)箇所を以下のように変更します。

@handler.add(MessageEvent, message=TextMessage)
def handle_text_message(event):
    text = event.message.text

    if text == '使い方':
        bubble_string = """
            {
              "type": "carousel",
              "contents": [
                {
                  "type": "bubble",
                  "body": {
                    "type": "box",
                    "layout": "vertical",
                    "spacing": "sm",
                    "contents": [
                      {
                        "type": "text",
                        "text": "1. 仕事を選ぶ",
                        "weight": "bold",
                        "align": "center",
                        "size": "xl",
                        "offsetTop": "-5px"
                      },
                      {
                        "type": "image",
                        "url": "https://portal.line-sukimani.me/hubfs/pic_step.png",
                        "size": "full",
                        "aspectMode": "fit",
                        "aspectRatio": "1.6:1"
                      },
                      {
                        "type": "text",
                        "text": "あなたの経験やスキルが活かせる仕事を選べます。「数時間だけ」や「明日すぐに」などあなたのスキマ時間に合わせて探しましょう。",
                        "size": "xxs",
                        "wrap": true
                      }
                    ]
                  }
                },
                {
                  "type": "bubble",
                  "body": {
                    "type": "box",
                    "layout": "vertical",
                    "spacing": "sm",
                    "contents": [
                      {
                        "type": "text",
                        "text": "2.即マッチング",
                        "size": "xl",
                        "weight": "bold",
                        "align": "center",
                        "offsetTop": "-5px"
                      },
                      {
                        "type": "image",
                        "url": "https://portal.line-sukimani.me/hubfs/pic_step_02.png",
                        "size": "full",
                        "aspectRatio": "1.6:1"
                      },
                      {
                        "type": "text",
                        "text": "LINEでプロフィールなどの情報を入力すれば、初回最短15分で応募完了です。企業との選考なしで求人案件とのマッチングが即完了します。",
                        "size": "xxs",
                        "wrap": true
                      }
                    ]
                  }
                },
                {
                  "type": "bubble",
                  "body": {
                    "type": "box",
                    "layout": "vertical",
                    "spacing": "sm",
                    "contents": [
                      {
                        "type": "text",
                        "text": "3.給与を受け取る",
                        "size": "lg",
                        "weight": "bold",
                        "align": "center",
                        "offsetTop": "-5px"
                      },
                      {
                        "type": "image",
                        "url": "https://portal.line-sukimani.me/hubfs/pic_step_03.png",
                        "size": "full",
                        "aspectRatio": "1.6:1"
                      },
                      {
                        "type": "text",
                        "text": "給与はLINEスキマニ内に勤務後即時反映され、好きなときに口座から引き出せます。口座振込申請もいつでも手数料0円です。",
                        "size": "xxs",
                        "wrap": true
                      }
                    ]
                  }
                }
              ]
            }
        """
        message = FlexSendMessage(alt_text="面接なしですぐ働けて、すぐ給与受け取れます!", contents=json.loads(bubble_string))
        line_bot_api.reply_message(
            event.reply_token,
            message
        )
    elif text == '働き方ガイド':
        bubble_string = """
            {
              "type": "carousel",
              "contents": [
                {
                  "type": "bubble",
                  "body": {
                    "type": "box",
                    "layout": "vertical",
                    "spacing": "sm",
                    "contents": [
                      {
                        "type": "text",
                        "text": "1. 出勤",
                        "weight": "bold",
                        "align": "center",
                        "size": "xl",
                        "offsetTop": "-5px"
                      },
                      {
                        "type": "image",
                        "url": "https://line-sukimani.zendesk.com/hc/article_attachments/4408163296015/___________320_-_LINE_Sukimani_App_-_Zeplin.png",
                        "size": "full",
                        "aspectMode": "fit",
                        "aspectRatio": "1.6:1"
                      },
                      {
                        "type": "text",
                        "text": "出勤簿から該当求人の「チェックイン」を押し、就業先のQRコードを読み取ります。",
                        "size": "xxs",
                        "wrap": true
                      }
                    ]
                  }
                },
                {
                  "type": "bubble",
                  "body": {
                    "type": "box",
                    "layout": "vertical",
                    "spacing": "sm",
                    "contents": [
                      {
                        "type": "text",
                        "text": "2.退勤",
                        "size": "xl",
                        "weight": "bold",
                        "align": "center",
                        "offsetTop": "-5px"
                      },
                      {
                        "type": "image",
                        "url": "https://line-sukimani.zendesk.com/hc/article_attachments/4408163296015/___________320_-_LINE_Sukimani_App_-_Zeplin.png",
                        "size": "full",
                        "aspectRatio": "1.6:1"
                      },
                      {
                        "type": "text",
                        "text": "出勤簿から該当求人の「チェックアウト」を押し、就業先のQRコードを読み取ります。",
                        "size": "xxs",
                        "wrap": true
                      }
                    ]
                  }
                },
                {
                  "type": "bubble",
                  "body": {
                    "type": "box",
                    "layout": "vertical",
                    "spacing": "sm",
                    "contents": [
                      {
                        "type": "text",
                        "text": "3.給与受取",
                        "size": "lg",
                        "weight": "bold",
                        "align": "center",
                        "offsetTop": "-5px"
                      },
                      {
                        "type": "image",
                        "url": "https://line-sukimani.zendesk.com/hc/article_attachments/360006133836/________2021_02_10_13_34.png",
                        "size": "full",
                        "aspectRatio": "1.6:1"
                      },
                      {
                        "type": "text",
                        "text": "マイページから「振込申請」を押すと、ご登録の口座にすぐに振込まれます。",
                        "size": "xxs",
                        "wrap": true
                      }
                    ]
                  }
                }
              ]
            }
        """
        message = FlexSendMessage(alt_text="簡単に出退勤でき、給与すぐ受け取れます!", contents=json.loads(bubble_string))
        line_bot_api.reply_message(
            event.reply_token,
            message
        )
    else:
        line_bot_api.reply_message(
            event.reply_token, TextSendMessage(text=event.message.text))

ローカルで実行して、テストする場合は下記をご覧ください。

LINEサンプルボット(Python)をローカルで動かしてみた(2021年版)

シナリオ・メッセージで応答

リッチメニューの「よくある質問」に対して、ポストバックアクションを使って、シナリオ・メッセージで応答してみました。

完成デモ

※ 全画面表示で再生ください。

シナリオメッセージ設計

今回もLINEスキマニを題材に、「よくある質問」をタップした際のシナリオ・メッセージを参考にさせていただきました。全シナリオは大変なので、以下、1シナリオのみ作成します。

よくある質問 > 本人確認が完了しない > (お役に立ちましたか?)はい

Flex Message作成

「よくある質問」と「お役に立ちましたか?」はFlex Message Simulatorで作成しました。それぞれのActionにpostbackを設定するのがポイントです。JSONコードをコピーして、以下、Pythonコードで使用します。

Pythonコード

公式のサンプルボットコードをベースに、@handler.add(MessageEvent, message=TextMessage)@handler.add(PostbackEvent)箇所を以下のように変更します。

@handler.add(MessageEvent, message=TextMessage)
def handle_text_message(event):
    text = event.message.text

    if text == 'よくある質問':
        bubble_string = """
            {
              "type": "bubble",
              "header": {
                "type": "box",
                "layout": "vertical",
                "contents": [
                  {
                    "type": "text",
                    "text": "よくある質問",
                    "weight": "bold",
                    "align": "center",
                    "color": "#ffffff"
                  },
                  {
                    "type": "text",
                    "text": "お困りの状況に該当するものをお選びください。",
                    "wrap": true,
                    "color": "#ffffff"
                  }
                ],
                "backgroundColor": "#00CC62"
              },
              "body": {
                "type": "box",
                "layout": "vertical",
                "contents": [
                  {
                    "type": "box",
                    "layout": "vertical",
                    "contents": [
                      {
                        "type": "text",
                        "text": "求人に応募できない",
                        "align": "center",
                        "color": "#42659a"
                      }
                    ],
                    "action": {
                      "type": "postback",
                      "label": "question",
                      "data": "action=question&id=1",
                      "displayText": "#応募できない"
                    }
                  },
                  {
                    "type": "box",
                    "layout": "vertical",
                    "contents": [
                      {
                        "type": "text",
                        "text": "本人確認が完了しない",
                        "color": "#42659a",
                        "align": "center"
                      }
                    ],
                    "margin": "12px",
                    "action": {
                      "type": "postback",
                      "label": "question",
                      "data": "action=question&id=2",
                      "displayText": "#本人確認が完了しない"
                    }
                  },
                  {
                    "type": "box",
                    "layout": "vertical",
                    "contents": [
                      {
                        "type": "text",
                        "text": "退会したい",
                        "align": "center",
                        "color": "#42659a"
                      }
                    ],
                    "margin": "12px",
                    "action": {
                      "type": "postback",
                      "label": "question",
                      "data": "action=question&id=3",
                      "displayText": "#退会したい"
                    }
                  }
                ]
              }
}
        """
        message = FlexSendMessage(alt_text="よくある質問", contents=json.loads(bubble_string))
        line_bot_api.reply_message(
            event.reply_token,
            message
        )
    else:
        line_bot_api.reply_message(
            event.reply_token, TextSendMessage(text="メニューから選択いただけると幸いです。"))
@handler.add(PostbackEvent)
def handle_postback(event):
    if event.postback.data == 'action=question&id=2':
        bubble_string = """
            {
              "type": "bubble",
              "size": "kilo",
              "body": {
                "type": "box",
                "layout": "vertical",
                "contents": [
                  {
                    "type": "text",
                    "text": "お役に立ちましたか?どちらかをタップしてください",
                    "size": "md",
                    "color": "#18202f",
                    "wrap": true
                  }
                ],
                "spacing": "sm",
                "paddingAll": "11px",
                "paddingStart": "14px",
                "paddingEnd": "14px",
                "backgroundColor": "#fafafa"
              },
              "footer": {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                  {
                    "type": "box",
                    "layout": "vertical",
                    "contents": [
                      {
                        "type": "text",
                        "text": "はい",
                        "align": "center",
                        "gravity": "center",
                        "flex": 1,
                        "color": "#42659a"
                      }
                    ],
                    "height": "30px",
                    "action": {
                      "type": "postback",
                      "label": "yesno",
                      "data": "yes",
                      "displayText": "はい"
                    }
                  },
                  {
                    "type": "box",
                    "layout": "vertical",
                    "contents": [
                      {
                        "type": "text",
                        "text": "いいえ",
                        "align": "center",
                        "gravity": "center",
                        "flex": 1,
                        "color": "#42659a"
                      }
                    ],
                    "height": "30px",
                    "action": {
                      "type": "postback",
                      "label": "yesno",
                      "data": "no",
                      "displayText": "いいえ"
                    }
                  }
                ],
                "paddingTop": "14px",
                "paddingBottom": "13px",
                "spacing": "sm"
              },
              "styles": {
                "footer": {
                  "separator": true
                }
              }
}
        """
        message2 = FlexSendMessage(alt_text="お役に立ちましたか?どちらかをタップしてください", contents=json.loads(bubble_string))
        text_string = """本人確認が失敗してしまう場合、以下の項目をご確認いただき、再度本人確認書類を提出してください。

■失敗例
✅本人確認書類とプロフィール情報(氏名/住所/生年月日)が一致していない
プロフィール情報の記載に誤りがないかご確認ください

✅本人確認書類の住所とプロフィール情報が一致していない
丁目、番地、マンション名、部屋番号など本人確認書類に記載されているとおりに入力してください

✅利用できない本人確認書類を提出している
利用可能な本人確認書類をご確認ください

✅書類全体が写っていない
一部が隠れていたり、破損している箇所がないか確認してください

✅カラーや白黒コピー、もしくはスキャンデータを提出している
コピーやスキャンデータではなく、原本を撮影し提出してください

以下のヘルプもご参照ください
https://line-sukimani.zendesk.com/hc/ja/articles/360002128296"""
        message1 = TextSendMessage(text=text_string)
        line_bot_api.reply_message(
            event.reply_token,
            [message1, message2]
        )
    elif event.postback.data == 'yes':
        line_bot_api.reply_message(
            event.reply_token, TextSendMessage(text="ご回答ありがとうございます。\nお役に立てて何よりです!"))

※返答テキスト箇所のコードが雑なのはご容赦ください。

ローカルで実行して、テストする場合は下記をご覧ください。

LINEサンプルボット(Python)をローカルで動かしてみた(2021年版)

まとめ

チャット(非定型メッセージ)ではなく、ユーザーにタップしてもらうような定型メッセージであれば、ポストバックアクションを使うのが、シナリオ・メッセージを作成するのに、簡単でした。

非定型メッセージの場合は、会話のステータス(文脈)管理をすると、シナリオ・メッセージを実現できそうでした。DBと連携してユーザーの状態を加味すると、よりリッチなコミュニケーションができそうです。

また、PythonのチャットライブラリChatterBotも自然言語処理などありそうだったので、非定型メッセージに有用そうでした。

ただ、LINE Botを活用するのに、今回のようなルールベースでも十分な気がします。