IT邦 2022鐵人賽 .NET 6 C# & Line Services 串接
Hello 各位好,本篇要介紹的是 Imagemap message,從 Imagemap 開始,後面要介紹的訊息與前面幾個相比都複雜非常多,會盡量將各個面向都介紹到的,馬上開始!
Imagemap 是一個以圖片為基礎,可以在圖片上面設定多個可點擊區域並且指定點擊時產生事件的訊息,而一張圖片最多可以設置 50 個可點擊區域。
另外,Imagemap 也可以在圖片上嵌入一個影片,並放置一個超連結給這部影片。
首先給各位看幾個 Imagemap 的實際應用
星巴克將 Imagemap 用作選單,使用透明背景提高圖片泛用性。
路易莎將 Imagemap 用作活動行銷,圖片上方說明活動內容,下方提供訂餐與分享按鈕來提高活動的觸及率。
CoCo 使用 Imagemap 製作了一系列的心理測驗與飲料推薦遊戲,提高使用者與其LineBot互動的趣味性。
從這幾個例子可以得知 Imagemap 的用途非常廣泛。
在 Imagemap 上可使用的 action 有以下兩個
Message Action
此動作執行後,使用者會傳送 Text 屬性帶入的文字給 Line Bot
URI Aciton
此動作執行後,會開啟 LinkUri 屬性帶入的網址
值得一提的是,Line 有提供一系列的 url schema,使得 uri action 也能夠做到許多動作,也就是這個功能使 Imagemap 完全不輸之後要介紹的幾種訊息
Area 是用來定義區域範圍的 Class,根據坐標 XY 為左上角的起點,向右畫出 Width 長度,向下畫出 Height 長度的長方形範圍。
namespace LineBotMessage.Dtos
{
public class ImagemapActionDto
{
public string Type { get; set; }
public string? Label { get; set; }
// Message action
public string? Text { get; set; }
// Uri action
public string? LinkUri { get; set; }
public ImagemapAreaDto Area { get; set; }
}
}
using LineBotMessage.Enum;
namespace LineBotMessage.Dtos
{
public class ImagemapMessageDto : BaseMessageDto
{
public ImagemapMessageDto()
{
Type = MessageTypeEnum.Imagemap;
}
public string BaseUrl { get; set; }
public string AltText { get; set; }
public ImagemapBaseSizeDto BaseSize { get; set; }
public ImagemapVideoDto? Video { get; set; }
public List<ImagemapActionDto> Actions { get; set; }
}
public class ImagemapBaseSizeDto
{
public int Width { get; set; }
public int Height { get; set; }
}
public class ImagemapVideoDto
{
public string OriginalContentUrl { get; set; }
public string PreviewImageUrl { get; set; }
public ImagemapAreaDto Area { get; set; }
public ImagemapVideoExternalLinkDto ExternalLink { get; set; }
}
public class ImagemapAreaDto
{
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
}
public class ImagemapVideoExternalLinkDto
{
public string LinkUri { get; set; }
public string Label { get; set; }
}
}
case MessageTypeEnum.Imagemap:
messageRequest = _jsonProvider.Deserialize<BroadcastMessageRequestDto<ImagemapMessageDto>>(strBody);
break;
根據文件內容,一個 Imagemap 的圖片需要準備5種不同寬度的尺寸,分別是 240px、300px、460px、700px、1040px,並且是 JPEG 或 PNG 格式,並且將5張圖片放入同一個資料夾後將副檔名刪除,最後傳送 Imagemap 訊息時的 BaseUrl 帶到存放圖片的資料夾名稱即可,Line 會依據使用者裝置的大小選擇要載入哪種寬度的圖片,並將這個 Request 送給我們的伺服器。
例如 : (5張圖片放在 UploadFiles/ImagemapImages/DemoImage 中)
------ 以上是官方提供的方法 ------
不過,因為 .NET 機制的關係,不容易實現這種機制,並且想要有個通道控制其圖片的傳輸,所以我這邊決定另外實作一個 Controller 去負責這個圖片的 Request。
在 UploadFiles 中新增 ImagemapImages 資料夾
再新增一個 DemoImage 資料夾放入準備好的 5 種寬度的圖片(不用刪除副檔名) 範本圖片連結。
在 Controllers 資料夾新增 FileController.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.StaticFiles;
namespace LineBotMessage.Controllers
{
[Route("api/[Controller]")]
[ApiController]
public class FileController : ControllerBase
{
private readonly IConfiguration _configuration;
public FileController(IConfiguration configuration)
{
_configuration = configuration;
}
/// <summary>
/// Only for Imagemap message 讀取圖片
/// </summary>
/// <param name="folderName"></param>
/// <param name="imageSize"></param>
/// <returns></returns>
[HttpGet("UploadFiles/ImagemapImages/{folderName}/{imageSize}")]
public IActionResult GetImagemapImage(string folderName, string imageSize)
{
//FileStream fs = new FileStream();
var path = $"{_configuration.GetValue<string>(WebHostDefaults.ContentRootKey)}/UploadFiles/ImagemapImages/{folderName}/{imageSize}.png";
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
var fileBytes = System.IO.File.ReadAllBytes(path);
new FileExtensionContentTypeProvider().TryGetContentType(Path.GetFileName(path), out var contentType);
return new FileContentResult(fileBytes, contentType ?? "application/octet-stream");
}
}
}
}
使用 Swagger 廣播測試
沒有嵌入影片的 Imagemap Json Body
{
"Messages": [
{
"Type": "imagemap",
"BaseUrl": "{ngrok 位置}/api/File/UploadFiles/ImagemapImages/DemoImage",
"AltText": "This is an imagemap",
"BaseSize": {
"width": 1040,
"Height": 1040
},
"Actions": [
{
"Type": "message",
"Text": "查看商品1",
"Area": {
"X": 0,
"Y": 0,
"Width": 520,
"Height": 520
}
},
{
"Type": "uri",
"LinkUri": "https://www.appx.com.tw/newcourse",
"Area": {
"X": 520,
"Y": 0,
"Width": 520,
"Height": 520
}
},
{
"Type": "uri",
"LinkUri": "https://www.appx.com.tw/lecture",
"Area": {
"X": 0,
"Y": 520,
"Width": 520,
"Height": 520
}
},
{
"Type": "message",
"Text": "查看商品4",
"Area": {
"X": 520,
"Y": 520,
"Width": 520,
"Height": 520
}
}
]
}
]
}
廣播結果,各位自行測試點擊效果是否跟傳送的 Json 設定一樣。
嵌入影片的 Imagemap 會將影片蓋到圖片上方,我這邊將影片位置放在上半部商品1、2的範圍。
{
"Messages": [
{
"Type": "imagemap",
"BaseUrl": "{ngrok 位置}/File/UploadFiles/ImagemapImages/DemoImage",
"AltText": "This is an imagemap",
"BaseSize": {
"width": 1040,
"Height": 1040
},
"Video": {
"OriginalContentUrl": "{ngrok 位置}/UploadFiles/video1.mp4",
"PreviewImageUrl": "{ngrok 位置}/UploadFiles/appx.png",
"Area": {
"X": 0,
"Y": 0,
"Width": 1040,
"Height": 520
},
"ExternalLink": {
"LinkUri": "https://www.appx.com.tw",
"Label": "See More"
}
},
"Actions": [
{
"Type": "uri",
"LinkUri": "https://www.appx.com.tw",
"Area": {
"X": 0,
"Y": 520,
"Width": 520,
"Height": 520
}
},
{
"Type": "message",
"Text": "Hello",
"Area": {
"X": 520,
"Y": 520,
"Width": 520,
"Height": 520
}
}
]
}
]
}
Imagemap 介紹就到這邊結束了,如果照著訊息順序介紹下去的話下一篇應該要介紹的是 template message,不過既然這篇已經使用到了 message action 和 uri action,那下一篇就把 line actions 補上,正好 template 也會用到 line action 的功能,所以在介紹 template message 之前先插入 line actions 介紹~下一篇見。
如果想要參考今天範例程式碼的部份,下面是 Git Repo 連結,方便大家參考。