bpeldi2oerkd8の開発日誌

とある大学院生の成長の記録。

Hubotから出欠更新APIを叩く-自作サービス作り6

今回の記事もWeb開発の勉強に関する記事です。
前回は出欠更新APIの実装をしました。
developer-bpeldi2oerkd8.hatenablog.com

今回はbotからAPIを叩くことでbot経由で出欠更新ができるようにします。

構成

今回は2つのシステムを開発しています。
図にすると以下の通りです。
f:id:bpeldi2oerkd8:20210610162127j:plain

1つは予定の作成・削除・編集と自らの出欠が更新できるLattendanceです。
ここには、APIとDBが存在しており、外部からAPIを叩くことでも出欠を更新できます。

もう1つは外部から出欠登録を行うbotであるLattendance Botです。
今回はHubotを用いてSlack用のbotを作成しています。
LattendanceのAPIを叩くことで出欠の更新が行えるため、
これをbotを入れたいツールに応じて作り変えることで、
別のコミュニケーションツール(Twitter・ChatWorkなど)に対応することが可能です。

RoomIdの追加

今回は1つの予定につき1つのSlackのチャンネルを作成し、
そこに1つの出欠更新用のbotを入れることを想定しています。
DBのScheduleテーブルにroomIdというカラムを追加します。
RoomIdはチャンネルを右クリックし、「リンクをコピー」でコピーしたリンクの

https://***.slack.com/archives/〇〇〇〇〇〇〇

の〇〇〇〇〇〇〇の部分です。

まずは、RoomIdを登録できるように実装を変更しました。
下の図のようにし、roomIdが重複した場合にはアラートを出すようにしました。
f:id:bpeldi2oerkd8:20210610164804j:plain

f:id:bpeldi2oerkd8:20210610164817j:plain

コードについては以下のリンクを確認してください。
github.com

HubotからAPIを叩く

このようにSlackのチャンネルとLattendance上の予定を1:1で結びつけることができたら、
APIを叩くbotのほうを作成していきます。

Slack上のbot上でわかる情報は以下のようになっています。

情報 意味
roomId SlackのチャンネルID
(Lattendance上の予定と1:1で紐づいている)
SlackId SlackでのユーザーID
(Lattendance上のユーザーと1:1で紐づいている)
dateString 予定の日付
(フォーマットはYYYY-MM-DD)
availability 出欠情報
(欠席:0, 不明:1, 出席:2でLattendance上のと同じ)
(この情報のみPOSTデータとして送る)

この情報をもとにAPI側でDBの出欠情報を更新し、
以下のようにJSONとしてstatus(OK: 成功, NG: 失敗)と関連データが返ってきます。

成功した場合

res.json({
  status: 'OK',
  data: {
    slackId: user.slackId,
    date: date.date,
    availability: availability
  }
});

失敗した場合

res.json({
  status: 'NG',
  error: {
    messages: [scheduleMessage, userMessage, dateMessage]
  } 
});

このJSONをパースし、返ってきた結果に応じてメッセージを返します。
その部分を実装したコードは以下の通りです。

function updateAvailability(msg, roomId, slackId, dateString, availability){
  const update_url = api_url + '/' + roomId + '/users/' + slackId + '/dates/' + dateString;
  const param = JSON.stringify({
    availability: availability
  });
    
  msg.http(update_url)
  .header('Content-Type', 'application/json')
  .post(param) ((err, res, body) => {
    if(err) {
      msg.send("Error :( " + err);
      return;
    }

    const data = JSON.parse(body);
    const availabilityStatus = ['欠席', '不明', '出席'];
    if(data.status === 'OK'){
      msg.send('出欠更新完了:' + '<@' + data.data.slackId + '> さんの' 
        + data.data.date + 'の予定は ' + availabilityStatus[data.data.availability] + ' です');
    } 
    else {
      msg.send('出欠更新失敗:' + '\n' + data.error.messages.join('\n'));
    }
  });
}

動作確認

ここまで作ったものが実際に動作するか確認します。
今まで作った2つのシステムを起動し、bot経由で出欠が更新できるか確認します。

変更前はこのようになっています。
f:id:bpeldi2oerkd8:20210612132902p:plain

ここで、Slackで出欠情報を更新します。
f:id:bpeldi2oerkd8:20210612132933p:plain

すると、出欠情報が更新されているのが確認できます。
f:id:bpeldi2oerkd8:20210612132943p:plain


今回はHubotからAPIを叩き、出欠情報を更新できるようにしました。
次回は、APIに認証をつけることでセキュリティを高めたいと思います。