/** @type {string} line チャンネルアクセストークン */
var CHANNEL_ACCESS_TOKEN = PropertiesService.getScriptProperties().getProperty('CHANNEL_ACCESS_TOKEN');
/** @type {string} Slack レガシートークン */
var SLACK_LEGACY_TOKEN = PropertiesService.getScriptProperties().getProperty('SLACK_LEGACY_TOKEN');
/** @type {object} スプレットシートオブジェクト */
var SPREADSHEETS = SpreadsheetApp.openById(PropertiesService.getScriptProperties().getProperty('SPREADSHEET_KEY'));
/** @type {object} [description] */
var SHEET = SPREADSHEETS.getSheetByName(PropertiesService.getScriptProperties().getProperty('SHEET_NAME'));
/** @type {array} sheetデータが格納された配列 */
var SHEET_DATA = SHEET.getDataRange().getValues();
/**
* Postを受け付けるメソッド
* @method doPost
* @param {object} e イベントデータ
* @return {Int} 戻り値(使用しないので0を返す)
*/
function doPost(e) {
/** @type {string} メッセージの通知先 */
var SYSTEM_NOTIFICATION_CHANNEL = PropertiesService.getScriptProperties().getProperty('SYSTEM_NOTIFICATION_CHANNEL');
/** @type {string} メッセージの通知先 */
var NOTIFICATION_CHANNEL = PropertiesService.getScriptProperties().getProperty('NOTIFICATION_CHANNEL');
var line = JSON.parse(e.postData.contents).events[0];
console.log(JSON.stringify(line));
switch (line.type) {
case 'follow':
var profile = get_line_profile(line);
idRecordsRegistration(line, profile, '', 1, 1);
postSlackMessage(SYSTEM_NOTIFICATION_CHANNEL, '```フォローしました。\nステータスメッセージ: ' + profile.statusMessage + '```', profile);
break;
case 'unfollow':
var rowNo = searchIdFromSpreadSheet(line.source.userId);
if (rowNo == undefined) {
postSlackMessage(SYSTEM_NOTIFICATION_CHANNEL, '```ブロックされましたが、該当IDが見つかりませんでした。\nID: ' + line.source.userId + '\n```');
} else {
SHEET.getRange("E"+(rowNo+1)).setValue(0);
SHEET.getRange("F"+(rowNo+1)).setValue(0);
var userName = getValFromCell(rowNo, 0);
postSlackMessage(SYSTEM_NOTIFICATION_CHANNEL, '```ブロックされました。\nNAME: ' + userName + '\n```');
}
break;
case 'join':
idRecordsRegistration(line, undefined, '', 1, 0);
postSlackMessage(SYSTEM_NOTIFICATION_CHANNEL, 'グループに追加されました。\n登録情報を確認してください。 ' + line.source.groupId);
break;
case 'leave':
var groupInfo = getValFromCell(searchIdFromSpreadSheet(line.source.groupId), 0);
if (groupInfo == '') {
postSlackMessage(SYSTEM_NOTIFICATION_CHANNEL, 'グループから外されましたが、該当IDが見つかりませんでした。\n ' + line.source.groupId);
} else {
SHEET.getRange("E"+(rowNo+1)).setValue(0);
SHEET.getRange("F"+(rowNo+1)).setValue(0);
postSlackMessage(SYSTEM_NOTIFICATION_CHANNEL, 'グループから外されました。\n ' + groupInfo);
}
break;
case 'message':
var profile = get_line_profile(line);
switch (line.source.type) {
case 'user':
postSlackMessage(NOTIFICATION_CHANNEL, get_line_message(line), profile);
break;
case 'group':
case 'room':
var groupInfo = getValFromCell(searchIdFromSpreadSheet(line.source.groupId), 0);
var sendCh = getValFromCell(searchIdFromSpreadSheet(line.source.groupId), 3);
if (groupInfo == '') {
groupInfo = line.source.groupId;
}
if (sendCh == '') {
sendCh = NOTIFICATION_CHANNEL;
}
postSlackMessage(sendCh, get_line_message(line), profile, groupInfo);
break;
}
break;
default:
postSlackMessage(SYSTEM_NOTIFICATION_CHANNEL, line);
break;
}
return 0;
}
/**
* lineメッセージ内容毎の仕分け処理
* @method get_line_message
* @param {object} line line eventオブジェクト
* @return {string} メッセージ内容 or GDriveへアップロしたオブジェクトUrl
*/
function get_line_message(line) {
switch (line.message.type) {
case 'text':
return line.message.text;
case 'image':
var blob = get_line_content(line.message.id);
return uploadToGoogleDrive(line.message.id + '.png', blob, 'image/png');
case 'video':
var blob = get_line_content(line.message.id);
return uploadToGoogleDrive(line.message.id + '.mp4', blob, 'video/mp4');
case 'audio':
var blob = get_line_content(line.message.id);
return uploadToGoogleDrive(line.message.id + '.m4a', blob, 'audio/aac');
case 'file':
var blob = get_line_content(line.message.id);
return uploadToGoogleDrive(line.message.fileName, blob);
case 'location':
return '位置情報を受信\naddress: ' + line.message.address + '\nlatitude: ' + line.message.latitude + '\nlongitude: ' + line.message.longitude;
case 'sticker':
var timestamp = new Date();
return 'https://stickershop.line-scdn.net/stickershop/v1/sticker/' + line.message.stickerId + '/android/sticker.png?' + timestamp.getTime();
default:
return 0;
}
}
/**
* lineからコンテント取得処理
* @method get_line_content
* @param {string} message_id メッセージID
* @return {object} 送信されたオブジェクト情報
*/
function get_line_content(message_id) {
try {
var headers = {
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN
};
var options = {
'headers': headers
};
var url = 'https://api.line.me/v2/bot/message/' + message_id + '/content';
var blob = UrlFetchApp.fetch(url, options);
return blob;
} catch (e) {
console.log(e);
return null;
}
}
/**
* lineからプロファイル情報取得
* @method get_line_profile
* @param {object} line line eventオブジェクト
* @return {object} プロファイルオブジェクト
*/
function get_line_profile(line) {
var headers = {
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN
};
var options = {
'headers': headers
};
var url;
switch (line.source.type) {
case 'user':
url = 'https://api.line.me/v2/bot/profile/' + line.source.userId;
break;
case 'group':
url = 'https://api.line.me/v2/bot/group/' + line.source.groupId + '/member/' + line.source.userId;
break;
case 'room':
url = 'https://api.line.me/v2/bot/room/' + line.source.groupId + '/member/' + line.source.userId;
break;
}
var response = UrlFetchApp.fetch(url, options);
var content = JSON.parse(response.getContentText());
return content;
}
/**
* slackへのメッセージ送信処理
* @method postSlackMessage
* @param {string} sendCh 送信先チャネル名
* @param {string} mes メッセージ情報
* @param {object} profile プロファイルオブジェクト情報
* @param {object} auxiliary 補足情報'(グループ名とか)'
* @return {object} なし
*/
function postSlackMessage(sendCh, mes, profile, auxiliary) {
/** @type {string} システムアイコン */
var SYSTEM_ICON = PropertiesService.getScriptProperties().getProperty('SYSTEM_ICON');
var slackApp = SlackApp.create(SLACK_LEGACY_TOKEN);
if (profile != undefined) {
var options = {
username: profile.displayName + (auxiliary != undefined ? ' from ' + auxiliary : ''),
icon_url: profile.pictureUrl
};
} else {
var options = {
username: 'system announce',
icon_url: SYSTEM_ICON
};
}
console.log(JSON.stringify(options));
slackApp.postMessage(sendCh, mes, options);
}
/**
* G Driveからフォルダ名に一致するフォルダIDを取得する
* @method getAllFolderID
* @param {string} folderName フォルダ名
* @return {string} フォルダID
*/
function getAllFolderID(folderName) {
var all_folders = DriveApp.getFolders();
while (all_folders.hasNext()) {
var folder = all_folders.next();
if (folderName == folder.getName()) {
return folder.getId();
}
}
console.log('not unmatch folder name:' + folderName);
return null;
}
/**
* G Driveへファイルのアップロード処理
* @method uploadToGoogleDrive
* @param {string} fileName ファイル名
* @param {object} blob blobオブジェクト(ファイルオブジェクト)
* @param {string} fileType ファイルMIMEタイプ
* @return {string} ファイルへのアクセスURL
*/
function uploadToGoogleDrive(fileName, blob, fileType) {
/** @type {string} g Drive上のアップロード先 */
var LINE_UPLOAD_FORDER = PropertiesService.getScriptProperties().getProperty('LINE_UPLOAD_FORDER');
var file = null;
try {
var folderId = getAllFolderID(LINE_UPLOAD_FORDER);
if (folderId != null) {
var fileOption = {
title: fileName,
parents: [{
id: folderId
}]
};
if (fileType != undefined) fileOption.mimeType = fileType
file = Drive.Files.insert(fileOption, blob);
return file.thumbnailLink?file.thumbnailLink:file.embedLink;
} else {
file = DriveApp.createFile(blob);
return file.getThumbnail()!=null?file.getThumbnail():file.getUrl();
}
} catch (e) {
return e.message;
}
}
/**
* ID情報の登録処理(Spread sheetへの書き込み)
* @method idRecordsRegistration
* @param {object} line lineメッセージオブジェクト
* @param {object} profile プロファイル情報 無い場合はundefined
* @param {string} sendCh 送信するチャンネル
* @param {integer} followFlg フォローされているか判定情報
* @param {integer} enabledFlg 有効無効フラグ
* @return {none} なし
*/
function idRecordsRegistration(line, profile, sendCh, followFlg, enabledFlg) {
var id = '';
var name = '';
switch (line.source.type) {
case 'user':
id = line.source.userId;
break;
case 'group':
case 'room':
id = line.source.groupId;
break;
default:
console.log('未定義type');
return ;
}
if (profile != undefined) {
name = profile.displayName
}
SHEET.appendRow([name, id, line.source.type, sendCh, followFlg, enabledFlg]);
}
/**
* スプレットシートデータから指定値が格納された行番号を返す
* @method searchIdFromSpreadSheet
* @param {string} val 検索値
* @return {stirng} 該当値が格納された行番号 無い場合はundefined
*/
function searchIdFromSpreadSheet(val) {
for (var rowNo=0; rowNo<SHEET_DATA.length; ++rowNo) {
if (SHEET_DATA[rowNo].indexOf(val) !== -1) {
return rowNo;
}
}
return undefined;
}
/**
* スプレットシートデータの特定セルからデータを取り出すあ
* @method getValFromCell
* @param {integer} row 行番号
* @param {integer} col 列番号
* @return {string} セルに格納されている情報
*/
function getValFromCell(row, col) {
if (row == undefined || col == undefined) {
return '';
}
return SHEET_DATA[row][col];
}