還記得上一篇我們在玩 Telegram Bot 嗎?那時候還在 AWS 外面閒晃,主要都在 Telegram 那邊設定 webhook、搞 token、測試訊息傳遞。
但今天就不一樣了。
今天,我們要正式進入 AWS 的地盤。
這階段簡直就是從「LINE 群組閒聊」進化成「正式開會有會議記錄」的等級。
先來建立一個 Lambda。這傢伙的任務很單純:
接收 webhook 傳來的訊息 → 處理一下 → 再丟回 Telegram。
沒錯,它就是那個你公司裡最辛苦、最沒人感謝、永遠被叫「先幫我寫個小 function 就好啦~」的工程師。
而這個 Lambda 會用到 Bot Token。
這串東西可以說是你機器人的「身份證 + 銀行卡 PIN 碼」合體。
所以,千萬不要像某些初學者一樣,直接把它硬塞在程式碼裡然後還很驕傲地 git push
到 GitHub 公開 repo。
(真的有這種人,然後隔天他的 bot 在群組裡開始自動發「愛你唷 ❤️」給陌生人。)
機密資料該放哪?理論上 AWS 有一個很專業又安全的地方叫 Secrets Manager。
你可以把 token 放進去,它會幫你上鎖、加密,甚至還會幫你記得密碼。
不過今天我們為了簡化流程,採用 環境變數 的方案。
這招雖然不完美,但夠用、方便、能跑。
就像下班後肚子餓沒店開,去買 7-11 的茶葉蛋一樣,雖然不是頂級料理,但它撐得過今晚。
建立一個 Lambda function:
callback-tg
Lambda 的程式邏輯大概長這樣:
botToken
。import json
import urllib3
import os
http = urllib3.PoolManager()
def lambda_handler(event, context):
print(f"event: {event}")
# get enviroment variable botToken.
botToken = os.environ['botToken']
# 取得 Telegram 傳來的 message 資料
jsonBody = json.loads(event.get('body'))
# 從Webhook傳遞來的訊息當中取得我們需要的必要資訊
# 發送者的ID
senderID = jsonBody.get('message').get('from').get('id')
# 發送者的 First Name
senderFirstName = jsonBody.get('message').get('from').get('first_name')
# 發送者的 last name
senderLastName = jsonBody.get('message').get('from').get('last_name')
# 發送者的 username
senderUserName = jsonBody.get('message').get('from').get('username')
# 與發送者傳訊的聊天室ID
chatID = jsonBody.get('message').get('chat').get('id')
# 使用者發送來的訊息
msgtext = jsonBody.get('message').get('text')
# 取得發送者的FirstName和LastName組合成訊息後,回傳給使用者
msg = 'Hello, ' + senderFirstName + ' ' + senderLastName + '!'
url = 'https://api.telegram.org/bot' + botToken + '/sendMessage?chat_id=' + str(chatID) + '&text=' + msg
print(f"url: {url}")
response = http.request('GET', url)
data = json.loads(response.data.decode('utf-8'))
print(f"data: {data}")
return {
'statusCode': 200,
'body': json.dumps('Hello')
}
在 AWS Lambda 頁面中:
然後在編輯畫面裡:
botToken
。這樣就完成啦 🎉
從此你的 Lambda 會變得又乾淨又安全(至少不會在 GitHub 被人玩壞)。
前面我們已經建立好 Lambda,搞定環境變數,接下來要幹嘛?當然是把它們湊成一對啦 。
今天的主角是 API Gateway —— AWS 裡那個既是門神、又是櫃台、還兼任交通警察的服務。
它的任務就是幫我們接 webhook、轉給 Lambda、然後假裝自己什麼都不知道。
打開 API Gateway 介面,我們先來加一個 resource。
在「根節點」下面新增一個 resource,取名叫 callback
。
名字要不要一定叫 callback?
不一定,你要取 callmebaby
、ihatewebhook
都行,
只要你自己之後不要搞混。
記得把 Proxy Resource 選項打勾,這樣 Lambda 才能完整收到 webhook 傳來的內容。
接著,在這個 callback
resource 底下建立一個 method。
我們選擇 POST,因為 Telegram 的 webhook 是用 POST 來傳資料。
在設定畫面中:
callback-tg
這一步就像在替 Lambda 開了一個直通熱線。
從此 Telegram 傳來的訊息,都會第一時間被丟進 Lambda 裡,
然後 Lambda 就能帥氣地回傳訊息回去。
(工程師之間稱這叫「自動回嗆機制」。)
設定完一切之後,請一定、一定、一定要記得:
Deploy API 到某個 stage!
我知道這句聽起來廢話,但相信我,
有 80% 的工程師第一次都會忘記這步,
然後對著空白的 webhook URL 開始懷疑人生。
建議部署到 prod
stage。
因為聽起來很專業。
雖然你可能根本只有一個使用者(還是你自己)。
部署完之後,點進去 callback
下面的 POST
method,
就會看到一個「Invoke URL」。
這一串網址就是你接下來要給 Telegram 當 webhook 用的。
趕快複製下來,待會兒要使用。
終於來到最後一步。
Telegram Bot 的 webhook 設定沒有什麼 fancy 的介面可按,
只能用一條 URL 去設定。
格式如下👇
https://api.telegram.org/bot[Bot_Token]/setWebhook?url=[你的API Gateway網址]
注意,bot
後面是小寫喔,然後要接你的 Token。
就像這樣:
https://api.telegram.org/bot1234567890:ABCdefGHIjklMNOpqRSTuvwxyz/setWebhook?url=https://b5ou0dlsdc.execute-api.us-east-1.amazonaws.com/prod/callback
然後打開瀏覽器,把這整串貼上去,按下 Enter。
如果一切順利,你會看到這樣的回應:
{"ok":true,"result":true,"description":"Webhook was set"}
這時候你就可以舉雙手歡呼了,
因為這代表 Telegram Bot 的 webhook 已經正式接上你的 API Gateway!
你剛剛辛苦建立的 Lambda, 現在終於能從雲端接收到使用者的訊息、然後回覆回去。
整個流程看起來很多步驟,實際上邏輯很單純:
Telegram → API Gateway → Lambda → 回訊息 → 使用者
Serverless 的魅力就在這裡。
你不用維護伺服器、不用管 Nginx、甚至不用看 log(雖然你最後還是得看)。
下次有人問你:
「你那個 Telegram Bot 是跑在哪台伺服器?」
你就可以神秘地笑一下說:
「哪台伺服器?呵,我的 Bot 根本沒有伺服器。它跑在空氣裡。」
前面兩篇我們搞了半天 Lambda、API Gateway、Webhook……
終於要測試!
這就像你追了三個月的女生終於願意回你訊息一樣——雖然她只是回了「嗨」。
我們之前在建立 Telegram Bot 時,設定的用戶名是:
smallbee123_bot
所以現在打開 Telegram,在搜尋欄輸入 @smallbee123_bot
,
咻~就會看到你親手打造的機器人。
那個瞬間真的會有點小感動。
因為你知道,這傢伙不是你下載的、不是哪個大神寫的,
是你自己用血與眼淚(還有 AWS 免費額度)生出來的。
點開聊天視窗,禮貌地打個「嗨」給它。
然後等個幾秒(或幾十秒,看你 Lambda timeout 設多少)。
如果一切順利,機器人就會依照 Lambda 的邏輯,
讀取你的 First Name 和 Last Name,
然後熱情地回覆你一句:「Hello, [你的名字]!」
第一次看到它回話的時候,那感覺真的很神奇。
你會突然理解什麼叫「雲端真的在動」。
那是一種「程式碼活了」的感覺。
(雖然它還不會幫你泡咖啡或請假,但至少願意理你。)
目前這個 bot 只是單純回覆打招呼,
但你可以讓它變得更聰明,像個真正的聊天夥伴。
怎麼做?
加點邏輯、串個 LLM(大型語言模型),
然後你就能跟它聊股票、聊程式、聊人生低谷都沒問題。
如果想再更猛一點,可以試試看 AWS Bedrock。
它讓你不用養 GPU、也不用為了推理模型開 EC2,
直接用 API 調用模型聊天。
一句話形容它的方便程度:
「像 Uber Eats 一樣,你只要負責下單,AI 自己會來接單。」
除了 Bedrock,其實還有幾個超划算又實用的服務:
對個人開發者來說,這些服務的免費層級其實都夠玩。
真的要課金,至少你是為了夢想,不是為了修 bug。
這系列寫著寫著,不知不覺竟然到了 第 30 篇。
(老實說我自己都懷疑真的完成了嗎?)
原本想繼續寫到「串 Bedrock 讓 bot 跟你聊天」那一段,
但篇幅太長,還是留給下次好了。
畢竟工程師最懂的道理就是——
「有 backlog 的人生,才有活下去的動力。」
第一次參加這種每天要發文的挑戰,
真心感謝那些會在半夜私訊:「你今天還沒發喔」的朋友。
沒有他們的催稿,我大概早就把 Lambda 當枕頭睡著了。
不過說真的,能一路堅持下來還滿開心的。
也算是解鎖一個人生成就了。