今天要介紹的是 Account Link,此功能可以將網站帳號和 LINE Bot 整合,讓用戶可以使用網站帳號操作 LINE Bot 功能,例如購物、查訂單等等。
兩者對帳號的應用是相反的。
POST https://api.line.me/v2/bot/user/{userId}/linkToken
GET https://access.line.me/dialog/bot/accountLink?
linkToken={linkToken}&nonce={nonce}
接下來我們就能透過 nonce 將網站帳號和 LINE userId 關聯在一起。
詳細說明可以參考 #account-link-sequence。
var flexMessage = new FlexMessage("AltText")
{
Contents = new BubbleContainer
{
Body = new BoxComponent
{
Layout = BoxLayout.Vertical,
Contents = new List<IFlexComponent>
{
new TextComponent
{
Text = "尚未綁定帳號",
Weight = Weight.Bold,
Size = ComponentSize.Md,
Align = Align.Center
}
}
},
Footer = new BoxComponent
{
Layout = BoxLayout.Vertical,
Contents = new List<IFlexComponent>
{
new ButtonComponent
{
Style = ButtonStyle.Primary,
Action = new PostbackTemplateAction("綁定帳號", "Link")
}
}
},
Styles = new BubbleStyles
{
Footer = new BlockStyle
{
Separator = true
}
}
}
};
await _messagingClient.ReplyMessageAsync(ev.ReplyToken,
new List<ISendMessage> { flexMessage });
protected override async Task OnPostbackAsync(PostbackEvent ev)
{
if (ev.Postback.Data == "Link")
{
//取得連接令牌
var token = await _messagingClient
.IssueLinkTokenAsync(ev.Source.UserId);
//回覆登入連結並帶上 linkToken
await _messagingClient.ReplyMessageAsync(ev.ReplyToken,
$"https://ibottestapi.azurewebsites.net/user/login?linkToken={token}");
}
}
[HttpGet("login")]
public IActionResult Login()
{
return View();
}
@model ViewModels.Login
@{
Layout = null;
}
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
</head>
<body>
<form method="post">
<div style="margin: 0px auto; text-align: center">
<div style="padding: 10px">
<span>帳號:</span>
<input type="text" asp-for="Account" />
</div>
<div style="padding: 10px">
<span>密碼:</span>
<input type="password" asp-for="Password" />
</div>
<div style="padding: 10px">
<input type="submit" value="登入" />
</div>
</div>
</form>
</body>
</html>
[HttpPost("login")]
public async Task<IActionResult> Login([FromForm]Login model,
[FromQuery] string linkToken)
{
//登入成功
if (model.Account == "abc" && model.Password == "123")
{
//產生隨機碼
var nonce = GenerateNonce();
//儲存隨機碼
var user = await _db.Users.Where(it => it.Account == "abc")
.FirstOrDefaultAsync();
user.Nonce = nonce;
user.UserId = "";
await _db.SaveChangesAsync();
//返回連結給用戶
return View("Link",
$"https://access.line.me/dialog/bot/accountLink?linkToken={linkToken}&nonce={nonce}");
}
return View(model);
}
//產生隨機碼
private static RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
private string GenerateNonce()
{
var bytes = new Byte[16];
rng.GetBytes(bytes);
return Convert.ToBase64String(bytes)
.Replace("=", "");
}
public class Login
{
public string Account { get; set; }
public string Password { get; set; }
}
@model string
@{
Layout = null;
}
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Link</title>
</head>
<body>
<div style="margin: 0px auto; text-align: center">
<a href="@Model">點擊連結完成帳號綁定</a>
</div>
</body>
</html>
protected override async Task OnAccountLinkAsync(AccountLinkEvent ev)
{
//綁定成功
if (ev.Link.Result == LinkResult.OK)
{
//儲存 LINE ID
var user = await _db.Users.Where(it => it.Nonce == ev.Link.Nonce)
.FirstOrDefaultAsync();
user.UserId = ev.Source.UserId;
await _db.SaveChangesAsync();
//回覆訊息
await _messagingClient.ReplyMessageAsync(ev.ReplyToken,
"帳號綁定完成!!");
}
}
LINE 規定使用 Account Link 必需提供取消鏈接的功能。
if (ev.Postback.Data == "UnLink")
{
//取消綁定
var user = await _db.Users.Where(it => it.UserId == ev.Source.UserId)
.FirstOrDefaultAsync();
user.Nonce = "";
user.UserId = "";
await _db.SaveChangesAsync();
}
下一篇要介紹 LINE Things,今天就到這裡,感謝大家觀看。 (´・ω・`)
如何讓 Chatbot 透過 Account Link 來串接使用者體驗