第12 屆iT邦幫忙鐵人賽系列文章 (Day29)
在上一篇我們用 Console App 發送訊息到 Api 的 Server Hub,並呈現在HTML上,今天這篇我們要來結合 chatbot,其實就是在chatbot當成SignalR的client而已,實際效果如下(本篇不會介紹CSS部分):
新增一個 MessageBoard class 來處理留言板發送,這部分可以看這篇
而透過 Line 的 User Id ,我們能取得使用者的大頭照.姓名…等等資訊
public async Task ReplyAsync(string replyToken)
{
var profile = await lineProfileUtility.GetUserProfile(userId);
var hubClient = new ClientSignalR();
await hubClient.Initialize("http://localhost:12733/message");
await hubClient.SendHubMessage("SendMessage", profile.pictureUrl, profile.displayName, message);
await lineMessageUtility.ReplyMessageAsync(replyToken, "謝謝您,我們已收到留言");
}
GetUserProfile
public async Task<UserProfile> GetUserProfile(string userId)
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("GET"), $"{lineMessageApiBaseUrl}/{userId}"))
{
request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {accessToken}");
var response = await httpClient.SendAsync(request);
if(response.StatusCode != HttpStatusCode.OK)
{
// 這邊未來應該要 log 起來
throw new Exception("get_profile_error");
}
var result = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<UserProfile>(result);
}
}
}
HTML 部分
這邊是用JavaScript去塞DOM,如果用主流框架Angular/Vue/React寫起來應該更簡潔~
document.addEventListener('DOMContentLoaded', function () {
// 建立連線
var connection = new signalR.HubConnectionBuilder()
.withUrl('/message') //因為是同個網域,要視情況換成完成Server Hub的URL
.build();
// 開始連線
connection.start()
.then(function () {
console.log('連線成功...');
})
.catch(function (error) {
console.error(error.message);
});
bindConnectionMessage(connection);
// 呈現資料到Html
function createMessageEntry(imgUrl, encodedName, encodedMsg) {
var entry = document.createElement('li');
var html = '<a href="#"><div><div id="divcss5"><img src="' + imgUrl +'" />';
html += '<span class="displayName">' + encodedName+'</span>';
html += '</div></div><p>' + encodedMsg+'</p></a>';
entry.innerHTML = html;
console.log(html);
return entry;
}
// 監聽接收訊息事件
function bindConnectionMessage(connection) {
connection.on('CallBackMessage', function (imgUrl, displayName, message) {
if (!message) return;
var encodedName = displayName;
var encodedMsg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var messageEntry = createMessageEntry(imgUrl, encodedName, encodedMsg);
var messageBox = document.getElementById('messages');
messageBox.appendChild(messageEntry);
messageBox.scrollTop = messageBox.scrollHeight;
});
}
});
這樣就能完成即時用Line傳送的留言板了,但這個只是Demo,真正的話還是要審核一下訊息,不然把怪怪的訊息發送到大螢幕就不好啦。Azure SignalR Service 已經大大降低做即時通訊的開發門檻,透過這種服務就能去發想更多的應用!
本篇文章同步發佈於我的 Medium 如果這篇文章對你有幫助,就大力追蹤和拍手鼓掌下去吧 !!