SlackのOAuthを使って独自アプリをインストールさせる

Shunsuke Sawada

自分専用のSlackアプリであれば、管理画面からtokenを取得して環境変数にでもセットしておけば、問題なく動かせます。
  
ただ、このままだと他の人が使えません。
もしろん Google Cloud Platform を準備して CloudFunctionとFirestoreをセットアップしたら使えますが、まずそんな人はいませんよね。

自分の作ったSlackアプリを色んな人に使ってもらいたい場合は、各人のSlackにアクセスする権限が必要です。そんな時にはOAuth。IDとパスワードを知らずとも、ワークスペースのメンバーが許可すれば、アクセスするためのtokenを取得することができます。

ユーザーにURLを踏んでもらう

https://slack.com/oauth/authorize こちらにアクセスさせます。
普通のリンクでも良いですし、動的にリダイレクトしてもOK。

その際に、client_idscope というパラメータが必要です。
client_id は API管理画面の Settings > Basic Information > App Credentials から取得できます。 scopeこちらから 適切なものをカンマ区切りで指定します。

こんな感じです。

1
https://slack.com/oauth/authorize?scope=channels:history,commands,users.profile:read&client_id=xxxx.xxxx

Redirect URL を指定

Slack API 管理画面で Features > OAuth Tokens & Redirect URLs > Redirect URLs に行くと リダイレクト先を設定できます。
これはユーザーがOAuthの画面で許可を選択した後にリクエストが飛ぶ先ですの。もちろん設定しただけではダメで、実装する必要があります。

リダイレクト先の実装

リダイレクト先のURLには GETcode というパラメータ付きでリクエストが入ります。
この code はワンタイムの文字列で、これを使って oauth.access にリクエストすることで token を含むユーザー情報を取得することができます。

Cloud Function でやってみるとこのような感じ。

js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
require('dotenv').config();
const require = require('require');
const Firestore = require('@google-cloud/firestore');
const firestore = new Firestore({
  projectId: process.env.GCP_PROJECT,
});

// Slackアプリの紹介ページなど
const landingPageUrl = 'https://www.google.com/';

module.exports = async (req, res) => {
  const { code, error } = req.query;

  // 許可されなかった場合はerror
  if (error) {
    console.log('Error on registration', error);
    return res.redirect(landingPageUrl);
  }

  requeset({
    url: 'https://slack.com/api/oauth.access',
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
    },
    form: {
      client_id: process.env.SLACK_APP_CLIENT_ID,
      client_secret: process.env.SLACK_APP_SECRET,
      code,
    }
  }, (error, response, body) => {
    if (body.ok) {
      const { team_id, access_token } = body;
      // Firestoreに保存したりして後で使えるようにしておく。
      // 重要な情報なのでRules等でアクセスできないように設定しておく。
      docRef = firestore.collection('credentials').doc(team_id);
      await docRef.set({ access_token });
      return res.redirect(landingPageUrl);
    } else {
      console.log('Failed to get access');
      return res.redirect(landingPageUrl);
    }
  });
}

SLACK_APP_CLIENT_IDSLACK_APP_SECRETSettings > Basic Information > App Credentials から取得できます。

Tokenを使ったアクション

Token が取得できたので、指定したscope内であれば自由にアクションが起こせます。
チャットに投稿したり、ユーザーのアイコンを取得したり、自由自在 :)

  
本日は以上です。
  

参考

  

1
Shunsuke Sawada

おすすめの記事

はてなのAPIをつかってみた / Rails4とWSSE認証
121
RailsでFacebookログインを実装する
20
Rails / Google Analyticsのデータを使って分析や管理画面のためのグラフをつくる
435