はじめに
Slackを使ってると @〜〜 さま という様にさま付けでメンションする事が多く見受けられます。個人的意見としてはSlackメンションで"さま"を付けるのは、非常に無駄だし、やらんでも良いと思ってるのですが。。
一部の方々からしたら、("さま"をつけないのは呼び捨てで呼ばれてる感じがする、失礼)という意見もあるらしく、潜在的に失礼を働くのも嫌だな〜、と思いました。
そんな経緯もあり、そもそも自動的に"さま"って付けられんの?と思ったのが発端です。
仕組みを考える
SlackにはBotを作ったりAPIでメッセージ内容を見たり投稿したりする機能が備わってます。
Botが任意のチャンネルを監視して、"さま"無しメンションの投稿をしたら、Botが修正してくれるみたいなのをイメージしました。今回はBolt for JavaScriptをGlitch環境化でhookする構成で実現してみました。
目的は達成できませんでした、
メッセージ内容を見て、正規表現を使って適宜"さま"を付ける編集をすることはできました。
ただ、Slackスペースに居座るBotが、そのSlackスペースに居る全ユーザの投稿を監視(read)して、"さま"をつけた状態で編集投稿(update)することは出来ませんでした。
そりゃそうですよね、、全ユーザの投稿を弄れるとかスゲー権限だし、こんなの悪用されたら溜まったもんじゃ無い、、セキュリティ的にも相当リスクがある権限になってしまいます。
やるならSlack投稿前に投稿内容をチェックして"さま"付きの投稿文に変える?みたいなのを聞くブラウザ補助ツールを作るとかですかね?、その方向での解決策を考えるのもめんどくさくなり、今回は制限付きで出来たという内容でご容赦ください。
出来たこと
とりあえず自分の投稿内容を編集する権限tokenを使うことで、アプリを作成した人だけが有効になる投稿編集Botは作れました。アプリを作成した人がさま無しメンションをした時にさまを付加して編集してくれます。
それ以外の人がさま無しメンションしても手出しできません。。。
作り方
下記ページを参考に作りました。
Slackに適切な権限を付与したBotをインストールして、Glitch側にリダイレクトさせて、そこからメッセージをパース、更新投稿するという内容です。
Botサンプルとの差分は、
① Bot側(Slack側)でユーザトークンを作成してGlitch側の投稿で使用するようにした
② Glitch側のjavascriptを変えた
まあどこか別のページやSaaSを利用してインテグレートしたとかじゃ無いから単純ですよね。
コード(投稿内容をみて"さま"を付ける)
const { App } = require('@slack/bolt');
const app = new App({
signingSecret: process.env.SLACK_SIGNING_SECRET,
token: process.env.SLACK_BOT_TOKEN
});
//メッセージが投稿された時に呼ばれるメソッド
app.message(async ({ message, say}) => {
console.log("channel:" + message.channel);
console.log("ts:" + message.ts);
console.log("text:" + message.text);
// メッセージをパースしてさん無しメンションがあるか確認する
let text = String(message.text);
let ex = /<@+[A-Z0-9]+>( | )*(?!さん).*/g; //"さん"が無いメンションがあるか確認、1行ごとに有る無しの検出しかできない
let text_result = text;
let update_f = false;
if (text.search(ex) >= 0) {
update_f = true;
text_result = "";
let arr = text.split(/(?=<@+[A-Z0-9]+>)/); //メンションごとに分割する
arr.forEach(function(tmp2) {
let tmp = String(tmp2);
if(tmp.match(/<@+[A-Z0-9]+>( | )*さん/g) == null) {
//さんが付いてない物は" さん "を追加する
let sub_index = tmp.indexOf(">");
let text_a = tmp.slice(0, sub_index + 1);
let text_b = " さん ";
let text_c = tmp.slice(sub_index + 1);
text_result = text_result + text_a + text_b + text_c;
} else {
//さん付きはそのまま使う
text_result = text_result + tmp;
}
});
}
console.log("text result : " + text_result);
if (update_f){
app.client.chat.update({
// token: process.env.SLACK_BOT_TOKEN,
token: process.env.SLACK_USER_TOKEN,
channel: message.channel,
ts: message.ts,
text: text_result
})
}
});
//アプリが起動時に呼ばれるメソッド
(async () => {
await app.start(process.env.PORT || 3000);
console.log('⚡️ Bolt app is running!');
})();
Slackの投稿内容はmessage.textで取得できます。
メンションになってるところは<@XXXXXXX>(本文だと@〜〜となる所)みたいな形で格納されてます。message.textの中身を見て、さまが付いてない<@XXXXXXX>を探して、" さま "を挿入すれば良いはずです。
"<@XXXXXXX> さま"を除外しつつ、"<@XXXXXXX>"(さま無し)を探すのが結構難しかったです。。
動作状況(全員がこんな感じで動けばバンザイでした、)
あとがき
成功例じゃないし大した内容でもなくすみません。(ニーズはあると思うんだけどなぁ。)
SlackBotを使わない、投稿後からの編集でもxxxでやれば上手くできるよ?的な情報があれば、教えていただけると嬉しいです。