iT邦幫忙

2025 iThome 鐵人賽

DAY 30
0
Build on AWS

最適合小型工作室精打細算的服務使用法系列 第 30

Day 30 - API Gateway、Lambda 與 Telegram 衝撞的火花 之 Serverless 完成式

  • 分享至 

  • xImage
  •  

還記得上一篇我們在玩 Telegram Bot 嗎?那時候還在 AWS 外面閒晃,主要都在 Telegram 那邊設定 webhook、搞 token、測試訊息傳遞。

但今天就不一樣了。
今天,我們要正式進入 AWS 的地盤。
這階段簡直就是從「LINE 群組閒聊」進化成「正式開會有會議記錄」的等級。

AWS Lambda 登場:Serverless 世界的打工仔

先來建立一個 Lambda。這傢伙的任務很單純:
接收 webhook 傳來的訊息 → 處理一下 → 再丟回 Telegram。

沒錯,它就是那個你公司裡最辛苦、最沒人感謝、永遠被叫「先幫我寫個小 function 就好啦~」的工程師。

而這個 Lambda 會用到 Bot Token
這串東西可以說是你機器人的「身份證 + 銀行卡 PIN 碼」合體。
所以,千萬不要像某些初學者一樣,直接把它硬塞在程式碼裡然後還很驕傲地 git push 到 GitHub 公開 repo。
(真的有這種人,然後隔天他的 bot 在群組裡開始自動發「愛你唷 ❤️」給陌生人。)

關於機密:不要讓全世界都能用你的 Token

機密資料該放哪?理論上 AWS 有一個很專業又安全的地方叫 Secrets Manager
你可以把 token 放進去,它會幫你上鎖、加密,甚至還會幫你記得密碼。

不過今天我們為了簡化流程,採用 環境變數 的方案。
這招雖然不完美,但夠用、方便、能跑。
就像下班後肚子餓沒店開,去買 7-11 的茶葉蛋一樣,雖然不是頂級料理,但它撐得過今晚。

Lambda 設定懶人包

建立一個 Lambda function:

  • Function namecallback-tg
  • Runtime:Python 3.13
  • Timeout:30 秒(因為 Telegram 回得太慢總比你加班久好)

Lambda 的程式邏輯大概長這樣:

  1. 從環境變數抓出 botToken
  2. 接 webhook 傳來的 JSON 訊息。
  3. 整理一下內容(通常是幫你擋掉一些亂碼或 emoji 轟炸)。
  4. 再把訊息發回 Telegram,完成一個完美的「你傳我回」循環。
    程式碼
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')
    }

環境變數設定教學(也就是「別再亂塞 Token」篇)

在 AWS Lambda 頁面中:

  1. 點上方的 Configuration
  2. 左邊找到 Environment Variables
  3. 點右邊的 Edit
    https://ithelp.ithome.com.tw/upload/images/20251010/20141071Ym4FHMEeHZ.png

然後在編輯畫面裡:

  • 紅框 1:點「Add Environment Variable」。
  • 紅框 2:Key 填 botToken
  • 紅框 3:Value 填入你前一篇拿到的 Bot Token。
  • 紅框 4:按下 Save
    https://ithelp.ithome.com.tw/upload/images/20251010/20141071XnmrvufUi2.png

這樣就完成啦 🎉
從此你的 Lambda 會變得又乾淨又安全(至少不會在 GitHub 被人玩壞)。

API Gateway × Telegram 的最終連線篇

前面我們已經建立好 Lambda,搞定環境變數,接下來要幹嘛?當然是把它們湊成一對啦 。

今天的主角是 API Gateway —— AWS 裡那個既是門神、又是櫃台、還兼任交通警察的服務。
它的任務就是幫我們接 webhook、轉給 Lambda、然後假裝自己什麼都不知道。

建立 Resource(也就是那扇「機器人要敲的門」)

打開 API Gateway 介面,我們先來加一個 resource。
在「根節點」下面新增一個 resource,取名叫 callback

名字要不要一定叫 callback?
不一定,你要取 callmebabyihatewebhook 都行,
只要你自己之後不要搞混

記得把 Proxy Resource 選項打勾,這樣 Lambda 才能完整收到 webhook 傳來的內容。
https://ithelp.ithome.com.tw/upload/images/20251010/20141071MFUBfM7Wcz.png

建立 Method(讓這扇門可以收「信」)

接著,在這個 callback resource 底下建立一個 method
我們選擇 POST,因為 Telegram 的 webhook 是用 POST 來傳資料。

https://ithelp.ithome.com.tw/upload/images/20251010/2014107178ergxSNci.png

在設定畫面中:

  • Method Type:POST
  • Integration type:Lambda Proxy Integration (一定要勾起來)
  • Lambda Function:選剛剛建立的那個 callback-tg
    https://ithelp.ithome.com.tw/upload/images/20251010/20141071TtTf5hHCiS.png

這一步就像在替 Lambda 開了一個直通熱線。
從此 Telegram 傳來的訊息,都會第一時間被丟進 Lambda 裡,
然後 Lambda 就能帥氣地回傳訊息回去。
(工程師之間稱這叫「自動回嗆機制」。)

Deploy API(不部署 = 白做)

設定完一切之後,請一定、一定、一定要記得:

Deploy API 到某個 stage!

我知道這句聽起來廢話,但相信我,
有 80% 的工程師第一次都會忘記這步,
然後對著空白的 webhook URL 開始懷疑人生。

https://ithelp.ithome.com.tw/upload/images/20251010/201410719B0NN09Z2R.png

建議部署到 prod stage。
因為聽起來很專業。
雖然你可能根本只有一個使用者(還是你自己)。

部署完之後,點進去 callback 下面的 POST method,
就會看到一個「Invoke URL」。
這一串網址就是你接下來要給 Telegram 當 webhook 用的。

趕快複製下來,待會兒要使用。
https://ithelp.ithome.com.tw/upload/images/20251010/20141071g4ftqWBIkW.png

設定 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 根本沒有伺服器。它跑在空氣裡。」

測試開始:當 Telegram 機器人真的回你話的那一刻

前面兩篇我們搞了半天 Lambda、API Gateway、Webhook……
終於要測試!
這就像你追了三個月的女生終於願意回你訊息一樣——雖然她只是回了「嗨」。

先找到我們的 Bot

我們之前在建立 Telegram Bot 時,設定的用戶名是:
smallbee123_bot

所以現在打開 Telegram,在搜尋欄輸入 @smallbee123_bot
咻~就會看到你親手打造的機器人。

https://ithelp.ithome.com.tw/upload/images/20251010/20141071y7dzn5JQuy.png

那個瞬間真的會有點小感動。
因為你知道,這傢伙不是你下載的、不是哪個大神寫的,
是你自己用血與眼淚(還有 AWS 免費額度)生出來的。

對機器人說句「嗨」

點開聊天視窗,禮貌地打個「嗨」給它。
然後等個幾秒(或幾十秒,看你 Lambda timeout 設多少)。

如果一切順利,機器人就會依照 Lambda 的邏輯,
讀取你的 First NameLast Name
然後熱情地回覆你一句:「Hello, [你的名字]!」

第一次看到它回話的時候,那感覺真的很神奇。
你會突然理解什麼叫「雲端真的在動」。
那是一種「程式碼活了」的感覺。
(雖然它還不會幫你泡咖啡或請假,但至少願意理你。)

想要更聰明?就加點 AI

目前這個 bot 只是單純回覆打招呼,
但你可以讓它變得更聰明,像個真正的聊天夥伴。

怎麼做?
加點邏輯、串個 LLM(大型語言模型)
然後你就能跟它聊股票、聊程式、聊人生低谷都沒問題。

如果想再更猛一點,可以試試看 AWS Bedrock
它讓你不用養 GPU、也不用為了推理模型開 EC2,
直接用 API 調用模型聊天。

一句話形容它的方便程度:

「像 Uber Eats 一樣,你只要負責下單,AI 自己會來接單。」

順便推一下平價又好用的 AWS 家族

除了 Bedrock,其實還有幾個超划算又實用的服務:

  • DynamoDB:NoSQL 資料庫,
    免費額度夠你養一整個 side project,
    而且不用維護伺服器,資料照樣穩定存著。
  • Lambda + API Gateway:真正的無伺服器組合拳。
    只要設定好 webhook,就能讓機器人 24 小時上班不請假。
    (比人力部的 intern 還穩定。)
  • Bedrock:直接讓你調用 LLM。
    不用自己架 GPU,錢包也不會因為 Hugging Face 而哭出來。

對個人開發者來說,這些服務的免費層級其實都夠玩。
真的要課金,至少你是為了夢想,不是為了修 bug。

寫到第 30 篇的感性瞬間

這系列寫著寫著,不知不覺竟然到了 第 30 篇
(老實說我自己都懷疑真的完成了嗎?)

原本想繼續寫到「串 Bedrock 讓 bot 跟你聊天」那一段,
但篇幅太長,還是留給下次好了。
畢竟工程師最懂的道理就是——

「有 backlog 的人生,才有活下去的動力。」

第一次參加這種每天要發文的挑戰,
真心感謝那些會在半夜私訊:「你今天還沒發喔」的朋友。
沒有他們的催稿,我大概早就把 Lambda 當枕頭睡著了。

不過說真的,能一路堅持下來還滿開心的。
也算是解鎖一個人生成就了。


上一篇
Day 29 - API Gateway、Lambda 與 Telegram 衝撞的火花 之 Telegram Bot 的建立
系列文
最適合小型工作室精打細算的服務使用法30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言