GameWith Advent Calendar 2018 9日目担当のiOSアプリエンジニアの chuymaster です。
先日、LINE DEVELOPER DAY 2018に参加してきて、クロージングセッションでの「今日のカンファレンスで聞いた内容で何かを作って欲しい」というメッセージを真に受けて、勢いでチャットボットを作った話を共有したいと思います。
サービスの背景
GameWithが取り扱っているゲーム攻略情報の中で、「モンスト」ことモンスターストライクが非常に人気で、多くのユーザーに見ていただいています。
モンストには、「マルチプレイ」というモードがあって、最大4人で集まってゲームをするとクエストがクリアしやすくなったり、報酬がたくさんもらえたりします。
GameWithアプリでは、プレイヤーが集まりやすいように、「自動マルチ募集掲示板」機能を提供しています。クリアしたいクエストに、欲しい条件のプレイヤーに一緒にマルチしてもらえる掲示板です。
GameWithユーザーが抱える課題
さて、そんな便利なマルチ自動掲示板ですが、実は一つ手間があります。
それは、募集のとき、募集メッセージをLINEからコピペする必要があることです。
募集する手順は
- モンストでクリアしたいクエストのLINEでのマルチ募集を選ぶ
- LINEで友達を探す
- 友達に募集メッセージを送る(LINEチャットボットに送ることが多いらしいです)
- 送ったメッセージをコピーする
- GameWithアプリの募集画面を開く
- メッセージをペーストする
- 条件を決めて募集を始める
・・・長い!
募集メッセージを保存しておいたり、LINEを経由しない裏技的なことをしてマルチ募集の手間を減らすこともできますが、 公式の手順で、自然な流れで、「本当の友達とマルチする」みたいに募集したいというユーザーが多いはずです。
そこで、LINEを通すことは仕方ないのなら、その後の手間をなくそう!という発想が、今回のチャットボットを作成する経緯になります。
どんなチャットボット?
「マルチ募集をワンタップでできる」チャットボットです。
このチャットボットにマルチ募集メッセージを送ると、GameWithアプリで募集するURLを返信してくれます。
そのURLをタップするだけでGameWithアプリで募集の必要な項目を埋めてくれて、コピペ要らずに募集開始ができるようになります。
デモ動画
さっそくデモ動画を見ましょう!
ポチポチタップするだけで募集ができて、サクサク感が伝わるんじゃないかと思います!
それでは、実装の説明をしていきます。
チャットボットの準備
まずは、公式のチャットボットサンプルでのセットアップです。 私はPythonが少し書けるので、Pythonのサンプルを選び、こちらの記事を参考に開発を始めました。
LINE@のアカウント作成、Herokuの環境作成は上記の記事で詳しく説明しているので割愛します。
ただし、記事で紹介された flask-echo
というオウム返しするだけのサンプルを使うと、
LINEのチャットボットは何ができるかイマイチわからないので、flask-kitchensink
(https://github.com/line/line-bot-sdk-python/tree/master/examples/flask-kitchensink)を使いました。
実装
ボット返信の大まかな流れは
- 送信者から受け取った、マルチ募集メッセージをサーバーに一時的に保存する
- メッセージファイルのURLを、GameWithアプリで処理するURLスキーマ
gamewith://
のパラメータにくっつける - 送信者に返信する
パラメータを受け取った後の処理はアプリ側の責任になります。
- URLスキーマを解析する
- メッセージファイルのデータを取得する
- 取得したデータを文字列に変換する
- マルチ募集画面を開いて、文字列を入力ボックスにセットする
アプリ側の実装は詳細を割愛します。以下、サーバー側の実装を説明します。
1. 送信者から受け取ったメッセージをサーバーに一時的に保存する
嬉しいことに、flask-kitchensink
のサンプルでは既に画像を一時的に保存する処理が実装されているので、それを活用します。
もらったテキストをファイルに保存して、URLを返すメソッドを作りました。
def write_message_to_file(text): ext = 'txt' with tempfile.NamedTemporaryFile(dir=static_tmp_path, prefix=ext + '-', delete=False) as tf: tf.write(text.encode()) tempfile_path = tf.name dist_path = tempfile_path + '.' + ext dist_name = os.path.basename(dist_path) os.rename(tempfile_path, dist_path) message_url = (request.host_url + os.path.join('static', 'tmp', dist_name)).replace("\\","/") return message_url
2. 保存したファイルのURLを、GameWithアプリで処理するURLスキーマ gamewith://
のパラメータにくっつけて返信する
ここは単純に文字列を結合するだけです。URLスキーマと処理するパラメータは予めアプリ側と合意を得る必要があります。
def get_monst_reply_message(message_url): message = "このURLをタップして、GameWithアプリですぐマルチ募集を始めよう!(*'▽')\n" gamewith_app_prefix = "gamewith://line?message_url=" return message + gamewith_app_prefix + message_url
3. 送信者に返信する
linebotのSDKを使って返信します。サンプルからコピペするだけで良いです。
def handle_text_message(event): #------- # サンプル中略 #------- elif "https://static.monster-strike.com/line" in text: message_url = write_message_to_file(text) reply = get_monst_reply_message(message_url) line_bot_api.reply_message( event.reply_token, TextSendMessage(text=reply) )
今後の課題
価値の検証
ユーザーが使って本当に喜ぶかどうかを検証する必要があります。まず社内の攻略チームの方々にお願いして、使ってフィードバックをもらおうと考えています。
全体的なユーザーフローの設計
チャットボット自体は便利ですが、歓迎メッセージや使い方の説明をちゃんと案内してあげないとユーザーが離脱してしまいます。 価値検証できたら、ユーザーフローやサポートを含めた設計をします。
本番稼働に向けた開発
まだプロトタイプ段階なので、Herokuの無料プランでチャットボットを稼働させていますが、 本番稼働に向けて、安全性・安定性・メンテナンス性を考慮した開発が必要になります。 この辺りのサーバーサイド開発はほぼ経験がないので、他のサーバーエンジニアからいろいろ学ぼうと考えています。
最後に
私はiOSアプリエンジニアですが、今回はサーバーのコーディング、社内でまだ使ったことのないLINE Messaging APIという未知の領域に挑戦しました。 GameWithは、会社のミッションである「ゲームをより楽しめる世界を創る」ことに繋がる挑戦を積極的に応援しているからこそ、実施できたと思います。
そんなGameWithは、ゲームが大好きで、新しい技術をどんどん使っていきたいという方を大募集中! Wantedly でもよいので是非お気軽にお声がけください!