チャネルトークとほかのツールと連携したい(スニペット・asana編) その5
ついに完結?!チャネルトークとasanaの連携!
どうもこんにちはtmdです、終わりが見えてくるとうれしいですね。
この記事シリーズの目標
・チャネルトークで気になるチャットを見つけた時に、スニペットにあるボタンを押したらasanaにタスクが作成されるようにしたい。
・すでにasanaにタスクがある場合はチャネルトークのスニペットに表示させたい。
今回の目標
チャネルトークでボタンを押したらasanaにチケットを作成する。
初回について
こちらの記事を参考にしてください。
事前準備
asanaのワークスペースIDが必要です。
右上のユーザー名>このワークスペースについてを押したら開く画面の以下の部分のURLからワークスペースIDをメモしておいてください。
https://app.asana.com/admin/【ワークスペースID】/members
参考になった記事
こちらの記事が参考になりました。ありがとうございました。
コードのサンプル
長いので分割しています。
function doPost(e) {
var snippetData = JSON.parse(e.postData.getDataAsString());
var asanaData = getAsanaTasks(snippetData["user"]["id"]);
var asanaCreateMessage=""
if (snippetData["submit"]){
create(snippetData["user"]["id"])
asanaCreateMessage="作成しました。"
}
var data2 = [{
"id": "title",
"type": "text",
"text": snippetData["user"]["name"],
"style": "h1"
},
{
"id": "submit-button",
"type": "button",
"label": "asanaを作成",
"action": {
"type": "submit"
}
},
{
"id": "message",
"type": "text",
"text": asanaCreateMessage,
"style": "h3"
}];
for (i=0;i<asanaData.length;i++){
data2.push({
"id": "asanaData"+i,
"type": "text",
"text": asanaData[i],
"style": "h3"
});
};
var data ={
"snippet": {
"version": "v0",
"layout":data2,
"params": {
"customerKey": "channelIO"
}
}
};
return ContentService.createTextOutput(JSON.stringify(data))
.setMimeType(ContentService.MimeType.JSON);
};
function getAsanaTasks(userID1) {
var options = {
'method': 'get',
'contentType': 'application/json',
'headers': {
'Authorization': 'Bearer ' + 【アクセストークン】},
}
var response = UrlFetchApp.fetch('https://app.asana.com/api/1.0/projects/【プロジェクトID】/tasks?opt_fields=notes,permalink_url', options);
var result = JSON.parse(response);
var list = [];
if(result.data){
for(var i = 0; i < result.data.length; i++){
var asanaNotesData= result.data[i]["notes"].replace(/\r?\n/g,",");
var asanaNotesDataSplit= asanaNotesData.split(",");
if((asanaNotesDataSplit[0])==userID1){
list.push(result.data[i]["permalink_url"]);
};
};
};
return list;
};
以下は参考にさせていただいた記事より、必要なものをピックアップする形で流用させていただきました。
function create(userID1) {
const token = 【アクセストークン】;
const workspaceId = 【ワークスペースID】;
const projectId = 【プロジェクトID】;
const name = 'タスク名';
const planText = userID1;
const objTask = {
"data": {
"workspace": workspaceId,
"projects": [projectId],
"name": name,
"notes": planText,
}
};
//オブジェクトを作成する
const asanaManager = new AsanaManager(token);
//処理を呼ぶ
console.log(asanaManager.createTask(objTask));
}
class AsanaManager {
constructor(token) {
this.token = token;
}
//タスクの作成
//https://developers.asana.com/docs/create-a-task
//objPayload(object) Body parameter
createTask(objPayload) {
const url = `https://app.asana.com/api/1.0/tasks`;
const data = this.postAsanaData(url, objPayload);
console.log('createTask', data);
return data;
}
//postでAsanaからデータ追加する関数
postAsanaData(url, objPayload) {
console.log(url);
const token = this.token;
const options = this.getPostOption(token, objPayload);
const response = UrlFetchApp.fetch(url, options);
console.log(response.getResponseCode());
const jobj = JSON.parse(response);
const data = jobj["data"];
return data;
}
//postバージョンのオプションを返すよ
getPostOption(token, objPayload) {
const headers = {
"Authorization": "Bearer " + token
};
const payload = this.getJson(objPayload);
const options = {
"method": "post",
"contentType": "application/json",
"Accept": "application/json",
"headers": headers,
"payload": payload,
"muteHttpExceptions": true
}
console.log(options);
return options;
}
//オブジェクトをJSONにする
getJson(object) {
var json = JSON.stringify(object);
console.log(json);
return json;
}
}
コードの説明
ボタンを押している場合はチャネルトークのユーザーIDを抱えてasanaを作るためのfunctionに駆け込んでます。
ボタンを押してない場合は何もしません。
ついでにボタンを押してる場合と押していない場合でメッセージ用の変数の値を変えています。
var asanaCreateMessage=""
if (snippetData["submit"]){
create(snippetData["user"]["id"])
asanaCreateMessage="作成しました。"
}
スニペット側もボタンを押したときはメッセージが追加で表示されるようにしました。
,
{
"id": "message",
"type": "text",
"text": asanaCreateMessage,
"style": "h3"
}
これで無事作成されるはずです。
あとは作る先やタイトル、説明(※2行目以降は何入れても流用できるよ)を変えるなど考えてみてください。
事件のお知らせ
さて!これで完結と思ってプロジェクトIDを本番のasanaプロジェクトに変更したところエラーが出ました。
実はこのコードは公開用で実際に作ったものと比較するとだいぶシンプルに書き直しているのですが、いずれにせよエラーになりそうです。
問題はこの箇所。
UrlFetchApp.fetch('https://app.asana.com/api/1.0/projects/【プロジェクトID】/tasks?opt_fields=notes,permalink_url', options);
どうやら「UrlFetchApp.fetch」には制限があるようです。
次回は(スニペット用としては好ましくありませんが)制限回避の対策をかけたらなと思います!!!続け次回!
余談
いまのところtmdはvar・let・constの使い分けがとっさにできずvarで書いてる傾向が強くちゃんと分けて書かないとならないなと思ってる次第。
参考にする人は意識して変更していただいた方が良いかもです。