2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Slackでスタンプがしたい

Last updated at Posted at 2018-10-21

Slackの絵文字ってちっさくて見えないよね?だから大きくしてみようぜ!っていう話

先行事例

調べたらやってる方がいらっしゃった。

ただ、今回自分が作りたいものはすぐに誰でもできるようにしたかったので、ユーザートークンをとってきたりすることは不必要とした。また、ドライブのフォルダに絵文字のエイリアス(例: :thinking:=thinking)と同じ名前の画像をアップロードするだけで使えるようにした。

Outgoing Webhook(発信 Webフック)

先行事例に則ってOutgoing Webhook(発信 Webフック)を設定する。Integration(カスタムインテグレーション)から作成する。

Outgoing Webhookの説明画像

こんな感じで、「引き金となる言葉」のところに「:」を登録する。それだけ。説明とかはお好みで。URLだけはあとで作成するGASスクリプトのURLを設定する。

投稿用のbotを作成する

同じく、Integration(カスタムインテグレーション)から作成する。このとき、

ueckoken.slack.com_services_B26DEHP5Y(iPhone 6_7_8).png

tokenをコピーしておく。

GASスクリプトの作成

Googleドライブから作成する。左上の新規→その他→Google Apps Scriptを選択。名前を適当につけて編集画面へ

GASでSlackAPIを叩くためのライブラリとして、soundTrickerさんの「Slack BotをGASでいい感じで書くためのライブラリを作った」を使わせてもらう。導入方法はこの素晴らしい記事を参考に。

その後以下のコードをコピーする。

bigstamp.js
///Googleドライブ上の画像フォルダのID
var folderID = ""

function doGet(e) {
}

function doPost(e) {
    if (!e) {
        // 異常終了
        return null;
    }
    if (e.parameter.user_name == "slackbot") {
        // slackbotの投稿は無視する
        return null;
    }
    // パラメータにテキストがなかったら終了
    if (!e.parameter.text) {
        throw new Error("exit");
    }
    //スタンプだけのテキストじゃなかったら終了
    if (!isStamp(e.parameter.text.trim())) {
        throw new Error("exit");
    }
    //最長一致
    var m = e.parameter.text.match(/\:(.+)\:/);
    var textMessage = "";
    if (m && m[1]) {
        textMessage = m[1];
        var files = DriveApp.getFolderById(folderID).getFiles();
        var file = undefined;
        for (var i = 0; files.hasNext(); i++) {
            file = files.next();
            var filename = file.getName().replace(/(.+)\..+$/, "$1");
            if (filename == m[1]) {
                textMessage = filename;
                break;
            }
        }
        if (file) {
            var fileId = file.getId();
            var date = new Date();
            var stamp_url = "https://drive.google.com/uc?id=" + fileId + "&" + date.getTime();
            var channel_id = e.parameter.channel_id;
            var user_name = e.parameter.user_name;
            ///SlackのBotsのトークン
            var token = "";
            var att = [{ "fallback": "スタンプを送信しました", "image_url": stamp_url }];
            param = {
                attachments: JSON.stringify(att),
                as_user: true,
            };
            var app = SlackApp.create(token);
            if (e.parameter.thread_ts !== undefined) {
                param["thread_ts"] = e.parameter.thread_ts;
            }
            var post_info = app.postMessage(channel_id, "", param);
        }
    }

    return true;
}

///
/// スタンプかどうかのチェック関数
/// 最初と最後が:ならスタンプとみなす(だから絵文字で挟むともしかしたら余計な判定をするかも)
///
function isStamp(text) {
    if (text.slice(0, 1) == ":" && text.slice(-1) == ":") return true;
    else return false;
}

このうち最初の
var folderID = ""
にGoogleドライブ上の画像フォルダのIDを入れる。IDはそのフォルダにアクセスしたときのhttps://drive.google.com/drive/u/0/folders/hogehogefugafugaだったらhogehogefugafugaのところ。

これだけでOK

コードの説明

まず最初の

bigstamp.js
function doPost(e) {
    if (!e) {
        // 異常終了
        return null;
    }
    if (e.parameter.user_name == "slackbot") {
        // slackbotの投稿は無視する
        return null;
    }
    // パラメータにテキストがなかったら終了
    if (!e.parameter.text) {
        throw new Error("exit");
    }
    //スタンプだけのテキストじゃなかったら終了
    if (!isStamp(e.parameter.text.trim())) {
        throw new Error("exit");
    }
    ...

は、SlackからのPOSTであることと、次の部分に移る前のバリデーションチェックである。

bigstamp.js
    //最長一致
    var m = e.parameter.text.match(/\:(.+)\:/);
    var textMessage = "";
    if (m && m[1]) {
        textMessage = m[1]
        var files = DriveApp.getFolderById(folderID).getFiles();
        var file = undefined
        for (var i = 0; files.hasNext(); i++) {
            file = files.next();
            var filename = file.getName().replace(/(.+)\..+$/, "$1");
            if (filename == m[1]) {
                textMessage = filename;
                break;
            }
        }
        ...

この部分は、受信したテキストメッセージのうち絵文字のエイリアスのところを持ってくる部分と、それと一致する名前をもつ画像をドライブから検索する部分である。このあたりはTakumaKawashiroさんの「GAS入門 - DriveAppクラスリファレンス」を参考につくってみた。for文のなかでbreakするのは許して

bigstamp.js
        if (file) {
            var fileId = file.getId();
            var date = new Date();
            var stamp_url = "https://drive.google.com/uc?id=" + fileId + "&" + date.getTime();
            var channel_id = e.parameter.channel_id;
            var user_name = e.parameter.user_name;
            ///SlackのBotsのトークン
            var token = "";
            var att = [{ "fallback": "スタンプを送信しました", "image_url": stamp_url }];
            param = {
                attachments: JSON.stringify(att),
                as_user: true,
            };
            var app = SlackApp.create(token);
            if (e.parameter.thread_ts !== undefined) {
                param["thread_ts"] = e.parameter.thread_ts;
            }
            var post_info = app.postMessage(channel_id, "", param);
        }

最後の部分は、ファイルが見つかったらIDを取得して、外部ファイルとして表示できるURLにパラメータとしてくっつけたものをSlackAPIのchatMessageで投げているところ。元記事がすばらしいのでスレッドにも対応してる。

おわりに

スタンプっていいよね

2
2
1

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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?