前面幾篇記錄了怎麼設定LINE Bot、架設Web API、申請LUIS和設定等
今天就把整個都串起來吧!
(上次LUIS好像是設定天氣..但我之前已經寫好的是匯率..只好先說聲抱歉啦!!)
Web API的部分除了之前LINE的部分之外,
我們還要把LINE收到的訊息送給LUIS分析,
分析完之後才知道User到底問了甚麼 我們要回甚麼~
對吧~ 那就 開始吧!!
微軟有提供SDK來給大家使用,
如果對SDK不了解怎麼使用的話(像我....)
請進入到NuGet 下載Mircrosoft.Congnitive.LUIS
已經下載完成的畫 到已安裝就會看的到~
下圖就是API的內容啦
其中NLPInfo 只用到了LUIS的appId和appkey
只要提供appId和appkey 產生LUIS的實體並呼叫predict Method 就可以幫你做語意分析
所以假如我們先不管GetResult到底分析了甚麼結果,
可以看到會回傳一個ReplyMessage,再將該訊息傳到原本LINEBot裡面
這樣就完成了 回應使用者了
public class LineBotWithLUISController : ApiController
{
BotRepository db = new BotRepository();
public async Task<IHttpActionResult> Post()
{
try
{
//Get Message
string postData = Request.Content.ReadAsStringAsync().Result;
var RequestBody = isRock.LineBot.Utility.Parsing(postData);
string Message = RequestBody.events[0].message.text;
//取得LUIS的相關設定值
NLPInfo LUISInfo = db.GetNLPInfo("LineBotNLP");
//Send to Analysis
Microsoft.Cognitive.LUIS.LuisClient lc
= new Microsoft.Cognitive.LUIS.LuisClient(LUISInfo.appid, LUISInfo.appKey, true);
var AnalysisResult = await lc.Predict(Message);
//Get Reply Message
string replyMessage = db.GetResult(AnalysisResult);
//Response Message
string ChannelAccessToken = db.GetBotToken("Line");
isRock.LineBot.Utility.ReplyMessage(RequestBody.events[0].replyToken, replyMessage, ChannelAccessToken);
return Ok();
}
catch (Exception ex)
{
string errorMessage = string.Format("ErrorMessage:{0},ErrorStack:{1},InnerExcepton:",
ex.Message,
ex.StackTrace,
ex.InnerException);
db.InsertRequestLog(errorMessage);
return Ok(errorMessage);
}
}
}
因為LUIS回傳回來的物件 大概是長這樣(來回憶一下前一篇的內容)
來看一下GetResult的內容,要怎麼判斷
首先根據上一張圖可以看到
1.intent :是有關User要問的問題
2.entities:有兩個,分別的type是Currency和AskQuantify
所以根據intent和entities就可以抓出 User想要問甚麼~
此時我們只要根據這些內容來去資料庫抓資料就可以了
/// 判斷User查詢內容
/// <summary>
/// 判斷User查詢內容
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public string GetResult(Microsoft.Cognitive.LUIS.LuisResult analysisResult)
{
string Default = "很抱歉,無法解析你所問的問題";
if (analysisResult == null)
{
return Default;
}
var intent = analysisResult.TopScoringIntent;
var enitiesDictinary = analysisResult.Entities;
IList<Microsoft.Cognitive.LUIS.Entity> entitiesCollection;
try
{
//TODO 要用設計模式比較好
if (intent.Name == "匯率查詢")
{
string CurName;
DateTime ExDate;
if (enitiesDictinary.TryGetValue("Currency", out entitiesCollection))
{
CurName = entitiesCollection.Select(o => o.Value).FirstOrDefault();
}
else
{
return Default;
}
if (enitiesDictinary.TryGetValue("ExDate", out entitiesCollection))
{
DateTime.TryParse(entitiesCollection.Select(o => o.Value).FirstOrDefault(), out ExDate);
}
else
{
ExDate = DateTime.Today;
}
return GetCurrencyExRate(CurName, ExDate);
}
else
{
return Default;
}
}
catch (Exception ex)
{
return Default;
}
}
抓取資料庫的匯率就更簡單了,想必大家都會了吧
(別問我匯率怎麼來,可以做爬蟲可以手動建立..可以用LINEBot抓...)
private string GetCurrencyExRate(string CurrencyName, DateTime ExDate)
{
string currency = DB.CurInfo.AsQueryable()
.Where(o => o.CurChtName == CurrencyName)
.Select(o=>o.CurAbName).FirstOrDefault();
var ExRateObj = DB.ExRate.AsQueryable()
.Where(o=>o.Cur == currency)
.Select(o => new
{
BuyRate = o.ExBRate,
SellRate = o.ExSRate
}).FirstOrDefault();
return string.Format("{0} {1}匯率 : {4}買進{2} 賣出{3}",
CurrencyName,
ExDate.ToString("yyyyMMdd"),
ExRateObj.BuyRate.ToString("#.####"),
ExRateObj.SellRate.ToString("#.####"),
Environment.NewLine);
}
大致上就是這樣啦!!
結果大致上是這樣 根據不同的問法,也可以解析出正確的問題回答確切的答案
Code 已經放在GitHub上囉!!!
-----------------------------------------
有時在會走之前你就得跑
你不解決問題 就等問題解決你