用 Python 建構 Telegram 股票監測機器人
有投資美股的人應該都有一樣的經歷,因為美國跟台灣的時差12小時,看盤可能都得要通宵坐鎮。因為我實在太愛睡覺了,年紀越大也越經不起熬夜折磨,所以就設法用最簡單的方式完成投資時需要做的事情。
為了讓解決方案能夠滿足我的需求,我思考了需要具備的特性:
- 能隨時隨地查詢
- 能主動告警
- 客製化圖表
- 未來可擴充 ML/DL 算法
經過摸索後,Telegram bots 可以很簡單快速的達到我的需求,而且彈性且自由。因此這篇主要會著重在如何架構出 Telegram 機器人,並幫助我達到最基本的需求。後續我會再不斷優化這個機器人,有興趣的可以關注我的Github。
本篇文章重點:
- 註冊 Telegram bots
- 用 Python 操作 Telegram bots
- 架構互動選單
- 股價波動告警
註冊 Telegram bots
要使用 Telegram 的機器人其實並不困難,官方提供的文件就足以建立自己的機器人。這裡我們手把手把流程跑一次。
首先,用自己的 Telegram 新增好友 BotFather,會出現一個很帥的機器人大叔。
加入他後輸入 /start
就可以取得建立一個機器人所需要的指令。這裡我們得知建立機器人輸入指令/newbot
,並依序輸入顯示名稱以及使用者帳號(用來搜尋以及呼叫用的)。
只要名稱帳號沒有重複,你會看到以下成功訊息,就代表你的機器人建好囉!基本上現在你去搜尋好友的地方打上你剛剛輸入的使用者名稱,就可以找到你的機器人。不過你的機器人現在還是空殼,沒有駕駛人坐在裡面。你要能駕駛它,就需要用到 BotFather 提供的鑰匙(就是下面紅色那一塊 API )。要特別注意的是,只要誰有這個鑰匙,誰就可以操作你的機器人,所以要格外小心這個鑰匙外流。
用 Python 操作 Telegram bots
到這一步我們就可以使用 Python 的套件 telegram 來連結我們建立好的機器人了。根據 官方文件 我們知道需要用 Updater 及 dispatcher 來接收及傳輸資訊。
1 | import telegram |
我們簡單設定一個歡迎語,確定我們有連結到機器人。這個歡迎語會在你第一次加入機器人為好友時發送。如想要手動啟動這個歡迎語,也可以直接在與機器人的對話框中輸入 /start
。
1 | def start(update, context): |
這個 CommandHandler 是接受指令的一個物件,當收到使用者傳送 / 開頭的指令內容時,就會交由這個 CommandHandler 來處理。Telegram 在新增機器人為好友時,就會送一個 /start
給機器人,這也是為什麼用戶加入時會收到這個歡迎語。
除了 CommandHandler 之外,還有 MessageHandler, ConversationHandler…等,用來處理使用者發送出的不同情境,詳細可以看官方網站做出不同變化。
到這裡還不算完成,直到執行下述指令。
1 | updater.start_polling() # 開始推送任務 |
這時候再去 Telegram 中加入機器人,就可以看到你設定的歡迎語了。
架構互動選單
為了讓我們的機器人更厲害一點點,這裡來架設互動式的選單,讓他可以富含不同的功能。看起來就像這樣:
要做到選單功能,底層的流程架構必須借助 ConversationHandler ,我草畫了這個函數的功用,並不會很難理解。
簡單的用下圖來說明,一開始會由 start 函數開場,在使用者做出動作後,這個動作 (CHOOSING) 會傳至 ConversationHandler,並依據使用者的動作內容進行判斷,看接下來應該由哪個函數接手後續動作。以這個例子來說,ConversationHandler 判斷並將流程交給 check_and_store 函數,而後這個函數完成後,會再將結果傳給 COMFIRM_STOCK 進行判斷。依此不斷循環。
了解架構後,讓我們直接進入程式的部分。首先,我們先把功能選單的介面用出來。
1 | # 載入功能選單的函數 |
接下來,稍微修改一下剛剛的 start 函數。
1 | # 建立回應變數,就是剛剛架構裡所介紹的東西 |
函數的型態大致就如上面的 start
相同,因此我們先來介紹 ConverstationHandler 該如何設置。
1 | from telegram.ext import (MessageHandler, Filters, |
這裡分幾個部分說明:
entry_points
是進到這個 ConversationHandler 的入口,也就是我們剛剛所建立的start
函數,可以注意的是start
函數中使用者輸入的結果會送到CHOOSING
處理。states
就是剛剛架構圖的主軸,是字典的資料型態,key 值就是我們剛剛設定的 CHOOSING, COMFIRM_STOCK, TYPING_CHOICE 等。MessageHandler
跟CommandHandler
功能差不多,但因為使用者在點選選單時,回傳的結果會是 Message 的型態,因此採用 MessageHandler 處理。要特別注意的是第二個參數會放入接著處理流程的函數,舉例來說,在start
函數中使用者點選輸入/移除追蹤股票
選項,那麼第二個參數就會放入input_stock
這個函數來處理後續流程。MessageHandler
第一個參數放入判斷值,這裡使用Filters
來做判別,以MessageHandler(Filters.regex('^輸入/移除追蹤股票$') & ~(Filters.command | Filters.regex('^結束$')), input_stock)
舉例,用正則表達式判別為輸入/移除追蹤股票
且不是指令或是結束
,則進到下一個步驟input_stock
。fallbacks
是結束這個ConverstationHandler
執行的函數。
完成這個 ConversationHandler
物件的設定後,我們就可以把他加到我們的機器人中了。
1 | dispatcher.add_handler(conv_handler) |
如果想要多瞭解其他的函數及關係,可以參考我的 GitHub,裡面有更詳盡的代碼。
股價波動告警
有了以上的選單,機器人就可以依據我們的要求來回應結果了。但如果希望機器人不是單純的接受/回傳訊息,而是能主動根據不同情境跳出通知來警示我們,這樣就更有價值了。因此,這裡會實作如何讓機器人在特定時間或特定事件發生時跳出通知。
要使用這個功能,就必須借助 JobQueue
來實作。
1 | # 建立 JobQueue 物件 |
這個 JobQueue
分別有以下幾種功能
job.run_once
job.run_repeating
job.run_daily
job.run_monthly
照著字面上的意思不難了解功用為何,我們來實作一個例子來幫助了解。這裡我們要建立一個提醒通知,每分鐘都會提醒現在過了幾分鐘。
1 | # 初始化分鐘數 |
如果不是 job.run_once
,我們必須手動關閉該工作,可以透過以下指令來完成。
1 | # 暫時停用該工作 |
透過上述函數,就可以達到每分鐘跳出提醒。依此類推,我們也可以設置每小時的檢查 JobQueue
,關注的股票有無最新新聞,如果有的話就跳通知,沒有的話則略過;或是建立一個在晚上期間關注股票變動超過 10% 時跳出告警等功能。
總結
透過上述對 telegram
套件的說明,我們簡單的介紹了如何用 Python 來架設 telegram 機器人,以幫助我們進一步追蹤股票或是應用在其他生活面向。因為隨著功能越多,設置的架構就會越複雜,在這篇文章就不多著墨在這些部分,有興趣的可以關注我的 GitHub。
如果你覺得這篇文章對你有幫助,還請熱情給我按個讚😂。期望你能順利製作出屬於你的機器人!