リモートが続いてふさぎ込んでしまう人を救いたい
コロナの影響でリモートでお仕事をすることが増えて、
よほどオープンにぐいぐい誘える人でない限り、人を飲みに誘うのも気がひけてしまう。(私もその一人です)
今、会社に入った新人の子たちなど、顔も知らない社員の人がいっぱいいる。なかなかつながりが広がらないのが課題です。
だけど飲みたい。(言わずもがな対策は必須で)
そんなときに会社の人たちを飲みに誘うサービスをLINE Botで作っています。
その1機能がこれです。まだDBへの接続などはやってなくて出し分けの部分のみ。
なんでLINE Botを使ったかというと、
シャイな人でも使えて、利点として大体の人が使っている。どこでもメッセージを送れる。
といったところがあります。
LINEということもあり、ユーザはメッセージやボタンで操作していくことになるので、
操作感の確認をしようと思い、○○したら××が返ってきて、そのあとどういうアクションをとるかなど、
アクションの設計について作ったものをヒアリングしています。
操作感を後輩(若い子)にヒアリング聞いてみた
■操作感
・LINEであるのはよい、導入しやすい。メッセージも簡潔で使いやすいと思う。
・自分が登録した名前が出るのも安心感がある。誰とも知らない人と飲むよりよい。
・今、1グループの人数をある限られた数にしているが、人数を言い出しっぺの人が決められるようにするとよいと思う。
■操作感というより企画の部分
・自分だと1人目になるのは恥ずかしいかもしれない。Bot内に含まれる人の多さがちょっと気になる。
・1年目の子が使うのはいいと思う。1年目の子が1人目であれば、2人目で続いて自分(先輩たち)も使いたい。
作っている機能
募集(登録)こんな人が飲み行くって言ってるよ!と伝えるようにBotの友達皆に「Broad」で連絡
集まった連絡 既定の人数集まったら、集まったメンバーをBotの友達皆に「Broad」で連絡
キャンセル いけなくなった時の機能。
一緒に飲みに行く人たちだけでいいので、そのデータをとってきて「Multicast」で配信
連絡 お店や集合時間の連絡に使用。
一緒に飲みに行く人たちだけでいいので、そのデータをとってきて「Multicast」で配信
他、想定にないメッセージ 送ってきた人にちゃんと書き方を守ってもらうように「Reply」で返信
構成
基本的にユーザの操作はLINEで完結させる予定です。
DBを通さない状態(固定データ)で出し分け出来るところまで作っています。

環境
Node.js
LINE Messaging API
Cloud Functions 諸事情でサーバレスの方がやりやすかったため。
ソース(動くけどまだ作りきってない)
アクセストークンなどは環境変数にしています。
'use strict';// LINESDKのライブラリをインポートconstline=require('@line/bot-sdk');// コンフィグconstconfig={channelAccessToken:process.env.CHANNEL_ACCESS_TOKEN,channelSecret:process.env.CHANNEL_SECRET,};constclient=newline.Client(config);// 1グループに入る最大人数を定義constGROUP_MEMBER_LIMIT=4;// LINEサーバーからWebhookがあると「サーバー部分」から以下の "handleEvent" という関数が呼び出されますasyncfunctionhandleEvent(event){console.log(event);varmessage='Please push text message.';if(event.type!=='message'||event.message.type!=='text'){returnPromise.resolve(null);}// レスポンスの関数を実行しますreturnresponseFunction(event);}// ユーザのメッセージに対してどう返すかを定義constresponseFunction=async(event)=>{// 送られてくるイベントがテキストメッセージであれば下記の対応if(event.type==='message'&&event.message.type==='text'){// 想定しているメッセージ形式であるかチェック// 送られてきたメッセージを分解constmessage_arr=event.message.text.split(" ");console.log(message_arr[0]);console.log(message_arr[1]);letpushText='';// 飲みに行きたい人が出たときの処理 チャンネル全体に告知if(check_go(message_arr[0])){console.log("飲みに行きたいってさ");// 名前の抽出constuser_name=message_arr[1];letmember_count=0;// すでに今日飲みに行きたい人に自分が入っているか確認。入っていたら入ってますと連絡して終了。// 現在の登録人数を確認 今日の最初の登録かの確認に使用// 一番数字が大きい今日のグループNoとメンバーNoを取得// 1グループに入る最大人数と同じであれば、新規グループを作ってメンバー1人目として登録、そうでなければ追加登録//後で書き換えする処理if(user_name==="ちょめお"){member_count=1;}elseif(user_name==="ちょめすけ"){member_count=2;}elseif(user_name==="ちょめこ"){member_count=3;}else{member_count=4;}pushText="飲みに行きたい人"+member_count+"人目 "+user_name;if(member_count===GROUP_MEMBER_LIMIT){// 最後に登録した人が所属するグループに入っている名前を取得して格納letuser_name_list=["ちょめお","ちょめすけ","ちょめこ","ちょむちょむ"];pushText+=" グループの飲みに行くメンバーは、"// 同じグループの人数分ループfor(vari=0;i<=user_name_list.length-1;i++){pushText+=user_name_list[i]+"さん、";}pushText+="です!張り切っていきましょう!"}// チャンネルに登録されている方たちに連絡returnclient.broadcast({type:"text",text:pushText}).then(data=>console.log(data)).catch(e=>console.log(e))// キャンセル者が出たときのメッセージ 同じグループの人に届ける}elseif(check_cancel(message_arr[0])){console.log("キャンセルしたい");try{// すでに今日飲みに行きたい人に自分が入っているか確認。入ってなかったら登録されてませんと連絡して終了。// 出席者リストからキャンセル者を削除する DELか、削除フラグを使うか考えどころ// キャンセル連絡をした人の名前をセットconstuser_name=message_arr[1];// 誰がキャンセルしたかグループの人に連絡する用のメッセージpushText=user_name+"さんがキャンセルしました";// メッセージ送信先配列の初期化letdestination_list=['ユーザID'];// メッセージ配列の初期化letmessage_list=[];message_list=[{type:'text',text:pushText}];// 同じグループの人たちを取り出す処理// 宛先リストにユーザIDを追加console.log(destination_list);console.log(message_list);// 対象は同じグループの人たちclient.multicast(destination_list,message_list)}catch(err){console.log(err.name+': '+err.message);process.exit(-1);}// resolveを返すreturnPromise.resolve(null);// 連絡事項が来た時の処理 飲みに行く同じグループの人へ届ける}elseif(check_contact(message_arr[0])){console.log("連絡事項あり!");try{// すでに今日飲みに行きたい人に自分が入っているか確認。入ってなかったら登録されてませんと連絡して終了。// 連絡事項の場合はそのままのメッセージを返すpushText=event.message.text;// メッセージ送信先配列の初期化letdestination_list=['ユーザID'];// メッセージ配列の初期化letmessage_list=[];message_list=[{type:'text',text:pushText}];// 同じグループの人たちを取り出す処理// 宛先リストにユーザIDを追加console.log(destination_list);console.log(message_list);// 対象は同じグループの人たちclient.multicast(destination_list,message_list)}catch(err){console.log(err.name+': '+err.message);process.exit(-1);}// resolveを返すreturnPromise.resolve(null);}else{// 提供している機能以外(飲みに行きたい・キャンセルしたい・連絡)だった時returnclient.replyMessage(event.replyToken,{type:'text',text:'「飲みに行きたい 名前」か「キャンセル 名前」か「連絡 内容を入れる」(全角スペースを真ん中に入れます。)と話しかけてね。'});}// 「プッシュ」で後からユーザーに通知しますreturnclient.pushMessage(event.source.userId,{type:'text',text:pushText,});}}// 飲みに行きたいパターンかチェックfunctioncheck_go(event_text){if(event_text==='飲みに行きたい'){returntrue;}else{returnfalse;}}// キャンセルしたいパターンかチェックfunctioncheck_cancel(event_text){if(event_text==='キャンセル'){returntrue;}else{returnfalse;}}// キャンセルしたいパターンかチェックfunctioncheck_contact(event_text){if(event_text==='連絡'){returntrue;}else{returnfalse;}}exports.handler=functionlinebot_message(req,res){Promise.all(req.body.events.map(handleEvent)).then(result=>res.status(200).send(`Success: ${result}`)).catch(err=>res.status(400).send(err.toString()));};今後の展開
・飲み会の同グループの人たちを抽出する機能を作る。
・データ登録機能からつくる
・キャンセル(削除)を作る。
・エラーが起きたときのユーザへのメッセージ
・人数の枠を可変にするのは、後々検討
