在這一篇,我們將透過機器人回覆方式取得對話相關資訊、設定新 WebAPI 取得天氣資訊後回傳、透過 Azure 排程器測試是否成功。話不多說,趕緊來實作。
當需要傳遞訊息給某位使用者時,必定需要一些辨識資訊,才能正確地指定使用者收到資訊。在撰寫程式之前,我們需要更多的資訊……。 透過 Bot Template 新增的專案,我們 Ctrl + 滑鼠左鍵點開 Activity 這個類別:
似乎有 ChannelId, From, Conversation 與 Recipient…這些識別資訊可以使用。
我們將 RootDialog.cs 內的 MessageReceivedAsync 方法更改如下,並將程式放上 Azure Web Application,進行測試,檢視會得到什麼資訊:
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
// return our reply to the user
await context.PostAsync($"ChannelId:{activity.ChannelId} " +
$"ChannelData:{activity.ChannelData} " +
$"Id:{activity.Id} " +
$"ServiceUrl:{activity.ServiceUrl} " +
$"Summary:{activity.Summary} " +
$"Text:{activity.Text} " +
$"TopicName:{activity.TopicName} " +
$"Action:{activity.Action} " +
$"AttachmentLayout:{activity.AttachmentLayout} " +
$"Conversation.Id:{activity.Conversation.Id} " +
$"Conversation.IsGroup:{activity.Conversation.IsGroup} " +
$"Conversation.Name:{activity.Conversation.Name} " +
$"From.Id:{activity.From.Id} " +
$"From.Name:{activity.From.Name} " +
$"HistoryDisclosed:{activity.HistoryDisclosed} " +
$"ReplyToId:{activity.ReplyToId} " +
$"Properties:{activity.Properties} " +
$"TextFormat:{activity.TextFormat} " +
$"Timestamp:{activity.Timestamp} " +
$"Type:{activity.Type} " +
$"Recipient.Id:{activity.Recipient.Id} " +
$"Recipient.Name:{activity.Recipient.Name} ");
context.Wait(MessageReceivedAsync);
}
我們可得到對話許多資訊,我們需要記下Recipient.Id 、From.Id 與 Conversation.Id
大致上彙整需要的參數:
參數 | 描述 | 型態 |
---|---|---|
From | 傳送者 (從誰傳出) | ChannelAccount |
Recipient | 接受者 (誰接受資訊) | ChannelAccount |
Conversation | (哪一個對話) | ConversationAccount |
ChannelAccount 物件內容如下:
變數名稱 | 型態 |
---|---|
Id | string |
Name | string |
ConversationAccount 物件內容如下:
變數名稱 | 型態 |
---|---|
Id | string |
Name | string |
IsGroup | bool? |
Step 1. 在MessageController.cs 內我們新增一個 API,名稱為 GetWeatherInformation (與上一篇Azure 排程器呼叫位置相同)
[HttpGet]
[Route("GetWeatherInformation")]
public async Task<HttpResponseMessage> GetWeatherInformation()
{
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
Step 2. 我們需要一個 ConnectorClient 連線到 skype 服務的 endpoint。除了位置外,您還需要機器人程式的 App Id 與 App Password
註:請透過 MicrosoftAppCredentials.TrustServiceUrl 加上欲使用服務的URL
MicrosoftAppCredentials.TrustServiceUrl("https://skype.botframework.com");
var connector = new ConnectorClient(new Uri("https://skype.botframework.com"), "MicrosoftAppId", "MicrosoftAppPassword");
Step 3. 接下來,我們需要建立一個message activity,並將從先前取得的 Recipient.Id 、From.Id 與 Conversation.Id 放入相對的位置。
IMessageActivity newMessage = Activity.CreateMessageActivity();
newMessage.Type = ActivityTypes.Message;
newMessage.From = new ChannelAccount("Your From Id", "Miniature Schnauzer");
newMessage.Conversation = new ConversationAccount(null, "Your Conversation Id", null);
newMessage.Recipient = new ChannelAccount("Your RecipientId", "Duran");
Step 4. 將我們之前天氣服務機器人的程式碼放入並做些修整
Step 4.1 專案內加入Messages新資料夾 → Messages 資料夾內加入 Responses 資料夾 → 建立一個 WeatherResponse.cs 程式,將相關 DTO 放入。
你的 WeatherResponse.cs 內容應該如下:
using System.Collections.Generic;
namespace InformationBotApplication.Messages.Responses
{
public class WeatherResponse
{
public string success { get; set; }
public Result result { get; set; }
public Records records { get; set; }
}
public class Field
{
public string id { get; set; }
public string type { get; set; }
}
public class Result
{
public string resource_id { get; set; }
public List<Field> fields { get; set; }
}
public class Parameter
{
public string parameterName { get; set; }
public string parameterValue { get; set; }
public string parameterUnit { get; set; }
}
public class Time
{
public string startTime { get; set; }
public string endTime { get; set; }
public Parameter parameter { get; set; }
}
public class WeatherElement
{
public string elementName { get; set; }
public List<Time> time { get; set; }
}
public class Location
{
public string locationName { get; set; }
public List<WeatherElement> weatherElement { get; set; }
}
public class Records
{
public string datasetDescription { get; set; }
public List<Location> location { get; set; }
}
}
Step 4.2 取得氣象資訊服務程式 放入 GetWeatherInformation 內:
註:記得安裝 RestSharp 套件
var client = new RestClient("http://opendata.cwb.gov.tw");
var request = new RestRequest("api/v1/rest/datastore/F-C0032-001?Authorization=CWB-xxxx-xxxxx-xxxxx&locationName=臺北市&elementName=Wx,PoP", Method.GET);
var weatherResponse= await client.ExecuteTaskAsync<WeatherResponse>(request);
var weather = weatherResponse.Data.records.location[0].weatherElement[0].time[1].parameter.parameterName;
var rainPercentage = weatherResponse.Data.records.location[0].weatherElement[1].time[1].parameter.parameterName;
Step 5. 將氣象資料放入回傳資料 newMessage.Text 內,透過 await connector.Conversations.SendToConversationAsync((Activity)newMessage); 將資訊發出。
newMessage.Text = $"天氣:{weather},降雨機率{rainPercentage}";
await connector.Conversations.SendToConversationAsync((Activity)newMessage);
您的整個 GetWeatherInformation 如下
[HttpGet]
[Route("api/GetWeatherInformation")]
public async Task<HttpResponseMessage> GetWeatherInformation()
{
MicrosoftAppCredentials.TrustServiceUrl("https://skype.botframework.com");
var connector = new ConnectorClient(new Uri("https://skype.botframework.com"), "MicrosoftAppId", "MicrosoftAppPassword");
IMessageActivity newMessage = Activity.CreateMessageActivity();
newMessage.Type = ActivityTypes.Message;
newMessage.From = new ChannelAccount("Your From Id", "Miniature Schnauzer");
newMessage.Conversation = new ConversationAccount(null, "Your Conversation Id", null);
newMessage.Recipient = new ChannelAccount("Your RecipientId", "Duran");
var client = new RestClient("http://opendata.cwb.gov.tw");
var request = new RestRequest("api/v1/rest/datastore/F-C0032-001?Authorization=CWB-xxxxxx-xxxxx&locationName=臺北市&elementName=Wx,PoP", Method.GET);
var weatherResponse = await client.ExecuteTaskAsync<WeatherResponse>(request);
var weather = weatherResponse.Data.records.location[0].weatherElement[0].time[1].parameter.parameterName;
var rainPercentage = weatherResponse.Data.records.location[0].weatherElement[1].time[1].parameter.parameterName;
newMessage.Text = $"天氣:{weather},降雨機率{rainPercentage}";
await connector.Conversations.SendToConversationAsync((Activity)newMessage);
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
Step 6.啟動程式,輸入測試網址 http://localhost:3979/api/GetWeatherInformation
註:你的測試網址可能有所不同,請依據啟動專案後開啟的網址進行調整
Step 7. 上傳 Azure Web Application,我們透過 Azure 排程器立即執行進行測試,也非常順利。