//認證身份 channel_access_token
var CHANNEL_ACCESS_TOKEN = '換上自己的LINE機器人ACCESS_TOKEN'
//連結google試算表
var google_sheet_url = '使用自己的google sheet表單連結';
var spreadsheet = SpreadsheetApp.openByUrl(google_sheet_url);
var sheet_translator = spreadsheet.getSheetByName("translator"); //翻譯資料存放區
// 在程式碼裡面Translate_N代表著是第幾組
var Group_language_Max = 7 //在單一個群組內能選取最多上限同時有7種不同翻譯語言
var today = new Date(); //取得日期與時間
function doPost(e) {
//接收使用者在 line bot 上所動作的觸發資訊
var msg = JSON.parse(e.postData.contents);
//從接收到的訊息中取出 replyToken 和發送的訊息文字資訊
var replyToken = msg.events[0].replyToken;
var type = msg.events[0].type;
var userid = msg.events[0].source.userId;
var groupid = msg.events[0].source.groupId;
//判斷訊息格式
//機器人被邀請到群組
if (type == 'join') {
//找尋google sheet空間內空的區域並回傳第N個
Translate_N = translate_vain_N()
if (Translate_N != "false") {
sheet_cancel(Translate_N, groupid)
add_data_to_sheet(Translate_N, groupid)
reply_message(replyToken, reply_bot_welcome);
}
else {
push_message_userid("目前已達到群組上限,請去檢查一下")
reply_message(replyToken, reply_all_group_full);
}
}
//非邀請到群組的事件
else {
//找尋在google sheet空間此事件群組ID的位置Translate_N
var Translate_N = translate_groupid_search_N(groupid);
//成員加入退出事件:改變google sheet內成員數
if (type == 'memberJoined' || type == 'memberLeft') {
member_number = group_member_counter(groupid);
sheet_translator.getRange(4 * Translate_N + 1, 11, 1, 1).setValue(member_number);
sheet_translator.getRange(4 * Translate_N + 1, 11, 1, 1).setBackground("white");
}
//機器人退出群組事件:刪掉google sheet內該群組資料
else if (type == 'leave') {
sheet_cancel(Translate_N, groupid)
}
//有人加入機器人好友事件:回傳介紹文
else if (type == "follow") {
reply_message(replyToken, reply_instruction);
}
//按壓按鈕flex後回傳的postback事件:對於相對應的按鈕處理
else if (type == 'postback') {
var postbackMessage = msg.events[0].postback.data
//在google sheet中找尋群組,若無則觸發產生錯誤自動修復
if (Translate_N != "false") {
//以防有人誤觸已失效按鈕(finish)
if (postbackMessage == "finish") { return }
//重製按鈕(reselect)
if (postbackMessage == "reselect") {
sheet_cancel(Translate_N, groupid)
add_data_to_sheet(Translate_N, groupid)
reply = [{ 'type': 'text', 'text': "重置完成,請重新點選\nReselect complete,please reselect" }, translate_reply[0]]
reply_message(replyToken, reply)
}
else {
//語言設定重製按鈕(en,zh-tw,ja,......)
var Language_list = translate_group_language(groupid);
var Language_list_length = Language_list.length + 1;
//重複設定語言
if (Language_list.includes(postbackMessage)) { return }
//設定過多語言
else if (Language_list_length >= Group_language_Max) {
var reply = [{ 'type': 'text', 'text': '錯誤:設定過多的語言\nError:Too many languages set' }]
reply_message(replyToken, reply);
}
else {
Language_list.push(postbackMessage)
sheet_translator.getRange(4 * Translate_N + 3, 2 + Language_list_length, 1, 1).setValue(postbackMessage)
sheet_translator.getRange(4 * Translate_N + 1, 2, 1, 1).setValue("true")
sheet_translator.getRange(4 * Translate_N + 1, 5, 1, 1).setBackground("white")
var reply = [{ 'type': 'text', 'text': '語言(language):' + Language_list }]
reply_message(replyToken, reply);
}
}
}
//錯誤自動修復
else if (groupid != null) {
sheet_cancel(Translate_N, groupid)
add_data_to_sheet(Translate_N, groupid)
reply = [{ 'type': 'text', 'text': "發生錯誤,請重新點選\nAn error occurred,please reselect" }, translate_reply[0]]
reply_message(replyToken, reply)
}
}
//一般的文字訊息事件:對於相對應的文字處理
else if (type == 'message' && msg.events[0].message.text != null) {
var userMessage = msg.events[0].message.text;
//使用說明
if (/^[//]?instruction$/i.test(userMessage) || /^[//]?使用說明$/i.test(userMessage)) {
reply_message(replyToken, reply_instruction);
}
//重選
else if ((/^[//]?reselect$/i.test(userMessage) || /^[//]?重選$/i.test(userMessage)) && groupid != null) {
sheet_cancel(Translate_N, groupid)
add_data_to_sheet(Translate_N, groupid)
reply = [{ 'type': 'text', 'text': "重置完成,請重新點選\nReselect is complete,please reselect" }, translate_reply[0]]
reply_message(replyToken, reply)
}
//忽略該句話的功能
else if (/^[//]/.test(userMessage)) { return }
//在google sheet中找尋群組,若無則觸發產生錯誤自動修復
else if (Translate_N != "false") {
var Language_list = translate_group_language(groupid);
if (Language_list.length != 0) {
var output_str = ""
for (language of Language_list) {
output_str = output_str + '\n【' + language + '】' + translate(userMessage, language);
}
output_str = output_str.replace(/^\n/, "")
reply = [{ 'type': 'text', 'text': output_str }]
reply_message(replyToken, reply);
sheet_translator.getRange(4 * Translate_N + 1, 5, 1, 4).setValue(today);
var data_userid = JSON.parse(sheet_translator.getSheetValues(4 * Translate_N + 2, 11, 1, 1)[0][0])
data_userid[userid] = ""
sheet_translator.getRange(4 * Translate_N + 2, 11, 1, 1).setValue(JSON.stringify(data_userid))
check_porn_group(userMessage, Translate_N, groupid, Language_list)
}
else {
//沒有選擇任何語言就打字說話
reply = [{ 'type': 'text', 'text': '錯誤:請先設定語言\nError:Please set the language first' }]
reply_message(replyToken, reply);
}
}
//錯誤自動修復
else if (groupid != null) {
sheet_cancel(Translate_N, groupid)
add_data_to_sheet(Translate_N, groupid)
reply = [{ 'type': 'text', 'text': "發生錯誤,請重新點選\nAn error occurred,please reselect" }, translate_reply[0]]
reply_message(replyToken, reply)
}
//個人與機器人對話(無groupid)
else {
reply = [{ 'type': 'text', 'text': "只限群組翻譯功能,如說明圖所示\nTranslation functionality is only available for groups, as shown in the explanatory diagram." }]
reply_message(replyToken, reply)
}
}
}
}
// 翻譯
function translate(userMessage, language) {
var translated_txt = ""
// 使用自己帳戶的 google apps script translate
try {
translated_txt = LanguageApp.translate(userMessage, "", language)
return translated_txt
} catch (e) { }
}
// 刪除google sheet群組資料(有groupid參數會刪GROUP ID data)
function sheet_cancel(Translate_N, groupid) {
if (Translate_N == "false" || Translate_N == -1) { return }
if (typeof groupid !== 'undefined') {
data_groud_1 = JSON.parse(sheet_translator.getSheetValues(2, 16, 1, 1)[0][0])
data_groud_2 = JSON.parse(sheet_translator.getSheetValues(2, 17, 1, 1)[0][0])
delete data_groud_1[groupid]
delete data_groud_2[groupid]
sheet_translator.getRange(2, 16, 1, 1).setValue(JSON.stringify(data_groud_1));
sheet_translator.getRange(2, 17, 1, 1).setValue(JSON.stringify(data_groud_2));
}
sheet_translator.getRange(4 * Translate_N + 2, 3, 2, 6).setValue('');
sheet_translator.getRange(4 * Translate_N + 3, 9, 1, 1).setValue('');
sheet_translator.getRange(4 * Translate_N + 1, 2, 1, 1).setValue('false');
sheet_translator.getRange(4 * Translate_N + 1, 5, 1, 4).setValue('');
sheet_translator.getRange(4 * Translate_N + 1, 5, 1, 4).setBackground("white");
sheet_translator.getRange(4 * Translate_N + 1, 11, 1, 1).setValue('false');
sheet_translator.getRange(4 * Translate_N + 2, 11, 1, 1).setValue({})
sheet_translator.getRange(4 * Translate_N + 1, 13, 1, 1).setValue("false");
sheet_translator.getRange(4 * Translate_N + 1, 11, 1, 1).setBackground("#FF4D00")
}
// 新增資料到google sheet
function add_data_to_sheet(Translate_N, groupid) {
if (Translate_N == "false") { Translate_N = translate_vain_N(groupid) }
if (Translate_N <= 1200) {
data_groud_1 = JSON.parse(sheet_translator.getSheetValues(2, 16, 1, 1)[0][0])
data_groud_1[groupid] = Translate_N
sheet_translator.getRange(2, 16, 1, 1).setValue(JSON.stringify(data_groud_1));
}
else {
data_groud_2 = JSON.parse(sheet_translator.getSheetValues(2, 17, 1, 1)[0][0])
data_groud_2[groupid] = Translate_N
sheet_translator.getRange(2, 17, 1, 1).setValue(JSON.stringify(data_groud_2));
}
member_number = group_member_counter(groupid);
sheet_translator.getRange(4 * Translate_N + 2, 3, 1, 6).setValue(groupid);
sheet_translator.getRange(4 * Translate_N + 1, 5, 1, 4).setValue(today);
sheet_translator.getRange(4 * Translate_N + 1, 11, 1, 1).setValue(member_number);
sheet_translator.getRange(4 * Translate_N + 1, 11, 1, 1).setBackground("white");
sheet_translator.getRange(4 * Translate_N + 1, 5, 1, 4).setBackground("#FF4D00")
}
// 利用groupid搜尋是否在translate_group表單內,若在裡面則回傳Translate_N數值(第幾組),反之則回傳false
function translate_groupid_search_N(groupid) {
var data_groud_1 = JSON.parse(sheet_translator.getSheetValues(2, 16, 1, 1)[0][0])
var data_groud_2 = JSON.parse(sheet_translator.getSheetValues(2, 17, 1, 1)[0][0])
var data = Object.assign(data_groud_1, data_groud_2)
if (data.hasOwnProperty(groupid)) { return data[groupid] }
return "false"
}
// 在表單內搜尋是否有空位,若有則回傳Translate_N數值(第幾組)
function translate_vain_N() {
var Translate_N
var data_groud_1 = JSON.parse(sheet_translator.getSheetValues(2, 16, 1, 1)[0][0])
var data_groud_2 = JSON.parse(sheet_translator.getSheetValues(2, 17, 1, 1)[0][0])
var data = Object.assign(data_groud_1, data_groud_2)
const values = Object.values(data).sort((a, b) => a - b);
var Translate_N_Max = Math.max(...values)
const all_numberArr = Array.from({ length: Translate_N_Max }, (_, i) => i);
const vain_N_Arr = all_numberArr.filter(num => !values.includes(num));
for (Translate_N of vain_N_Arr) {
var sheet_groupid = sheet_translator.getSheetValues(4 * Translate_N + 2, 3, 1, 6)[0][0]
if (sheet_groupid == "") {
return Translate_N
}
}
Translate_N = Translate_N_Max
while (true) {
Translate_N++
var sheet_groupid = sheet_translator.getSheetValues(4 * Translate_N + 2, 3, 1, 1)[0][0]
if (sheet_groupid == "") {
return Translate_N
}
}
}
// 在translate_group表單內搜尋這個人所選過的翻譯語言,若有則回傳語言組成的矩陣
function translate_group_language(groupid) {
Translate_N = translate_groupid_search_N(groupid)
Language_list = sheet_translator.getSheetValues(4 * Translate_N + 3, 3, 1, Group_language_Max)[0]
return Language_list.filter(item => item !== '')
}
// 計算並回傳群組的人數
function group_member_counter(groupid) {
try {
var group_member_counter_object = UrlFetchApp.fetch('https://api.line.me/v2/bot/group/' + groupid + '/members/count', {
'headers': {
"Content-Type": "application/json; charset=UTF-8",
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
},
});
return parseInt(group_member_counter_object.getContentText().replace(/[^0-9]/ig, ""))
} catch (e) {
return "false"
}
}
// 利用userid搜尋並回傳username(使用者名稱)
function userid_to_username(userid) {
var username_object = UrlFetchApp.fetch("https://api.line.me/v2/bot/profile/" + userid, {
'headers': {
"Content-Type": "application/json; charset=UTF-8",
'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
},
});
return JSON.parse(username_object.getContentText()).displayName
}
這個是google apps script
https://script.google.com/d/1fJXb2Go_K8r1Hi9M-EeV_XMCvbJK0DLXoDfVU1miNlb2-g9eQxKwQsKW/edit?usp=sharing
這個是google sheet表單
https://docs.google.com/spreadsheets/d/1BfMS7W5CUG_uxiVUPgZHrvy0xN91-I0EM3n8zSxCNxw/edit?usp=sharing
由於整個LINE BOT的功能是一個一個被加上去的,所以一開始程式碼也是相對的簡單一兩個if-else而已,到最後程式龐大了起來就變成雜亂不堪,又加上我個人也覺得整體程式碼寫法過於簡單,但我也懶得修改了,哈哈哈哈~~
再請各位耐心觀賞了 (●'◡'●)
在當初我研究LINE BOT的時候也碰到了很多的困難,完全都是靠著各大神的資料來讓我一步步的來完成。
最後,也感謝各個平台與各大神借我引用於此,讓更多人能夠學習LINE BOT並獲得其中的樂趣,若有任何冒犯或抄襲之虞,請向我告知並移除內容,感謝~~
另外有任何想要跟我討論,或是想要給我建議的,都可以留言跟我說喔!!
(1) 操作說明與應用
(2) 建立LINE BOT及Google Apps Script專案
(3) 連結 Google sheet 與 LanguageApp 翻譯功能
(4) 用 Google Apps Script API 傳送 LINE 訊息
(5) LINE 各事件 event & 各訊息 Message 及 官方文獻
(6) 為各位呈現 原始程式碼 啦~~
接案 (☛´∀`*)☛ LINE ID:albert20699