第12 屆iT邦幫忙鐵人賽系列文章 (Day14)
在 Line 的官方帳號可以設定進入時的選單,讓使用者快速點選,設定方式可以從官方帳號後台(有既定的範本可以參考),或者是用程式自己指定(可以自己控制圖片的座標&設定點選區塊),以下分別介紹
這應該是最方便的方式了,Line 已經提供了一些範本和設計規範,只要照著範本製作一個圖片,並設定每個區塊要觸發的事件,即可完成一個圖文選單
進入 https://manager.line.biz/ 選擇圖文選單 => 建立 => 設計規範 => 下載範本,(或者直接點此下載),下載後會是一個壓縮檔,今天來用這個範例做修改
我們用 PhotoShop 改成我們要的圖片 (這就不介紹啦)
https://imgur.com/ev4LQzp.jpg
上傳圖片,並設定 A.B.C 所要觸發的文字
這樣就完成了,是不是很方便阿
程式就沒有用 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
之前 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);
}
如何取得所有 Rich Menu
https://developers.line.biz/en/reference/messaging-api/#get-rich-menu-list
如何上傳 Rich Menu 的圖片
https://developers.line.biz/en/reference/messaging-api/#upload-rich-menu-image
如何設定 Rich Menu 圖片
https://developers.line.biz/en/reference/messaging-api/#set-default-rich-menu
本篇文章同步發佈於我的 Medium 如果這篇文章對你有幫助,就大力追蹤和拍手鼓掌下去吧 !!