iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 29
0
AI & Data

利用Google App Script 實作Telegram Bot系列 第 29

Day 29-Telegram Bot:定時自動發送訊息

  • 分享至 

  • xImage
  •  

Day 29-Telegram Bot:定時自動發送訊息

最後我們來講一下這個定時發送訊息的功能。

這個功能可以用在官方發送定期訊息的時候,而GAS在執行這樣子的定時功能相當的方便,只要新增觸發條件就可以完成了,馬上就來試試看吧。

定時傳送訊息

首先先隨便寫個發送訊息的功能。

function auto_send(){
  var payload = {
        "method": "sendMessage",
        "chat_id": "1098175067", 
        "text": "auto send test"
      }
      start(payload);
   return payload;   
}

好了之後可以先點選執行,測試看看是否可以成功發送訊息。

觸發條件設定

接著點下上方選單的編輯,選擇現有專案的啟動程序。

https://ithelp.ithome.com.tw/upload/images/20201009/20130283pgqjBUgbu5.png

按下之後就會進到機器人的觸發條件頁面。

可以看到目前沒有任何的觸發條件,我們點選右下角的新增觸發條件,就可以新增定時的功能。

https://ithelp.ithome.com.tw/upload/images/20201009/20130283GT3MYkBjY4.png

在觸發條件的畫面裡,可以選擇要執行的功能,這邊就選擇我們剛剛新增的發送訊息功能。

執行的部屬作業則要記得選擇部屬完的最新版本。

而活動來源有時間驅動跟來自日曆兩種選擇,如果選擇來自日曆就可以透過Google日曆來選擇發動的時間,這邊我選擇時間驅動。

之後就可以接著選取時間型觸發條件類型,可以根據特定日期時間或是依據分鐘、小時、日、週、月不同時間單位的計時器。

依照選取的時間型觸發條件類型就可以有不同的時間區段。

這邊我選擇測試的是分鐘計時器,觸發的間隔則是每分鐘。

https://ithelp.ithome.com.tw/upload/images/20201009/20130283aFW3FIBVEL.png

完成後就會看到機器人的觸發條件多了剛剛新增的觸發條件。

https://ithelp.ithome.com.tw/upload/images/20201009/20130283CZHENwGeBR.png

執行的結果就會像是這樣,每分鐘都傳送一樣的方法。

https://ithelp.ithome.com.tw/upload/images/20201009/20130283SprdrVQLfr.png

定時傳送圖片:

換成是圖片也可以有同樣的效果。

function auto_send(){
  var payload = {
        "method": "sendPhoto",
        "chat_id": "1098175067", 
        "photo": "https://i.pinimg.com/originals/07/31/4f/07314f8ab5bc45b1bc1d9253cb4f1dc9.png"
      }
      start(payload);
   return payload;   
}

https://ithelp.ithome.com.tw/upload/images/20201009/20130283w726POV6b8.png

定時發送天氣訊息:

接著我們來嘗試搭配上次寫的天氣機器人,來做定時發送天氣訊息的功能。

之前發送的天氣訊息是取得了使用者輸入的地點,來傳送相應地點的天氣資訊,而為了做定時發送天氣的訊息,我設計儲存最後一次使用者輸入的地點,來做為定時發送天氣訊息的地點。

我們先在試算表建立一個新的表單來儲存使用者最後一次輸入的地點,試算表的第一行是儲存使用者的ID,第二行則是儲存使用者最後一次輸入的地點。

https://ithelp.ithome.com.tw/upload/images/20201009/20130283fo70w7oC3p.png

接著我們新開一個指令碼檔案,裡面放入讀取試算表的方法locationData跟儲存資料進試算表的方法saveLocation。

location.gs

function locationData(chatid){
  var SpreadSheet = SpreadsheetApp.openById("1h9kJrX7bIdrGqiwUP6Bf45JQ5iMlWdYLXWFRpcq6gOQ");
  var Sheet = SpreadSheet.getSheetByName("user_location");
  var data = Sheet.getDataRange().getValues();
  var row = 0;
  if(chatid == 0) return data;
  for (var i = 0; i < data.length; i++) {
    if(chatid == data[i][0]){
      row = i;
      break;
    }
  }
  var userData = {"chatid": data[row][0] , "location": data[row][1] , "row": row};
  return userData;
}

第4行:getDataRange().getValues()沒有指定範圍,則代表將所有試算表的資料都存進去。
第5行:設一個變數row用來確定使用者是在第幾行。
第6行:如果使用者的id0則會return data的資料,這行做的事情在後面會再說明。
第7-12行:設定一個for迴圈,用來搜尋整個試算表的資料。如果使用者的iddata[i][0]的值,則代表使用者在第i行,我們將row設為i,就可以透過row來取得location的值。
第13行:將data[row][0]chatiddata[row][1]locationrowrow,如果不加這個"row": row的話會出現這個範圍的起始值過小的問題,因此我們要明確地告訴程式這個row是甚麼。

function saveLocation(location,chatid ,row){
    var SpreadSheet = SpreadsheetApp.openById("1h9kJrX7bIdrGqiwUP6Bf45JQ5iMlWdYLXWFRpcq6gOQ");
    var Sheet = SpreadSheet.getSheetByName("user_location");  
    Sheet.getRange(row + 1 , 2).setValue(location);
}

第4行:把(row + 1 , 2)的位置設為location,也就是我們輸入地點之後就把這個地點儲存下來,因為range跟array的索引會差1,所以我們這邊必須要寫row+1

sendtext.gs

function sendtext(estringa,name,row){
  if(estringa.message.text.match("/weather ")){
    var temp  = estringa.message.text.split("/weather ");
    var location = temp[1];
    var Weatherfile = get_weather(location,chatid);
    var mensaje = weather_forecast(Weatherfile,location,chatid); 
    var data = locationData(chatid);
    saveLocation(location,chatid ,data.row);
  return mensaje;
  }
}

而再來就是稍微改寫一下sendtext方法,記得要把前面儲存下來的row放入方法的後面括號()

並且把locationDatasaveLocation方法都一起放進來,這樣就可以在輸入/weather <城市>的同時做儲存。

而這邊同樣要將locationData轉為data物件儲存,並且放到saveLocation裡面引用。

觸發定時發送天氣訊息事件:

而在最後我們要做的就是另外寫一個方法,把這個讀取訊息和傳送訊息的方法通通都寫進去,這樣我們的觸發事件只要執行這個方法就可以了。

function clockWeather(){
  var allData = locationData(0);
  for(var i = 0;i < allData.length;i++){
    var data = {"chatid": allData[i][0].toFixed() , "location": allData[i][1]};
    Logger.log(data);
    var Weatherfile = get_weather(data.location,data.chatid);
    var mensaje = weather_forecast(Weatherfile,data.location,data.chatid);
    start(mensaje);
  }
}

第2行:這裡我們將locationData(0)的資料寫入allData,可以看到我們前面locationData(chid)方法裡面括號是chid,這個locationData(0)也就代表chid=0。而我們前面在locationData(chid)方法裡面有寫到,如果chid=0的話,就會回傳整個試算表的資料,也就是說allData資料裡就是所有試算表的資料。這也代表著使用這個clockWeather方法時會對所有在試算表有儲存id的使用者傳送訊息。
第4行:這邊則是要把試算表的資料抓出來,同時要特別注意,如果你的id會出現科學記號的情況,要使用toFixed()將資料轉型,不確定取得的資料長怎樣的話可以像我第5行設一個Log來檢查資料。
第6行:將試算表的資料放入上一篇的get_weatherweather_forecast方法來取得API資料和傳送訊息。

這樣子我們只要執行clockWeather方法就可以讀取試算表的資料來傳送天氣資訊了,最後再照著前面說的設定觸發條件,就可以讓機器人依照設定的時間來傳送天氣訊息囉。


上一篇
Day 28-Telegram Bot:天氣機器人後端
下一篇
Day 30-結語
系列文
利用Google App Script 實作Telegram Bot30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言