Last active
March 15, 2021 02:32
-
-
Save YoshiteruIwasaki/420aa7c9473a3adf35d9f209b24e4ee9 to your computer and use it in GitHub Desktop.
fondeskの投稿に対してメンションを追加するGoogle Apps Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function doPost(e) { | |
var channel = 'XXXXXXXX'; // fondeskの通知先チャンネル | |
var url = 'https://hooks.slack.com/services/XXXXXXXX'; // Incoming Webhook URL | |
var TOKEN = 'XXXXXXXX'; // Verification Token | |
var botId = 'XXXXXXXX'; //fondeskのアプリのBOT ID | |
var historySave = true; //データをスプレッドシートに保存する | |
var sheetName = 'list'; //名簿リストのスプレッドシート名 | |
var historySheetName = 'history'; //入電履歴のスプレッドシート名 | |
var suppressedSheetName = 'suppressed'; //営業電話のスプレッドシート名 | |
var postData = {}; | |
var jsonData = {}; | |
var isPost = false; | |
// subscribe posted messages | |
try { | |
var decodeData = unescapeUnicode(e.postData.getDataAsString()); | |
postData = JSON.parse(decodeData); | |
isPost = true; | |
} catch (ex) { | |
// debug(ex); | |
} | |
// Interactive messages | |
try { | |
if (e.parameter) { | |
var parameter = e.parameter; | |
var payload = parameter.payload; | |
jsonData = JSON.parse(decodeURIComponent(payload)); | |
} | |
} catch (ex) { | |
// debug(ex); | |
} | |
// 認証 | |
if (isPost && postData.type == 'url_verification' && postData.token == TOKEN) { | |
var res = { | |
'challenge': postData.challenge | |
}; | |
return ContentService.createTextOutput(JSON.stringify(res)).setMimeType(ContentService.MimeType.JSON); | |
} | |
// fondeskのチャンネルを監視 | |
if (isPost && postData.token == TOKEN && postData.type == "event_callback" && postData.event.type == "message" && postData.event.channel == channel && postData.event.bot_id == botId) { | |
var getContents = ""; | |
var getSender = ""; | |
var historyData = []; | |
var message = ''; | |
var nobody = true; | |
var array = []; | |
var options = {}; | |
//投稿内容の取得 | |
var thread = postData.event.event_ts; | |
var time = thread.split("."); | |
var date = new Date(time[0] * 1000); | |
historyData.push(formatDate(date)); | |
var text = postData.event.text; | |
historyData.push(text); | |
try { | |
if(postData.event.blocks) { | |
// 発信者 あて先 | |
var attachments = postData.event.blocks[0].text.text.split(/\r\n|\n/); | |
for (var i = 0; i < attachments.length; i++) { | |
var sender = attachments[i].indexOf("*発信者*"); | |
if (sender !== -1) { | |
getSender = attachments[i].replace("*発信者* ", ""); | |
} | |
var address = attachments[i].indexOf("*あて先*"); | |
if (address !== -1) { | |
getContents = attachments[i].replace("*あて先* ", ""); | |
} | |
} | |
// 内容 | |
getContents += "\n" + postData.event.blocks[postData.event.blocks.length - 1].text.text; | |
} | |
} catch(ex) { | |
debug(ex); | |
} | |
// 受電履歴を保存 | |
if (historySave) { | |
var historySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(historySheetName); //シートを取得 | |
historySheet.appendRow(historyData); | |
} | |
//営業電話リストのチェック | |
var suppressedSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(suppressedSheetName); | |
var textFinder = suppressedSheet.createTextFinder(getSender); | |
var ranges = textFinder.findAll(); | |
var isSuppressed = ranges.length > 0 ? true : false; | |
if (isSuppressed) { | |
//営業電話 | |
message = "営業電話がありました。"; | |
options = { | |
"method": "post", | |
"contentType": "application/json", | |
"payload": JSON.stringify({ | |
"text": message, | |
"thread_ts": thread, | |
"reply_broadcast": true, | |
}) | |
}; | |
} else { | |
//該当するユーザーの検索 | |
var recordsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName); | |
var sheetValues = recordsheet.getRange('A:A').getValues(); //A列の値を全て取得 | |
var lastRow = sheetValues.filter(String).length; //空白の要素を除いた長さを取得 | |
var sheetRange = 'A2:C' + lastRow; //名簿リストのスプレッドシートデータ取得範囲 | |
var range = recordsheet.getRange(sheetRange); | |
var data = range.getValues(); | |
for (var k = 0; k < data.length; k++) { | |
if (data[k][0] != null && data[k][0] != "") { | |
var result1 = getContents.indexOf(data[k][0]); | |
var result2 = getContents.indexOf(data[k][1]); | |
if (result1 !== -1 || result2 !== -1) { | |
if (array.indexOf(data[k][2]) == -1) { | |
// メンションを追加 | |
message = "<@" + data[k][2] + "> " + message; | |
nobody = false; | |
array.push(data[k][2]); | |
} | |
} | |
} | |
} | |
if (nobody) { | |
//該当者がいない場合 | |
message = "<!here> *" + getSender + "* 様から 宛先不明のお電話です。 対応したら「OK」をお願いします。"; | |
} else { | |
message = message + " *" + getSender + "* 様から お電話がありました。対応したら「OK」をお願いします。"; | |
} | |
//返信投稿 | |
options = { | |
"method": "post", | |
"contentType": "application/json", | |
"payload": JSON.stringify({ | |
"text": message, | |
"thread_ts": thread, | |
"reply_broadcast": true, | |
"attachments": [{ | |
"text": "", | |
"callback_id": "callback_button", | |
"attachment_type": "default", | |
"actions": [{ | |
"name": "ok", | |
"text": "OK", | |
"type": "button", | |
"style": "primary", | |
"value": "ok" | |
}, | |
{ | |
"name": "suppressed", | |
"text": "営業電話", | |
"type": "button", | |
"style": "danger", | |
"value": getSender, | |
"confirm": { | |
"title": "営業電話", | |
"text": "*" + getSender + "* 様からの電話を今後誰にもメンションしないようにしてもよろしいですか?", | |
"ok_text": "はい", | |
"dismiss_text": "いいえ" | |
} | |
} | |
] | |
}] | |
}) | |
}; | |
} | |
UrlFetchApp.fetch(url, options); | |
} else if (!isPost && jsonData.token == TOKEN && jsonData.type == "interactive_message" && jsonData.channel.id == channel) { | |
// ボタンクリック時のアクション | |
var buttonName = ''; | |
var buttonValue = ''; | |
var text = ''; | |
if (jsonData.actions[0].type == "button") { | |
buttonName = jsonData.actions[0].name; | |
buttonValue = jsonData.actions[0].value; | |
} | |
var actionUserName = jsonData.user.name; | |
var originalText = jsonData.original_message.text; | |
if (buttonName == 'ok') { | |
//電話応対済 | |
text = actionUserName + " :telephone_receiver:が対応しました。"; | |
} else if (buttonName == 'suppressed') { | |
//営業電話リスト追加 | |
text = actionUserName + " が営業電話リスト:no_bell:に追加しました。"; | |
var suppressedData = []; | |
suppressedData.push(formatDate(new Date())); | |
suppressedData.push(buttonValue); | |
suppressedData.push(actionUserName); | |
var suppressedSheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(suppressedSheetName); //シートを取得 | |
suppressedSheet2.appendRow(suppressedData); | |
} | |
var replyMessage = { | |
"replace_original": true, | |
"response_type": "in_channel", | |
"text": originalText, | |
"attachments": [{ | |
"text": text, | |
}], | |
}; | |
return ContentService.createTextOutput(JSON.stringify(replyMessage)).setMimeType(ContentService.MimeType.JSON); | |
} | |
} | |
/** | |
* デコード | |
* @param {[String]} string | |
* @return {[String]} | |
*/ | |
function unescapeUnicode(string) { | |
return string.replace(/\\u([a-fA-F0-9]{4})/g, function(matchedString, group1) { | |
return String.fromCharCode(parseInt(group1, 16)); | |
}); | |
} | |
/** | |
* 日付のフォーマッター | |
* | |
* @param {[Date]} date | |
* @param {[String]} format | |
* @return {[String]} | |
*/ | |
function formatDate(date, format) { | |
if (!format) format = 'YYYY-MM-DD hh:mm:ss'; | |
format = format.replace(/YYYY/g, date.getFullYear()); | |
format = format.replace(/MM/g, ('0' + (date.getMonth() + 1)).slice(-2)); | |
format = format.replace(/DD/g, ('0' + date.getDate()).slice(-2)); | |
format = format.replace(/hh/g, ('0' + date.getHours()).slice(-2)); | |
format = format.replace(/mm/g, ('0' + date.getMinutes()).slice(-2)); | |
format = format.replace(/ss/g, ('0' + date.getSeconds()).slice(-2)); | |
if (format.match(/S/g)) { | |
var milliSeconds = ('00' + date.getMilliseconds()).slice(-3); | |
var length = format.match(/S/g).length; | |
for (var i = 0; i < length; i++) format = format.replace(/S/, milliSeconds.substring(i, i + 1)); | |
} | |
return format; | |
} | |
/** | |
* スプレッドシートに出力 | |
* | |
* @param {[Object]} postData | |
*/ | |
function debug(postData) { | |
var debugSheetName = 'debug'; //デバッグ出力先のスプレッドシート名 | |
var data = []; | |
data.push(formatDate(new Date())); | |
data.push(postData); | |
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(debugSheetName); | |
sheet.appendRow(data); | |
} |
2020/12/01のfondesk仕様変更に合わせてBOTを調整しました。
検証用POSTデータ
curl -X POST -H 'Content-type: application/json' --data '{"text":"*発信者* 株式会社テスト ヤマダ\n*あて先* 佐藤\nメールご確認くださいとのことでした。"}' https://hooks.slack.com/services/XXXXXXXXX
解説記事
https://qiita.com/neeton_iwasaki/items/f32baa321e3353263b18
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
デバッグ用のPOSTデータ例