iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 14
0
Modern Web

宅男的浪漫 - 用 .NET Core 打造 Line 婚禮聊天機器人經驗分享系列 第 14

Line 的圖文選單

第12 屆iT邦幫忙鐵人賽系列文章 (Day14)

在 Line 的官方帳號可以設定進入時的選單,讓使用者快速點選,設定方式可以從官方帳號後台(有既定的範本可以參考),或者是用程式自己指定(可以自己控制圖片的座標&設定點選區塊),以下分別介紹

從官方帳號後台

這應該是最方便的方式了,Line 已經提供了一些範本和設計規範,只要照著範本製作一個圖片,並設定每個區塊要觸發的事件,即可完成一個圖文選單

進入 https://manager.line.biz/ 選擇圖文選單 => 建立 => 設計規範 => 下載範本,(或者直接點此下載),下載後會是一個壓縮檔,今天來用這個範例做修改

我們用 PhotoShop 改成我們要的圖片 (這就不介紹啦)
https://imgur.com/ev4LQzp.jpg

上傳圖片,並設定 A.B.C 所要觸發的文字

這樣就完成了,是不是很方便阿

從程式指定 Rich Menu

程式就沒有用 Business 後台直接上傳圖片來得那麼方便,但程式可以做到極彈性,它可以自訂圖片的座標來設定 click 的範圍,可以針對使用者來動態的切換 Rich Menu 等等…。Rich Menu 所牽扯的 Api 有點多,故先整理今天會實作的 Api 清單如下

Get rich menu list:取得此 chatbot 已註冊的 Rich Menu 清單
Upload rich menu image:設定 Rich Menu 的圖片
Set default rich menu:設定所檢視的 Rich Menu

新增 LineRichMenuUtility.cs

之前 Message API 我們做了 一個 Utility ,Rich Menu 我們也新增一個

public class LineRichMenuUtility

{

private readonly string accessToken;

private static string lineMessageApiBaseUrl = "https://api.line.me/v2/bot/richmenu";

private static string lineMessageApiBaseUrlForAllUser = "https://api.line.me/v2/bot/user/all/richmenu";

public LineRichMenuUtility(IOptions<LineSetting> lineSetting)

{

accessToken = lineSetting.Value.ChannelAccessToken;

}

....

}

Get rich menu list:取得此 chatbot 已註冊的 Rich Menu 清單

RichMenuResponse 這個 class 內容來自於這個文件

public async Task<RichMenuResponse> GetRichMenuListAsync()

{

using (var httpClient = new HttpClient())

{

using (var request = new HttpRequestMessage(new HttpMethod("GET"), $"{lineMessageApiBaseUrl}/list"))

{

request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {accessToken}");

var response = await httpClient.SendAsync(request);

var result = await response.Content.ReadAsStringAsync();

var richMenuRes = JsonConvert.DeserializeObject<RichMenuResponse>(result);

return richMenuRes;

}

}

}

Upload rich menu image:設定 Rich Menu 的圖片

public async Task UploadRichMenuImage(string imgUrl, string richMenuId)

{

using (var httpClient = new HttpClient())

{

using (var request = new HttpRequestMessage(new HttpMethod("POST"), $"lineMessageApiBaseUrl/{richMenuId}/content"))

{

request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {accessToken}");

var imgBytes = GetImage(imgUrl);

request.Content = new ByteArrayContent(imgBytes);

request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

var response = await httpClient.SendAsync(request);

var results = await response.Content.ReadAsStringAsync();

};

}

}

private byte[] GetImage(string url)

{

var request = (HttpWebRequest)WebRequest.Create(url);

var response = (HttpWebResponse)request.GetResponse();

using (Stream dataStream = response.GetResponseStream())

{

if (dataStream == null)

return null;

using (var sr = new BinaryReader(dataStream))

{

byte[] bytes = sr.ReadBytes(100000000);

return bytes;

}

}

}

Set default rich menu:設定預設的 Rich Menu

CreateRichmenu 這個 class 內容來自於這個文件

自己用程式定義的麻煩點就在這,要設長寬和這種座標與Action,但未來可以考慮將一些常用範本用程式封裝起來,直接使用

public async Task<Richmenu> SetDefaultRichMenuAsync()

{

using (var httpClient = new HttpClient())

{

using (var request = new HttpRequestMessage(new HttpMethod("POST"), lineMessageApiBaseUrl))

{

request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {accessToken}");

var defaultRichMenu = new CreateRichmenu();

defaultRichMenu.size = new CreateSize(1200, 810);

defaultRichMenu.selected = true;

defaultRichMenu.name = "Default RichMenu";

defaultRichMenu.chatBarText = "Kyle's Wedding";

defaultRichMenu.areas = new List<CreateArea>()

{

new CreateArea(boundx:0,boundy:0,width:800,height:810, _action: new MessageAction("婚紗輪播"))

};

var postJson = JsonConvert.SerializeObject(defaultRichMenu, new JsonSerializerSettings

{

NullValueHandling = NullValueHandling.Ignore,

ContractResolver = new DefaultContractResolver

{

NamingStrategy = new CamelCaseNamingStrategy()

}

});

request.Content = new StringContent(postJson);

request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

var response = await httpClient.SendAsync(request);

var results = await response.Content.ReadAsStringAsync();

var richmenu = JsonConvert.DeserializeObject<Richmenu>(results);

return richmenu;

};

}

}

Set default rich menu:設定所"指定"的 Rich Menu

public async Task SetDefaultRichMenuAsync(string richId)

{

using (var httpClient = new HttpClient())

{

using (var request = new HttpRequestMessage(new HttpMethod("POST"), $"{lineMessageApiBaseUrlForAllUser}/{richId}"))

{

request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {accessToken}");

var response = await httpClient.SendAsync(request);

var results = await response.Content.ReadAsStringAsync();

}

}

}

回到 Api Controller,我們在 app 啟動的時候給設定 Rich Menu

InitRichMenu 實作

public async Task InitRickMenu()

{

var rickResponse = await lineRichMenuUtility.GetRichMenuListAsync();

if(rickResponse.richmenus.Count == 0)

{

// 沒有取到任何 Rich Menu,設定預設

var richMenu = await lineRichMenuUtility.SetDefaultRichMenuAsync();

await lineRichMenuUtility.UploadRichMenuImage("https://i.imgur.com/ev4LQzp.jpg", richMenu.richMenuId);

}

else

{

// 取得預設並設定該 Rich Menu

var defaultRich = rickResponse.richmenus.First(c => c.name == "Default RichMenu");

await lineRichMenuUtility.SetDefaultRichMenuAsync(defaultRich.richMenuId);

}

懶人包,本次學到了什麼?

本篇文章同步發佈於我的 Medium 如果這篇文章對你有幫助,就大力追蹤和拍手鼓掌下去吧 !!


上一篇
各種訊息都玩過了,來聊聊使用者體驗 (Quick Reply)
下一篇
切換 Line 的圖文選單
系列文
宅男的浪漫 - 用 .NET Core 打造 Line 婚禮聊天機器人經驗分享30

尚未有邦友留言

立即登入留言