PLAY DEVELOPERS BLOG

HuluやTVerなどの日本最大級の動画配信を支える株式会社PLAYが運営するテックブログです。

HuluやTVerなどの日本最大級の動画配信を支える株式会社PLAYが運営するテックブログです。

GASを活用したSlack–Asana間のデザイン依頼フロー構築

今年も秋が短かったですね。こんにちは、デザイナーの池田です。

今回は「デザイナーへの依頼を効率化したいよぉ〜〜」という思いから、地味〜に2022年からやっていた事を世に出して行こうと思います。

さいしょに

デザイナーへ依頼したいな〜〜という時に、弊社では「依頼用のSlackチャンネル」への投稿をお願いしています。
当時は依頼したい人が「@designer」というデザイナー全員にメンションを付けて依頼内容を投稿!というやり方でした。
最初は良かったのですが、依頼された後にこちらが質問するやり取り(例えば締切はいつ?コーディング込み?といったこと)が多く発生するなぁと気づきました。

Slackのワークフローを導入

実際のワークフロー
ということで活用したのがSlackのワークフローです(添付は最新のフォームになります)
これがあれば初手の投稿で知りたいことがわかって効率的!
この内容以外に知りたい内容があれば、投稿された後にスレッドでやり取りをすれば問題なしです。

やりたい事は増えていく

運用していくうちに「もっとこういうことが出来れば便利だよなぁ」と思うようになりました↓

  • ①依頼の一覧性が欲しい
  • ②依頼投稿のスレッドにアサインのお知らせをしたい
    • スレッドに「やります」や絵文字リアクションで名乗り出ていました
  • ③クローズしたことをスレッドに自動で投稿したい
    • 今までは「完」や「済」の絵文字リアクションをアサインしたデザイナーが手動で押していました

Slackの「リスト」機能を使ってみるがやりたい事が出来ないッ

2024年頃にSlackに「リスト」という機能が追加されました。
ワークフローとの連携も可能だったので、手始めにこの機能を使ってみることに。

依頼用ワークフローのステップを追加し、「リスト」へ自動登録ができた!
だけどリストの項目「担当者」が変更されたとしても、②③の条件である「依頼投稿のスレッド」に対して、特定のメッセージを送信することは残念ながら出来なかったのです…。

SlackAppがあるじゃない

実は2021年からGoogle Apps Script(以下GAS)を利用してSlackAppを作る事を楽しんでいました。
今回もSlackAppを作ってGASと連携させればやりたいことは出来そうだな、ということでやりましょう。

やりたいことはこんな感じ

こういう流れ

  • Slackのワークフロー
  • スプレッドシート
  • Slack Bot
  • GAS
  • Asana

上記5つのツールを使用して実現させました。

一覧はAsanaにお任せ

タスク管理としてはAsanaは結構優秀だったので今回の「一覧性」はAsanaを利用させていただきました。

実際のAsana画面
Asanaには「ルール」というものがあり、それがもうめちゃくちゃ便利。
個人的にセクション分けは「アサイン前」「デザイナー1」「デザイナー2」…「完了」としたかったし、ステータスを変えるだけで勝手にセクション移動してくれるのは便利すぎる。
Slackとも連携している点も良い。
Slackで完結しなくなりますが、見た目も好みなのでこちらを採用させていただきました。
少し面倒にはなりますが、やりたいようにやります。

STEP1 依頼投稿されたのをAsanaに登録

準備:スプレッドシートを用意

投稿された依頼を一時保管するスプレッドシートを用意します。

スプレッドシート

1列目には必ず「項目タイトル」を記入してください。
ワークフローで記入してもらった内容をこのスプレッドシートに追加するのですが、1列目のタイトルを参照し、2列目以降から値を入れていくためです。
必要な項目としては以下となります。

  • TimeStamp(Slackの投稿メッセージを参照するのに必要)
  • 依頼タイトル
  • 期限
  • デザインorコーディング(Asanaのフィールドを使用している場合)
  • SlackURL(ワークフローで投稿されたメッセージのURL)
  • task gid(AsanaのタスクID)

STEP 1-1 Slackワークフロー「チャンネルに投稿」

チャンネルに投稿

依頼用のワークフローを作成します。

ワークフロー作成画面
Slackのサイドメニューに「ツール」があるのでそこから「ワークフロー」を選択し、「新規」から「ワークフローを構築」で上記画像の画面へ遷移します(この遷移の仕方じゃなくても勿論良いです)

入力して欲しい情報を追加していく

「イベントを選択する」を編集し、「Slack内のリンクから開始します」を選択してください。
「その後これらを実行」の「ステップを追加する」が活性化されますので、そこを選択し「情報をフォームで収集する」でワークフローで入力して欲しい内容を作っていきます。

ワークフローのステップ

「ステップを追加」で実行する内容を追加していくのですが、「情報をフォームで収集する」の次のステップでは、必ず一度メッセージを送信してください。
そうしないと、投稿した「メッセージのURL」が取れないため、タイムスタンプを取ることができなくなります。

STEP 1-2 Slackワークフロー「依頼ストック」

スプレッドシート

フォームの内容を用意したスプレッドシートに追加していきます。

Google Sheetを追加

「ステップを追加」からGoogle Sheetsを選択し、「スプレッドシートに追加する」で追加していきます。
自分自身のGoogleアカウントを紐付け、用意したスプレッドシートを「スプレッドシート」から選択します。

スプレッドシートに追加する値を当てはめる

列部分にはスプレッドシートの1列目に記載したタイトルが表示されるので、該当する項目にフォームで収集した値を当てはめていきます。
当てはめる値はワークフローの前のステップで実行された内容になります。
もちろんワークフローで取れない値は空で問題ありません。

メッセージの送信・リンク
TimeStampの部分にはステップ2で送信された値なので「2.チャンネルへメッセージを送信する」>「メッセージの送信時間」を選択してください。
同様に、SlackURLは「メッセージのリンク」で投稿メッセージに対するURLが取れるようになります。

送信時間の型を選択
「メッセージの送信時間」のドロップダウンをクリックすると、どういう型で追加するかを選択できます。
送信時間は「タイムスタンプ」で設定してください。

実際に入るとこんな感じ
実際にワークフローを動かしてみると、上記のように値が入っていきますいぇ〜〜〜い!

補足:ワークフローで取れる「タイムスタンプ」の桁が足りない!?

タイムスタンプとは、Slackで投稿したメッセージに割り当てられているidのようなものです。
このタイムスタンプを指定することで、「このメッセージのスレッドに投稿してね!」と指示ができるのです。

投稿されたメッセージのURLにある、p以降がタイムスタンプ↓
https://ワークスペース.slack.com/archives/チャンネルID/p1762408808273739

見比べてもらえるとわかるんですが、求めているタイムスタンプが「1762408808273739」に対し、実際にワークフローから取れるタイムスタンプが「1762408808」と桁数が足りない〜!
メッセージを特定するには16桁が必要〜〜!

つまり、「URL後半から取る」か「doPostに届いたBotのリクエストボディ」のどちらかから取らないといけない…。
今回は後者ですが、念の為URLは取っておきます。
Asanaに登録しておけばURLクリックするだけで飛べたりしますし。

STEP 1-3 SlackBot

Bot
フローの要であるBotを作成します。

Bot作成

Slack API: Applications
上記URLにある「Create New App」>「From Scratch」からアプリを作成することができます。

権限付与

「Features」>「OAuth & Permissions」>「Scopes」>「Bot Token Scope」で以下の権限を付与してください。

  • app_mentions:read
  • chat:write

Tokenを作成

OAuth Tokensの画面
「Features」>「OAuth & Permissions」>「OAuth Tokens for Your Workspace」で「Install to Workspace」を実行すると、権限リクエスト画面が開くので許可してください。
そうすると先ほどの画面が「OAuth Tokens」に変わるので、発行された「Bot User OAuth Token」をCopyしてください。

GASのプロジェクトを作成

STEP 1-2で使用したスプレッドシートを元に、GASで処理をしAsanaへ登録するステップです。

スプレッドシートの「拡張機能」>「Apps Script」でプロジェクトを開きます。
「無題のプロジェクト」になるので、わかるように命名しておいてください。
最初は「function myFunction()」という関数があると思いますが、そちらは削除して下記サンプルコードに書き換えてください。

デプロイ

右上にある「デプロイ」から「新しいデプロイ」を選択し、「種類の選択」横のギアアイコンから「ウェブアプリ」を選択します。

GASのデプロイ画面

  • 説明:自分が管理しやすい説明文で大丈夫です(未入力の場合は無題になります)
  • 次のユーザーとして実行:自分
  • アクセスできるユーザー:全員

上記設定でデプロイをします(権限についてのダイアログが出たら許可をしてください)

ウェブアプリURLをコピー

デプロイが完了するとウェブアプリのURLが発行されます。
このURLをコピーして、Slack apiの先ほどの画面に戻ります。

GASへのリクエストURLをSlackアプリに設定

「Features」>「Event Subscriptions」>「Enable Event」をONにし、「Request URL」に先ほどコピーしたURLを貼り付けます。 Request URL横に「Verified」と表示されれば成功です。
成功したら下にある「Save Changes」で保存。

これでBotの作成は完了です。
ワークフローを使用するチャンネルに /invite @dg-asana-NEKO などでアプリを追加してもらえればオッケーです。

ワークフローにBotのメンションを追加

依頼用のワークフローのステップとして、Botにメンションをさせます。
Botにメンションをすることで、GASのイベントを発火させるためです。

ステップ追加

ステップ4としてスレッドにメンション付きのメッセージを送信します。
ステップ2として追加した投稿にメンションをつけると、まだスプレッドシートに内容が追加されていないため、イベントが発火しても上手くいかないので、必ずスプレッドシートに追加した後で呼んでください。

全て終わったら「公開」を押してワークフローの作成は終了です。

STEP 1-4 GAS

GAS

さて、次はスプレッドシートに追加された内容を元に、Asanaへタスクとして登録させるためにゴリゴリコードを書いていきます。


まず「doPost」に追加の部分を追加してください。
doPostはGASのWebアプリがPOSTリクエストを受け取ったときに自動的に呼ばれる特別な関数です。

スプレッドシートのどのタスクを追加するかを指定する

Asanaにタスクを追加するための準備コードです。


taskTsuikasuru() でdoPostから受け取った「1234567890.123456」といったようなタイムスタンプを、スプレッドシートの1列目のワークフローで取得した「1234567890」のタイムスタンプと照らし合わせて「この行のタスクをAsanaへ追加して〜」と言えるようにしておきます。 前述の通りタイムスタンプの桁数が違うので、ごにょごにょと整数にして比較し、正しいものへと置き換えます。

getSheetとgetIraiListですが、スプレッドシートの内容を取得したり書き換えたりするには、都度「どのスプレッドシート?」「列はどこまで?」など指定しないといけないので、何回も同じ事を書かずにすむようにしています。

Asana API利用の準備

Asanaへ追加させるための処理を書く前に、Asana APIを利用するための準備をします。

Asana Tokenの取得

まず開発者コンソールへアクセス。
「個人アクセストークン」>「トークンを新規作成」でAPIを利用するためのトークンを発行していきます。

トークンを新規作成

トークン名は任意ですが、あとで見てわかるように書けば良いと思います。
「Asana API 利用規約に同意します」をチェックし、「トークンを作成」でトークンが作成されます。

その後、「トークンをコピーしてください」といったダイアログが表示されるのでコピーをしてください。
モーダルを閉じた後にはコピーができないのでご注意を!

GASに戻り、最初に記載した「ENV」に「ASANA_TOKEN」を追加します。

const ENV = {
  BOT_TOKEN: "xxxxxxxxxxxxxxx",
  SHEET_ID: "aaaaaaaaaaaaaaaaa",
  // コピーしたトークンを追加↓
  ASANA_TOKEN: "cccccccccccccccccccccc"
}

ワークスペースIDを取得

次にタスクを追加したいAsanaのワークスペースIDを取得します。

Asanaにログインをした状態で下記URLにアクセスすると、ワークスペースの情報がでます。
そこに記載されている「gid」がワークスペースIDです。
https://app.asana.com/api/1.0/workspaces

{"data":[{
  "gid":"oooooooooooooo", ←これ
  "resource_type":"workspace",
  "name":"ワークスペースの名称"
}]}

コピーしたワークスペースIDを「ENV」に追加してください。

const ENV = {
  BOT_TOKEN: "xxxxxxxxxxxxxxx",
  SHEET_ID: "aaaaaaaaaaaaaaaaa",
  ASANA_TOKEN: "cccccccccccccccccccccc",
  // コピーしたワークスペースIDを追加↓
  ASANA_WORKSPACE_GID: "oooooooooooooo"
}

プロジェクトIDを取得

次にプロジェクトIDを取得します。
プロジェクトIDは、タスクを追加させたいAsanaのプロジェクトを開きます。
登録されているタスク、もしくはプロジェクトのURLに記載があります↓

https://app.asana.com/1/****************/project/プロジェクトID/list/****************

project/ の後に続く16桁の数字がプロジェクトIDです。
それをコピーしておいてください。

これで準備は完了です!

GASからAsanaへタスクを追加する

さて、いよいよGASからAsanaへとタスクを追加させます。

dayjs

ライブラリからdayjsを追加する

GASのライブラリである「dayjs」ですが、日付操作を楽〜にしてくれる優れものです。
GASの左側にある「ライブラリ」から上記のダイアログを開き、下記コードを入力して検索し、特段とくに変更することなくそのまま追加してください。
1ShsRhHc8tgPy5wGOzUvgEhOedJUQD53m-gd8lG2MOgs-dXC_aCZn9lFB

カスタムフィールド

Asanaのカスタムフィールドについてはこちらをご確認ください。
事前に登録してあるカスタムフィールドIDを指定することで、設定された状態で登録が可能です。
今までのようにWebから確認する方法がないため、下記ブログ等をご参考に取得してください。

technicalsoumu.com

payloadの説明

  • workspace:ワークスペースID
  • projects:プロジェクトID
  • name:タスクの名前
  • start_on:タスク開始日(YYYY-MM-DD)
  • due_on:タスク終了日(YYYY-MM-DD)
  • custom_fields:カスタムフィールド
  • notes:説明

上記の内容でAsanaへ登録します。

taskGid

「response」 で送信した内容をJSONの形にしたものを「result」に入れています。
その結果には登録されたタスクの「タスクID」が含まれているので、スプレッドシートに追加します。
その後のステップに必要です。

以上で「STEP1 依頼投稿されたのをAsanaに登録したい」は終了となります。

STEP2 アサインした事をスレッドに投稿したい

Asanaで「担当者」が追加された時に、依頼メッセージのスレッドに「担当者がつきました」という内容を投稿させます。
STEP2-1 AsanaはAsana上で担当者を追加させるだけなので、特にやることはありません。

STEP2-2 Slackワークフロー「アサイン用」

STEP2-2 Slackワークフロー「アサイン用」

Slackのワークフローで「アサイン用」を作成します。

トリガーを指定

トリガーを追加

ワークフローが開始されるトリガーを、「Asana」>「ワークスペースのタスクの担当者が更新された時」とします。
「ワークフロー実行用アカウント」を聞かれるので、ご自身のアカウントと連携させてください。

ワークスペースとプロジェクトを指定

Asanaのワークスペースとプロジェクトを指定してください。 担当者は未設定で大丈夫です。

チャンネルへ投稿

チャンネルへメッセージを送信する

このワークフローを依頼が投稿された#依頼チャンネルではなく、#デザイナーのチャンネルへ投稿させます。
そこでSTEP1で作成したBotにメンションをさせ、GASのイベントを発火させるのです。

投稿メッセージを編集

投稿させるチャンネルを指定し、メッセージに以下を追加させます。

  • Botのメンション:先頭においてください
  • アサイン用とわかる文言
  • タスクID:「変数を挿入する」>「タスク」>「ID」で追加できます
  • タスク名:「変数を挿入する」>「タスク」>「名前」で追加できます
  • 担当者:「変数を挿入する」>「タスク」>「担当者(Slackユーザー)」で追加できます

担当者は表示させる型が選択できますが、@浅田で大丈夫です。

あとは公開をすればAsana上で担当者が更新されるたびにこのワークフローが動いてくれます。

実際に投稿させたメッセージはこんな感じ

STEP2-3 GAS

アサインされた処理を書いていこう

#デザイナーに投稿されたメッセージをトリガーにした処理を一気に書いていきましょう。


チャンネルID

依頼メッセージがあるチャンネルのIDです。
該当チャンネルの右上にある「…(その他)」>「チャンネル詳細を開く」で「チャンネル情報」の一番下にあります。
そちらをコピーして貼ってください。

BotのメンバーID

アプリの詳細

Slackのサイドメニュー「App」から作成したBotを追加させ、DMを開きます。
右上にある「…(その他)」>「アプリの詳細を開く」で「チャンネル情報」の「設定」下にある「メンバーID」です。

デプロイ

GASをデプロイして反映させましょう。

デプロイを管理

「デプロイ」>「デプロイを管理」を開きます。

実際のデプロイ管理です

左の「アクティブ」が選択された状態で鉛筆アイコンの「編集」を選択します。
そうすると、「バージョン」と「説明」が活性化されるので、「バージョン」>「新バージョン」を選択します。
「説明」はそのバージョンの説明文をわかるように書いたら、ひとつ前の状態のバージョンでデプロイし直したい場合などに便利です。

STEP1-3でやった「新しいデプロイ」からデプロイしてしまうと、SlackAPIで指定したウェブアプリのURLが変更されてしまうので、修正や追記する場合は必ず「デプロイを管理」からデプロイしてください。

デプロイが完了したら、これでSTEP1〜STEP2が完了しました。

実際の投稿メッセージ

STEP3 クローズした事をスレッドに投稿したい

これも実はSTEP2とやっていることは一緒です。
ワークフローのトリガーにする条件を「ワークスペースのタスクが完了した時」に設定をさせた「完了用」のワークフローを作成すればオッケーです。
あとはdoPostに「完了とわかるキーワード」をif文で分岐させ、完了処理をさせれば完了です。

補足:SlackワークフローからAsanaのタスクを登録しなかった理由

STEP2で、ワークフローでAsanaが使用できることを紹介しました。
トリガーとして紹介しましたが、ステップでもAsanaを利用することができます。
そこに「タスクを作成する」という項目があるんですが、今回は以下の理由でこちらを使用しませんでした。

  • ワークフローを実行する人も、Asanaアカウントが必要になる
  • 期日に入れる値は、ワークフローでは「日時」を選択していないとダメだった

デザイナーに依頼をする社内メンバー全員がAsanaのアカウントを保持しているわけではないので、このワークフローをそもそも使用できなくなります。
上記だけで選択肢から外しているんですが、さらに期日が「日時」でないとダメなようでした。
ワークフローの情報で入力する「締め切り」を「日付」で対応したかったので、フォーマットが合わずに断念しました(時間まで細かく設定して欲しいわけじゃないので…)

さいごに

すごい長くなりましたが、弊社のデザイナーへの依頼フローはこのようにして構築しております。
もう少し簡単なやり方もあるのかもしれませんが、自分が納得する形としては現状これで良いなと思っております。
Slackのリストがもう少し自分好みにカスタマイズできたらSlackで完結させられるかな〜とも思っています。

以上、GASを活用したSlack-Asana間のデザイン依頼フロー構築についてでした。
ありがとうございました。