← 開發日常

架設小遊戲機器人(上)

這篇文章主要是紀錄一下自己的 Side Project :小遊戲機器人的演進過程

這個 Side Project 啟動於三年前,剛好那陣子聽到或學到比較多自己沒用過的技術,LINE BOT、ASP.NET Core、Docker ...等,於是就想練習一下這些新技術,看看能不能用這些技術做出一些好玩的東西。

啟發於上個時代的通訊軟體MSN Messager、Yahoo Messager,當時這些通訊軟體上有一些小遊戲,讓同一個群組的人可以透過這些遊戲互動,當時覺得這個功能很有趣。如今自己最常用的通訊軟體就是LINE,於是想到可以在 LINE 上面做一些簡單的小遊戲,讓群組的朋友無聊的時候可以一起互動,一起玩個小遊戲增加趣味,也可以藉此增加一些聊天的話題。

Hello World? Bot?

一開始自己跟著 LINE 官方教學開始,把 LINE BOT Server 架設在 Heroku 上。Heroku 是一個滿方便的雲端服務平台,可以在 Heroku 上開設一個免費方案的 app。在 Heroku app 設定完成後,把官方提供的 example 部署上去,就馬上得到一個會重複上一句話的 echo LINE BOT,自己也對著這個範例修修改改的,稍微玩了一下。

當完成官方範例後,雖然機器人已經可以正常運作,但是跟當初想練習的技術不太一樣,所以就開啟了用 C# 寫 LINE BOT 之旅。

ASP.NET Core 實作 LINE BOT

因為自己想練習的是 ASP.NET Core,但是 LINE 官方提供的範例都不是 C# 的,所以自己就用 ASP.NET Core 做了一個簡單的 Web API Server,寫了一個 API 給 LINE BOT Webhook 使用。當有人傳訊息給 LINE BOT 時,LINE 就會呼叫我們提供的 API 並傳入訊息內容。

LINE BOT 傳過來資料的是 Json 格式,裡頭包含訊息內容、送訊息的使用者ID、訊息格式、回覆用的 token ...等,所以我自己是用了 LineBotSDK 套件來幫忙把資料轉成物件,除了轉換資料物件之外,這個套件也能用來回覆或推送訊息。

當做好一個 Web API Server 之後,是該把程式部署到 Heroku 上了。

Heroku 不支援 ASP.NET

當我開始研究如何部署時,赫然發現 Heroku 不支援 C#,如果是直接把代碼放到 Heroku git,就會出現不支援的錯誤。當時也找到一些答案可以解決這個問題的,例如在 Heroku 上安裝第三方的 buildpack,透過這個 buildpack 來建置部署 C# 的程式。而另外一個解法,也是我現在使用的解法,就是使用 Docker,透過 Docker 來 build 出 ASP.NET 的應用,然後部署 image 到 Heroku image registry 上,最後 Heroku 就能執行這個 image 來啟動服務。

至此,小遊戲機器人已經可以開始使用了,在機器人所在的群組中,送出一些固定命令,然後機器人就會根據狀況來回覆訊息。

自動化部屬

每次修改完代碼之後,除了要把代碼 push 到 Github 之外,還要手動在本機 build 出 image,然後再透過 docker 命令把 image 上傳到 Heroku 的 registry 上。為了解決太多手動操作的問題,自己就開始研究 Github Action,期望透過它達到自動化部署,省去手動部署的麻煩。當每次 commit 到 Github 時,Github Action 就會抓取最新的代碼,嘗試建置和測試,通過之後就開始 build image 和把 image 傳到 Heroku 的 registry 中,透過自動化來避免每次部署都要手動操作。

完成 Github Action 後,每一次 commit 都能自動的建置、測試與部署,讓整體開發更為順暢。

每次部署資料都會消失

在最一開始版本中,所有遊戲的狀態都是存在記憶體中,當 Server 重新部署後,所有玩到一半的遊戲都會消失。一開始的遊戲只有井字遊戲和猜數字,這些遊戲很快就能結束,所以不至於產生太大的問題。隨著後來加入五子棋後,這個問題就開始變得嚴重,因為沒有限制下棋的時間,當玩到一半就離開處理事情,過一陣子處理完後才走下一步,甚至等到隔天才想起來要走下一步,若中間有修改代碼,commit 後的自動部署就會導致遊戲狀態的消失。

為了解決這個問題,也為了學習如何使用 Redis,所以在 Heroku 上加上了一個 Redis 的 Add-on,並讓 Container 裡的機器人連到這個 Redis。在 C# 的部分,自己使用了StackExchange.Redis 來處理 Redis 的連線與操作,在 Redis 中儲存正在進行的遊戲的狀態,當 Server 重新部署後,只要從 Redis 讀取進行中的遊戲狀態,就可以避免遊戲狀態因為重新部署而消失。

當機器人開始用 Redis 時,終於可以達到隨時都可以部署的狀態了。

未完待續...

做這個機器人的過程中碰到了許多問題,也產生了許多學習的機會,除了上面提到問題之外,還有其他關於資料庫、LINE BOT的限制...等,會在下一篇文章中補完,因為這篇文章主要是紀錄一下整個專案的歷程,所以沒有過多地講述細節,如果有人有興趣其中某一個部分,可以聯繫我讓我知道,我會再找時間寫得更詳細的,也謝謝大家努力看到這邊,最後附上我的 Github Repository