LoginSignup
0
0

[Slack API]OAuthの認可サーバをCloud Functionsで実装

Last updated at Posted at 2024-04-16

はじめに

SlackのOAuthを使ったユーザートークンの取得方法はいろいろ紹介されていますが、私が今回行ったGCPのCloud Functionsを使ったユーザートークンの取得方法について備忘録の意味であげています。

背景

そもそもSlackのユーザートークンが必要になったのは、IoT機器からSlackにアクセスする必要があったためです。IoT機器と言っていますが、実はおもちゃの「へぇボタン」を改造してIoT機器にしたものです。詳しくは以下の記事を御覧ください。

このおもちゃの「へぇボタン」からSlack APIを叩くことでSlackの投稿に対してリアクションできるようになりますが、操作した人のアカウントでリアクションさせたかったので、操作する人自身のユーザートークンにする必要がありました。

ちなみに、この「へぇボタン」はSlackの指定チャンネルの新着投稿を監視してLEDで通知できるようになっています。投稿の監視は操作する人のユーザートークンである必要はありませんが、せっかく取得するので同じユーザートークンを使って監視するようにしています。

Slackアプリの作成

最終的にOAuthを使ってユーザートークンを取得することになりますが、その土台となるSlackアプリを作成していきます。

「Create App」するまでの設定

api.slack.comに入ったあと、「Your Apps」で「Create an App」をクリックします。

slackapi1.png

つづいて、「From scrach」を選び、

slackapi2.png

「Name app & choose workspace」の設定のところで次のように設定します。

slakcapi3.png

App Name
HeiButton (一応「へぇボタン」用なので)
Pick a workspace to develop your app in:
mafws (アプリをインストールするワークスペース名を指定)

設定後、「Create App」をクリックすることで「HeiButton」というアプリが作られます。(この時点では中身はカラです)

OAuth & Permissionsの設定

左のメニューから「OAuth & Permissions」を選びます。

slackapi4.png

「OAuth & Permissions」の設定が開くので「User Token Scopes」に移動して次のようにScopeを設定します。

slackapi5.png

ここでchannels:historyreactions:writeを「OAuth Scope」に追加しているのは、APIを介してSlackの投稿を監視するのと投稿に対してリアクションできるようにするためです。

slackapi6.png

本来ならば、「OAuth & Permissions」設定内の「Redirect URLs」を設定することになりますが、このタイミングではリダイレクト先のURLはまだ決まっていませんので、後述のCloud Functions側設定が終わってURLが確定したあとに再度設定します。

Cloud FunctionsでOAuthの認可サーバの作成

Slackから認可コードを受けるための認可サーバをCloud Functions上に作成します。

cloudfunc1.png

「ファンクションを作成」に入り次のように設定して行きます。

cloudfunc2.png

環境
第1世代 ※第2世代も選べますが設定が容易な第1世代で今回は済ませます
関数名
authfunc ※設定保存用の名前なので任意でOK
リージョン
asia-northeast1(東京) ※任意のリージョンでOK

つづいて、次のように「トリガー」を設定します。

cloudfunc3.png

「認証が必要」に設定しますが、後述の「権限」の設定のところで誰でもアクセスできるように権限を変更します。

つづいて、認可サーバーのコードを実装します。

cloudfunc4.png

ランタイムはnode.js 20を選び、エントリポイントにはauthfuncを指定して、authfuncは次のように実装しました。

index.js
const request = require('request')

exports.authfunc = (req, res) => {
    const code = req.query["code"];
    request({
        url: "https://slack.com/api/oauth.access",
        method: "POST",
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'charset': 'utf-8'
        },
        form: {
            client_id: 'xxxxxxxxxxxxx.xxxxxxxxxxxxx',
            client_secret: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
            code: code
        }
    }, (error, response, body) => {
        const param = JSON.parse(body);
        const access_token = param["access_token"]
        const scope = param["scope"]
        const user_id = param["user_id"]
        const team_id = param["team_id"]
        const team_name = param["team_name"]
        console.log(param);
        return res.send(`
            access_token: ${access_token}<br>
            scope: ${scope}<br>
            user_id: ${user_id}<br>
            teams_id: ${team_id}<br>
            team_name: ${team_name}
        `);
    })
};
package.json
{
    "dependencies": {
        "request": "^2.88.0"
    }
}

client_idclient_secretに指定している値は、前段で作成したSlackアプリの「Basic Information」の「App Credentials」からClient IDClient Secretの値を拾ってそれぞれ設定します。

slackapi7.png

コードの入力が完了したらディブロイします。

cloudfunc5.png

ディプロイが完了したら、次は作成した「ファンクション」の権限を変更します。「権限」のタブから「アクセス権の付与」を選択します。

cloudfunc6.png

今回作成した「ファンクション」はSlackからの認可コードを受ける認可サーバとなるため、だれでも実行できるよう変更します。

cloudfunc7.png

追加するプリンシパルには「allUser」を指定し、割り当てるロールは「Cloud Functions起動元」にします。これで、未認証でも実行できるようになります。

以上でCloud Functionsの設定は完了となりますが、最後に作成した「ファンクション」のURLをSlackアプリの「Redirect URLs」に反映させます。

slackapi6.png

ユーザートークンの取得方法

自身のユーザートークンを取得したい人に次の形式で書かれたURLを踏んでもらうのが一番早いです。

https://slack.com/oauth/authorize?scope=reactions:write&client_id=xxxxxxx.xxxxxxx

xxxxxxx.xxxxxxxの部分は作成したSlackアプリの「App Credentials」にある「Client ID」を指定します。

slackapi8.png

scopeにはreaction:writeしか指定していませんが、今回のSlackアプリのScopeで設定したreaction:writechannels:historyのどちらかが指定されていれば大丈夫なようです。

最終的にユーザーにURLを踏んでもらうことで、ユーザー側のブラウザには次のような画面が表示されます。

slackuser1.png

これを許可することでSlackから認可コードが発行され、今回Cloud Functions上に作ったリダイレクト先の認可サーバーへ渡され、ユーザー側のブラウザ上には最終的なレスポンスとして次のように表示されます。

slackuser2.png

この表示内のaccess tokenの部分のxoxp-で始まる文字列がユーザートークンとなります。このトークンを使ってSlack APIを叩くことで、ユーザー自身のアカウントでリアクションができるようになります。

最後に

今回Cloud Functionsで作った「ファンクション」は第1世代を指定しましたが、Cloud Runを使う第2世代にもトライしてみたいと思います。

参考記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0