🕊️

最新の技術記事を自動配信するSlackアプリを作って公開してみた

2021/06/15に公開

はじめに

この度、各社のテックブログを中心に、最新技術記事を配信するSlackアプリWinkieを作って公開しました。
毎日定時に最新の技術記事がお使いのSlackワークスペースのチャンネルに配信されます。
現在Winkie FrontendtとWinkie Backendの二種類があり、それぞれフロントエンド、バックエンドの情報が配信されます。

開発チームの技術力向上に、個人の情報収集に、お使いください。
編集部からのおすすめポイントの解説もあるので、読む前の参考になります。

スクリーンショット 2021-06-07 12.37.07.png

この記事では、当サービスWinkieがどのような技術を使って開発されているかをご紹介したいと思います。

Slackアプリの開発に関心のある方は特に必見です。

サービス構成図

以下がサービスの構成図です。
スクリーンショット 2021-06-07 13.05.11.png

管理画面

投稿する記事の登録や、編集部からのおすすめの文章を編集する管理画面が必要になるため、その管理画面のフロントをReact+Typescriptで実装しています。基本的には記事の追加・編集・削除等の単純で軽量なものとなっているためRedux等のツールは導入していません。デザインも、とりわけ凝ったものにはしておらず、Material UIを使って実装しています。

APIサーバー

記事の登録や配信、slack情報の取得などを行うAPIサーバーはScala+PlayFrameWorkで実装しています。
DatabaseはPostgresを使用していて、Slickを使用してデータベースへのアクセスを行なっています。

アーキテクチャについてはDDD(ドメイン駆動開発)で構築しています。

デプロイ

デプロイは管理画面・サーバーともにHerokuを使ってデプロイを行なっています。
また、記事配信のための定期実行もherokuで行なっています。heroku schedulerで実装

つまずいたポイント

今回このSlackアプリWinkieを開発するにあたってつまずいたポイントをいくつか列挙したいと思います。同じ問題に苦しむ方の参考になれば幸いです。

slack event api

Botがアンインストールされたり、channelに招待されたりなどといったイベントが起こった際に、それにhookしてapiリクエストを飛ばしてくれる仕組みが用意されているのですが、イベントごとにリクエストURLの指定ができず、全ての受信イベントが1つのURLにアクセスします。
そのため、そのイベントがなんのイベントであるかを受け取ったサーバー側で判定する必要がありました。

Winkieのサーバーではadapter層で送られてきたJsonに型をつけたり、バリデーションを挟んだりしています。
そのためリクエストのbodyのJsonからどの型か(どのリクエストか)をその処理の前に判定しています。

Scalaにはapplicativeという概念があり、これを使って型の判定、振り分けを行いました。
やり方としては同一のEventBodyというtraitを各々が継承してその後型のパターンマッチングでどの処理を走らせるか決めています。

sealed trait EventBody

final case class AppUninstalledEventBody(
  teamId: String,
  apiAppId: String,
  eventType: "app_uninstalled") extends EventBody

final case class AppHomeOpenedEventBody(
  channelId: String,
  userId: String,
  eventType: "app_home_opened"
) extends EventBody

def mapToEventCommand = 
 case body: AppUninstallEventBody => // 後続する処理
 case body: AppHomeOpenedEventBody => // 後続する処理

リクエストのJson形式

Slack event apiは日本語ドキュメントが用意されていて非常にわかりやすいのですが、たまにドキュメントとは異なる形でJsonが送られてくる場合がありました。ドキュメント通りのJsonを想定して実装を進めるとフォーマットが異なると怒られてしまうケースがあります。
もしおかしいなと思ったら、一度リクエストをそのままログ出力してみるなどして確認してみるといいと思います。

Block Kit Builderを活用する

Block Kit Builderを使うと、送信するメッセージのプレビューを確認しながらUI構築が可能です。
スクリーンショット 2021-06-07 14.23.56.png

画面左でぽちぽちで操作すると、そのUIを構築するのに必要なJsonが自動で画面右に生成されます。画面最左のメニューから、どんなUIテーマが用意されているかを確認することも可能ですね。
それに加えて例えば、ユーザーがセレクトボックスから何か選択した時にどういったリクエストが飛んでくるかもここから確認ができ、非常に便利です。
画面中央上にある、Action Previewのタブをクリックした上で、左側のUIプレビュー画面で実際に操作することで確認できます。

ちなみに右上のSend to Slackボタンから実際に送信できます。

終わりに

いかがでしたか。外部APIを多く利用するようなサービスはそのAPIの仕様や制約に結構引っ張られてしまいがちなので、やはりそこが難しいですね。

Winkieはhttps://winkie.app/ から簡単にインストールができます。ぜひインストールしてください!

Discussion