警告
記事内で利用しているライブラリ「
request
」「
request-promise
」は、非推奨(deprecated)になりました。
HTTPリクエストができる他のライブラリ(
axios
など)や、
https.requst
に書き換えることをおすすめします。
はじめに
Cisco Webex Messaging(旧称: Cisco Webex Teams)とcybozu.comの連携シリーズ第4弾です。
第3弾では、Cisco Webex MessagingのBotを使ってkintoneアプリに登録されている自分のタスクをCisco Webex Messagingに呼び出す方法を紹介しました。
第4弾はCisco Webex Messagingのメンション機能をつかって、担当者を指定してタスクをkintoneに登録する方法を紹介します。
似たようなTipsとして、Slackとkintoneを連携させた
Slackから手軽にkintoneへレコード登録する方法
や、
Slack-kintone連携をAzureでもやってみた
があります。
連携のしくみや動作もほとんど同じですが、本Tipsではタスクの担当者を指定できる点がポイントです。
これまでのCisco Webex Messagingとcybozu.comの連携シリーズはこちらです。
第1弾(Garoonとの連携) Cisco Webex MessagingからGaroonスケジュールを予約する
第2弾(ユーザー連携) Cisco Webex Messagingとcybozu.comでユーザー連結を行う
第3弾(kintoneとの連携) kintoneのアプリデータをCisco Webex Messagingに投稿する方法
連携イメージ
Cisco Webex Messagingにタスク投稿用Botを使ってタスクを投稿するとkintoneのタスク管理アプリにレコードが登録されます。
Cisco Webex Messagingのメンション機能を使って人を選択するとkintoneアプリの担当者欄にメンションされた人の名前が登録されます。
また、誰にもメンションをしない場合は投稿者が担当者欄に登録されるしくみです。
連携概要
Azure fuctions(Node.js)にて、以下の処理を行う。
- Cisco Webex MessagingのWebhookからPOSTされた投稿メッセージ、投稿者のメールアドレス、メンションされた人のCisco Webex MessagingのユーザーIDを取得する。
- Cisco Webex Messagingとcybozu.comのユーザーをマッチングする。
- kintoneへのリクエストデータを作成する。
- kintone REST APIを実行し、タスク管理アプリにレコードを登録する。
下準備
kintoneアプリ
kintoneアプリのデータをCisco Webex Messagingに投稿する方法 で作成したアプリをそのまま使うことも可能です。
誰のタスクかがわかるシンプルなタスク管理アプリを作成します。
フィールド名 | フィールドタイプ | フィールドコード |
---|---|---|
タスク | 文字列(1行) | task |
ステータス | ラジオボタン | status |
担当者 | ユーザー選択 | responsible |
詳細 | 文字列(複数行) | detail |
cybozu.com
kintoneアプリのデータをCisco Webex Messagingに投稿する方法 で用意したユーザーを使えます。
- Cybozu.comの管理権を有するユーザーを用意する。(ユーザー情報を取得できる権限が必要)
Cisco Webex Messaging用Bot
- webex for Developers から MyApps を開く。
- 「Create a Bot」をクリックし、以下を参考に設定する。
項目 | 設定例 |
---|---|
Display Name | InputTask(bot) 日本語可 |
Bot Username | 任意文字列@sparkbot.io |
Icon | 任意(URL) |
kintoneアプリのデータをCisco Webex Messagingに投稿する方法 でMyAppsの画面ショット付きの説明を記載しています。
Cisco Webex Messaging
- 任意のスペース(タスクを表示させるスペース)のユーザーに作成したBotを追加する。
- 上記のスペースを利用するユーザーを1人以上登録する。
- 登録するユーザーのメールアドレスは、cybozu.comに登録されているメールアドレスと一致させる。 Cisco Webex Messagingとcybozu.comのユーザー連携は、メールアドレスで一致させています。
ユーザー連携の詳細は Cisco Webex Messagingとcybozu.comでユーザー連結を行う を参照してください。
環境作成
Azure Functions
Azure Functionsの準備に関しては、 kintoneとMicrosoft Azureを連携してみよう (Azure Functionsその1) の「Azure Functionsの準備」欄を参考にしてください。
ここでは簡単にポイントのみ記述します。(アカウント等の準備は省略)
-
関数を作成する。
- Function Appの画面からクイックスタート画面を開く。
- シナリオ選択は、「Webhook + API」を選択する。
- 言語の選択は、「JavaScript」を選択する。
-
パケットモジュールのインストールする。
-
「Function Appの設定」→「Kuduに移動」を選択する。
-
「site」→作成した関数のフォルダーに移動する。
-
package.jsonを生成する。
-
npmコマンドを実行し、「request」「request-promise」をインストールする。
-
package.jsonを開いて下図のようになっているか確認する。(①、②、③)
1 2 3 4 5 6 7 8
// npmコマンド実行 D:\home\site\wwwroot\<function_name>> npm init // requestのインストール D:\home\site\wwwroot\<function_name>> npm install request --save-dev // request-promiseのインストール D:\home\site\wwwroot\<function_name>> npm install request-promise --save-dev
-
-
Node.js
-
次のJavaScripプログラムをコピーし、作成した関数の「</>開発」のコード欄に貼り付ける。
-
「XXX」で記載されている各パラメーターをご自身の環境に合わせて記入する。
-
「保存」ボタンをクリックする。
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 227 228 229 230 231 232 233 234 235
/* * Cisco Webex Messagingとkintoneの連携 * Copyright (c) 2017 Cybozu * * Licensed under the MIT License * https://opensource.org/license/mit/ */ (function() { 'use strict'; const request = require('request-promise'); /* Cisco Webex Messaging用のパラメータ*/ // BotのID const botID = 'XXX'; // BotのAccess Token const BEARER = 'XXX'; /* kintone用のパラメータ*/ // API実行用のユーザー(「ログイン名:パスワード」をBASE64エンコードしたもの) const CYBOZU_AUTH = 'XXX'; // cybozu.comのドメイン const DOMAIN = '{subdomain}.cybozu.com'; // アプリID const APP_ID = XXX; // URI const BASE_URL = 'https://' + DOMAIN + '/k/v1/'; // アプリのAPI Token const APITOKEN = 'XXX'; const headers = {'X-Cybozu-API-Token': APITOKEN}; let context; // Cisco Webex Messaging会議室にメッセージを投稿 function sendSpark(msg, roomid) { // 投稿する内容内容 const body_post_spark = { // "roomId": ROOMID, //会議室ID roomId: roomid, // 会議室ID text: msg // 投稿内容 }; body_post_spark.roomId = roomid; // Cisco Webex Messagingに投稿するためのオブジェクト const postspark = { url: 'https://api.ciscospark.com/v1/messages/', method: 'POST', auth: {bearer: BEARER}, 'Content-type': 'multipart/form-data', json: body_post_spark }; // 投稿を実行する return request(postspark); } // kitoneアプリ「【Cisco Webex Messaging連動】タスク管理」にタスクを登録する function setkintoneTask(task, detail, code) { // kintoneアプリに登録する内容 const body_post_kintone = { app: APP_ID, record: { // 担当者 responsible: { value: [{code: code}] }, // タスク task: { value: task }, // 詳細 detail: { value: detail } } }; // kintoneに登録するためのオブジェクト const postkintone = { url: BASE_URL + 'record.json', method: 'POST', headers: headers, 'Content-Type': 'application/json', json: body_post_kintone }; // 登録を実行する return request(postkintone).then((res) => { sendSpark('kintoneにタスクが登録されました'); context.log('kinotneに登録されました'); }); } // cybozu.comのユーザー情報を取得する function getUser(opt_offset, users) { const offset = opt_offset || 0; const objUser = users || {}; // ユーザー情報を取得するためのオブジェクト const objGetUser = { url: 'https://' + DOMAIN + '/v1/users.json', headers: {'X-Cybozu-Authorization': CYBOZU_AUTH}, method: 'GET', 'Content-Type': 'application/json' }; // ユーザー情報の取得を実行する return request(objGetUser).then((res) => { const resUser = JSON.parse(res); // 取得したユーザー情報をオブジェクトに格納する for (let i = 0; i < resUser.users.length; i += 1) { objUser[resUser.users[i].email] = {code: resUser.users[i].code, name: resUser.users[i].name}; } // 100件取得してる場合は、offsetを100ずらして再度ユーザー取得 if (resUser.users.length === 100) { return getUser(offset + 100, objUser); } return objUser; }); } // Cisco Webex Messagingの投稿者とメンションされた人とe-mailが一致する .comのユーザー情報を取得する function getPostingUser(email, roomid) { return getUser().then((rtnUser) => { if (!(rtnUser[email])) { throw Error('cybozu.com上に該当するユーザーが見つかりませんでした。'); } return rtnUser[email]; }); } // Cisco Webex Messagingの投稿データkintoneに登録するデータを作成する function allocation(html, email, roomid) { // taskと詳細に登録するデータの作成 // 取得したデータからtaskと詳細を抜き出す const temp = html.split('</spark-mention>'); const temp2 = temp[temp.length - 1].split('</p>')[0]; // taskと詳細に分割する const message = temp2.split('+'); const task = message[0]; const detail = message[1]; // ユーザー情報を取得する return getPostingUser(email, roomid).then((rtnUser) => { // task、detail、投稿者の.comのユーザーのcode/メンションされたユーザーの.comのcode return setkintoneTask(task, detail, rtnUser.code); }); } // メンションされたユーザーのemailを取得する function getMentionedPeopleEmail(mid) { // メンションされた人のidからemailデータを取得 const getmentionedemail = { url: 'https://api.ciscospark.com/v1/people/' + mid, method: 'GET', auth: {bearer: BEARER}, 'Content-Type': 'application/json' }; // 登録されている最初のemailを取得 return request(getmentionedemail).then((people) => { const objPeople = JSON.parse(people); return objPeople.emails[0]; }); } // Webhookを受けた際の処理 module.exports = function(ct, event) { // var objbody, ids; let objbody, ids, roomid; // contextの情報をグローバル変数に保持する context = ct; context.log('start!!'); // 投稿先のroomidを保持しておく // roomid = objbody.roomid; // event.body.data.idで投稿されたメッセージのidを取得する // idを利用してメッセージの詳細を取得する const getmessage = { url: 'https://api.ciscospark.com/v1/messages/' + event.body.data.id, method: 'GET', auth: {bearer: BEARER}, 'Content-Type': 'application/json' }; // メッセージの詳細の取得を実行する return request(getmessage).then((body) => { objbody = JSON.parse(body); // メンションされたIDからBotのIDを除く ids = objbody.mentionedPeople; ids.splice(ids.indexOf(botID), 1); // 担当者欄に登録するユーザーのemailを取得する if (ids.length < 1) { // Bot以外のメンションが無い場合は、投稿者のEmailを取得 return objbody.personEmail; } // Bot以外のメンションがある場合はは、メンション先の1人目のEmailを取得 return getMentionedPeopleEmail(ids[0]); }).then((email) => { // Cisco Webex Messagingのメッセージ本文を解析し、kintoneに登録するデータを準備する return allocation(objbody.html, email, roomid); }).catch((err) => { context.log('Error: ' + err.message); }); }; })();
-
Cisco Webex Messaging Webhookの設定
- Cisco Webex for Developers(旧:Cisco Spark for Developers) からWebhookの Create a Webhook を開く。
- TestModeを「ON」にする。
- 以下の項目を入力し、「Run」をクリックする。
項目 | 設定値 |
---|---|
Authorization | Bearer 「Botのアクセストークン」 *1 |
name | 今回作成するWebhookの名前(任意) |
targetUrl | Azure Functionsの関数のURL *1 |
resource | messages(固定) |
event | created(固定) |
filter | mentionedPeople=me *1 |
*1 詳しくは kintoneアプリのデータをCisco Webex Messagingに投稿する方法 を参照してください。 ^
試してみよう
実際にCisco Webex Messagingのタスク登録用Botが参加しているスペースからタスクを投稿してみましょう。
まず自分が担当するタスクの場合、「@InputTask(Bot)タスク + 詳細」のフォーマットで入力します。
「+」は区切り文字になっており、「+」の前後でタスクと詳細に分けてkintoneに登録されます。
kintoneアプリを確認してみましょう。
次に自分以外の誰かが担当するToDoを登録してみましょう。
今度はCisco Webex Messagingのメンション機能を使って「@InputTask(Bot)@ユーザータスク + 詳細」のフォーマットで入力します。
こちらもkintoneアプリを確認してみましょう。
関連技術情報
Cisco Webex Messagingに投稿されたメッセージ(Botへのメンション)を取得する: Get Message Details
cybozu.comのユーザー情報を取得する: ユーザー情報をエクスポートする
kintoneアプリにレコードを登録する: 1件のレコードを登録する
おわりに
今回は、タスクの担当が一人の場合を想定した例で説明しましたが、担当者が複数いる場合などにもチャレンジしてみてください。