public void Convert_TemplateMessageWithCustomIConfirmTemplate_ConvertedToConfirmTemplate() { TestTemplateMessage message = new TestTemplateMessage() { Template = new TestConfirmTemplate() }; ISendMessage[] messages = MessageConverter.Convert(new ISendMessage[] { message }); Assert.AreEqual(1, messages.Length); Assert.AreNotEqual(message, messages[0]); TemplateMessage templateMessage = messages[0] as TemplateMessage; Assert.AreEqual("AlternativeText", templateMessage.AlternativeText); ConfirmTemplate template = templateMessage.Template as ConfirmTemplate; Assert.AreEqual("ConfirmText", template.Text); MessageAction okAction = template.OkAction as MessageAction; Assert.AreEqual("MessageLabel", okAction.Label); Assert.AreEqual("MessageText", okAction.Text); UriAction cancelAction = template.CancelAction as UriAction; Assert.AreEqual("UriLabel", cancelAction.Label); Assert.AreEqual(new Uri("tel://uri"), cancelAction.Url); }
public async Task ReplyTemplateMessageAsync(string replyToken, ConfirmTemplate template) { using (var httpClient = new HttpClient()) { using (var request = new HttpRequestMessage(new HttpMethod("POST"), $"{lineMessageReplyApiBaseUrl}")) { request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {accessToken}"); LineMessageReq req = new LineMessageReq(); req.ReplyToken = replyToken; req.Messages.Add(new TemplateMessageBase() { Template = template }); var postJson = JsonConvert.SerializeObject(req, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() }, Formatting = Formatting.Indented }); request.Content = new StringContent(postJson); request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); var response = await httpClient.SendAsync(request); var result = await response.Content.ReadAsStringAsync(); } } }
public void ShouldNotThrowExceptionWhenValueIsInvalidType() { var template = new ConfirmTemplate(); ExceptionAssert.Throws <NotSupportedException>("The action type is invalid.", () => { template.OkAction = new TestAction(); }); }
public void ShouldThrowExceptionWhenValueIsEmpty() { var template = new ConfirmTemplate(); ExceptionAssert.Throws <InvalidOperationException>("The text cannot be null or whitespace.", () => { template.Text = string.Empty; }); }
public void ShouldThrowExceptionWhenValueIsMoreThan240Chars() { var template = new ConfirmTemplate(); ExceptionAssert.Throws <InvalidOperationException>("The text cannot be longer than 240 characters.", () => { template.Text = new string('x', 241); }); }
public void OkAction_Null_ThrowsException() { ConfirmTemplate template = new ConfirmTemplate(); ExceptionAssert.Throws <InvalidOperationException>("The ok action cannot be null.", () => { template.OkAction = null; }); }
public void Text_MoreThan240Chars_ThrowsException() { ConfirmTemplate template = new ConfirmTemplate(); ExceptionAssert.Throws <InvalidOperationException>("The text cannot be longer than 240 characters.", () => { template.Text = new string('x', 241); }); }
public void Text_Empty_ThrowsException() { ConfirmTemplate template = new ConfirmTemplate(); ExceptionAssert.Throws <InvalidOperationException>("The text cannot be null or whitespace.", () => { template.Text = string.Empty; }); }
public void CancelAction_InvalidTemplateActionType_ThrowsException() { ConfirmTemplate template = new ConfirmTemplate(); ExceptionAssert.Throws <NotSupportedException>("The template action type is invalid. Supported types are: IPostbackAction, IMessageAction and IUriAction.", () => { template.CancelAction = new TestTemplateAction(); }); }
public void ShouldThrowExceptionWhenValueIsNull() { var template = new ConfirmTemplate(); ExceptionAssert.Throws <InvalidOperationException>("The ok action cannot be null.", () => { template.OkAction = null; }); }
public void ShouldNotThrowExceptionWhenValueIsInvalidType() { var template = new ConfirmTemplate(); ExceptionAssert.Throws <NotSupportedException>("The template action type is invalid. Supported types are: IPostbackAction, IMessageAction and IUriAction.", () => { template.OkAction = new TestTemplateAction(); }); }
public async Task HandleTextMessage() { var textMessage = JsonConvert.DeserializeObject <TextMessage>(lineEvent.Message.ToString()); Message replyMessage = null; if (textMessage.Text.ToLower() == "buttons") { List <TemplateAction> actions = new List <TemplateAction>(); actions.Add(new MessageTemplateAction("Message Label", "sample data")); actions.Add(new PostbackTemplateAction("Postback Label", "sample data", "sample data")); actions.Add(new UriTemplateAction("Uri Label", "https://github.com/kenakamu")); ButtonsTemplate buttonsTemplate = new ButtonsTemplate("https://github.com/apple-touch-icon.png", "Sample Title", "Sample Text", actions); replyMessage = new TemplateMessage("Buttons", buttonsTemplate); } else if (textMessage.Text.ToLower() == "confirm") { List <TemplateAction> actions = new List <TemplateAction>(); actions.Add(new MessageTemplateAction("Yes", "yes")); actions.Add(new MessageTemplateAction("No", "no")); ConfirmTemplate confirmTemplate = new ConfirmTemplate("Confirm Test", actions); replyMessage = new TemplateMessage("Confirm", confirmTemplate); } else if (textMessage.Text.ToLower() == "carousel") { List <TemplateColumn> columns = new List <TemplateColumn>(); List <TemplateAction> actions = new List <TemplateAction>(); actions.Add(new MessageTemplateAction("Message Label", "sample data")); actions.Add(new PostbackTemplateAction("Postback Label", "sample data", "sample data")); actions.Add(new UriTemplateAction("Uri Label", "https://github.com/kenakamu")); columns.Add(new TemplateColumn() { Title = "Casousel 1 Title", Text = "Casousel 1 Text", ThumbnailImageUrl = "https://github.com/apple-touch-icon.png", Actions = actions }); columns.Add(new TemplateColumn() { Title = "Casousel 2 Title", Text = "Casousel 2 Text", ThumbnailImageUrl = "https://github.com/apple-touch-icon.png", Actions = actions }); CarouselTemplate carouselTemplate = new CarouselTemplate(columns); replyMessage = new TemplateMessage("Carousel", carouselTemplate); } else if (textMessage.Text.ToLower() == "imagemap") { var url = HttpContext.Current.Request.Url; var imageUrl = $"{url.Scheme}://{url.Host}:{url.Port}/images/githubicon"; List <ImageMapAction> actions = new List <ImageMapAction>(); actions.Add(new UriImageMapAction("http://github.com", new ImageMapArea(0, 0, 520, 1040))); actions.Add(new MessageImageMapAction("I love LINE!", new ImageMapArea(520, 0, 520, 1040))); replyMessage = new ImageMapMessage(imageUrl, "GitHub", new BaseSize(1040, 1040), actions); } else { replyMessage = new TextMessage(textMessage.Text); } await Reply(replyMessage); }
public void ShouldNotThrowExceptionWhenValueIs240Chars() { string value = new string('x', 240); var template = new ConfirmTemplate() { Text = value }; Assert.AreEqual(value, template.Text); }
public void Text_240Chars_ThrowsNoException() { string value = new string('x', 240); ConfirmTemplate template = new ConfirmTemplate() { Text = value }; Assert.AreEqual(value, template.Text); }
public async Task <IList <IRequestMessage> > GetReplyMessagesAsync() { // tips: 您也可以傳入confirm的文字跟預期的actions var msg = new ConfirmTemplate(); await Task.CompletedTask; return(new List <IRequestMessage> { msg }); }
public void ShouldNotThrowExceptionWhenValueIsNotNull() { var action = new UriAction { Label = "testLabel2", Url = new Uri("http://www.bing.com") }; var confirmTemplate = new ConfirmTemplate { OkAction = action }; Assert.AreEqual(action, confirmTemplate.OkAction); }
public void ShouldThrowExceptionWhenTextIsNull() { ITemplate template = new ConfirmTemplate() { OkAction = new MessageAction(), CancelAction = new UriAction() }; ExceptionAssert.Throws <InvalidOperationException>("The text cannot be null.", () => { template.Validate(); }); }
public void ShouldThrowExceptionWhenCancelActionIsNull() { var template = new ConfirmTemplate() { Text = "ConfirmText", OkAction = new MessageAction() }; ExceptionAssert.Throws <InvalidOperationException>("The cancel action cannot be null.", () => { ConfirmTemplate.Convert(template); }); }
public void ShouldThrowExceptionWhenOkActionIsNull() { ITemplate template = new ConfirmTemplate() { Text = "ConfirmText", CancelAction = new UriAction() }; ExceptionAssert.Throws <InvalidOperationException>("The ok action cannot be null.", () => { template.Validate(); }); }
public async Task HandleTextMessage() { var textMessage = JsonConvert.DeserializeObject <TextMessage>(lineEvent.Message.ToString()); Message replyMessage = null; if (textMessage.Text.ToLower() == "buttons") { List <TemplateAction> actions = new List <TemplateAction>(); actions.Add(new MessageTemplateAction("Message Label", "sample data")); actions.Add(new PostbackTemplateAction("Postback Label", "sample data")); actions.Add(new UriTemplateAction("Uri Label", "https://github.com/kenakamu")); ButtonsTemplate buttonsTemplate = new ButtonsTemplate("https://github.com/apple-touch-icon.png", "Sample Title", "Sample Text", actions); replyMessage = new TemplateMessage("Buttons", buttonsTemplate); } else if (textMessage.Text.ToLower() == "confirm") { List <TemplateAction> actions = new List <TemplateAction>(); actions.Add(new MessageTemplateAction("Yes", "yes")); actions.Add(new MessageTemplateAction("No", "no")); ConfirmTemplate confirmTemplate = new ConfirmTemplate("Confirm Test", actions); replyMessage = new TemplateMessage("Confirm", confirmTemplate); } else if (textMessage.Text.ToLower() == "carousel") { List <TemplateColumn> columns = new List <TemplateColumn>(); List <TemplateAction> actions = new List <TemplateAction>(); actions.Add(new MessageTemplateAction("Message Label", "sample data")); actions.Add(new PostbackTemplateAction("Postback Label", "sample data")); actions.Add(new UriTemplateAction("Uri Label", "https://github.com/kenakamu")); columns.Add(new TemplateColumn() { Title = "Casousel 1 Title", Text = "Casousel 1 Text", ThumbnailImageUrl = "https://github.com/apple-touch-icon.png", Actions = actions }); columns.Add(new TemplateColumn() { Title = "Casousel 2 Title", Text = "Casousel 2 Text", ThumbnailImageUrl = "https://github.com/apple-touch-icon.png", Actions = actions }); CarouselTemplate carouselTemplate = new CarouselTemplate(columns); replyMessage = new TemplateMessage("Carousel", carouselTemplate); } else { replyMessage = new TextMessage(textMessage.Text); } await Reply(replyMessage); }
public void ShouldThrowExceptionWhenOkActionIsInvalid() { ITemplate template = new ConfirmTemplate() { Text = "ConfirmText", OkAction = new UriAction() { Label = "Foo" }, CancelAction = new MessageAction() }; ExceptionAssert.Throws <InvalidOperationException>("The url cannot be null.", () => { template.Validate(); }); }
public void ShouldNotThrowExceptionWhenValid() { ITemplate template = new ConfirmTemplate() { Text = "ConfirmText", OkAction = new MessageAction() { Label = "Foo", Text = "Bar" }, CancelAction = new MessageAction() { Label = "Foo", Text = "Bar" } }; template.Validate(); }
public void ShouldConvertCustomIConfirmTemplateToConfirmTemplate() { var template = new TestConfirmTemplate(); var confirmTemplate = ConfirmTemplate.Convert(template); Assert.AreEqual("ConfirmText", template.Text); var okAction = confirmTemplate.OkAction as MessageAction; Assert.AreEqual("MessageLabel", okAction.Label); Assert.AreEqual("MessageText", okAction.Text); var cancelAction = confirmTemplate.CancelAction as UriAction; Assert.AreEqual("UriLabel", cancelAction.Label); Assert.AreEqual(new Uri("tel://uri"), cancelAction.Url); }
public void Constructor_SerializedCorrectly() { ConfirmTemplate template = new ConfirmTemplate { Text = "Test", OkAction = new MessageAction() { Label = "OkLabel", Text = "OkText" }, CancelAction = new MessageAction() { Label = "CancelLabel", Text = "CancelText" } }; string serialized = JsonConvert.SerializeObject(template); Assert.AreEqual(@"{""type"":""confirm"",""text"":""Test"",""actions"":[{""type"":""message"",""label"":""OkLabel"",""text"":""OkText""},{""type"":""message"",""label"":""CancelLabel"",""text"":""CancelText""}]}", serialized); }
public void ShouldCreateSerializeableObject() { var template = new ConfirmTemplate { Text = "Test", OkAction = new MessageAction() { Label = "OkLabel", Text = "OkText" }, CancelAction = new MessageAction() { Label = "CancelLabel", Text = "CancelText" } }; var serialized = JsonConvert.SerializeObject(template); Assert.AreEqual(@"{""type"":""confirm"",""text"":""Test"",""actions"":[{""type"":""message"",""label"":""OkLabel"",""text"":""OkText""},{""type"":""message"",""label"":""CancelLabel"",""text"":""CancelText""}]}", serialized); }
public ActionResult DispatchTemplate2() { var actions = new List <TemplateActionBase>(); actions.Add(new MessageAction() { label = "同意", text = "yes" }); actions.Add(new MessageAction() { label = "拒絕", text = "no" }); var tmpl = new ConfirmTemplate() { text = "請問您想選擇的是?", altText = "快快樂樂發送了一個詢問,", actions = actions }; bot.PushMessage(toUserID, tmpl); return(View("Index")); }
public void ShouldPreserveInstanceWhenValueIsCarouselTemplate() { var template = new ConfirmTemplate() { Text = "ConfirmText", OkAction = new MessageAction() { Label = "PostbackLabel", Text = "PostbackText" }, CancelAction = new UriAction() { Label = "PostbackLabel", Url = new Uri("http://foo.bar") } }; var confirmTemplate = ConfirmTemplate.Convert(template); Assert.AreSame(template, confirmTemplate); Assert.AreSame(confirmTemplate.OkAction, template.OkAction); Assert.AreSame(confirmTemplate.CancelAction, template.CancelAction); }
public ConfirmQuestion(string question) { _Question = question; var actions = new List <TemplateActionBase>(); actions.Add(new PostbackAction() { label = "是", data = "Y" }); actions.Add(new PostbackAction() { label = "否", data = "N" }); var confirmTemplate = new ConfirmTemplate() { altText = "替代文字(在無法顯示Button Template的時候顯示)", text = _Question, actions = actions }; _ConfirmTemplateResponse = confirmTemplate; }
/// <summary> /// Get all messages from DirectLine and reply back to Line /// </summary> private async Task GetAndReplyMessages() { dl.MessageSet result = string.IsNullOrEmpty(watermark) ? await dlClient.Conversations.GetMessagesAsync(conversationId) : await dlClient.Conversations.GetMessagesAsync(conversationId, watermark); userParams["Watermark"] = (Int64.Parse(result.Watermark)).ToString(); foreach (var message in result.Messages) { if (message.FromProperty == lineEvent.Source.UserId) { continue; } Message replyMessage = new Message(); if (message.Attachments != null && message.Attachments.Count != 0) { foreach (var attachment in message.Attachments) { if (attachment.ContentType.Contains("image")) { var originalContentUrl = ""; var previewImageUrl = ""; if (!string.IsNullOrEmpty(attachment.Url)) { originalContentUrl = attachment.Url.Contains("http") ? attachment.Url : "https://directline.botframework.com/" + attachment.Url; } else { // Have to create Uri accessible to Line } replyMessage = new ImageMessage(originalContentUrl, previewImageUrl); } else if (attachment.ContentType.Contains("audio")) { var originalContentUrl = ""; var durationInMilliseconds = 0; if (!string.IsNullOrEmpty(attachment.Url)) { originalContentUrl = attachment.Url.Contains("http") ? attachment.Url : "https://directline.botframework.com/" + attachment.Url; } else { // Have to create Uri accessible to Line } replyMessage = new AudioMessage(originalContentUrl, durationInMilliseconds); } else if (attachment.ContentType.Contains("video")) { var originalContentUrl = ""; var previewImageUrl = ""; if (!string.IsNullOrEmpty(attachment.Url)) { originalContentUrl = attachment.Url.Contains("http") ? attachment.Url : "https://directline.botframework.com/" + attachment.Url; } else { // Have to create Uri accessible to Line } replyMessage = new VideoMessage(originalContentUrl, previewImageUrl); } } } else if (message.ChannelData != null) { Entity entity = JsonConvert.DeserializeObject <Entity>(message.ChannelData.ToString()); switch (entity.Type) { case "GeoCoordinates": GeoCoordinates geoCoordinates = JsonConvert.DeserializeObject <GeoCoordinates>(entity.Properties.ToString()); replyMessage = new LocationMessage(message.Text, geoCoordinates.Name, geoCoordinates.Latitude, geoCoordinates.Longitude); break; case "Place": Place place = JsonConvert.DeserializeObject <Place>(entity.Properties.ToString()); GeoCoordinates geo = JsonConvert.DeserializeObject <GeoCoordinates>(place.Geo.ToString()); replyMessage = new LocationMessage(place.Name, place.Address, geo.Latitude, geo.Longitude); break; case "Confirm": string title = entity.Properties.ToString(); ConfirmTemplate confirmTemplate = new ConfirmTemplate(title, new List <TemplateAction>() { new MessageTemplateAction("Yes", "Yes"), new MessageTemplateAction("No", "No") }); replyMessage = new TemplateMessage("Confirm template", confirmTemplate); break; case "Rich": List <Attachment> attachments = JsonConvert.DeserializeObject <List <Attachment> >(entity.Properties["Attachments"].ToString()); if (attachments.Count == 1) { var attachment = attachments.First(); HeroCard hcard = null; if (attachment.ContentType == "application/vnd.microsoft.card.hero") { hcard = JsonConvert.DeserializeObject <HeroCard>(attachment.Content.ToString()); } else if (attachment.ContentType == "application/vnd.microsoft.card.thumbnail") { ThumbnailCard tCard = JsonConvert.DeserializeObject <ThumbnailCard>(attachment.Content.ToString()); hcard = new HeroCard(tCard.Title, tCard.Subtitle, tCard.Text, tCard.Images, tCard.Buttons, null); } else { break; } ButtonsTemplate buttonsTemplate = new ButtonsTemplate(hcard.Images.First().Url, hcard.Title, hcard.Subtitle); foreach (var button in hcard.Buttons) { switch (button.Type) { case "openUrl": buttonsTemplate.Actions.Add(new UriTemplateAction(button.Title, button.Value)); break; case "imBack": buttonsTemplate.Actions.Add(new MessageTemplateAction(button.Title, button.Value)); break; case "postBack": buttonsTemplate.Actions.Add(new PostbackTemplateAction(button.Title, button.Value)); break; } } replyMessage = new TemplateMessage("Buttons template", buttonsTemplate); } else { CarouselTemplate carouselTemplate = new CarouselTemplate(); foreach (var attachment in attachments) { TemplateColumn tColumn = new TemplateColumn(); HeroCard hcard = null; if (attachment.ContentType == "application/vnd.microsoft.card.hero") { hcard = JsonConvert.DeserializeObject <HeroCard>(attachment.Content.ToString()); } else if (attachment.ContentType == "application/vnd.microsoft.card.thumbnail") { ThumbnailCard tCard = JsonConvert.DeserializeObject <ThumbnailCard>(attachment.Content.ToString()); hcard = new HeroCard(tCard.Title, tCard.Subtitle, tCard.Text, tCard.Images, tCard.Buttons, null); } else { continue; } foreach (var button in hcard.Buttons) { switch (button.Type) { case "openUrl": tColumn.Actions.Add(new UriTemplateAction(button.Title, button.Value)); break; case "imBack": tColumn.Actions.Add(new MessageTemplateAction(button.Title, button.Value)); break; case "postBack": tColumn.Actions.Add(new PostbackTemplateAction(button.Title, button.Value)); break; } } tColumn.ThumbnailImageUrl = string.IsNullOrEmpty(hcard.Images.First().Url) ? null : hcard.Images.First().Url; tColumn.Text = hcard.Subtitle; tColumn.Title = hcard.Title; carouselTemplate.Columns.Add(tColumn); } replyMessage = new TemplateMessage("Carousel template", carouselTemplate); } break; } } else if (!string.IsNullOrEmpty(message.Text)) { if (message.Text.Contains("\n\n*")) { var lines = message.Text.Split(new[] { "\n\n" }, StringSplitOptions.RemoveEmptyEntries); ButtonsTemplate buttonsTemplate = new ButtonsTemplate(text: lines[0]); foreach (var line in lines.Skip(1)) { buttonsTemplate.Actions.Add(new PostbackTemplateAction(line, line.Replace("* ", ""))); } replyMessage = new TemplateMessage("Buttons template", buttonsTemplate); } else { replyMessage = new TextMessage(message.Text); } } await Reply(replyMessage); } }
public IActionResult Post() { try { foreach (var lineEvent in this.ReceivedMessage.events) { if (lineEvent == null || lineEvent.replyToken == "00000000000000000000000000000000") { return(Ok()); } //準備回覆訊息 if (lineEvent.type.ToLower() != "message" || lineEvent.message.type != "text") { return(Ok()); } switch (lineEvent.message.text.ToLower()) { case "/quickreply": var quickReplyMsg = new TextMessage("拒絕融資推銷"); quickReplyMsg.quickReply.items.AddRange(new QuickReplyItemBase[] { new QuickReplyMessageAction("不需要", "不需要"), new QuickReplyMessageAction("再見", "再見"), new QuickReplyMessageAction("我超有錢", "我超有錢"), new QuickReplyDatetimePickerAction("選擇時間", DateTime.Now.ToString("yyyy-MM-dd"), DatetimePickerModes.date), new QuickReplyPostbackAction("PostBack Data 1", "Quick Reply PostBack Data", "顯示的文字", ""), new QuickReplyPostbackAction("PostBack Data 2", "Quick Reply PostBack Data", "", ""), new QuickReplyLocationAction("地點") }); this.ReplyMessage(lineEvent.replyToken, quickReplyMsg); break; case "/imagemap": var imgmapMsg = new ImagemapMessage { baseUrl = new Uri(@"https://i.imgur.com/7pxFJW8.jpg"), baseSize = new System.Drawing.Size(816, 649) }; var largeNumber = new string[] { "壹", "貳", "參", "肆", "伍", "陸", "漆", "捌", "玖" }; var address = new List <List <int> > { new List <int> { 666, 111, 90, 90 }, new List <int> { 719, 287, 90, 90 }, new List <int> { 655, 458, 90, 90 }, new List <int> { 490, 561, 90, 90 }, new List <int> { 265, 568, 90, 90 }, new List <int> { 79, 465, 90, 90 }, new List <int> { 30, 283, 90, 90 }, new List <int> { 56, 105, 90, 90 }, new List <int> { 357, 341, 90, 90 }, }; for (var i = 0; i < largeNumber.Length && i < address.Count; i++) { imgmapMsg.actions.Add(new ImagemapMessageAction { text = largeNumber[i], area = new ImagemapArea(address[i][0], address[i][1], address[i][2], address[i][3]) }); } imgmapMsg.actions.Add(new ImagemapUriAction { linkUri = new Uri(@"https://i.imgur.com/7pxFJW8.jpg"), area = new ImagemapArea(297, 71, 234, 201) }); this.ReplyMessage(lineEvent.replyToken, imgmapMsg); break; case "/flexmessage": //定義一則訊息 var baseFlexMessages = @" [ { ""type"": ""text"", ""text"": ""來源 : $source$"" }, { ""type"": ""flex"", ""altText"": ""Sample Flex Message"", ""contents"": $flex$ } ]"; var flexMessage = baseFlexMessages.Replace("$flex$", SampleFlexMessage.Sample1) .Replace("$source$", SampleFlexMessage.Source1); this.ReplyMessageWithJSON(lineEvent.replyToken, flexMessage); break; case "/flexmessage2": //定義一則訊息 var baseFlexMessages2 = @" [ { ""type"": ""text"", ""text"": ""來源 : $source$"" }, { ""type"": ""flex"", ""altText"": ""Sample Flex Message"", ""contents"": $flex$ } ]"; var flexMessage2 = baseFlexMessages2.Replace("$flex$", SampleFlexMessage.Sample2) .Replace("$source$", SampleFlexMessage.Source2); this.ReplyMessageWithJSON(lineEvent.replyToken, flexMessage2); break; case "/lineurlscheme": this.ReplyMessage(lineEvent.replyToken, "https://developers.line.biz/en/docs/messaging-api/using-line-url-scheme/#available-line-url-schemes"); break; case "/liff": //var liff = isRock.LIFF.Utility.AddLiffApp(_lineBot.ChannelAccessToken, new Uri("https://bu9lifftest.azurewebsites.net"), isRock.LIFF.ViewType.full); this.ReplyMessage(lineEvent.replyToken, "line://app/1655852489-2yE1NxMX"); break; case "/templatemessage": var templateAction = new List <TemplateActionBase>(); templateAction.AddRange(new TemplateActionBase[] { new MessageAction { label = "回覆訊息", text = "測試訊息" }, new UriAction { label = "開啟網頁", uri = new Uri("https://www.google.com.tw/") }, new PostbackAction { label = "PostBack", data = "Postback Data" } }); var buttomTemplate = new ButtonsTemplate { altText = "無法顯示", text = "測試text", title = "測試title", thumbnailImageUrl = new Uri(@"https://i.imgur.com/7pxFJW8.jpg"), actions = templateAction //設定回覆動作 }; this.ReplyMessage(lineEvent.replyToken, buttomTemplate); break; case "/templatemessage2": var templateAction2 = new List <TemplateActionBase>(); templateAction2.AddRange(new TemplateActionBase[] { new MessageAction { label = "回覆訊息", text = "測試訊息" }, new UriAction { label = "開啟網頁", uri = new Uri("https://www.google.com.tw/") }, new PostbackAction { label = "PostBack", data = "Postback Data" } }); var carouseTemplate2 = new CarouselTemplate { altText = "無法顯示", columns = new List <Column> { new Column { actions = templateAction2, text = "測試text", title = "測試title", thumbnailImageUrl = new Uri(@"https://i.imgur.com/7pxFJW8.jpg") }, new Column { actions = templateAction2, text = "測試text", title = "測試title", thumbnailImageUrl = new Uri(@"https://i.imgur.com/7pxFJW8.jpg") }, new Column { actions = templateAction2, text = "測試text", title = "測試title", thumbnailImageUrl = new Uri(@"https://i.imgur.com/7pxFJW8.jpg") } } }; this.ReplyMessage(lineEvent.replyToken, carouseTemplate2); break; case "/templatemessage3": var templateAction3 = new List <TemplateActionBase>(); templateAction3.AddRange(new TemplateActionBase[] { new UriAction { label = "開啟網頁", uri = new Uri("https://www.google.com.tw/") }, new PostbackAction { label = "PostBack", data = "Postback Data" } }); var confirmTemplate = new ConfirmTemplate { altText = "無法顯示", text = "測試text", actions = templateAction3 }; this.ReplyMessage(lineEvent.replyToken, confirmTemplate); break; default: return(Ok()); } } } catch (Exception ex) { this.PushMessage(_lineBot.AdminUserId, "發生錯誤:\n" + ex.Message); } return(Ok()); }