iT邦幫忙

0

【LINE BOT 翻譯機器人】(6) 為各位呈現 原始程式碼 啦~~

  • 分享至 

  • xImage
  •  

Google Apps Script 內部檔案分布

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

主程式原始碼(doPost)

//認證身份 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)
      }
    }
  }
}

支程式(translate_other_function)

// 翻譯
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並獲得其中的樂趣,若有任何冒犯或抄襲之虞,請向我告知並移除內容,感謝~~
另外有任何想要跟我討論,或是想要給我建議的,都可以留言跟我說喔!!


【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

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言