この記事は、ニフティグループ Advent Calendar 2023 18日目の記事です。
風邪を引いてアドベントカレンダー遅刻しました 😇
はじめに
ニフティ株式会社新卒入社一年目の中井です。今日は皆さんに会社でも回せるガチャを実装する方法、もとい、SlackワークフローからGoogle Apps Scriptを実行する簡単な方法についてご紹介します!
早速ですが、皆さんは普段、Slackを使われていますか?
ニフティでは、社員なら使わない日はないんじゃないかというほどSlackが利用されています。やっぱり単なるチャットツールとして以上に、Slackから様々なアクションを起こすことができる点が強いんですよね。そんな部分の一つの例として、今回は簡単に実行できるガチャを作ってみましょう。
ちなみにガチャというのは別に私がガチャを引きたかったわけではなくて、私自身は全然ソシャゲとか知らないので、単にガチャは楽しいよねという周囲の要望に応えただけであって、あくまでも技術的な探求のためにですね、はい。
なお、今回利用するSlackのワークフロー機能(を作成するワークフロービルダー)は有料プランでないと利用できないので、個人で試される場合はそこにご注意ください。とはいえ個人だと有料プラン高いですよねえ……。
SlackワークフローとGoogle Apps Scriptについてかんたんに
Slackワークフローとは、ざっくり言えばSlackの中のリンクなどから開始できる一連のアクションのことです。最近大きめのアップデートがあって、できることがかなり増えました。アクションには例えばメッセージを送信したり、チャンネルに招待したり、そしてGoogleスプレッドシートに書き込んだりということができます。
Google Apps Scriptとは、かんたんに言えばGoogleの基盤上で簡単なJavaScriptのスクリプトを動かすことができるというサービスです。このサービス、何がとんでもないかというと、まず1つは無料なこと、そしてもう1つは実行タイミングの設定が豊富なことです。例えばGoogleスプレッドシートに変更があった時に実行、のようなことができてしまうんですよね。
さて、なんとなくおわかりでしょうか?
そう、Slackからガチャを回すとはこういうことです。
- まずSlackワークフローからGoogleスプレッドシートに書き込む
- 書き込みに対する変更通知でGoogle Apps Scriptを発火する
Google Apps Scriptさえ発火してしまえばこちらのもの。JavaScriptでなんでもできるので、ランダムに文字列を抽選して、結果をSlackのIncoming Webhook機能を通してチャンネルへ投稿するということが可能なわけですね。便利!
スプレッドシートを作成する
ところで、実はGoogle Apps Scriptにはざっくり2種類があります。
- スクリプト単独で存在するもの
- スプレッドシートに結びついて存在するもの
今回は「スプレッドシートが変更されたときに発火されてほしい」ので、スプレッドシートに結びついて存在するスクリプトのほうが簡単です。すなわち我々のガチャづくりはスプレッドシートを作成するところから始まります。
おもむろに次のURLをタイプしましょう。
すると新規にスプレッドシートが作成され、白紙のスプレッドシートが立ち上がります。わからなくなる前に、左上のタイトル欄に適当に「ガチャ」とでも入れておきましょう。このスプレッドシートはあなたのGoogleドライブに自動保存されています。
さて、後々設定するSlackワークフローでは、スプレッドシートのシート全体を表と見立て、そこに行を追加するという形でスプレッドシートを編集することができます。そのために最低限、表として認識されるようにシートを修正します。
- シート名をわかりやすく「実行履歴」に変更する。
- シートの一番左上のセルに「実行者」と入力(最初の行は表のヘッダー行として扱われます)する。
これで1列の表ができました。実行されるたびに「実行者」の下にどんどんと行が増えていくイメージですね。もちろん、実行した時刻や内容など、列をもっと増やすこともできます。
さて、ここからGoogle Apps Scriptでガチャを作っていきます。
「拡張機能」→「Apps Script」を開いて、ガチャを引くコードを書いていきましょう。
一つの例ですが、ここでは次のようなコードを使ってみました。これは、いわゆるカタカナから3文字を抽出して単純に連結するというものです。もちろん他にも、もしかしたら0〜9の数字などにしてスロットっぽくするなどの応用もあるかもしれませんね。夢も膨らみます。
1 2 3 4 5 6 7 8 9 10 11 12 |
function gacha() { const KATAKANA = "アイウエオカキクケコサシスセソタチツテトナニヌネノ" + "ハヒフヘホマミムメモヤユヨラリルレロワン" + "ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポァィゥェォッャュョヴー"; const pick = () => { return KATAKANA[Math.floor(Math.random() * KATAKANA.length)]; }; const word = pick() + pick() + pick(); console.log(word); } |
そしてプロジェクトを保存した上で実行ボタンを押すと…
この通り、下部の「実行ログ」の部分に、カタカナ3文字が適当に表示されたのがわかると思います。コードは上手く動いていそうですね。
次は、これをSlackのIncoming Webhookを使ってSlackに投稿する部分を作っていきます。
SlackのIncoming Webhookをつくる
SlackのIncoming Webhookとは、外から特定のURLにアクセスすることにより、予め指定したチャンネルにメッセージを送信することができる魔法です。このURLを用意するためには、まず「アプリ」を作成して、そのアプリでIncoming Webhookの機能を有効化するというステップが必要です。しかし、これをGUIでやるとなかなか大変になります。主に説明が。
そこで、その辺を簡単に作れちゃうURLを生成しておきましたので、ぜひ使ってください。
ちなみにこのURLにアクセスすると、次のようなApp Manifestを持ったアプリを一つ新規に作成することになります。ざっくりと説明すると、Incoming Webhookを一つ、そしてそれを利用するために必要なBot情報を一つ追加しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{ "display_information": { "name": "gacha" }, "features": { "bot_user": { "display_name": "gacha", "always_online": false } }, "oauth_config": { "scopes": { "bot": [ "incoming-webhook" ] } }, "settings": { "org_deploy_enabled": false, "socket_mode_enabled": false, "token_rotation_enabled": false } } |
何はともあれ、とりあえず先のURLをクリックすればいいんです。画面の指示に従ってどんどん進めちゃってください!
- アプリをインストールするワークスペースを指定する。
- 色々進んだ後、吹き出しなどで誘導してくれるボタンに従って、アプリのインストール先のワークスペースを指定する(上と同じでOK)。
ここまで終わると、もうすでにIncoming Webhookの作成は完了しています。URLを確認しにいきましょう。
- 画面左側から「Basic Information」へ進む。
- 「Add features and functionality」をクリックして開く。
- 中に並んでいるボタンたちのうち「Incoming Webhooks」を選ぶ。
- ページの下方にURLが表示されている。
URLの横に「Copy」ボタンがあると思いますので、URLをコピーしておいてください。
Incoming WebhookのURLをGoogle Apps Scriptのプロパティに設定する
先のURLをGoogle Apps Scriptのスクリプトプロパティという機能に登録していきます。
一応、理屈としてはとにかくURLが叩ければよいわけですから、別に直接文字列としてソースコードに貼り付けても問題はないです。ただ、なにかできちゃう秘密の文字列を直接コードに貼るのはうっかりGitHubで流出みたいなことになりかねないのでやめておいたほうがいいな、と個人的には思います。
まず、Slackの設定からGoogle Apps Scriptの画面に戻りましょう。そして左側のバーから「プロジェクトの設定」を開き、スクリプトプロパティを追加します。INCOMING_WEBHOOK_URLという名前のプロパティで、値には先程コピーしたURLを入れ、「スクリプトプロパティを保存」を選択してください。
これで、Google Apps Scriptのコード側からはINCOMING_WEBHOOK_URLという名前のプロパティを問い合わせるだけでURLを取得することができるようになりました!
先程のコードをもう少し書き換えて、Slackに送るコードを追記します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
function gacha() { const KATAKANA = "アイウエオカキクケコサシスセソタチツテトナニヌネノ" + "ハヒフヘホマミムメモヤユヨラリルレロワン" + "ガギグゲゴザジズゼゾダヂヅデドバビブベボパピプペポァィゥェォッャュョヴー"; const pick = () => { return KATAKANA[Math.floor(Math.random() * KATAKANA.length)]; }; const word = pick() + pick() + pick(); console.log(word); const incoming_webhook_url = PropertiesService .getScriptProperties() .getProperty("INCOMING_WEBHOOK_URL"); UrlFetchApp.fetch(incoming_webhook_url, { "method": "post", "contentType": "application/json", "payload": JSON.stringify({"text": word}), }); } |
このコードを初めて実行すると、アクセス権限を要求されるかもしれません。これはUrlFetchAppという外部APIを叩くライブラリを利用するためです。
きちんと承認すれば、Incoming Webhookを設定したチャンネルにメッセージが届くはずです。
コード部分はこれで完成。残りはこれをSlackワークフローから呼び出せるようにするだけですね!
スプレッドシート変更時に実行する
Slackワークフローとの連携はスプレッドシートの変更イベントで行いますので、Google Apps Scriptにそのトリガーを設定します。左のメニューから「トリガー」を選択し、次のような設定でトリガーを追加してください。注意点は、イベントの種類で「変更時」を選ぶことです。ややこしいことに「イベントの種類を選択」の部分には「編集時」と「変更時」の二つがありますが、「編集時」はどうも人間が編集した場合のトリガーで、今回のようにSlackワークフローから自動で連携されるケースではトリガーされないようでした。
保存するとまた承認ダイアログが現れます。スプレッドシートを起点にしたことでスプレッドシートへのアクセスが要求されていますので、ここは承認して次へ進みましょう。
設定できたらスプレッドシートへ戻り、何でも良いので適当な変更を加えてみてください。A2セルに適当な文字を打ってみるとか。しばらく待って、Slackへガチャ結果が通知されたら問題なく動作しています!
Slackワークフローからスプレッドシートへ書き込む
いよいよ最後のステップです。SlackのWFを作りましょう。
左上のワークスペース名をクリックし、「ツールと設定」→「ワークフロービルダー」を選択します。この選択肢は、有料プランに入っていないと現れないかもしれません。
開いた画面の右上の「ワークフローを作成する」を押し、ついで「Slack内のリンクから」として進んでいきます。右側のステップ欄でsheetsなどと検索して、「スプレッドシートに追加する」を選んでください。
現れたフォームで、先程までに準備したシートを指定します。これで保存です。
最後にWFの公開を行います。これは別に全世界に大公開ということではなく、WFの編集が終わったからワークスペースで使用可能な状態にするよ、くらいの意味です。
- 公開ボタンから画面の指示に従って適当な説明を付ける。
- 必要ならコラボレーターを追加して「公開」にすすむ。
- 最後のフォームでリンクをコピーする。
最後にコピーしたリンクはもう準備万端で、踏めばガチャが引けるようになっています!次に進みましょう。
Slackで実行してみる
チャンネルに貼ってみると、こんな感じの枠がでます。そして枠をクリックすると…
いい感じですね!!
このリンクはどこにあっても良いので、チャンネルにピン止めするでも、ブックマークバー的なところに登録するでも、お好きなところにどうぞ。
まとめ
今回はSlackワークフローからスプレッドシートの変更通知を通してGoogle Apps Scriptを実行する例を実装してみました。今回はガチャのために使いましたが、このスプレッドシートの変更通知を利用するという方針は、Zapierなど他のスプレッドシートと連携するツールへもすぐに応用できます。また、今回はSlackが外部API呼び出しに対応していないために回りくどい手法を取りましたが、元々Google Apps ScriptにはGETリクエストでスクリプトを実行するなどの、さらに便利な機能もあります。これからも色々できることを探求していきたいです。…ガチャの探求ではないですよ?