はじめに
GaroonのワークフローからChatworkへメッセージを送信するサンプルです。
Chatworkに「Garoon連携用のユーザーアカウント」を作成し、個人ユーザーとコンタクトすることで、Garoonのワークフロー画面上から承認者宛てに催促メッセージを送ることができます。
概要
Garoonのワークフローから申請した後に、申請者から承認者へ「承認の催促」を行うボタンを表示します。
「催促」ボタンをクリックすると、直近の未処理の承認者あてにChatworkのメッセージを送信します。
ワークフローの承認が完了したり、却下された場合は、催促ボタンが表示されなくなりますので、これ以上の催促が行えなくなります。
以下は紹介動画です。
カスタマイズの適用
-
サンプルに使用するユーザアカウントをGaroon、Chatworkそれぞれで作成します。
(登場人物は実在の人物ではありません)組織イメージ
以下の1名をChatworkにアカウント作成します。
- 連携用:外部連携さん(Garoonとの連携用です)
以下の3名をChatwork、Garoonにアカウントを作成します。
- 申請者:藤田一さん(開発部:一般職)
- 承認者1 :谷啓介さん(開発部:課長)
- 承認者2 :佐藤一二三さん(開発部:部長)
以下の2名は、Garoonにアカウントを作成します。
- 回覧 : 林原さん(経理部:課長)
- 回覧 : 恋沼さん(経理部:部長)
「外部連携」アカウントのコンタクト一覧に申請者、承認者のアカウントが追加されているか確認してください。
表示されていない場合は、「コンタクト管理」からユーザーを追加してください。
-
Garoonのユーザのプロフィール項目にカスタマイズ項目を追加します。
項目名 項目コード タイプ 公開/非公開 ユーザーによる変更 ChatworkアカウントID cw_account_id 文字列(1行) 公開 許可 -
Chatworkの各個人それぞれの「アカウントID」をGaroonの各個人のカスタマイズ項目へ登録してください。
-
Chatworkの「外部連携」ユーザの「API Token」を取得しておいてください。
-
Garoonの「プロキシAPIの設定」で、ChatworkのURLを登録します。
プロキシAPIの詳細については、プロキシAPIの設定 クラウド版 ・ パッケージ版 を参照してください。-
メッセージの送信用
- プロキシコード:AP0001
- メソッド:POST
- URL:https://api.chatwork.com/v2/room
- ヘッダー
- キー:X-ChatWorkToken
- 値:上記4. で取得したAPITokenの値
-
コンタクト一覧の取得用
- プロキシコード:AP0002
- メソッド:GET
- URL:https://api.chatwork.com/v2/
- ヘッダー
- キー:X-ChatWorkToken
- 値:上記4. で取得したAPITokenの値
-
-
Garoonの「ファイル管理」に今回のJavaScriptを登録します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
/* * Garoon × Chatwork連携 サンプルプログラム * * 「gr_post_ext_chat.js」ファイル * * Copyright (c) 2018 Cybozu * * Licensed under the MIT License */ (function() { 'use strict'; const g_garoon_base_url = location.origin; const g_chatwork_base_url = 'https://api.chatwork.com'; const g_garoon_proxy_id_CW_postmessage = 'AP0001'; const g_garoon_proxy_id_CW_contasts = 'AP0002'; const g_garoon_workflow_top_url = g_garoon_base_url + '/g/workflow/index.csp?'; const g_garoon_custom_item_name = 'cw_account_id'; // ////////////////////////////////////////////// // ■(非同期3)Chatwork承認者あてにメッセージを送信 // 送信メッセージを編集してChatworkへ送信する // // <非同期後の処理> // ・成功/失敗のアラートを表示する // ////////////////////////////////////////////// function postMessage(room_id, from_account_id, to_account_id, to_account_name, workflow_name, form_url) { // Chatwork room_id const cw_room_id = room_id; // Garoon Proxy code const garoon_proxy_code = g_garoon_proxy_id_CW_postmessage; // Chatwork url const posturl = g_chatwork_base_url + '/v2/rooms/' + cw_room_id + '/messages'; // METHOD const post_method = 'POST'; // body(送信するメッセージを編集) const msg = encodeURIComponent('[piconname:' + from_account_id + '] [hr] [To:' + to_account_id + '] ' + to_account_name + 'さん [info][title](devil)承認をお願いします:' + workflow_name + '[/title] ' + form_url + ' [/info]'); const post_data = 'body=' + msg; // proxy経由で外部メソッドコール garoon.base.proxy.send(garoon_proxy_code, posturl, post_method, {}, post_data).then((args) => { /* args[0] -> レスポンスボディ(文字列) * args[1] -> ステータスコード(数値) * args[2] -> レスポンスヘッダ(オブジェクト) */ console.log(args[1], JSON.parse(args[0]), args[2]); if (args[1] === 200) { alert('成功しました'); } else { alert('失敗しました "' + JSON.parse(args[0]).errors[0] + '"'); } }, (error) => { console.log(error); // proxy APIのレスポンスボディ(文字列)を表示 alert('Proxy送信が失敗しました'); }); } // ////////////////////////////////////////////// // Garoonのアカウント情報から、カスタム項目の // 値を取得する // ////////////////////////////////////////////// function getAccountCustomItem(acount_info, item_name) { let returnValue = ''; for (let i = 0; i < acount_info.customItemValues.length; i++) { if (acount_info.customItemValues[i].code === item_name) { returnValue = acount_info.customItemValues[i].value; } } return returnValue; } // ////////////////////////////////////////////// // Garoonのアカウント一覧から、指定したコードの // アカウント情報を取得する // ////////////////////////////////////////////// function getAccount(acount_list, code) { for (let i = 0; i < acount_list.users.length; i++) { if (code === acount_list.users[i].code) { return acount_list.users[i]; } } return null; } // ////////////////////////////////////////////// // ■(非同期2)Chatwork 「外部連携」ユーザのコンタクト一覧を取得 // // <非同期後の処理> // ・コンタクト一覧から催促したい承認者のルームIDを取得 // ・Chatworkチャットのメッセージを送信処理をコール // ////////////////////////////////////////////// function getContactList(acount_list) { // Garoon Proxy code const garoon_proxy_code = g_garoon_proxy_id_CW_contasts; // Chatwork url const posturl = g_chatwork_base_url + '/v2/contacts'; // METHOD const get_method = 'GET'; // proxy経由で外部メソッドコール garoon.base.proxy.send(garoon_proxy_code, posturl, get_method, {}, '').then((args) => { /* args[0] -> レスポンスボディ(文字列) * args[1] -> ステータスコード(数値) * args[2] -> レスポンスヘッダ(オブジェクト) */ const contact_list = JSON.parse(args[0]); // ///////////////// // コンタクト一覧から、承認者のアカウントIDがあるものを取得 // ///////////////// // ワークフローのリクエスト内容取得 const req = window.garoon.workflow.data['workflow.request.detail.show'].request; let send_process_account_code; // "承認" 以外のステータスの承認者を探す for (let p = 0; p < req.steps[req.processingStepCode].processors.length; p++) { if (req.steps[req.processingStepCode].processors[p].result !== '承認') { send_process_account_code = req.steps[req.processingStepCode].processors[p].code; break; } } // Garoonの申請者のアカウント情報を探す const send_account_info = getAccount(acount_list, send_process_account_code); const my_account_info = getAccount(acount_list, req.applicant.code); // 催促した承認者のルームIDを取得する let send_account_id = getAccountCustomItem(send_account_info, g_garoon_custom_item_name); let send_account_name, send_room_id; for (let c = 0; c < contact_list.length; c++) { if (contact_list[c].account_id === Number(send_account_id)) { // 催促した承認者のルームIDが見つかった場合、 // 承認者の「ChatworkアカウントID」「Garoonの表示名」「ルームID」を保存 send_account_id = contact_list[c].account_id; send_account_name = send_account_info.name; send_room_id = contact_list[c].room_id; } } // ///////////////// // Chatworkへメッセージ送信 // ///////////////// const room_id = send_room_id; const from_account_id = getAccountCustomItem(my_account_info, g_garoon_custom_item_name); const to_account_id = send_account_id; const to_account_name = send_account_name; const workflow_name = req.name; const form_url = g_garoon_workflow_top_url; postMessage(room_id, from_account_id, to_account_id, to_account_name, workflow_name, form_url); }, (error) => { console.log(error); // proxy APIのレスポンスボディ(文字列)を表示 }); } // ////////////////////////////////////////////// // ■(非同期1)Garoonユーザ一覧取得 // // ////////////////////////////////////////////// function getAllUsers(request) { const req = new XMLHttpRequest(); const url = g_garoon_base_url + '/v1/users.json'; req.open('GET', url, true); req.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); req.onload = function() { const acount_list = JSON.parse(req.responseText); // ///////////////// // Chatworkからコンタクト一覧を取得 // ///////////////// getContactList(acount_list); }; req.send(null); } // ////////////////////////////////////////////// // 外部連携メイン処理 // // <処理順序> // ■この関数 // ┗■(非同期1)ユーザ一覧取得 // ┗■(非同期2)Chatwork 「外部連携」ユーザのコンタクト一覧を取得 // ┗■(非同期3)Chatwork承認者あてにメッセージを送信 // ////////////////////////////////////////////// function postChatWork(request) { // ///////////////// // ユーザ一覧取得 // ///////////////// getAllUsers(request); } // ////////////////////////////////////////////// // 画面表示時の処理 // 催促ボタンを表示する // ////////////////////////////////////////////// garoon.events.on('workflow.request.detail.show', (event) => { // 申請者本人の場合に「催促」ボタン表示 if (event.request.applicant.code === garoon.base.user.getLoginUser().code) { // ワークフローの「進行中」の場合に「催促」ボタン表示 if (event.request.status.type === 'UNPROCESSING' || event.request.status.type === 'IN_PROGRESS') { // 項目コードSaisokuButtonの要素を取得 const el = garoon.workflow.request.getSpaceElement('JS01'); const e = document.createElement('button'); e.innerHTML = '催促'; e.onclick = function() { postChatWork(event.request); }; el.appendChild(e); } } }); })();
ここでアップしたJavaScriptファイルのダウンロードリンクを、のちほど使うので控えておいてください。
ファイルの詳細から右クリックし、「リンクのアドレスをコピー」でダウンロードリンクが生成できます。
-
ワークフローの申請フォームで、「JavaScriptカスタマイズ用項目の追加」を行います。
申請フォームはGaroonにサンプルがいくつか用意されていますので、試す際はそちらを利用してください。
今回の例では、サンプルフォーム > 経理関連 > 交際費申請を利用しています。
続けて、「JavaScript/CSSによるカスタマイズ」で、(5)で追加したJavaScriptファイルのリンクを追加してください。
動作確認
-
藤田さんでGaroonにログインし、上記でJavaScriptを組み込んであるワークフローを選択し、申請してください。
経路の設定では、課長欄:谷さん、部長欄:佐藤さん、回覧の欄:恋沼さんと林原さんを設定してください。
設定が済んだら、申請します。
-
申請後にホーム画面の「ワークフロー」から、先ほど申請したワークフローを開きます。
「催促」ボタンは表示されているでしょうか?
催促ボタンがある場合は、クリックしてみましょう。
直近の承認者の「谷さん」へメッセージが送信されます。
おわりに
ChatworkとGaroonを連携することで、コミュニケーションがより手軽になります。
ぜひご活用ください。
このTipsは、2018年10月版Garoonで動作を確認しています。