デザイン改善とSlackとの連携機能の実装 - 自作サービスづくり9
今回もWeb開発に関する記事です。
前回は認証付きAPIを作る前準備を行いました。
developer-bpeldi2oerkd8.hatenablog.com
ここでは設計を行ったため、今回はAPIの実装の前にSlackとの連携に必要な情報を登録する機能の実装をします。
デザイン改善
その前にデザインの改善をします。
今のままでは味気ないので、トップページやマイページのデザインの改善に取り組みます。
まず、このサービスのロゴを考えました。
そのあと、自分の中で良いと思ったデザインを画像にしました。
画像にするために使ったものは、Inkscapeです。
点を結んでいくことで簡単に作成できるためおすすめです。
完成したロゴはこちらです。
サービス名であるLattendanceの頭文字Lと出席を意味するチェックマークを組み合わせたものです。
加えて、トップページはスライド式でサービスの名前と特徴が交互に入れ替わるものにしました。
これには、Bootstrapの「Carousel」を用いています。
つまづいた点は、文字を好きな位置に配置する方法です。
最初は「Carousel」のcaptionを用いる方法を考えたのですがうまくいかず、
「Carousel」に「Card」を入れることができることに気付いたため、最終的にはCardのImage overlaysを利用しました。
Slackとの連携登録機能の実装
Slackとの連携に必要なチャンネルIDとチャンネルのトークンを予定に紐づけます。
Roomテーブルを作成し、そこにroomIdカラムとroomTokenカラムを追加します。
さらに、ScheduleテーブルにroomIdカラムを追加し、roomIdを外部キーを設定します。
チャンネルIDを入力し、トークンを発行するように実装します。
router.post('/:scheduleId/new2', authenticationEnsurer, csrfProtection, (req, res, next) => { const scheduleId = req.body.scheduleId; const roomId = req.body.roomId.trim(); //scheduleIdに紐づくscheduleにroomIdが登録されていないかチェック const noRoomId = (scheduleId) => { return new Promise((resolve, reject) => { Schedule.findByPk(scheduleId) .then((schedule) => { if(schedule) console.log('exist'); else console.log('not exist'); if(schedule && schedule.roomId === null) { resolve(schedule); } else { reject('This schedule is already linked to room ID.'); } }); }); }; //同じRoomIDが登録されていないかチェック const checkRoomId = (roomId) => { return new Promise((resolve, reject) => { Room.findByPk(roomId) .then((room) => { if(room) { reject('Room ID is registered.'); } else { resolve(); } }); }); }; Promise.all([noRoomId(scheduleId), checkRoomId(roomId)]) .then((result) => { let schedule = result[0]; if(isMine(req, schedule)) { //roomTokenの生成 const N = 40; const roomToken = crypto.randomBytes(N).toString('base64'); //チャンネル情報の登録 Room.create({ roomId: roomId, roomToken: roomToken }) .then(() => { //roomIdの登録 schedule.roomId = roomId; schedule.save(); res.render('slack-channel-linker-new2', { schedule: schedule, roomToken: roomToken, csrfToken: req.csrfToken() }); }); } else { const err = new Error('指定された予定がない、または、予定する権限がありません'); err.status = 404; next(err); } }) .catch((err) => { console.log(err); res.redirect(`/schedules/slack-channel-linker/${scheduleId}/new?alert=1`); }); });
細かい実装は以下の通りです。
github.com
実装後はこのようになります。
つまづいた点は、トークンを表示するページを無関係の方に表示させない方法です。
最終的には、isMineという自身が作った予定かを確認する関数に加えて、
1ページ目からpostした情報をもとに処理し、そのページのままレンダリングをすることで解決しました。
フォームにはCSRF対策も施してあるため、無関係のユーザーがトークンを発行するページにアクセスできないと思われます。
Slackとの連携変更機能の実装
次に、Slackとの連携設定の変更機能を実装します。
必要な機能としては、以下の3つです。
- Slack連携の解除
- チャンネルIDの変更
- トークンの再発行
この機能それぞれについて実装しました。
細かい実装については以下の通りです。
実装は登録の際に使ったものを再利用してます。
github.com
また、予定の削除機能についてもRoomテーブルを加えたことで削除するデータが増えたため、変更しています。
github.com
実装後はこのような画面になります。
ここで変更したい項目のボタンを押すと、変更されます。
以上で、Lattendance上にSlack連携に必要な情報を登録することができるようになりました。
次回は、JWT認証を導入したAPI実装について取り組みたいと思います。