參考網站 - Telegram 聊天機器人原理
參考網站 - 向 @BotFather 申請一隻機器人吧!
參考網站 - Telegram 機器人的設定
參考網站 - CI/CD trigger WebHook to Telegram Bot
參考網站 - How to setup a Telegram bot for your Drone CI/CD builds
Telegram 聊天機器人原理
機器人的運作原理

現在你發了一段訊息給機器人
但是並不是機器人直接回你訊息
詳細情況如下圖:

- 一開始你的訊息會被傳送到 TG 伺服器
- TG 伺服器會通知機器人:欸!有一則新訊息
- 機器人會發一個指令給 TG 伺服器
- TG 伺服器照著指令的需求,回應訊息給你
機器人接收訊息的兩種模式
機器人可以放在伺服器,也可以用客戶端的方式運作

- Webhook
以 伺服器
方式被動接收訊息,需要有 IP 位置,通常會放在 網站伺服器(Web Hosting)
上,要自己架設網站伺服器不是件容易的事,所以官方還提供了另一種做法 - Long Polling。
以 客戶端
方式主動跟 TG 伺服器要訊息,可以直接 在自己電腦上運作
,不需要架(租)伺服器也能讓機器人順利運作,缺點就是電腦要一直開著,當然你也可以使用 雲端服務(IaaS、PaaS、SaaS)
。
機器人發送訊息的三種方式
- HTTP GET
1
| https://api.telegram.org/bot{Token}/{Method}?{Parameter1}={Value1}&{Parameter2}={Value2}
|
直接以 網址參數
的方式傳送指令,GET 沒有 Body,只傳送 Headers (你可以當作不會傳送檔案過去),通常是用來取資料用,優點是可以直接用瀏覽器執行,缺點是有 2KB 的限制,雖然不太可能用到這長的指令,但還是比較建議使用 POST。
- HTTP POST

1
| {"method":"Method","Parameter1":"Value1","Parameter2":"Value2"}
|
POST 是 以 Body 傳送資料(檔案)
,程式通常都是以這種方式溝通,網頁裡的表單也經常是以這種方式傳送,資料不會顯示在網址列,可以傳送的資料大小比 GET 大得多:1MB ~ 2GB。
- 直接 Print

這個方式 只有在 webhook 模式
下才能使用,因為只有伺服器可以直接回應訊息。
向 @BotFather
申請一隻機器人吧!
The BotFather

The Botfather 這個名字是致敬 1972 年的美國電影《教父》
它是機器人,也是機器人的管理者
幾乎所有機器人的設定、建立都要透過他
用機器人設定機器人聽起來就很有趣,對吧?
@BotFather 的功能
私訊 @BotFather ,按「開始」後就會顯示出一大堆指令,真是令人眼花撩亂

官方網頁版說明
簡單介紹幾個比較常用的功能:
指令 | 說明 |
---|
/newbot | 建立一個新的機器人 |
/mybots | 列出所有機器人,用按鈕的方式設定機器人,而非指令(這樣可以讓聊天紀錄變得很乾淨,我比較喜歡用這個) |
修改相關 | |
/setname | 修改顯示名稱 |
/setdescription | 修改說明 |
/setabouttext | 修改簡介 |
/setuserpic | 修改大頭貼 |
/setcommands | 修改指令選單 |
/deletebot | 刪除機器人 |
設定相關 | |
/token | 顯示機器人的 token |
/revoke | 產生新的 token,舊的會失效 |
/setjoingroups | 設定是否能被加入群組 |
/setprivacy | 設定是否能讀取所有聊天室訊息(機器人的訊息除外,機器人不論如何都不會看到機器人的訊息) |
建立你的機器人吧
- 輸入 /newbot 指令

- 幫機器人取名字
1
| Alright, a new bot. How are we going to call it? Please choose a name for your bot.
|
這邊它會要你幫你的機器人取一個名字,這個以後能修改,所以隨便取沒差

- 設定 username
1
| Good. Now let's choose a username for your bot. It must end in `bot`. Like this, for example: TetrisBot or tetris_bot.
|
⚠️ 注意:設定後就不能修改了,請謹慎思考之後設定,避免反悔時需要請使用者遷移
需要幫你的機器人設定一個 username,必須符合以下規則:
- 不需要打 @
- 以 a~z 開頭
- 以 bot 結尾
- 只能使用 a~z、0~9 和底線
- 最小長度為 5 個字元
顯示時會區分大小寫,使用時不區分大小寫(例如設定成 @TetrisBot,用 @tETrISbOt 一樣會指到同一個機器人)
常見問題:

1
| Sorry, this username is invalid.
|

1
| Sorry, the username must end in 'bot'. E.g. 'Tetris_bot' or 'Tetrisbot'
|

1
| Sorry, this username is already taken. Please try something different.
|
出現 Done 表示你設定成功了

使用你的機器人吧
現在你已經可以使用機器人了
按下說明裡的連結(t.me/ironman2021_by_miku3920_bot
點你自己的),並且點擊「開始」
然後你就會發現什麼事情都沒發生,因為我們還沒寫機器人的程式嘛
不過就算不寫程式也可以讓它說話,利用 HTTP GET
方法,與 sendMessage 這個 API

1
| https://api.telegram.org/bot{Token}/{Method}?{Parameter1}={Value1}&{Parameter2}={Value2}
|
- Token:1985044907:AAEdySrbzTc8tVdBjfymlfyaBUJGeu7r-v4(你的 bot token)
- Method:sendMessage
- Parameter1:chat_id
- Value1:127355800(你的 uid,可以透過 @userinfobot 取得)
- Parameter2:text
- Value2:Hello,+World!+你好,世界!(空白要用「+」替換)
組合完會像這個樣子,直接貼到瀏覽器的網址列就能使用囉:
1
| https://api.telegram.org/bot1985044907:AAEdySrbzTc8tVdBjfymlfyaBUJGeu7r-v4/sendMessage?chat_id=127355800&text=Hello,+World!+你好,世界!
|
PS:聊天室的 chat_id,先將你的機器人邀請進入聊天室,再使用此網址取得:https://api.telegram.org/bot${your_bot_token}/getUpdates
常見問題:
1
| {"ok":false,"error_code":401,"description":"Unauthorized"}
|
1
| {"ok":false,"error_code":404,"description":"Not Found"}
|
1
| {"ok":false,"error_code":400,"description":"Bad Request: chat_id is empty"}
|
1
| {"ok":false,"error_code":400,"description":"Bad Request: chat not found"}
|
1
| {"ok":false,"error_code":403,"description":"Forbidden: bot can't initiate conversation with a user"}
|
1
| {"ok":false,"error_code":400,"description":"Bad Request: message text is empty"}
|
成功的話會返回機器人發送的訊息(json 格式)到網頁上:
1
| {"ok":true,"result":{"message_id":5,"from":{"id":1985044907,"is_bot":true,"first_name":"2021 iThome\u9435\u4eba\u8cfd","username":"ironman2021_by_miku3920_bot"},"chat":{"id":127355800,"first_name":"\u521d\u97f3","last_name":"\u30df\u30af","username":"miku3920","type":"private"},"date":1631440402,"text":"Hello, World! \u4f60\u597d\uff0c\u4e16\u754c\uff01"}}
|

Telegram 機器人的設定
輸入 /mybots 指令後就會出現機器人列表

1
| Choose a bot from the list below:
|
選擇一個你要查看或設定的機器人
我之前就有建立過機器人,所以會顯示兩個

1
2
| Here it is: 2021 iThome鐵人賽 @ironman2021_by_miku3920_bot.
What do you want to do with the bot?
|
點下去後就會出現六個選項,我一個個來講解:
API Token - 查看 token

1
2
3
| Here is the token for bot 2021 iThome鐵人賽 @ironman2021_by_miku3920_bot:
1985044907:AAH1kZaEZFHoA6YqB6IFtvbkyOjvcpPOfbQ
|
忘記 token 時可以來這裡查看,或是你想要重置 token
- Revoke current token - 重置 token

1
2
3
| Token for the bot 2021 iThome鐵人賽 @ironman2021_by_miku3920_bot has been revoked. New token is:
1985044907:AAG3E05XowN2sqy286aplwr6oBc17q0CByg
|
按下重置按鈕後,它就會給你一個新的 token,舊的會立即失效
Edit Bot - 修改機器人

1
2
3
4
5
6
7
| Edit @ironman2021_by_miku3920_bot info.
Name: 2021 iThome鐵人賽
Description: ?
About: ?
Botpic: ? no botpic
Commands: no commands yet
|
Edit Name - 修改名字
按下按鈕後會出現以下訊息

1
| OK. Send me the new name for your bot.
|
直接傳送新的名稱給它就行了

1
| Success! Name updated. /help
|
看到這個就是修改成功了
Edit Description - 修改說明
這個會顯示在聊天室的最上方,用來說明機器人有能些功能,或是如何使用

1
| OK. Send me the new description for the bot. People will see this description when they open a chat with your bot, in a block titled 'What can this bot do?'.
|
傳送一段訊息給它,可以是多行的文字

1
| Success! Description updated. /help
|
看到這個就是修改成功了

原本在聊天室上方啥都沒有,現在多了一個訊息框
Edit About - 修改簡介
這個會顯示在機器人的個人資訊頁面上

1
| OK. Send me the new 'About' text. People will see this text on the bot's profile page and it will be sent together with a link to your bot when they share it with someone.
|
傳送一段訊息給它,可以是多行的文字

1
| Success! About section updated. /help
|
看到這個就是修改成功了

原本是只有顯示 username,現在多了 簡介
Edit Botpic - 修改大頭貼

1
| OK. Send me the new profile photo for the bot.
|
建議先裁切成正方形(1:1)

1
| Please send me the picture as a 'Photo', not as a 'File'.
|
這邊要傳送照片,不能傳檔案

1
| Success! Profile photo updated. /help
|
成功的話,機器人的大頭貼就會更新成剛剛上傳的圖片

Edit Commands - 修改指令選單

1
2
3
4
5
6
| OK. Send me a list of commands for your bot. Please use this format:
command1 - Description
command2 - Another description
Send /empty to keep the list empty.
|
要按照它給的格式輸入,不需要打 /

1
| Success! Command list updated. /help
|
成功的話,選單中就會出現剛剛設定的指令

如果機器人是在群組使用,建議改成空的,避免誤觸
群組裡較常使用 ! 開頭的指令,這樣才不會變成藍藍的容易按到
在剛剛那邊,按 /empty 就行了

修改完會變成這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
| Edit @ironman2021_by_miku3920_bot info.
Name: 2021 iThome鐵人賽
Description: 一些說明文字,功能如下:
1. AAA
2. BBB
3. CCC
About: 鐵人賽展示用機器人 by @miku3920
鐵人賽展示用機器人 by @miku3920
鐵人賽展示用機器人 by @miku3920
Botpic: ? has a botpic
Commands: no commands yet
|
Bot Settings - 設定機器人

1
| Settings for @ironman2021_by_miku3920_bot.
|
Inline Mode - 內聯模式(內嵌模式)
可以讓機器人直接在訊息輸入框使用,不需要將機器人加入群組
這個功能夠講一整天了,目前還用不到,我們以後專門找一天來講

Allow Group? - 是否能被加入群組?

1
2
3
| Groups are currently enabled for bot 2021 iThome鐵人賽 @ironman2021_by_miku3920_bot
Disabling groups will forbid users to add 2021 iThome鐵人賽 to groups.
|
enabled(預設) - 表示機器人能被別人拉進群組
如果你不想讓別人拉你的機器人,可以按 Turn groups off

1
2
3
| Groups are currently disabled for bot 2021 iThome鐵人賽 @ironman2021_by_miku3920_bot.
Enabling groups will allow users to add 2021 iThome鐵人賽 to groups.
|
disabled - 表示機器人不能被別人拉進群組
如果你想讓別人的群組也能使用你的機器人,就按 Turn groups on
Group Privacy - 是否能讀取所有聊天室訊息
官方說明

1
| Privacy mode is enabled for 2021 iThome鐵人賽 @ironman2021_by_miku3920_bot.
|
enabled(預設) - 表示機器人是成員時不能讀取群組裡的所有訊息

機器人只看的到它的指令和回覆它的訊息

但是如果升級成管理員就沒這限制

1
| Privacy mode is disabled for 2021 iThome鐵人賽 @ironman2021_by_miku3920_bot.
|
disabled - 表示機器人就算不是管理員也能讀取群組裡的所有訊息

機器人是成員時就能讀取所有訊息
Payments - 付款相關設定
台灣不能用,有生之年系列,跳過
Domain - 網站登入用
與機器人較無關,暫時不提
Payments - 付款相關設定

歐付寶、綠界、台灣 pay、街口、悠遊付,不考慮進駐一下嗎
Transfer Ownership - 轉移機器人
⚠️ 注意:非必要請勿使用!

Choose recipient - 選擇使用者

1
| Please share the new owner's contact or their username.
|
按下按鈕後,它會請你把對方以聯絡人的方式分享給它,或是輸入對方的 username
常見問題:
- 要輸入 @username,不能只輸入 username

1
| Incorrect format. Please make sure to send either a contact or username.
|

1
| Bot ownership can't be transferred to channel, another bot or yourself.
|

1
| Oops! Please make sure the new owner has sent at least one message to the bot and didn't block it.
|
輸入正確的話,就會出現以下訊息:

1
2
3
4
5
| You are about to transfer ownership of the bot @ironman2021_by_miku3920_bot to 初音 ミク.
After this you won't be able to control the bot anymore. The new owner will get access to the bot messages and other data – and can even delete the bot completely.
Please make sure you don't violate your users' privacy (consider GDPR and other laws). If you are sure please press the button below.
|
看到這則訊息代表離成功轉移不遠了
Yes, I am sure, proceed. - 確認轉移

如果你有設定兩步驟驗證的話,這邊會跳出來要你輸入
常見問題:

1
| Oops! has reached the maximum allowed number of bots. Please ask them to delete (or pass to another account) one of their unused bots first.
|
如果對方已經有 20 隻機器人(達到上限),就會出現這個對話框,他請你先叫對方轉移或刪除一些沒在用的機器人,這樣你才可以轉移給對方。

1
| It worked! We hope @ironman2021_by_miku3920_bot will enjoy its new home.
|
如果轉移成功就會出現這則訊息

1
2
3
| Ownership of the bot @ironman2021_by_miku3920_bot has been transferred to you by 初音 ミク. You can now control the bot using /mybots.
If you did not request this, you can delete the bot.
|
Delete Bot - 刪除機器人
⚠️ 注意:非必要請勿使用!

1
| You are about to delete your bot 2021 iThome鐵人賽 @ironman2021_by_miku3920_bot. Is that correct?
|
這邊的按鈕順序是隨機的,避免你頭腦不清楚把機器人刪了

1
| Are you TOTALLY sure you want to delete 2021 iThome鐵人賽 @ironman2021_by_miku3920_bot ?
|
要連續按兩次 Yes 機器人才會被刪掉

1
| You have deleted 2021 iThome鐵人賽 @ironman2021_by_miku3920_bot.
|
看到這則訊息表示機器人已經刪除,無法復原
所有群組裡的這隻機器人都會顯示成 Deleted Account
Bonus:Drone CI/CD 流程失敗時,叫你的 Telegram 機器人通知你!
建立群組,並取得群組的 chat_id
- Telegram 建立群組,並將你的 Telegram 機器人拉進群組內(
@{your bot username}
)。 - 透過此 API 取得群組的 chat_id:
1
| https://api.telegram.org/bot${your bot token}/getUpdates
|
getUpdates API 會取得 json,找到你剛剛開的群組的 chat_id

從 Drone Plugin 可以找到很多套件,可以搭配 CI/CD 使用,而我從這找到 Telegram by appleboy 的套件。

Drone CI/CD 補上告警的 step。
你的 Drone CI/CD step 加上使用 Telegram by appleboy 叫你的機器人於 pipeline 失敗時於群組內發出告警。
PS:記得將你的 telegram bot token 與群組的 chat_id 加到 Drone Secrets。
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
| kind: pipeline
type: docker
name: install and deploy
steps:
- name: build
image: node:15
commands:
- node --version
- yarn --version
# - yarn cache clean -f
- yarn install --ignore-engines
- yarn run build
- ls -al dist/static/
when:
branch:
- master
event:
- push
- name: deploy
image: thegeeklab/drone-s3-sync
settings:
bucket: xxxxxxxxx(你的aws s3 bucket)
access_key:
from_secret: aws_access_key_id
secret_key:
from_secret: aws_secret_access_key
source: ./dist/
target: /admin
acl:
"*": public-read
region: xxxxxxxxx(你的aws s3 region)
delete: true
cloudfront_distribution: xxxxxxxxx(你的aws cloudfront distribution)
when:
branch:
- master
event:
- push
+ - name: send telegram notification
+ image: appleboy/drone-telegram
+ settings:
+ token:
+ from_secret: telegram_bot_token
+ to:
+ from_secret: telegram_chat_id
+ format: markdown
+ message: >
+ `{{repo.name}}` 於 `{{commit.branch}}` 編譯失敗:#`{{build.number}}`
+ when:
+ status: [failure]
|
- token: 你的 Telegram 機器人的 token。
- to: chat_id。
- format: 使用 markdown 格式。
- message: 機器人傳的訊息。
- when.status [failure]: 當此 pipeline 失敗時觸發此 step(send telegram notification),亦可於成功或失敗皆告警:[success, failure]。
詳細參數可參考 Drone Plugin - appleboy/drone-telegram