Telegram Bot 學習筆記 – 2:用 Google Apps Script 接收 / 推播訊息

/

上一篇的 Telegram Bot 是把程式碼放在 GCP 上執行。這一篇改放在 Google Apps Script 上。

主要原因是,Google Apps Script(以下稱 GAP)比 GCP 更好上手,而且發佈速度也快,如果只是單純收發訊息,用 GAP 會更方便。


新增一個 GAP 檔案

只要有 Google 帳號,就可以新增 GAP 檔案。

登入 Google 帳號後,進到雲端硬碟的頁面,點選「新增」,就可以在清單中看到「Google Apps Script」的項目:

在Google雲端硬碟中新增Google Apps Script
在 Google 雲端硬碟中新增 Google Apps Script

點選後,改一下專案名稱,就可以開始使用了。

GAP初始介面
GAP 初始介面

加入 Firebase 功能

用 GAP 就很像在寫 JS 處理後端,預設的功能都是 Google 雲端硬碟上有的,像 Excel、Word 之類,Firebase 不在預設的功能裡,因此需要另外加上去。

網路蠻多教學都是接 Google Excel,Google 一下可以找到很多。不過本人開發的機器人,資料都是用每一個 user id 來當 key,各自的行為存在各自的欄位裡,用 Firebase 比較適合。

接 Firebase 的官方說明文件在這,以下步驟是參考文件說明的:

https://sites.google.com/site/scriptsexamples/new-connectors-to-google-services/firebase

這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝

1 加入 Firebase 程式庫

點選「資源」 → 「程式庫」:

「資源」 → 「程式庫」
「資源」 → 「程式庫」

會出現一個燈箱,在「新增程式庫」的欄位填入:

MYeP8ZEEt1ylVDxS7uyg9plDOcoke7-2l

2021.03.08 更新:
有人留言說輸入上面那串找不到,查了一下後發現 FirebaseApp 的 ID 更新了,要改輸入這個:
1hguuh4Zx72XVC1Zldm_vTtcUUKUA6iBUOoGnJUWLfqDWx5WlOJHqYkr

按下新增,就會看見 FirebaseApp 被新增上去。版本的部份選擇「Public release」,最後按下儲存,就接上 Firebase 的功能了。

版本的部份選擇「Public release」
版本的部份選擇「Public release」

2 接上指定的 Firebase

GAP 有了 Firebase 的功能,下一步就是要指定資料要讀寫 Firebase 裡的哪一個資料庫。

進到 Firebase 的首頁 後,新增一個 Firebase 資料庫,新增完成就可以進到資料庫的介面。

左側選單點選「Database」,會看見資料庫的介紹,用 GAP 的話要選擇「Realtime Database」:

資料庫選 Realtime Database
資料庫選 Realtime Database

點選建立資料庫後,會出現選擇安全規則,選用鎖定模式,防止別人可以讀寫資料庫:

安全性規則為鎖定模式
安全性規則為鎖定模式

按下啟用後,就會看到資料表。接著為了讓資料庫能被GAP讀寫資料,還需要一個密鑰。點選左上角「Project Overview」旁邊的齒輪,再點選「專案設定」,會看到設定的後台介面:

這是廣告,點擊一下可以幫本站多個一點點的廣告收入,謝謝

點選專案設定
點選專案設定

設定頁面選「服務帳戶」,再選「資料庫密鑰」:

進到資料庫密鑰
進到資料庫密鑰

雖然頁面上出現一句警告,但有趣的是,在官方文件上針對這點也說:

Google warns that this authentication method is deprecated. In fact you can still use this method but standard Service Accounts are more secure and are recommended. As Database secrets are easier to use, far from really deprecated and safe enough for most use cases, that’s what we will use here.

大意是說,雖然有警告,但他好用也夠用,所以就拿來用吧。

把密鑰存下來,可以先在GAP上設一個變數來存:

var secret = 'firebase上拿到的密鑰';

有了 secret,還需要一個 database url。

點選「資料庫密鑰」上面的「Firebase Admin SDK」,會看見一段「Admin SDK 設定程式碼片段」的 code,裡面就有一個「databaseURL」,他的值就是 database url:

拿database url
拿 database url

*databaseURL上,最後沒有「/」,記得下一行的存成變數時要加上去。

一樣在 GAP 上設一個變數來存:

var firebaseUrl = 'https://xxxxxxxxxxx.firebaseio.com/';

secret、database url,這 2 個有了,就可以在 GAP 上使用 Firebase。

3 GAP 上讀寫 Firebase

上一步拿到 secret、database url,有了這 2 項,就可以設定一個 base 變來用,為了維持主要機器人工作的檔案乾淨,建議在 GAP 上新增一個 firebase.gs 來用,主要存讀寫 Firebase 的 function。

firebase.gs 前 3 行先寫變數:

var firebaseUrl = 'https://xxxxxxxxxxx.firebaseio.com/';
var secret = 'firebase上拿到的密鑰';
var base = FirebaseApp.getDatabaseByUrl(firebaseUrl, secret);

讀寫 Firebase,官方文件上有說明,本篇就是參考文件的:

https://sites.google.com/site/scriptsexamples/new-connectors-to-google-services/firebase/tutorials/read-and-write-data-in-firebase-from-apps-script

Firebase 的寫入資料有 3 種方式:

  • set:原有的資料整個覆蓋
  • update:跟原有的資料,有不一樣的部份會更新
  • push:原有資料不動,新增一份資料上去

官方文件上提供的 methods 如下:

// set
base.setData(key, value);
// update
base.updateData(key, value);
// push
base.pushData(key, value);
// 讀資料
base.getData();

因為在寫機器人的時候,會一直要讀寫資料,因此可以把讀寫都設成 function,存在 firebase.gs 上,以下是自己的設定,可以參考:


GAP 設定成 Telegram Bot 的 webhook

建立機器人的步驟,在上一篇「Telegram Bot 學習筆記-1:用 GCP + Node.js 接收 / 推播訊息」有講到,這邊就不寫。

Telegram Bot 接 webhook,要有一個 https 的 URL,GAP 上生成很容易。

在 GAP 的介面上,點選上排的「發佈」,再點「部署為網路應用程式」:

點選 佈署為網路應用程式
點選 佈署為網路應用程式

會出現一個燈箱,「將應用程式執行為」這邊選「我」。

「具有應用程式存取權的使用者」選「任何人,甚至是匿名使用者」。

部署設定
部署設定

按下部署後,因為有另外接了 Firebase 的功能,所以會出現需要授權的步驟,這個 GAP 的 code 都是由我們自己寫的,就放心授權。

授權完後,會出現一段「目前的網路應用程式網址」,那段網址就是 Telegram Bot Webhook 上要用的。

拿到webhook用的網址
拿到 webhook 用的網址

有了網址後,就是開啟一個空白頁,網址輸入:

https://api.telegram.org/bot{機器人token}/setWebhook?url={GAP生成的網址}

按下 Enter,就會看見設定成功的訊息:

webhook + GAP
webhook + GAP

GAP 的 GET、POST

GAP 處理 GET、POST 這兩個事件很簡單,只要寫在 function 裡就行了。

GET 是:

function doGet() { ... }

POST 是:

function doPost() { ... }

1 接收訊息

當機器人收到訊息,會 POST 到 webhook 網址上,所以只要在 doPost() 裡寫下收到訊息後要做的事就行了。

在上一篇「Telegram Bot 學習筆記 – 1:用 GCP + Node.js 接收 / 推播訊息」有寫收到文字訊息時,格式是這樣子:

接收到訊息的格式
接收到訊息的格式

message.from.id 是傳訊息的人,每一個都不一樣,因此把他當主要的 key。

message.text 就是傳來的訊息內容。

以下是 GAP 上,寫收到訊息的部份:

GAP 更新後,記得再重新發佈一次。

隨便發個訊息給機器人後,就會看見 Firebase 成功收到資料了:

firebase成功存到訊息資料
Firebase 成功存到訊息資料

2 發送訊息

doPost 是被 POST 時處理的 function。

發送訊息是主動 POST 到 Telegram 的 API。

用 GAP 寫 POST 也很簡單,跟 Fetch API 很像,只是前面要多寫一個 UrlFetch。

官方 Fetch 說明文件:

https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app

主動發訊息的 code 如下:

對象的 id,就是收到訊息時的 message.from.id。

token,就是機器人的 token。

更新完 code 後,可以在 GAP 上直接執行。

按最上排選單上的「執行」 → 「執行函式」,或是按一個甲蟲圖案的右側選單都行。

選單上的「執行」 → 「執行函式」
選單上的「執行」 → 「執行函式」
甲蟲圖案的右側選單,選完後再按播放鈕
甲蟲圖案的右側選單,選完後再按播放鈕

執行完後機器人就會發出訊息了:

發送訊息
發送訊息

設定排程

GAP 跟 GCP 的 cron 一樣,也有排程功能。

在上排的項目中點「編輯」 → 「現有專案的啟動程序」,就會看見觸發條件的設定頁面:

「編輯」 → 「現有專案的啟動程序」
「編輯」 → 「現有專案的啟動程序」
觸發條件的設定頁面
觸發條件的設定頁面

按下右下角的新增觸發條件就可以新增排程了。

不過不像寫 cron.yaml 一樣可以指定到幾點幾分,GAP 的條件區間一日的話是一個小時一個小時的算。目前實測是會隨機給一個分鐘,然後每日就是設定的小時的那個分鐘執行。


看到 Google 有 Apps Script 這個功能,覺得就像撿到寶一樣,就不用一些需要後端的小東西都放上 GCP 了。


Telegram Bot 學習筆記系列

  1. 用 GCP + Node.js 接收 / 推播訊息
  2. 用 Google Apps Script 接收 / 推播訊息
  3. 鍵盤 Keyboard
  4. 命令列 Commands
  5. 取得使用者大頭照
  6. Google 表單提交時收到通知
Summary
Telegram Bot學習筆記-2:用google apps script接收/推播訊息
Article Name
Telegram Bot學習筆記-2:用google apps script接收/推播訊息
Description
本篇大綱:新增一個GAP檔案、加入Firebase功能、加入firebase程式庫、接上指定的firebase、GAP上讀寫 firebase、GAP設定成Telegram Bot的webhook、GAP的GET、POST、接收訊息、發送訊息、設定排程。
Augustus
Let's Write
Let's Write
https://letswrite.tw/wp-content/uploads/2020/08/logo_512.jpg

隨選筆記文

Front-End

Markdown 常用語法筆記

Front-End

TestCafe 學習筆記 – 2:常用設定及功能

Front-End Vue

用 Vue.js 製作圖片版 EDM 生成器

Front-End

postMessage:主頁、iframe 頁可互相傳值

Analytics Google

GA 自訂維度的應用 分類之下的文章成效

Analytics Google

Google Analytics 用戶計時 / User Timings

Front-End

像 Medium 的漸近式圖片加載

Vue

Nuxt.js 一些好用的設定

Vue

用 VuePress 製作說明文件頁面 – 4:佈景主題、外掛

Vue

Vue Transitions 製作簡單的 Carousel / Slider / 輪播功能

以下是留言,但關於留言的部份必需先讓你們知道:

本站的文章都是 Augustus 因為覺得有趣,才會實作並整理成筆記文而後進行發表。

如果留言是希望把 Demo 改成「你想要」的樣子,或是把功能改成「符合你需求」的樣子,

Sorry~ 除非那修改是 Augustus 也有興趣的,不然不會幫你們寫程式去面對工作或是交作業。

未來這類的留言不會再主動回覆。😎

另外,公開信箱是為了讓金流驗證用,

因為之前遇過幾次回信協助解決問題後,對方卻一聲謝謝也沒有,就這樣拿去幫工作交差。

因此決定不再回覆信件,有疑問就利用留言功能囉。

訂閱
通知
guest
11 Comments
最舊
最新
Inline Feedbacks
看所有留言
洪振勛
洪振勛
1 年 之前

您好,我設定完程firebase後無法從firebase找到telegram回傳的資料耶…

songsong
songsong
1 年 之前

发现宝藏了,谢谢你!

KRIS
KRIS
1 年 之前

不好意思,請問 sendMessage出現以下錯誤:
ReferenceError: 對象的id is not defined (第 44 行,檔案名稱:index)

可以請教是什麼設定錯誤嗎?謝謝

KRIS
KRIS
回覆給  KRIS
1 年 之前

不好意思,原來「對象的id」要改成 實際的 chat_id (i.e. 199712345)
感謝您的教學文章

另外,關於buymeacoffee , 我無法使用paypal付款,查了一下,似乎台灣PayPal 帳戶無法直接支付給另一台灣帳戶,看您有沒有其他管道接受贊助,謝謝。

張毓宸
張毓宸
7 月 之前

MYeP8ZEEt1ylVDxS7uyg9plDOcoke7-2l這串無法被添加進Library

xiaodaoke
xiaodaoke
1 月 之前

您好,我設定完firebase之後,能看到tg回傳的信息。但是不知道如何處理callback_data這塊了。能指導一下嗎?