今天要介紹如何取得用戶上傳的內容,到目前為止 Line Bot 只能接收文字訊息,那如果使用者傳的是圖片或影片呢,這篇就來看 Line Bot 還可以處理哪些訊息格式。
Message event:
message
。時效為 30 秒,只能使用一次
。text
。來源官方文件: #wh-text
程式碼:
protected override async Task OnMessageAsync(MessageEvent ev)
{
switch (ev.Message.Fix())
{
//文字訊息
case TextEventMessage textMessage:
{
await _messagingClient.ReplyMessageAsync(ev.ReplyToken,
$"收到的是文字訊息,內容: {textMessage.Text}");
}
break;
}
}
結果:
image
。line
: 訊息由使用者上傳,可以從 content 取得檔案。external
: 訊息由 liff.sendMessages()
方法送出,可從下列屬性取得檔案。來源官方文件: #wh-image
程式碼:
protected override async Task OnMessageAsync(MessageEvent ev)
{
switch (ev.Message.Fix())
{
//圖片訊息
case ImageEventMessage imageMessage:
{
if (imageMessage.ContentProvider.Type != ContentProviderType.Line)
break;
//取得檔案串流
using (var stream =
await _messagingClient.GetContentStreamAsync(imageMessage.Id))
{
//取得副檔名
var ext = GetFileExtension(
stream.ContentHeaders.ContentType.MediaType);
//儲存檔案
using (var fs =
File.Create($@"D:\home\site\wwwroot\App_Data\image{ext}"))
{
stream.CopyTo(fs);
}
await _messagingClient.ReplyMessageAsync(ev.ReplyToken,
$"收到的是圖片訊息\n" +
$"檔案名稱: image{ext}\n" +
$@"儲存路徑: D:\home\site\wwwroot\App_Data\image{ext}");
}
}
break;
}
}
沒辦法取得使用者上傳的檔名,只有 MediaType 可以用。
string GetFileExtension(string mediaType)
{
switch (mediaType)
{
case "image/jpeg":
return ".jpg";
case "audio/aac":
return ".aac";
case "video/mp4":
return ".mp4";
default:
return "";
}
}
結果:
video
。line
: 訊息由使用者上傳,可以從 content 取得檔案。external
: 訊息由 liff.sendMessages()
方法送出,可從下列屬性取得檔案。來源官方文件: #wh-video
程式碼:
protected override async Task OnMessageAsync(MessageEvent ev)
{
switch (ev.Message.Fix())
{
//影片訊息
case VideoEventMessage videoMessage:
{
if (videoMessage.ContentProvider.Type != ContentProviderType.Line)
break;
//取得檔案串流
using (var stream =
await _messagingClient.GetContentStreamAsync(videoMessage.Id))
{
//取得副檔名
var ext = GetFileExtension(
stream.ContentHeaders.ContentType.MediaType);
//儲存檔案
using (var fs =
File.Create($@"D:\home\site\wwwroot\App_Data\video{ext}"))
{
stream.CopyTo(fs);
}
await _messagingClient.ReplyMessageAsync(ev.ReplyToken,
$"收到的是影片訊息\n" +
$"Duration: {videoMessage.Duration}\n" +
$"檔案名稱: video{ext}\n" +
$@"儲存路徑: D:\home\site\wwwroot\App_Data\video{ext}");
}
}
break;
}
}
結果:
audio
。line
: 訊息由使用者上傳,可以從 content 取得檔案。external
: 訊息由 liff.sendMessages()
方法送出,可從下列屬性取得檔案。來源官方文件: #wh-audio
程式碼:
protected override async Task OnMessageAsync(MessageEvent ev)
{
switch (ev.Message.Fix())
{
//音訊訊息
case AudioEventMessage audioMessage:
{
if (audioMessage.ContentProvider.Type != ContentProviderType.Line)
break;
//取得檔案串流
using (var stream =
await _messagingClient.GetContentStreamAsync(audioMessage.Id))
{
//取得副檔名
var ext = GetFileExtension(
stream.ContentHeaders.ContentType.MediaType);
//儲存檔案
using (var fs =
File.Create($@"D:\home\site\wwwroot\App_Data\audio{ext}"))
{
stream.CopyTo(fs);
}
await _messagingClient.ReplyMessageAsync(ev.ReplyToken,
$"收到的是音訊訊息\n" +
$"Duration: {audioMessage.Duration}\n" +
$"檔案名稱: audio{ext}\n" +
$@"儲存路徑: D:\home\site\wwwroot\App_Data\audio{ext}");
}
}
break;
}
}
結果:
可以從 content 取得檔案。
file
。來源官方文件: #wh-file
程式碼:
protected override async Task OnMessageAsync(MessageEvent ev)
{
switch (ev.Message.Fix())
{
//檔案訊息
case FileEventMessage fileMessage:
{
//取得檔案串流
using (var stream =
await _messagingClient.GetContentStreamAsync(fileMessage.Id))
{
//取得副檔名
var ext = GetFileExtension(
stream.ContentHeaders.ContentType.MediaType);
//儲存檔案
using (var fs =
File.Create($@"D:\home\site\wwwroot\App_Data\{fileMessage.FileName}"))
{
stream.CopyTo(fs);
}
await _messagingClient.ReplyMessageAsync(ev.ReplyToken,
$"收到的是檔案訊息。\n" +
$"FileName: {fileMessage.FileName}\n" +
$"FileSize: {fileMessage.FileSize}\n" +
$@"儲存路徑: D:\home\site\wwwroot\App_Data\{fileMessage.FileName}");
}
}
break;
}
}
結果:
可以從 content 取得檔案。
location
。來源官方文件: #wh-location
程式碼:
protected override async Task OnMessageAsync(MessageEvent ev)
{
switch (ev.Message.Fix())
{
//位置訊息
case LocationEventMessage locationMessage:
{
await _messagingClient.ReplyMessageAsync(ev.ReplyToken,
$"收到的是位置訊息。\n" +
$"Title: {locationMessage.Title}\n" +
$"Address: {locationMessage.Address}\n" +
$"Latitude: {locationMessage.Latitude}\n" +
$"Longitude: {locationMessage.Longitude}");
}
break;
}
}
結果:
可以使用的 Line 貼圖清單。
sticker
。STATIC
、ANIMATION
、SOUND
、ANIMATION_SOUND
、POPUP
、POPUP_SOUND
、NAME_TEXT
來源官方文件: #wh-sticker
目前 SDK 沒有 stickerResourceType 屬性可以用,如果自己加需要改很多地方,所以就等作者更新吧。
程式碼:
protected override async Task OnMessageAsync(MessageEvent ev)
{
switch (ev.Message.Fix())
{
//貼圖訊息
case StickerEventMessage stickerMessage:
{
await _messagingClient.ReplyMessageAsync(ev.ReplyToken,
$"收到的是貼圖訊息。\n" +
$"Package: {stickerMessage.PackageId}\n" +
$"Sticker: {stickerMessage.StickerId}");
}
break;
}
}
結果:
不知道什麼原因作者把 ImageEvent、AudioEvent、VideoEvent 這三個物件,
合併成一個 MediaEvent,所以目前 GitHub 上的寫法是沒辦法使用的。
我自己寫了一個 Fix() 方法修正這件事。
/*
MIT License
Copyright (c) 2017 pierre3
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
namespace FixMessageEvent
{
public static class MessageEventExtension
{
public static EventMessage Fix(this EventMessage eventMessage)
{
switch (eventMessage)
{
case MediaEventMessage media:
{
if (media.Type == EventMessageType.Image)
return new ImageEventMessage(
media.Type,
media.Id,
media.ContentProvider,
media.Duration);
if (media.Type == EventMessageType.Video)
return new VideoEventMessage(
media.Type,
media.Id,
media.ContentProvider,
media.Duration);
if (media.Type == EventMessageType.Audio)
return new AudioEventMessage(
media.Type,
media.Id,
media.ContentProvider,
media.Duration);
}
break;
}
return eventMessage;
}
}
public class ImageEventMessage : MediaEventMessage
{
public ImageEventMessage(
EventMessageType type,
string id,
ContentProvider contentProvider = null,
int? duration = null
) : base(type, id, contentProvider, duration)
{
}
}
public class VideoEventMessage : MediaEventMessage
{
public VideoEventMessage(
EventMessageType type,
string id,
ContentProvider contentProvider = null,
int? duration = null
) : base(type, id, contentProvider, duration)
{
}
}
public class AudioEventMessage : MediaEventMessage
{
public AudioEventMessage(
EventMessageType type,
string id,
ContentProvider contentProvider = null,
int? duration = null
) : base(type, id, contentProvider, duration)
{
}
}
}
如果怕麻煩,也可以直接判斷 Message.Type
,作者的範例中大多使用這種寫法。
protected override async Task OnMessageAsync(MessageEvent ev)
{
switch (ev.Message.Type)
{
case EventMessageType.Text:
var textMessage = ev.Message as TextEventMessage;
break;
case EventMessageType.Image:
var imageMessage = ev.Message as MediaEventMessage;
break;
case EventMessageType.Audio:
var audioMessage = ev.Message as MediaEventMessage;
break;
case EventMessageType.Video:
var videoMessage = ev.Message as MediaEventMessage;
break;
case EventMessageType.File:
var fileMessage = ev.Message as FileEventMessage;
break;
case EventMessageType.Location:
var locationMessage = ev.Message as LocationEventMessage;
break;
case EventMessageType.Sticker:
var stickerMessage = ev.Message as StickerEventMessage;
break;
}
}
下一篇要介紹 LINE Bot 的邀請處理,今天就到這裡,感謝大家觀看。 (´・ω・`)