Slackアプリ(OAuth)をささっと開発し、Slack App ディレクトリに掲載するまでの方法と対策まとめ


Repsona LLCの@GussieTechです。「ガントチャートも無料でサクサク便利なプロジェクト管理ツール」Repsona(レプソナ)を開発しています。

クリックだけでできるSlack連携を実装しました。案外簡単で、Slack App ディレクトリへの掲載ハードルも高くなかったのです。実装や掲載までの方法、ハマったポイントなどを書きたいと思います。同様の機能を検討している方の参考になれば嬉しいです。

なぜ作ったのか?

Slack連携は、Repsonaユーザーのみなさまからかなり多くのご要望をいただきました。開発後すぐにSlackコミュニティでも連携開始しましたが、更新がリアルタイムで確認できるのはかなり便利です。

Incoming WebhooksでWebhook URLを払い出してユーザーにコピペしてもらう方式でも同様の連携は実現できるのですが、Repsonaの設定画面からクリックだけで連携が完了する体感を作りたかったのです。

これを実現するためには、「Slackアプリであること」と「App ディレクトリへの掲載」が必要でした。

Slackアプリ(OAuth)の仕組み

簡単な流れは下記のような感じです。

  • Your Appsの画面でSlack上に「アプリ」を作る
  • ユーザーに、ワークスペースへのインストールを許可してもらう
  • 許可してもらうとアクセストークンがもらえる(OAuth)
  • アクセストークンを使うとAPIをコールできるようになる

シーケンス図にするとこんな感じです(これが公式ドキュメントになくて、なかなか流れがイメージできなかった・・ので、初めての方にはかなり参考になるのではないでしょうか)。

登場人物は「ユーザー」、「サーバー(ここではRepsona)」、「Slack API」、「Slackアプリ」です。この流れがわかってしまえばもう簡単です。

Slackアプリの作り方

Slack上で「アプリ」を作ります

Create New AppからApp Nameを入力してCreate App。これだけです。

アプリ名やアイコンなどを設定をしていきます。わくわくしますね。

スコープに、Incoming Webhooksを設定して、なぜ必要なのか(Request Reason)を記載します(App ディレクトリへの申請で必要です)。

リダイレクトURLを指定します。ここに設定したURLにマッチしたものしかリダイレクトできません。

Save URLs を押さないと反映されないので注意です。

Slackの認証画面を表示してみる

OAuthを開始するためにパラメータをつけてSlackにリンクします。

<a href="https://slack.com/oauth/v2/authorize?scope=incoming-webhook&client_id=00000000.000000000000&redirect_uri={redirect_uri}">Slack連携する</a>

scopeにはincoming-webhookclient_idは、Basic Informationに記載されてます。redirect_uriにはリダイレクトで戻したいURLをいれます。

クリックしてアクセスするとインストール許可の画面が出てきます。ここまでくると興奮しますね。

でもまだサーバーが実装されていないので動きません。

サーバーを実装します

RepsonaサーバーはNodeで開発していますが、API利用はSDKが用意されておりかなり便利です。以下、SDKを使ったサンプルです。

ユーザーが「許可する」をクリックすると、リダイレクトURLにリダイレクトされてきます。このときワークスペースへのインストールが成功しているとcodeという引数がついてきます。

これを使って、以下のようにアクセストークンを受け取り、保持する実装をします(公式ドキュメント)。

const { WebClient } = require('@slack/web-api');

// App credentials found in the Basic Information section of the app configuration
const clientId = process.env.SLACK_CLIENT_ID;
const clientSecret = process.env.SLACK_CLIENT_SECRET;

// Not shown: received an authorization grant called `code`.
(async () => {
  // Create a client instance just to make this single call, and use it for the exchange
  const result = await (new WebClient()).oauth.v2.access({
    client_id: clientId,
    client_secret: clientSecret,
    redirect_uri: redirectUri,
    code: code
  });

  // It's now a good idea to save the access token to your database
  // Some fictitious database
  await db.createAppInstallation(result.team_id, result.enterprise_id, result.access_token, result.bot);
})();

codeに渡ってきたcodeを、redirect_uriにはSlackの認証画面に飛ばす時に渡したredirect_uriを設定します。これが一致しないと通りません。

成功するとこんな感じアクセストークンチャンネルID、そしてWebhook URLが取得できます。

{
    "ok": true,
    "access_token": "xoxp-XXXXXXXX-XXXXXXXX-XXXXX",
    "scope": "identify,bot,commands,incoming-webhook,chat:write:bot",
    "user_id": "XXXXXXXX",
    "team_name": "Your Workspace Name",
    "team_id": "XXXXXXXX",
    "incoming_webhook": {
        "channel": "#channel-it-will-post-to",
        "channel_id": "C05002EAE",
        "configuration_url": "https://workspacename.slack.com/services/BXXXXX",
        "url": "https://hooks.slack.com/TXXXXX/BXXXXX/XXXXXXXXXX"
    }
}

これをDBなどに永続化して、この後の連携に利用します。

Webhook URLが取得できればあとは簡単です(公式ドキュメント)。jsonをpostするだけでご指定のチャンネルにメッセージが送れます。Repsonaでは更新があるごとに、多少整形して、Webhook URLにpostする実装を追加しました。

POST https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Content-type: application/json
{
    "text": "Hello, world."
}

SDKでやるならこんな感じです(公式ドキュメント)。とっても簡単ですね。

const { IncomingWebhook } = require('@slack/webhook');
const url = process.env.SLACK_WEBHOOK_URL;

const webhook = new IncomingWebhook(url);

// Send the notification
(async () => {
  await webhook.send({
    text: 'I\'ve got news for you...',
  });
})();

Slack App ディレクトリとは?

Slackチームが審査したアプリが掲載されている場所です。ここに掲載されているアプリは、どのワークスペースでもインストールすることができるようになります。

Repsonaは申請からわずか35時間で掲載されました。Slackチームさん仕事早い!!
https://slack.com/apps/ASNKGK9U3-repsona

Slack App ディレクトリに掲載するには?

公式のSlack App ディレクトリにアプリを提出しように全てが書いてあります。

英語で47個チェック項目がありますが、苦手な方でもGoogle翻訳などを使えば簡単です。申請する前に確認しておいた方がいいものは下記あたりです。

  • トークン等をハードコーディングしていないこと
  • スコープの使用目的を記載しているか
  • リダイレクトURLはhttpsであるか(テスト用も残しちゃダメ)
  • インストールまでの詳細な説明を書いたランディングページ
  • プライバシーポリシーのページ
  • サポートの手段(メールアドレスなど)
  • 審査のためのログインアカウントなどが必要であれば用意する

苦労話

  1. そもそもの流れを掴むのに苦労しました(初歩的ですが、どうやって始めるのか、codeがどこからくるのかがわからなかったり・・)。

  2. 公式ドキュメントは、実装の流れよりも、説明の流れが重視されているので、やりたいことをやるために、かなりいったりきたりしました。この辺とかこの辺とかこの辺とか

  3. やりたい連携の仕組みの作り方から、App ディレクトリ申請までを含めた一連の情報がまとまっていなくて、開発できるまで情報を整理するのに苦労しました。

まとめ

  • Slackアプリ作ること自体はとっても簡単
  • Slack App ディレクトリの敷居は決して高くない
  • Slackの中の人はテンションが高くて好き

苦労話はありましたが、実装は簡単で、Slackチームはスピーディーで、やりたいことは簡単に実現できました。いまは更新情報をWebhookしているだけですが、今後はRepsona内のタスクや情報の追加更新や検索などもできるようにしていきたいと思います。

Slack連携も簡単にできて便利な「プロジェクト管理と情報共有のためのツール(ガントチャート無料)」Repsona(レプソナ)もぜひお試しください。