0%

birds

前言

因為遇到了很多不算坑的坑(說啥呢?),有些是文件沒有寫而有些可能是我沒有注意到的,但既然都知道了就乾脆記下來吧!

LIFF reply 到底算不算收費?

LIFF SendMessage api

字面上看起來很像 Push Message 的事件,但實際上是走 Flex Message,使用 Message api 的 Reply 功能來幫忙使用者發送條件引發 Bot 行為,並非是透過 Push api 發送讓 Bot 反應,這邊需要多注意喔!

1
2
3
4
5
6
liff.sendMessages([
{
type: "text",
text: "You've successfully sent a message! Hooray!",
},
]);
閱讀全文 »

最近 LINE 釋出了一個我很喜歡的功能 - Icon Switch🎚,從字面上的意思就是可以切換機器人的 Icon (名稱以及大頭貼),過往開發者在使用時都只能較死板的使用同一個頭像或暱稱來回應使用者,而現在只要使用這個這個功能就可以很輕易地切換你想要的大頭貼以及暱稱了 😇

據可靠消息指出這以前是需要收費的功能,而現在則是免費推出來給大家使用,讓大家可以有更多的彈性去開發新功能~

閱讀全文 »

前言

最近一次的 Chatbot 小聚因為在疫情期間可預期現場來的會眾一定不多,所以在這場小聚中也加上線上直播的部分,但因為我首次導入還不是很熟悉,在谷歌大神的幫忙下找到本篇介紹的軟體 - Streamlabs,使用 XR 錄影起來的品質覺得還不錯,且連講者 Demo 時的 LINE token 都看得一清二楚 🤣,接下來就來介紹一下我使用的過程。

這邊我使用 iOS 做範例,小聚資訊可以參考 Chatbot GitHub

閱讀全文 »

workload

前言

之前鐵人賽寫了一篇文章有提到 Cold Start 的問題,不過只有粗略介紹,最近看到大家忽然又開始討論這個話題,這次就來好好的搜尋資料介紹一下。

平常在做 open source 時比較常遇到休眠狀態應該就是 Heroku,而開頭要先澄清一下他是屬於 PaaS 的架構,而 AWS、Google、Azure 裡提供的 LambdaCloud RunAzure Function 這些則屬於 FaaS 架構,而最常討論 Cold start 時最常會在 FaaS 上討論,只是剛好 Heroku 使用起來也是一樣,這次文章就把他一起抓進來討論啦~

有很多各式各樣的服務,SaaS、FaaS、KaaS、IaaS… 等各式各樣的架構,每個都是為了解決某個問題所誕生的,至於好或不好其實就是看使用場景而定,所以大家在選用時要注意一下你使用的場景哦!

為什麼會休眠

一般會有休眠機制是因為這些供應商在提供服務都是提供按次計費的方案,讓開發者在用時可以需要才喚醒使用,也就是說這些服務都是 事件驅動(Event-Driven)導向,意指是當前服務若收到訊息後,會呼叫對應的 Function 來處理對應服務所接收到的資料(Queue、Notify …),但相對的就是會有休眠讓服務暫停,進而讓較少使用的服務不會因為掛在線上而一直被收費用,而重新啟動這件事就是本篇要提的Cold start

Cold start 流程

在處理資料之後過一段時間若沒有繼續執行,雲端供應商會將模組暫停,此時 function 會處於 inactive 狀態(cold),而當 function 再度被觸發時(cold start)則會再啟動模組來執行對應 function 來處理事件,在模組與 function 之間的關係可以稱他們為 Function chain

休眠狀態喚醒流程

[參考](https://mikhail.io/2018/08/serverless-cold-start-war/#how-do-languages-compare-)

以 AWS 為例,在喚醒時會到 S3 去取得檔案,接著找到相關的 Lambda 並載入相關模組套件,然後再執行觸發的事件,整理過後的下:

事件處理 ➡️ 過段時間 ➡️ 暫停 function 模組(休眠) ➡️ 觸發 ➡️ 啟動 function 模組 ➡️ 事件處理…

這整個流程就是俗稱的 cold start,因為在這個過程中會花些時間,所以若是拿來處理 api 相關問題的話就會有第一批請求很久,然後之後的請求卻特別快的狀態,請大家莫急莫慌莫害怕呀!

平台比較表

平台 多少時間後暫停
AWS Lambda 10 minutes
Google Cloud Functions 介於 3 minutes 之間 5+ hours 都有
Azure Functions 20 minutes
Heroku 30 minutes

前三個為 FaaS 架構,而 Heroku 則為 PaaS 架構喔!

下圖則來自 2019/09 的一篇文章,較深色的部分則為啟動時間。
FaaS platform cold start time

如何處理或是盡可能避免?

以我熟悉使用 serverless framework 部署到 AWS 來說,他們提供了一個 warm-up 的套件,可以設定排程時間讓這個 function 固定去戳其他 function,避免他們進入休眠的狀態,雖然這樣子就能達到跟一般服務一樣的常駐狀態,不過相對來說就要注意次數的使用問題,若是流量還小的話沒什麼問題,但若有一定的流量就須注意一下帳單,因為這些在互戳的過程中還是有算進費用的喔!使用上還要多注意才行。

另一方面要注意相依套件的問題,引用 google 文件的其中一段:

謹慎使用依附元件,如果您使用動態語言搭配相依的程式庫,例如匯入使用 Node.js 的模型,這些模組的載入時間會增加冷啟動期間的延遲時間。您可以透過以下方式縮短啟動延遲時間:

  • 儘可能減少相依元件的數量和大小以建置精簡的服務。
  • 只有在必要時才載入不常用的程式碼 (如果您使用的語言支援)。
  • 使用程式碼載入的最佳化,例如 PHP 的 composer 自動載入器最佳化。

畢竟在載入模組的時候相依套件也是要一起抓進來,若是程式本身太多依賴的話也是會導致 cold start 的時間變長哦!

最後就在幫大家整理一下三大平台的 warm-up 資源:

結論

為什麼要有 cold start 的機制,以供應商的角度來說他們可以提供一定的量讓使用者免費在平台上先建置服務,但若要免費就是服務會被暫時暫停,畢竟現在流量就是錢嗎 💰,像我常用的 Heroku 就會是這樣,而當你流量大的時候就看你要不要搬家,不過一般應該都懶得搬,就會形成所謂的養、套、殺🤣(離題)。

總而言之,若是需要服務時常活著,就是需要付出點流量的錢 💰,也或許你的作品服務時間可能不用那麼長,只要在服勤時間內長駐活著就可以在省下一些費用,如果有需要的話還是付一些錢給供應商,畢竟人家也幫你保管了服務你說是不是?

參考

learn records

前言

礙於最近做事有點手忙腳亂,沒有很有效的管理時間,記錄下來讓往後能有個經驗可循並增加自我管理能力。

實作項目

Docker & Docker-Compose

我記得上次自己弄 docker container 已經是一年多前,當時還結合 Drone CI 來跑(好久了 👀),對於 Dockerfile 使用方法依稀有點印象,而最近因為看了許多 open source 後對於 Dockerfile 的內容了解度也提升了許多(實在是個不錯的方法 👍),會這樣子弄的原因是我認為 Serverless 的架構很容易被 AWS 綁架,我認為 API 這類可拆出來的功能應該要包成 container 增加彈性不讓平台限制,被這個想法 trigger 後就來好好練習 Docker 了 🏋️‍♂️。

這次使用 Twitch-Bot 做我的練習對象,裡面主要用了 node 以及 mongo 兩個服務,在此同時如果各別起 docker 挺麻煩,因此就需要使用 docker-compose 幫忙啟動,而在這過程中學到了:

  • 把 Dockerfile 遷移到 docker-compose 上 (如何複製別人的檔案(大誤))。
  • 藉由 docker-compose 裡面的 network 連接兩個容器的使用方法。
  • Google container-registry 上傳以及 gcloud 過期的 docker 使用方法(參考),同時也修正後可以使用 docker 的原生指令將 container 送上 Google。

接下來就是趁六月 credit 過期前趕快來玩玩 Google Kubernetes 🚀

AWS IoT Job

最近在公司實作 AWS IoT Job 部分的功能(以下稱為 Job),因為 Job 每次執行收費約 1 塊台幣,之所以會用它是因為在 IoT 執行時不是只會單純發送訊號出來讓後台收訊號做事,而是需要跟後台經過一連串的溝通來達成功能(例如 韌體更新),當然還有很多更複雜的功能,這邊只列舉一個小部分。

從這段時間的實作上學到的部分:

裝置工作列表

當後台的 Queue 同時塞進很多工作時要如何管理並通知裝置此時的工作有哪些(All Job)以及要做哪件事(Next Job),實作這功能時不能只考慮到一個裝置,而是考慮到 N 個裝置時要如何過濾並管理狀態機,限制裝置要依照狀態執行避免系統錯亂。

平台化

之前主要功能都是介接 AWS IoT,而這次是要實作一個類似的功能提供給其他使用者,不能只開一個 API 就想要功能都包好,而是將功能明確劃分,讓使用者可以有彈性的去組合,只是在此時我沒有處理得很好,之後的 Task 需要更注意。

LINE SDK - Narrowcast Client API

參考 Pull Request: Add narrowcast client api #237

工廠模式

功能主要是讓開發者可以透過 API 來做分眾的推播,在實作這個 issue 時讓我原本模糊的工廠模式清晰了許多,主要是 SDK 使用了 Python Class 來擔任 Model 的角色,讓進來資料可以經過 model 去轉換成對應的 key-value,所有的資料都分類進去對應的工廠處理完再回傳出來。

在還沒開始看 code 前只想著要寫什麼邏輯去處理,其實使用 Model 的方法就處理掉大部分資料格式的問題,很多 LINE 文件已經清楚定義的格式只要照著填就解決了,只是在這個 Task 遇到了Python 保留字的問題,而經過各種 google 後只好自己寫邏輯去判斷掉這件事,之後只能繼續看有沒有更好的寫法可以取代掉這個保留字的問題。

Lint

官方 Github 有寫要 Contribute 時需要執行的內容(參考),lint 則是遵照flake8,而執行tox後會對每個版本的 python 去做測試,但像我電腦只有 3.7 版 tox 就只會針對這個版本做測試。

  • 在這件事上學到的 tab空白鍵(space) 的差異,PEP-08 上也告訴建議使用空白鍵,而 python 3 之後也不允許兩個混用,畢盡 python 是很注重縮排,既然官網都寫了哪有不遵守的道理呢?😃

Lint 也不會無緣無故來刁難開發者 XD

  • 內部函式(Class、Function)都需要再第一行下註解,而會這樣用的因素可能在 python 上並沒有 publicprivate 的觀念,透過這樣的方法來表示它(Class、Function)是一個內部函式,藉由 Lint 讓開發者可以知道這個功能是內部還外部,只是在 python 只能使用這個 lint 讓大家遵守這規則,如果沒有 CI 要硬上的話其實也管不住,畢竟不像 golang 這類語言會編譯(汗顏)。

總之使用 lint 的好處就是開發風格可以統一,能夠盡量避免不必要的 programing 麻煩,在寫任何語言都推薦使用各個語言的 lint,雖然一開始會很討厭它,但它真的是在幫助你 😆。

Netflix

這時間與家人一起訂閱了一年份的會員,而我的初衷就是想把英文學好,而我也花了時間好好的看完一部全英文影集(發英與字幕),第一次嘗試這樣看全英文,並且邊看邊 Google 翻譯不懂的單字同時口述跟著念一遍增加記憶力,隨著工作量減輕後下班也可以再安排時間繼續看下個影集學了~

然後迷上了愛的迫降這個韓劇,推薦喜歡看愛情片的朋友去看 ❤️

武漢肺炎

最近剛好因為這傳染病盛行,除了防疫之餘,g0v 也提供 API 讓開發者可以拿去介接,隨著大家各種開發前端 web 以及 chatbot …的應用後本來在想有個什麼想法可以參與這個全民黑客松,只是我認為用途實在重複性太高,而在大家開發應用時我又剛好在寫 LINE SDK,錯失了第一時間發佈口罩相關的服務建立時間,本來想到 LIFF v2 + LINE Notify,但只是在使用上很容易吵到用戶進而封鎖它(LINE Notify),因此要考慮好功能再來看會不會有比較好的使用情境。

出入公共場所記得戴口罩,有帶隨身瓶酒精的記得消毒!😷

結論

有時候在思考與規劃的過程中如果經驗不夠時真的很難馬上到位,不過任何事情都一樣,若這件事可以輕鬆且又得心應手,代表它可能已經是你熟悉的領域或是過於簡單,就像我一開始處理社群一樣,若是沒有前輩們帶著走的話我跟本無法有效地處理事情,總之凡是起頭難,即早加入即早熟悉各個領域才是王道 😆

參考

AWS IoT 觸發後可以執行的功能
Job Events
Tab 與 space 的差異(PEP-08)

前言

我對這錯誤的印象是某次在練習寫測試時裝 jest 後出現的,檢查了package-lock.json後看起來jest-haste-map這個套件有用到 fsevents,而之後使用npm install或者yarn install皆會出現以下這個訊息:
node-gyp rebuild error

環境為 Mac OS Catalina version 10.15.2

看起來是在執行階段時node-gyp出了問題,接著它自己重新執行了node-gyp rebuild後出錯,起初我認為是套件的問題並找到了這個回答並執行:

1
2
sudo npm uninstall node-gyp -g
sudo npm uninstall node-gyp

但從來沒有全域安裝node-gyp過,也有些網友執行node-gyp configure是可以的,而我執行後還是失敗,狀態跟這個 issue 差不多。

後來看到 fsevents 在套件說明裡有寫到:

The FSEvents API in MacOS allows applications to register for notifications of changes to a given directory tree. It is a very fast and lightweight alternative to kqueue.

並且注意到剛剛圖裡面有訊息是跟 xcode 以及 apple 相關,最後找到了這個 issue

我的解決方案

有些人可能是有重灌或環境重設導致沒有安裝 xcode,此時只要執行 xcode-select --install 即可(參考說明)。

這邊我使用的解決方案為這個 issue,執行以下兩個指令來重新安裝 xcode:

1
2
sudo rm -rf $(xcode-select -print-path)
xcode-select --install

原因可能是因為我重舊版本向上更新之後 xcode 沒有相容當前版本,所以我使用以上指令來刪除重新安裝。

不過這個指令很暴力的使用 rm -rf,使用它相對危險,使用前請詳閱公開說明書 😆。

結論

為了練習測試安裝了 jest 卻讓我看著一堆 warning 實在是恨得牙癢癢,所幸目前這樣解決完後是可以用的,就看接下來些新的 side project 後會不會有其他問題再來更新,

另一方面也可能因為我在寫 side project 時安裝了一堆有的沒的東西導致這個結果,看來也得找時間來整理一下環境了~

參考

清除 npm 快取

前言

最近剛好看到許多EKSGKE相關的文章,趁著過年時刻先來補足一下 Docker 這個既熟悉又陌生的技能 😆,之後再接著研究如何串接至 kubernetes 並同時到雲平台上,接下來一起來看我從建立到建置的過程紀錄 🙂。

以下就使用我的 side project - Twitch-Bot 做範例囉!

主要使用的功能為 node 以及 mongo

新增檔案

這邊我使用 vscode 的 Docker extension 來幫助我快速建立 docker 相關的檔案:

  • Dockerfile
  • docer-compose.yml
  • .dockerignore

透過以下的 gif 可以快速建立以上三個檔案

操作方式為 Cmd+Shift+P >docker: add > 選擇語言(Node) > 設定輸出 Port

處理 dockerfile

藉由 extension 來幫我們產生檔案第一步就完成了,接著對 Dockerfile 稍做修改:

1
2
3
4
5
6
7
8
9
FROM node:10.13-alpine
MAINTAINER NiJia <louis70109@gmail.com>
ENV NODE_ENV production
WORKDIR /app
COPY ["package.json", "package-lock.json*", "/app/"]
RUN npm install
COPY . /app/
EXPOSE 5000
CMD ["npm", "start"]
  • FROM: 來自什麼映像檔,這裡使用預設給的 node 版。
  • MAINTAINER: 寫描述的位置,這邊我標註我的名稱與 EMail。
  • ENV: 環境變數寫在這,不過這個專案是放在 Github 上,所以我就沒把 chatbot 平台的密鑰放在這了。
  • WORKDIR: 當前在一個乾淨的環境下,而你預想的工作路目錄要叫什麼就在這設定,同時也會一起幫你建立好 (我用/app這個工作資料夾當作範例)。
  • COPY: 把檔案複製到想要放的地方,這裡為了先讓容器安裝完相依套件,因此先把 package.json 以及 package-lock.json 先複製進 /app/ 這個資料夾內。
  • RUN: 執行終端機指令,在上面檔案複製過來之後,這裡我就來安裝相依套件庫。
  • COPY: 安裝完產生 node_modules 之後把原本的有的東西都複製過來。
    • . = 當前目錄
    • /app/ = 欲複製前往的地方
  • EXPOSE: 容器要打出去的 Port 出口,在前面呼叫 extension 時就已經輸入完這欄了。
  • CMD: 幫我執行指令 (參考: CMD 與 ENTRYPOINT 的差別)

docker-compose.yml

這邊我將預設的修改為:

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
version: '3'

services:
twitch-bot:
image: twitch-bot
restart: always
build: .
environment:
NODE_ENV: production
ports:
- 5000:5000
depends_on:
- mongo
networks:
- chatbot-network
mongo:
image: mongo
restart: always
volumes:
- ./data/db:/data/db
networks:
- chatbot-network

networks:
chatbot-network:
driver: bridge

首先將version改成 3,有向下相容的話當然就是要使用新的囉!

接著會建立兩個 container (services):

  1. twitch-bot
    build 後面接著 . 是指說建立在當前位置,depends_on 則是依賴哪個 container,最後則透過 networks (chatbot-network) 來讓服務互相溝通。
  2. mongo
    這邊則就直接去 dockerhub 裡面抓,restart鐵定是必要設定,不然會沒有資料庫 🤣,volumes則是設定說你想映射的檔案位置在哪,這邊我設定當前目錄的/data/db (./data/db)裡面,對應到映像檔裡面的 /data/db 的位置,然後一樣透過 networks (chatbot-network) 來讓服務溝通。

networks 這邊就有點像主機設定網卡一樣,我設定一個 chatbot-network 的網卡它是使用橋接(bridge)模式來驅動(driver)

這部分是參考知乎,對照改出來的

補給站: 一般看到 5000:5000 或是 ./data/db:/data/db 的寫法,它意思是 本地端位置 對應「:」到 容器的位置,像上述檔案就有 port 以及 資料庫位置,這邊就會因應服務而對應到不同的功能。

修改 .dockerignore

這邊因為我很偷懶不想把.env裡的環境變數寫進dockerfile😆,因此在這就把檔案中的**/.env拔掉方便做事 🤣

測試容器

啟動

1
docker-compose up -d
  • -d 表示讓容器跑在背景,如果沒加的話就會在終端機上看到容器們的行為。
  • 會建立本地端的 container image。

關閉

1
docker-compose down
  • 若是使用 Twitch-bot 來試玩的話,則需要多開一個視窗執行 npx ngrok http 5000 來建立一個暫時含有 SSL 的 URL。

建置(build)

如果是按照原本 docker-compose.yml 的打法:

1
2
3
services:
twitch-bot:
image: twitch-bot

這樣的話 docker 預設會幫忙下一個 latest 版號的 tag。

如果是按造以下做法的話在 build 就會幫忙建立 帳號/容器名,並下一個 0.1 的 tag

1
2
3
services:
twitch-bot:
image: louis70109/twitch-bot:0.1

接下來就執行 docker-compose build 幫忙建立一個有版本號(tag)的容器映像檔(container image)。

補給站:

  • 記得要 docker login 哦!
  • 到 dockerhub 或其他私有倉庫建立 container repository

結碖

趁著春節的零碎時間來跟這個熟悉陌生技能打個招呼 😆,同時也體會到大家說到 docker 好用的地方以及給予的彈性,之前都是有需要測試某些功能才會用到,對於 dockerfile 以及 docker-compose.yml 就甚少了解,藉著年假空檔練習,之後只要在熟悉一下整體的使用方法應該就能好好的~用它來幫忙做事了 🚀。

references

連線 mongo container
docker CMD 使用
Overview of Docker Compose
Twitch-Bot

前言

在去年大約五月的時候寫了一隻 Twitch 的 LINE bot,不過後來似乎 Twitch API 有改版讓機器人壞掉了,最近又有需要一隻機器人幫我查詢,就開始去翻一下 Twitch 官方文件,碰巧逛到這個 Community Resources page,看到了好多資料在裡面,就索性來重寫囉!

因為 Twitch package 都是 Typescript,因此本篇的範例都會是 Typescript 哦!

⭐️ 本專案: Twitch-Bot

加好友

  • LINE

    QRcode
  • Messenger

    QRcode

準備

1
2
3
yarn add twitch
// or...
npm install --save twitch

[2020/06/08 修正] 申請完後將 oauth: 後的 key 透過官方文件的 Validating requests 指令放入 access token 中取得 Client_id,如下:

1
curl -H "Authorization: OAuth <access token>" https://id.twitch.tv/oauth2/validate

本專案的 TWITCH_CLIENT_ID 的環境變數就是這個回傳值中的 client_id

這部分可能會需要去 twitch 設定 -> 連結 去綁定 Oauth 的樣子,再麻煩各位注意一下。

  • 平台

    • 需要有個 Facebook 粉絲頁
    • LINE bot
  • 資料庫

    • MongoDB: Heroku 上為 mLab

實作

Clone 專案下來看 ➡️ https://github.com/louis70109/Twitch-Bot.git
首先把.env.sample改成 .env,並將對應的MessengerLINE以及Twtich key 放置對應的位置

跨平台

跨平台含本地總共會有三個:

  • Console (本地端)
  • Messenger (線上)
  • LINE (線上)

Console 是 bottender 的特色之一,可以在終端機上直接測試 Bot 的行為,會先用此模式先測試路由的回覆是否正常。

接著要讓同樣的 Action 可以導到 Messenger 以及 LINE,bottender 提供了可以設計針對特定平台處理 Action,如下:

1
2
3
4
5
6
7
import { platform } from 'bottender/router';
export default async function App(): Promise<void> {
return await router([
platform('line', LineAction),
platform('messenger', MessengerAction),
]);
}

透過platform來把特定平台的訊息到打對應的 Action (如 LineActionMessengerAction),在傳遞 Action 過程中會有一個 context 的變數,裡頭會有底層幫忙整理好的參數:

1
2
3
4
5
6
7
8
9
10
11
12
ConsoleContext {
...
_session: {
_id: 5e08a45c719a1335aeae39bc,
id: 'console:1',
_state: {},
lastActivity: 1578743328620,
platform: 'console',
user: { id: '1', name: 'you', _updatedAt: '2019-12-29T13:04:25.633Z' }
},
...
}

_session 裡有個 platform 的參數,只要判斷這參數就能知道訊息是來自哪個平台,而user則是被正規化完後的使用者資訊 (這兩個參數為目前為止我最常用的參數)

遇到的問題

由於長期使用 LINE flex message 的 button template (參考),這按鈕事件可以設定按鈕上的文字並設定按下去回覆的字串。

而 Messenger 的按鈕就跟人家不一樣了(參考)!他沒有 LINE 的這個事件,差不多的事件只有 postback,在路由上就得特別處理這個事件,為了讓跨平台所使用的內容要統一,在訊息進 router 時就要處理掉:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { messenger } from 'bottender/router';
import { withProps } from 'bottender';

async function LineAction(context): Promise<void> {
return await router([
...
text(/^[f|F]ind\s*(?<topic>.*)$/, searchGame)
...
]);
}

async function MessengerAction(context): Promise<void> {
const payload = context.event?.postback?.payload;
return await router([
...
messenger.postback(
withProps(searchGame, { match: { groups: { topic: payload } } })
)
...
]);
}

這邊找到 bottender 官方文件中函式專門在處理 Messenger 的 postback 事件,並搭配withProps來幫忙把參數 postback 收到的參數傳進對應 Action。

為什麼會要把傳入的參數設定成巢狀 object -> { match: { groups: { topic: payload }}},因為在設計初期本是希望進來的內容都是從text傳進來,意指都是透過使用者打字進來,那 bottender 都會透過傳 match 參數進來(參考),而解析完 Messenger 的 postback 時也得需要符合這樣的格式,因此就這樣設計,當然如果有更好的設計歡迎送 PR 🎉。

Chatbot MVC

Model

  • Twitch: 這裡我設定 userId 為 unique,針對每個平台有自己的 id,每個平台都可以綁定 twitch 帳號,進而去做相關操作。
  • Game: 因為 Twitch 套件這部分是read only,因此我就在建立一個一樣的 model 來處理。

Twich id 是全開放的,只要知道其他使用者的 id 就可以查詢某些功能(參考),這邊我就使用查詢追隨的功能。

View

這裡設計上只要屬於送出訊息相關的樣板(FlexGeneticText)接放在此。

  • common: 作者資訊(author) 以及 幫助我(help) 的相關
  • LINE: Flex message 相關樣板
  • messenger: Genetic template 相關樣板

Controller

在呼叫 twitch api 出來的資料有時候會大於 LINE 以及 Messenger 的樣板限制,因此所有計算服務都會放在這邊,剛好就搭上 Controller 的對應功能。

  • common: 負責將 controller 處理完的內容送至 View
  • twitch: 處理最多人看得遊戲以及搜尋指定遊戲
  • user: 處理綁定以及查詢追隨

結論

基本上做到這如果之後要擴增Telegram或是Slack都可以很快速擴充,只要把相對只要把相對的 Action 加在 App.ts 就行了。

藉由這次也學到跨平台的機器人真的不好做,每家廠牌的行為都不一樣,所幸 bottender 已經處理大部分平台間的問題,接著我們只需要將欲輸出的內容處理好對應框架所提供的功能去回傳給使用者,讓整體的開發可以更專注在開發功能上並更有彈性。

歡迎各位幫我按個星星 ⭐️➡️ https://github.com/louis70109/Twitch-Bot
也一起支持開源專案 bottender⭐️➡️ https://github.com/Yoctol/bottender