Google Apps Script 內部檔案分布

  • 我將只會講解主程式碼(doPost)與支程式(translate_other_function)的部分

主程式原始碼(doPost)

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
// 認證身份 channel_access_token,請放上自己的CHANNEL_ACCESS_TOKEN
var CHANNEL_ACCESS_TOKEN=""
// 請放上自己的google sheet (可以打開我的進去參觀一下~~)
var google_sheet_url='https://docs.google.com/spreadsheets/d/1a2LjfrpoGb8dLYPX7piCsl0NEUMgiLIyxSrMAWSf0cA/edit?usp=sharing';
var spreadsheet = SpreadsheetApp.openByUrl(google_sheet_url);
var sheet_translator = spreadsheet.getSheetByName("translator");

// 在程式碼裡面Translate_N代表著是第幾組,其範圍為0~49
var Translate_N_Max=50 //Translate_N最多上限為同時有50組
var Group_language_Max=12 //在單一個群組內能選取最多上限同時有12種不同翻譯語言
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;
//取得觸發事件使用者所屬在Excel的位置(若無則false)
var Translate_N=translate_groupid_search_N(groupid);

//判斷有人把機器人加入群組
if(type=='join'){
if(translate_vain_N()!="false"){ //先檢查是否Excel內有無空處
//在空處地方填入
sheet_translator.getRange(4*translate_vain_N()+2,3,1,6).setValue(groupid);
reply_message(replyToken,reply_bot_welcome);
}
else{ //Excel內全部都滿了,到達上限(有很多空間,應該不太可能)
push_message_userid("目前已達到群組上限,請去檢查一下")
reply_message(replyToken,reply_all_group_full);
}
}
else if(type=='leave'){ //若有人把機器人退出群組,則刪除該群組對應在Excel的資料
sheet_cancel(Translate_N)
}
else if(type=="follow"){ //若有人把機器人加入為好友,則推送介紹文
reply_message(replyToken,reply_instruction);
}
else if(type=='postback'){ //若有人點選群組內的翻譯語言按鈕
postbackMessage=msg.events[0].postback.data //取得所按的按鈕
if(Translate_N!="false"){ //檢查是否所屬在Excel內(無則略過)
//檢查鎖定欄位已經為使用中True了(告知使用者要將機器人退出重加)
if(String(sheet_translator.getSheetValues(4*Translate_N+1,2,1,1)[0][0])=="true"){
reply_message(replyToken,reply_reselect);
}
else{ //鎖定欄位尚未使用False
var Language_list=translate_group_language(groupid);
if(postbackMessage=="finish"){ //點選finish後檢查是否又設定正確
if(Language_list.length==0){
reply_message(replyToken,[{'type': 'text','text': "錯誤:尚未設定語言\nError:Language not set yet"}])
}
else{ //都設定正確,鎖定欄位改為使用中True
sheet_translator.getRange(4*Translate_N+1,2,1,1).setValue("true")
reply_message(replyToken,[{'type': 'text','text': "設定完成,可以開始交談\nSetup is complete,can start talking"}])
}
}
else if(postbackMessage=="reselect"){ //點選reselect後讓使用者重新選擇
sheet_cancel(Translate_N)
sheet_translator.getRange(4*Translate_N+2,3,1,6).setValue(groupid);
reply=[{'type': 'text','text': "重置完成,請重新點選\nReselect is complete,please reselect"},translate_reply[0]]
reply_message(replyToken,reply)
}
// 非點選finish或reselect代表為點選翻譯語言
else if(postbackMessage.replace(/[a-z-A-Z]*/, '').length==0){
if(Language_list.includes(postbackMessage)){ //設定重複翻譯語言
var reply=[{'type': 'text','text':'錯誤:不能設定重複的語言\nError:Cannot set duplicate language'}]
reply_message(replyToken,reply);
}
//超過能夠設定的上限
else if(Language_list.length>=Group_language_Max){
var reply=[{'type': 'text','text':'錯誤:設定過多的語言\nError:Too many languages set'}]
reply_message(replyToken,reply);
}
//經過確認資料後存放至Excel
sheet_translator.getRange(4*Translate_N+3,3+Language_list.length,1,1).setValue(postbackMessage)
var reply=[{'type': 'text','text':'語言(language):'+String(translate_group_language(groupid))}]
reply_message(replyToken,reply);
}
}
}
} //最後判斷是文字訊息
else if(type=='message' && msg.events[0].message.text!=null){
var userMessage = msg.events[0].message.text;
//呼叫使用說明
if(userMessage.toLowerCase()=="instruction" || userMessage=="使用說明"){
reply_message(replyToken,reply_instruction);
}
else if(Translate_N!="false"){
//若是有存在Excel且檢查鎖定欄位已經為使用中True則翻譯
if(String(sheet_translator.getSheetValues(4*Translate_N+1,2,1,1)[0][0])=="true"){
var Language_list=translate_group_language(groupid);
for(i in Language_list){
if(i==0){output_str='【'+Language_list[0]+'】'+LanguageApp.translate(userMessage, "", Language_list[0])}
else{
output_str=output_str+'\n【'+Language_list[i]+'】'+LanguageApp.translate(userMessage, "", Language_list[i]);
}
}
sheet_translator.getRange(4*Translate_N+1,5,1,4).setValue(today);
reply=[{'type': 'text','text':output_str}]
reply_message(replyToken,reply);
}
else{ //若是有存在Excel但檢查鎖定欄位未使用中False則提示錯誤
reply=[{'type': 'text','text':'錯誤:請先設定【完成】\nError:Please set 【Finish】 first'}]
reply_message(replyToken,reply);
}
}
}
}

支程式(translate_other_function)

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
// 將對應的Excel存放位置(Translate_N)的資料清空
function sheet_cancel(Translate_N){
sheet_translator.getRange(4*Translate_N+2,3,2,12).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,11,1,1).setValue('');
}

// 利用groupid搜尋是否在translate_group_double表單內,若在裡面則回傳Translate_N數值(第幾組),反之則回傳false
function translate_groupid_search_N(groupid){
for(i=0; i<Translate_N_Max; i++){
if(groupid==sheet_translator.getSheetValues(4*i+2,3,1,6)[0][0]){
return i
}
}
return "false"
}

// 在translate_group_double表單內搜尋是否有空位,若有則回傳Translate_N數值(第幾組),反之則回傳false
function translate_vain_N(){
for(i=0; i<Translate_N_Max; i++){
if(""==sheet_translator.getSheetValues(4*i+2,3,1,6)[0][0]){
return i
}
}
return "false"
}

// 在translate_group_mutichat表單內搜尋這個人所選過的翻譯語言,若有則回傳語言組成的矩陣,反之則回傳false
function translate_group_language(groupid){
Translate_N=translate_groupid_search_N(groupid)
Language_list=[]
for(i=0; i<Group_language_Max; i++){
data=sheet_translator.getSheetValues(4*Translate_N+3, 3+i, 1, 1)[0][0]
if(""!=data){
var count=Language_list.push(data.replace(/ */, ''))
}
}
if(count==0){
return "false"
}
return Language_list
}

// 傳入groupid後,計算並回傳群組的人數
function group_member_counter(groupid) {
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,""))
}

// 利用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
}

程式碼(網址)


檢討

由於整個LINE BOT的功能是一個一個被加上去的,所以一開始程式碼也是相對的簡單一兩個if-else而已,到最後程式龐大了起來就變成雜亂不堪,又加上我個人也覺得整體程式碼寫法過於簡單,但我也懶得修改了,哈哈哈哈~~
再請各位耐心觀賞了 (●’◡’●)


謝謝~

在當初我研究LINE BOT的時候也碰到了很多的困難,完全都是靠著各大神的資料來讓我一步步的來完成,非常謝謝~~
最後,也感謝各個平台與各大神借我引用於此,讓更多人能夠學習LINE BOT並獲得其中的樂趣,若有任何冒犯或抄襲之虞,請向我告知並移除內容,感謝~~
另外有任何想要跟我討論,或是想要給我建議的,都可以留言跟我說喔~~