I'm developing a bot with Microsoft Bot Framework, on Facebook Messenger the carousel shows as it should, but in Telegram it shows as 2 different cards on two different messages.
Doesn't Telegram support carousels or is it my fault?
Code:
public async Task Carousel(IDialogContext context, IAwaitable<IMessageActivity> activity)
{
var act = await activity;
//carousel
var replyToConversation = context.MakeMessage();
replyToConversation.Text = "2+ Cards are a Carousel";
replyToConversation.Recipient = message.From;
replyToConversation.Type = "message";
replyToConversation.Attachments = new List<Attachment>();
//1
List<CardImage> cardImages = new List<CardImage>();
cardImages.Add(new CardImage(url: "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c0/Asimo_look_new_design.jpg/330px-Asimo_look_new_design.jpg"));
List<CardAction> cardButtons = new List<CardAction>();
CardAction plButton = new CardAction()
{
Value = "https://en.wikipedia.org/wiki/Robot",
Type = "openUrl",
Title = "WikiPedia Page"
};
cardButtons.Add(plButton);
HeroCard plCard = new HeroCard()
{
Title = "I'm a hero card",
Subtitle = "Robot Wikipedia Page",
Images = cardImages,
Buttons = cardButtons
};
Attachment plAttachment = plCard.ToAttachment();
replyToConversation.Attachments.Add(plAttachment);
//2
List<CardImage> cardImages2 = new List<CardImage>();
cardImages2.Add(new CardImage(url: "https://upload.wikimedia.org/wikipedia/en/thumb/9/9b/FANUC_6-axis_welding_robots.jpg/330px-FANUC_6-axis_welding_robots.jpg"));
List<CardAction> cardButtons2 = new List<CardAction>();
CardAction plButton2 = new CardAction()
{
Value = "https://en.wikipedia.org/wiki/Robot",
Type = "openUrl",
Title = "WikiPedia Page"
};
cardButtons2.Add(plButton);
HeroCard plCard2 = new HeroCard()
{
Title = "I'm a hero card",
Subtitle = "Robot Wikipedia Page",
Images = cardImages2,
Buttons = cardButtons2
};
Attachment plAttachment2 = plCard2.ToAttachment();
replyToConversation.AttachmentLayout = AttachmentLayoutTypes.Carousel;
replyToConversation.Attachments.Add(plAttachment2);
await context.PostAsync(replyToConversation);
}
It's not your fault. Per the Channel Inspector, the carousel in Telegram has a down-rendered appearance.
Related
I have to create a adaptive card which have city of name and each city have different holiday list.
I have to show city name in dropdown list and on selection of each city i have to show child card which contains Holiday list.
I have develop below code:
private async Task<DialogTurnResult> ShowCard(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
List<string> city = new List<string>() { "Delhi", "Bangalore", "Mumbai" };
List<string> date = new List<string>() { "1-Jan", "26-Jan", "15-Aug" };
List<string> des = new List<string>() { "New Year", "Republic Day", "Independence Day" };
List<string> date1 = new List<string>() { "1-Jan", "26-Jan", "15-Aug", "25-Dec" };
List<string> des1 = new List<string>() { "New Year", "Republic Day", "Independence Day", "Christmas Day" };
List<string> date2 = new List<string>() { "1-Jan", "25-Dec" };
List<string> des2 = new List<string>() { "New Year", "Christmas Day" };
List<AdaptiveCard> cards = new List<AdaptiveCard>();
cards.Add(HolidayListAdaptiveCard(date, des));
cards.Add(HolidayListAdaptiveCard(date1, des1));
cards.Add(HolidayListAdaptiveCard(date2, des2));
var mainCard = new AdaptiveCard(new AdaptiveSchemaVersion(1, 0));
var column3 = new AdaptiveColumn();
column3.Items.Add(new AdaptiveTextBlock() { Text = "Holiday City", Weight = AdaptiveTextWeight.Bolder });
var columnSet1 = new AdaptiveColumnSet();
columnSet1.Columns.Add(column3);
var container1 = new AdaptiveContainer();
container1.Style = AdaptiveContainerStyle.Emphasis;
container1.Items.Add(columnSet1);
mainCard.Body.Add(container1);
List<AdaptiveShowCardAction> adaptiveShowCardActions = new List<AdaptiveShowCardAction>();
for (int i = 0; i < city.Count; i++)
{
mainCard.Actions.Add(new AdaptiveShowCardAction() { Title = city[i], Card = cards[i] });
}
var attachment = new Attachment
{
ContentType = AdaptiveCard.ContentType,
Content = mainCard
};
var reply = MessageFactory.Attachment(attachment);
await stepContext.Context.SendActivityAsync(reply);
return new DialogTurnResult(DialogTurnStatus.Waiting);
}
private AdaptiveCard HolidayListAdaptiveCard(List<string> date, List<string> description)
{
var card = new AdaptiveCard(new AdaptiveSchemaVersion(1, 0));
List<AdaptiveColumn> columns = new List<AdaptiveColumn>();
var column = new AdaptiveColumn();
var column1 = new AdaptiveColumn();
var column2 = new AdaptiveColumn();
var textBlock = new AdaptiveTextBlock();
textBlock.Text = "Sr. No";
textBlock.Weight = AdaptiveTextWeight.Bolder;
textBlock.Size = AdaptiveTextSize.Large;
textBlock.Color = AdaptiveTextColor.Accent;
column.Items.Add(textBlock);
var textBlock1 = new AdaptiveTextBlock();
textBlock1.Text = "Date";
textBlock1.Weight = AdaptiveTextWeight.Bolder;
textBlock1.Size = AdaptiveTextSize.Large;
textBlock1.Color = AdaptiveTextColor.Good;
column1.Items.Add(textBlock1);
var textBlock2 = new AdaptiveTextBlock();
textBlock2.Text = "Description";
textBlock2.Weight = AdaptiveTextWeight.Bolder;
textBlock2.Size = AdaptiveTextSize.Large;
textBlock2.Color = AdaptiveTextColor.Dark;
column2.Items.Add(textBlock2);
for (int i = 0; i < date.Count; i++)
{
column.Items.Add(new AdaptiveTextBlock() { Text = (i + 1).ToString() });
column1.Items.Add(new AdaptiveTextBlock() { Text = date[i] });
column2.Items.Add(new AdaptiveTextBlock() { Text = description[i] });
}
var columnSet = new AdaptiveColumnSet();
columnSet.Columns.Add(column);
columnSet.Columns.Add(column1);
columnSet.Columns.Add(column2);
var container = new AdaptiveContainer();
container.Style = AdaptiveContainerStyle.Emphasis;
container.Items.Add(columnSet);
card.Body.Add(container);
return card;
}
O/P:
Issue: City name coming as separate button but i need city name in dropdown list.
You can create a dropdown menu in an Adaptive Card by using an Input.ChoiceSet element and setting style to "compact". Note that the compact style is the default in Teams.
You can only extend Adaptive Card functionality if you're using Web Chat so you won't be able to respond to events from this dropdown and you won't be able to modify the card as the user is filling it out. You'll need to have the user select a city and then click the submit button. While Teams does allow message updates and so you could update the card in response to the submit action, it's probably better and easier just to send a whole new card with the holiday list.
I want to use facebook's quick replies -
at first I tried to use IMessageActivity's SuggestedActions property
IMessageActivity result = Activity.CreateMessageActivity();
result.Type = ActivityTypes.Message;
result.TextFormat = TextFormatTypes.Plain;
result.SuggestedActions = suggestedActions.Select(x => new CardAction()
{
Title = x,
Type = ActionTypes.ImBack,
Value = x
}).ToList()
but, as it didn't work for facebook, I found another solution based on ChanelData
result.ChannelData = JObject.FromObject(new {
quick_replies = suggestedActions.Actions.Select(x => new
{
content_type = "text",
title = x.Title,
payload = x.Value is null ? x.Title : x.Value
}).ToArray()
});
sadly it still doesn't work. Is there anything else to do?
I beleive you can use HeroCards and attach them to an activity and send that via SendActivityAsync.
Activity activity = _context.Context.Activity.CreateReply();
var buttonList = new List<CardAction>();
foreach (var prompt in Prompts)
{
buttonList.Add(
new CardAction { Value = prompt.DisplayText, Type = "imBack", Title = prompt.DisplayText, });
}
var heroCard = new HeroCard { Text = "message text", Subtitle = string.Empty, Buttons = buttonList };
activity.Attachments.Add(heroCard.ToAttachment());
await stepContext.Context.SendActivityAsync(activity).ConfigureAwait(false);
Try using a TextPrompt with the PromptOptions like this:
await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions
{
Prompt = new Activity
{
Type = ActivityTypes.Message,
Text = "¡Bien! Ahora te envié un código de acceso a tu teléfono. Por favor ingrésalo aquí cuando lo recibas.",
SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction() { Title = "Reenviar token", Type = ActionTypes.ImBack, Value = "Reenviar token" }
},
},
}
});
Result:
Edit:
If you dont want to use prompts, try this:
Activity activity = stepContext.Context.Activity.CreateReply();
activity.Type = ActivityTypes.Message;
activity.Text = "This is an example of SuggestedAction";
activity.SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction() { Title = "Action", Type = ActionTypes.ImBack, Value = "Action" }
}
};
await stepContext.Context.SendActivityAsync(activity);
return await stepContext.EndDialogAsync();
Result:
Is it possible to include HeroCard attachment in WaterfallStepContext, i am able to call ITurnContext but not from WaterfallStepContext
Trying using C# code however .Activity is part of waterfallstep contenxt
var getFeedback = turnContext.Activity.CreateReply();
var feedbackChoices = new HeroCard
{
Text = "Our conversation was helpful?",
Buttons = new List<CardAction>
{
new CardAction() { Title = Constants.userResponseThumbsUp, Type = ActionTypes.ImBack, Value = Constants.userResponseYes},
new CardAction() { Title = Constants.userResponseThumbsDown, Type = ActionTypes.ImBack, Value = Constants.userResponseNo},
},
};
// Add the card to our reply to user.
getFeedback.Attachments = new List<Attachment>() { feedbackChoices.ToAttachment() };
await turnContext.SendActivityAsync(getFeedback, cancellationToken);
Yes, it is possible to include a HeroCard attachment in WaterfallStepContext. Here is the implementation below:
private static async Task<DialogTurnResult> ShowCardStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var getFeedback = stepContext.Context.Activity.CreateReply();
var feedbackChoices = new HeroCard
{
Text = "Our conversation was helpful?",
Buttons = new List<CardAction>
{
new CardAction() { Title = Constants.userResponseThumbsUp, Type = ActionTypes.ImBack, Value = Constants.userResponseYes},
new CardAction() { Title = Constants.userResponseThumbsDown, Type = ActionTypes.ImBack, Value = Constants.userResponseNo},
},
};
// Add the card to our reply to user.
getFeedback.Attachments = new List<Attachment>() { feedbackChoices.ToAttachment() };
await stepContext.Context.SendActivityAsync(getFeedback, cancellationToken);
}
Hope this helps.
Bot generate multiple questions using backdoor events from webchat in sequence
without getting answer from user. Below example for two questions :
//Question 1
var reply = ((Activity)activity).CreateReply("Question 1");
reply.Type = ActivityTypes.Message;
reply.TextFormat = TextFormatTypes.Plain;
reply.SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction() {Title = "Ans 1", Type = ActionTypes.ImBack, Value = "Ans 1"},
new CardAction() {Title = "Ans 2", Type = ActionTypes.ImBack, Value = "Ans 2"}
}
};
await connectorClient.Conversations.ReplyToActivityAsync(reply);
//Question 2 after 10 sec
var reply = ((Activity)activity).CreateReply("Question 2");
reply.Type = ActivityTypes.Message;
reply.TextFormat = TextFormatTypes.Plain;
reply.SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction() {Title = "Ans 1", Type = ActionTypes.ImBack, Value = "Ans 1"},
new CardAction() {Title = "Ans 2", Type = ActionTypes.ImBack, Value = "Ans 2"}
}
};
await connectorClient.Conversations.ReplyToActivityAsync(reply);
How to recognize in receiving Activity activity on what question user answered- on Question 1 or Question 2?
The solution to this is very simple, all you need to do Is make the Value parameter unique. In code, it would look like the snippet below. You may also want to consider using ActionTypes.PostBack rather than ActionTypes.ImBack that way the user does not actually see the Value
var connectorClient = new ConnectorClient(new Uri(activity.ServiceUrl));
var reply = ((Activity)activity).CreateReply("Question 1");
reply.Type = ActivityTypes.Message;
reply.TextFormat = TextFormatTypes.Plain;
reply.SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction() {Title = "Ans 1", Type = ActionTypes.PostBack, Value = "question 1 Ans 1"},
new CardAction() {Title = "Ans 2", Type = ActionTypes.PostBack, Value = "question 1 Ans 2"}
}
};
await connectorClient.Conversations.ReplyToActivityAsync(reply);
//Question 2 after 10 sec
reply = ((Activity)activity).CreateReply("Question 2");
reply.Type = ActivityTypes.Message;
reply.TextFormat = TextFormatTypes.Plain;
reply.SuggestedActions = new SuggestedActions()
{
Actions = new List<CardAction>()
{
new CardAction() {Title = "Ans 1", Type = ActionTypes.PostBack, Value = "question 2 Ans 1"},
new CardAction() {Title = "Ans 2", Type = ActionTypes.PostBack, Value = "question 2 Ans 2"}
}
};
await connectorClient.Conversations.ReplyToActivityAsync(reply);
I am currently developing a ChatBot with .NET using Microsoft bot Framework i created list of products available and display the list in carousel using a Herocard and put a button BUY when the client click on it it takes him to the page where the product is located the problem is how can i get a products url using its id so i can put it in the button BUY
List<product> c = ListProduct.GetProductList();
List<Bukimedia.PrestaSharp.Entities.AuxEntities.language> lan = new List<Bukimedia.PrestaSharp.Entities.AuxEntities.language>();
foreach (product p in c)
{
lan = p.name;
foreach (Bukimedia.PrestaSharp.Entities.AuxEntities.language l in lan)
{
;
List<CardImage> cardImages = new List<CardImage>();
cardImages.Add(new CardImage(url: $"http://test.com/123456.jpg"));
List <CardAction> cardButtons = new List<CardAction>();
CardAction plButton = new CardAction()
{
Value =$"i don't know what i should put here",
Type = "openUrl",
Title = "Buy"
};
cardButtons.Add(plButton);
HeroCard plCard = new HeroCard()
{
Title = l.Value,
Subtitle = (p.price.ToString("C", Cultures.usa)),
Images = cardImages,
Buttons = cardButtons
};
Attachment plAttachment = plCard.ToAttachment();
replyMessage.Attachments.Add(plAttachment);
}
}
}
I solved the problem by using the url below :
http://localhost:8080/prestashopdemo/index.php?controller=product&id_product="+p.id
so my code now is working perfectly
List<product> c = ListProduct.GetProductList();
List<Bukimedia.PrestaSharp.Entities.AuxEntities.language> lan = new List<Bukimedia.PrestaSharp.Entities.AuxEntities.language>();
foreach (product p in c)
{
lan = p.name;
foreach (Bukimedia.PrestaSharp.Entities.AuxEntities.language l in lan.Where(l => l.id == 2))
{
{
List<CardImage> cardImages = new List<CardImage>();
cardImages.Add(new CardImage(url: $"http://1234456789#localhost:8080/prestashopdemo/" + p.id_default_image + "-large_default/" + l.Value + ".jpg"));
List<CardAction> cardButtons = new List<CardAction>();
CardAction plButton = new CardAction()
{
Value = $"http://localhost:8080/prestashopdemo/index.php?controller=product&id_product="+p.id,
Type = "openUrl",
Title = "Buy"
};
cardButtons.Add(plButton);
HeroCard plCard = new HeroCard()
{
Title = l.Value,
Subtitle = (p.price.ToString("C")),
Images = cardImages,
Buttons = cardButtons
};
Attachment plAttachment = plCard.ToAttachment();
replyMessage.Attachments.Add(plAttachment);
}
}