國道交通狀況回報line bot(1)
如何使用MOTC Traffic API取得路況資料
環境與框架相關套件:
- 環境:node.js
- 框架:express
- 套件:dotenv、jssha、axios
專案構思及設計:
緣起:
平常上高速公路時僅能急急忙忙透過高速公路1968網站查詢國道狀況以判斷車程或選擇,有時候也需要仰賴副駕的協助查詢,於是想說若是有更方便使用、不用打開網站查看、也不用額外下載app,最好是駕駛人可以快速用單手就完成操作。
技術學習面:
作為技術的學習,此次希望透過專案的開發學習幾項技術:
- API:包含官方文件閱讀、實際運用,初步估計會運用到line API以及國家級MOTC Traffic API做為資料來源。
- webSocket:透過webSocket實現伺服器端定期回傳道路狀況給客戶端
- AWS:將server部署到AWS上。
範圍有點大,於是我預期拆分成兩個版本:
- v1.0:以較為熟悉的網站架構完成API介接以及AWS部署。
- v2.0:重構伺服器,讓程式變為適合line bot的伺服器,並成功啟用line bot,加上websocket廣播功能。
使用者故事:
已按照開發順序做排列。
- 使用者可以選擇高速公路的起點與終點,並得到預計車程、車速。
- 使用者可以選擇高速公路的起點與終點,並每特定時間更新去收到阻塞通知
- 使用者可以快速比較國道1號及3號
- (後續補充…)
MVC原則:
作為開發者已及使用者,預計先行完成使用者故事1及2即可
根據前面對於版本1跟2的規劃,v1.0會完成使用者故事1,v2.0會完成使用者故事2。
介接MOTC Traffic API
API介紹:
詳情可參考即時路況與停車資訊流通平台。
這個API是由交通部開發,裡面包含路況、停車兩個領域的動態、靜態資料,而這次我要完成的國道交通狀況line bot,需要取用的是高速公路局提供的動、靜態資料。
介接步驟總覽:
詳情可參考官方說明手冊
我們先把目標放在:取得國道一號(基隆端到基隆交流道)的道路即時狀況
- 註冊會員
- 了解API的URL
- 使用axios取得資料、處理HMAC驗證
- 使用OData語法取得特定資料
註冊會員:
API採用HMAC簽章驗證使用者身分,於是需要APPID以及APPKey,要取得這兩者就需要先去完成註冊網頁完成註冊。
既然是個人開發用,選擇一般會員即可。
選擇後會需要填寫資料,填妥後會收到一封會員帳號啟用信去啟用帳號。
帳號啟用完畢會收到一封API服務申請成功通知,裡面就包含了你需要的APPID跟APPKey囉。
了解API的URL:
接下來我們要試用看看AppID跟AppKey,先到這個API網站
在最上方先輸入你的AppID及AppKey,輸入完後按下Explore,接著我們看到的高速公路局動態路況,點開後會看到:
接著在裡面看到取得[高速公路局]路段即時資料:
他前面會有request method以及路由,不過他的路由省略了domain以及主要路由位置(/MOTC),{}代表的是要輸入特定資料。
所以我們要前往的是GET https://traffic.transportdata.tw/MOTC/v2/Road/Traffic/Live/Freeway
點開來後看到上半部是屬性簡介,也會包含資料的型別,他的排列方式是由父層到子層,所以以下圖為例:LiveTrafficList是父層,裡面包含了LiveTraffic這個陣列,於是也有列出LiveTraffic的屬性簡介。
我們先大致看一下,我們要的資料會集中在LiveTraffic裡面,包含SectionID, TravelTime(秒), TravelSpeed(公里/小時),也稍微注意一下儲存的型別跟單位。
下半部則是可以輸入的query參數,這邊是OData語法,我們最後要透過這個取的特定資料時會用到
最後就可以按下try it out啦,如果步驟沒錯的話你會看到資料如下。
- Request URL:這就是最終的路由內容,若我們在前面也有設定query參數,這邊也會顯示出來,為了開發方便,我會在這邊輸入相關參數,複製下來後再貼到程式上面。
- Response body:我們所需要的資料在這裡。
OK,這邊就拿到可以取得資料的request method跟url了。
GET https://traffic.transportdata.tw/MOTC/v2/Road/Traffic/Live/Freeway
使用axios取得資料、處理HMAC驗證:
接著就是在伺服器環境正式使用API取得資料了,為了降低使用的學習曲線,他們有提供範例。
大致來說就是丟出帶有HMAC簽章的request,並接住response:我們分成https跟HMAC來說明。
- https:
在溝通https時他用的是JS原生的ajax,以下使用promise base的axios套件去處理。
註:特別提醒,目前官方為了資安,已經禁止使用http去做API溝通,所以如果你是用http是會被禁止訪問的喔。
- HMAC:
原理:使用者在request API時,需要將APP Key 與當下時間(GMT時間) 做HMAC-SHA1 運算後轉成Base64 格式,帶入signature屬性欄位,最後在送出的request header上加上Authorization以及X-Date。
註:千萬不要把敏感資料像是AppID及AppKey直接用git commit,我的話是使用dotenv套件把他轉而儲存在.env環境變數上。
把裡面的apiURL賦值前面取得的request url,就搞定啦。
拿到data(正確應該是說response),通常資料會放在data這個Object內,然後記不記得我們前面說我們要的資料都放在LiveTrafficList.LiveTraffic裡,所以就可以直接使用拿到特定的陣列資料了
console.log(data.data.LiveTrafficList.LiveTraffic)
今天就先這樣吧,下次再來談OData。