第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 如果这篇文章对你有帮助,就大力追踪和拍手鼓掌下去吧 !!
<<: Day-28 了解 Namespace 与 Rbac
线性串列的循环链式储存 定义 线性串列的链式结构,尾节点的指标会指回首节点 优缺 优点: 任一节点都...
想要利用接下来的几篇文章把tree-based的模型稍微介绍一下,所有的tree-based模型基本...
这个得上一篇:https://ithelp.ithome.com.tw/articles/10258...
Gradle 的核心是由 Java 实作,但为了提供更好扩充的语法,Gradle 一开始使用 Gro...
今天要来进入到生命周期的第二个环节: Updating 更新,继上篇的 Mounting 元件挂载...