利用 Visual Studio Bot Application 結合政府開放資料查詢即時地點紫外線指數
當初在法國交換的時候突然收到新一屆的MSP活動
說是有所謂的Mentor Program於是就傻傻的填了資料(?)
想說就再回來一次能幫忙11屆的學弟妹就幫(順便也逼迫自己更新微軟的技術...這幾年實在更新的太快啦!!!)
(偏題啦)
----
於是就正文開始啦
然後就說個悲劇的開始...星期四寫完的測試Bot丟上去之後星期六就給我從V1改版到V3啦!(翻桌)
雖官方文件說沒有改動很大,但光是Emulator就讓人搞不清楚啊
以下是以我專案V1與V3版本已知的差異點
V1 | V3 |
Web.config AppID,AppSecret |
Web.config BotID, MicrosoftAppID,MicrosoftAppPassword |
Controller Message |
Controller Activity |
Emulator v1
上頭為: Emulator port, URL, AppID, AppSecret四個
Emulator v3
上頭為: Local Port, Emulator Url, Bot Url, Microsft App id, Microsoft App Password五個
最後還是就乾脆重寫一個V3的版本(懶得修修改改)
----
以下專案由行政院環保署 環境資源資料開放平台 作為資料來源,結合Microsoft Bot Application並以C#語言做為測試範本
之後也會再寫一篇簡單藉由Microsoft Bot Framework結合FB Messenger API直接連接並藉由Messenger Bot收發
首先到Microsoft Bot Framework的網站(網站在此) 並點選上方的Documentation
點選左方的Bot Builder for .NET
點開後點選 Connector Service
接著再點選 Getting started with the Connector
接著重要的是要下載兩個檔案:1.Bot Application的Zip檔 2.Emulator
若沒下載zip放在正確的位置是開專案是看不到Bot Application的唷
要放在"%USERPROFILE%\Documents\Visual Studio 2015\Templates\ProjectTemplates\Visual C#"這個資料夾內
這邊也有提示最好是更新到VS最新版本唷
1.
2.在Emulator的文章區塊下載Emulator(這超隱密= =)
以上的前置作業算是完成
---
接下來就是資料蒐集的部分
前面所述是以行政院環保署 環境資源資料開放平台 作為資料來源
就在搜尋字串內搜尋 紫外線 而我們選擇 紫外線及時監測資料
我們可以在這邊看到右邊顯示提供的資料格式有JSON, XML, CSV等
左邊可以挑選其他的過濾條件(ex.不想顯示發布機關)
同時也提供了 使用範例
應用程式存取網址已經包含了簡單的Query的條件
其中一個測站點的資料類別
包含了測站名稱, 紫外線指數, 發布機關, 縣市, 經度, 緯度, 發布時間
接著利用左邊的過濾條件讓他只顯示臺北的紫外線指數並點選增加過濾條件以及顯示查詢結果
我們應該可以成功的過濾出臺北的紫外線指數
同時我們點擊上圖的顯示欄位設定過濾出測站位置與紫外線指數
我們即可得到過濾條件的顯示內容提供給你Query的網址的大致雛形
點選右方的XML按鈕除了可以得知XML的格式外,同時也可以得到以下類似的Query網址
http://opendata.epa.gov.tw/ws/Data/UV/?$filter=SiteName '臺北' &$select=SiteName,UVI&$orderby=PublishTime%20DESC&$skip=0&$top=1000&format=xml
但因為我們實作為單一地點回報,因此我們不需要排序或者跳過的條件
因此把網址後半段刪掉精簡成
http://opendata.epa.gov.tw/ws/Data/UV/?format=xml&$filter=SiteName eq '臺北' &$select=SiteName,UVI
應該可以成功得到所要的資料
但後半段因為資料擷取分段以csv格式較為簡單,因此我們後面的格式以csv為主
前面測試建議以XML或JSON測試擷取字串,不然就會下載一堆CSV檔唷XD
-----
第三部分就是開始如何寫Bot啦
首先開起Visual Studio 2015新增專案並選擇Bot Application(若沒有看到Bot Applicatiuon就表示最前面Zip檔放錯位置啦!!!
我們可以看到整個專案不是很大,最重要的兩個檔案就是MessagesController.cs與Web.config
MessagesController主要是處理Message的邏輯判斷,在V1的版本稱為Message,V3版本為Activity
我想應該是認為之後不一定bot只收Message而有可能像是圖片啦等等
因為原本判定是message.text,現在變成了activity.message
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
// calculate something for us to return
int length = (activity.Text ?? string.Empty).Length;
// return our reply to the user
Activity reply = activity.CreateReply($"You sent {activity.Text} which was {length} characters");
await connector.Conversations.ReplyToActivityAsync(reply);
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
題外話講完
現在開始實作
1.新增一個Class取名叫UV
程式碼如下
public static async Task<double?> GetUVAsync(string site)
{
string url = $"http://opendata.epa.gov.tw/ws/Data/UV/?&$format=csv&$filter=SiteName%20eq%20%27{site}%27&$select=SiteName,UVI";
string csv;
using (WebClient client = new WebClient())
{
csv = await client.DownloadStringTaskAsync(url).ConfigureAwait(false);
}
string line = csv.Split(',')[2];
string UVI = line.Split('\r')[0];
double UVIresult;
if (double.TryParse(UVI, out UVIresult))
return UVIresult;
return null;
}
上圖簡單來說就是以WebClient從政府開放資料平台撈資料下來
url裡面的site就是我們要輸入的地點,也別忘了剛剛我們的資料擷取網址格式是XML,記得改成CSV唷
由於我們用的是CSV,照理下載下來的格式內容會像
SiteName | UVI |
臺北 | 7.61 |
但程式的字串應像"SiteName,UVI\r\n臺北,7.61\r\n"
因此後半段就是處理字串切割指得到7.61數值的部分
2.MessagesController
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
// calculate something for us to return
// return our reply to the user
Activity reply = activity.CreateReply(await GetUV(activity.Text));
await connector.Conversations.ReplyToActivityAsync(reply);
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private async Task<string> GetUV(string strUV)
{
string strRet = string.Empty;
double? dbSite = await UV.GetUVAsync(strUV);
if (null == dbSite)
{
strRet = string.Format("地點: \"{0}\"不是一個正確的測站地點", strUV.ToUpper());
}
else
{
strRet = string.Format("地點:{0} 所測得的紫外線指數為 {1}", strUV.ToUpper(), dbSite);
}
return strRet;
}
上圖的程式碼簡單來說
第一部分當Bot收到查詢的字串後CreateReply,當然因為後端需要撈資料所以是以Async Await的非同步方式實作
第二部分則是判定當回傳的數值是不是null,來判定要回傳的內容是什麼
這樣子就完成啦!!!
接著就是開始Run啦
同時也打開Microsoft Bot Framework Channel Emulator
要注意的是上方的輸入值
LocalPort指的是Emulator的監聽Port(預設9000)
所以與Emulator Url是相同的Port(預設localhost:9000)
BotUrl則是你程式跑起來的API接口的部分,會與IIS Express的Port相同(預設localhost:3979/api/messages)
(P.S.)若出現500 Internal Server error可能就會是你Port不對囉
Microsoft App ID與Microsoft App Password則參考自己專案的Web.config
<appSettings>
<!-- update these with your BotId, Microsoft App Id and your Microsoft App Password-->
<add key="BotId" value="" />
<add key="MicrosoftAppId" value="" />
<add key="MicrosoftAppPassword" value="" />
</appSettings>
預設是空白的,於是Emulator上的兩個欄位也是要空白的
因此最後在下方輸入"臺北"即可得到及時的紫外線指數值囉
下一篇則會介紹
如何註冊在Microsoft Bot Framwork註冊自己的Bot
並利用Bot Connector與Facebook Messenger API對接實作出FB Messenger Bot
連結在此
[Bot] 利用Bot Connector服務連結Bot Application實作Facebook Messenger Bot
- 文章中的敘述或資訊有誤,歡迎回應指正,討論與指教是進步的原動力:)
- 若喜歡此點部落文章,歡迎各位轉載並於文末附載原文網址超連結與站名【DriftMind】