LoginSignup
3
1

GASでSlack APIを使う:ユーザーIDからメールを取得する

Last updated at Posted at 2022-09-12

こんにちは、ユーゴです。
今回は、GASでSlack APIを使っていたときに直面した問題について紹介します。

この記事を書く前にネットで調べ尽くしましたが、GASでSlackのアカウントのメール→ユーザーIDを取得するはあっても、ユーザーID→メールを取得するがなかったので、記事化しました。

対象読者

・ひとまずSlackアプリの追加・作成ができる人
・GASがなんとなく書ける人

本記事でわかること

GASでSlack APIを使用し、SlackのユーザーIDからSlackのメールアドレスを取得する方法。

結論

以下が、SlackのユーザーIDから、メール含むアカウント情報を根こそぎ取得する方法です。
コピペ、商用利用OK。ただしあらゆる損害に対して自己責任でお願いします。

UsersInfoGet.gs
function doPost(e) {
    //いろんなユーザー情報が入ってる
    var userInfo = getUserInfoByUserId(e.parameter.user_id);
    //「example@gmail.com」的なのが返ってくる。gmailでなくてもいけるはず。
    var userEmail = userInfo.user.profile.email;
    //あとは好きな処理をする
}

function getUserInfoByUserId(user_id) {
    var options =
    {
        "method": "get",
        "payload":
        {
            //xoxb-で始まるはず。トークン何それ、どこ...という人は、まずSlackアプリを作成するところから始めましょう
            "token": 'ここにアプリのBot User OAuth Tokenを入れる',
            "user": user_id
        }
    };

    //ここのURLはそのまま。SlackのWeb APIで、ユーザ情報を取得する
    var userInfo_str = UrlFetchApp.fetch('https://slack.com/api/users.info', options).getContentText();
    //文字列「{"ok":true,"user":{"id":""W012A3CDE",...」が返されるが、それだと扱えないので扱いやすい変数の型にするだけ。
    var userInfo = JSON.parse(userInfo_str);
    return userInfo;
}

一応書いておきますが、GASのエディタから実行を押してもdoPost(e)のeにSlack上の値を投げられないため上手くいきません。Slack上でEvent Subscriptionsなどを経由して実行してください。

解説

doPost(e)

doPost(e)は、mainメソッドと同じで名前がこれじゃなきゃダメです。GASを動かすだけならdoPost(e)でなくてもいいと思います。しかし、Slackで「Event Subscriptions」「Slash Commands」「Interactive Components」など使うときは必ず使うことになると思います。

e.parameter.user_id

こちらは、Slackから投げられたアカウントの情報から、user_idを取り出しています。e.parameter.emailで取得できろよと思った。

options{ "method": "get", "payload": { "token": 'トークン', "user": user_id } }

これが最初は難解ですが、APIでユーザ情報を取得するための必要な引数です。
"method":"get"では、データを受信するよ、という宣言をしています。なので、Slackにメッセージを送るときは"post"って書いたはずです。
"token":'トークン',"user_id":user_idでは、Slackのアカウントを検索するためのワードを指定しています。多分。(本来ならuser_idだけでいけるはずであり、トークンは認証的な話だと思うが)

UrlFetchApp.fetch('https://slack.com/api/users.info', options).getContentText()

UrlFetchApp.fetch('https://slack.com/api/users.info', options):Slack APIの一種「users.info」を使用しています。先ほど指定したoptionsからユーザー情報を取得します。ここにSlackのメールアドレスが含まれています。
.getContentText():取得した「users.info」はHTTPResponse型の扱いにくい変数です。getContentTextはそれをString型にします。
ちなみに、返ってくる文字列は以下のような感じになります。欲しいのは、"user"の"profile"の"email"の項目です。

users.infoの中身
{
    "ok": true,
    "user": {
        "id": "W012A3CDE",
        "team_id": "T012AB3C4",
        "name": "spengler",
        "deleted": false,
        "color": "9f69e7",
        "real_name": "Egon Spengler",
        "tz": "America/Los_Angeles",
        "tz_label": "Pacific Daylight Time",
        "tz_offset": -25200,
        "profile": {
            "avatar_hash": "ge3b51ca72de",
            "status_text": "Print is dead",
            "status_emoji": ":books:",
            "real_name": "Egon Spengler",
            "display_name": "spengler",
            "real_name_normalized": "Egon Spengler",
            "display_name_normalized": "spengler",
            "email": "example@gmail.com",
            "image_original": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
            "image_24": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
            "image_32": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
            "image_48": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
            "image_72": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
            "image_192": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
            "image_512": "https://.../avatar/e3b51ca72dee4ef87916ae2b9240df50.jpg",
            "team": "T012AB3C4"
        },
        "is_admin": true,
        "is_owner": false,
        "is_primary_owner": false,
        "is_restricted": false,
        "is_ultra_restricted": false,
        "is_bot": false,
        "updated": 1502138686,
        "is_app_user": false,
        "has_2fa": false
    }
}

JSON.parse(userInfo_str)

手前のメソッドでString型の情報を取得したが、ではSplitを使って情報を取得するのでしょうか?不可能ではないですが、酷く手間をかけるでしょう。
そこで、JSON.parse(文字列)を使います。返り値は万能型のObject型です。そうすると、先ほど示した"user"の"profile"の"email"を、「userInfo.user.propfile.email (→example@gmail.com)」と取得できます。

ちなみに

会社で「データ編集中」というような、githubでコンフリクトを防ぐためスプレッドシートがありました。データを編集しているとその欄に自分のメアドが記入されるのですが、作業完了してもこれをよく消し忘れてしまい、ご迷惑をかけまくっていました。なので、Slackから「確認してくれ」と入力すると、たくさんあるスプレッドシートから自分のメールがある欄から「シート名:データ名」を出力してくれる仕組みを作ろう、と思った時のコードの一部です。

まとめ

いかがだったでしょうか。今回は、GASでSlack APIを用いて、ユーザーIDからメールアドレスを取得するプログラムを紹介しました。

Web APIは結構難しいと思います。今回のプログラムも、とても簡潔に書いたつもりですが、行数で見れば大変そうに見えて、自力でやろうとすると心が折れかけます。そんなときに、日本語で解説してあり、コピペOKなものが見つかれば楽だよね...と思い、本記事を書きました。

このように、プログラミングやアプリ開発で得た知見・技術に関して、初心者〜上級者向けのいろんな記事を書いていこうと思います。主に、Unityでアプリ開発周りの知見が多くなると思います。
この記事が役に立った・気に入ったという方は、ぜひLGTM&フォローの方、よろしくお願いいたします。

3
1
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
3
1