I am developing a Bot using Microsoft Bot Framework. I am using Adaptive Cards for displaying flights to users but they have a lot of limitations on their appearance. I am trying to render the adaptive card from one of the dialogs within my bot framework by creating a adaptive card renderer using my own hostconfig.json and then attaching the Html of my adaptive card back to the chat window. But its not working :(
public static Attachment CreateFlight(Flight flight)
{
var renderedAdaptiveCard = AdaptiveCardRenderer
.RenderCard(new AdaptiveCard
{
Body = new List<AdaptiveElement>
{
new AdaptiveContainer {Items = CreateFlightAdaptiveElements(flight)}
},
Actions = new List<AdaptiveAction>
{
new AdaptiveShowCardAction
{
Card = new AdaptiveCard
{
Body = new List<AdaptiveElement>
{
},
Actions = new List<AdaptiveAction>
{
new AdaptiveSubmitAction
{
Title = "Select",
Data = flight.Segments.Select(x => $"{x.Airline} {x.FlightNo}")
.Aggregate((i, j) => i + "/" + j),
}
},
BackgroundImage = new Uri($"{DomainUrl}/Images/ac_background.jpg")
},
Title = "Select"
},
},
BackgroundImage = new Uri($"{DomainUrl}/Images/ECEFF1.png")
});
var attachment = new Attachment
{
ContentType = "application/html",
Content = renderedAdaptiveCard.Html
};
return attachment;
}
Am I trying something that is impossible here ? How to change the default grey looks of my bot ? My primary channels would be Skype, Slack etc so I don't have plans to integrate this to a Web Chat. Kindly help me with this regard.
The idea behind Adaptive Cards is to allow each channel to render the cards in a way that's specific to that channel. A card "adapts" to any environment that might support it. While Adaptive Cards offer a lot of flexibility, the bot can only do so much because it's ultimately the channel that's in charge of rendering the card.
Card Authors describe their content as a simple JSON object. That
content can then be rendered natively inside a Host Application,
automatically adapting to the look and feel of the Host.
For example, Contoso Bot can author an Adaptive Card through the Bot
Framework, and when delivered to Skype, it will look and feel like a
Skype card. When that same payload is sent to Microsoft Teams, it will
look and feel like Microsoft Teams. As more host apps start to support
Adaptive Cards, that same payload will automatically light up inside
these applications, yet still feel entirely native to the app.
Users win because everything feels familiar. Host apps win because
they control the user experience. And Card Authors win because their
content gets broader reach without any additional work.
As you probably know, the RenderedAdaptiveCard type is meant to be used in client-side code. That means it can help you if you want to make your own channel for example, but it's not really meant to be used in a bot. Your code isn't working because there is no HTML attachment type and most channels don't support HTML at all. You can find more information in this question and this GitHub issue.
Hopefully you can achieve the appearance you're looking for using the tools available to you, such as images and links.
Related
I want to fetch a pptx from web and then grab the speaker notes of each slide. Is there an API that allows me to that?
Google Slides already provides that in their API here: https://developers.google.com/slides/api/reference/rest/v1/presentations/get
For powerpoint I've seen they have Javascript API, but it seems just for add-ins. Other option I've seen seems to be OpenXML SDK. Wondered what is the preferred approach?
If you deal with open XML documents only (*.pptx) you can use the Open XML SDK, see Welcome to the Open XML SDK 2.5 for Office for more information.
OfficeJS is for web add-ins only and not designed for standalone applications.
Aspose.Slides makes it easy to get speaker notes from a presentation. This library can be used in C#, Java, C++ and Python. The following C# code example shows you how to get the speaker notes from each slide:
using var presentation = new Presentation("example.pptx");
foreach (var slide in presentation.Slides)
{
// Get notes from the slide.
var slideNotes = slide.NotesSlideManager.NotesSlide.NotesTextFrame.Text;
Console.WriteLine(slideNotes);
}
This is a paid product, but you can get a temporary license to evaluate all its features. Alternatively, you can use Aspose.Slides Cloud SDK that provides REST-based APIs in many languages. The C# code example below shows you how to do the same using Aspose.Slides Cloud:
var slidesApi = new SlidesApi("my_client_key", "my_client_secret");
// A presentation saved in storage.
var fileName = "example.pptx";
var slideCount = slidesApi.GetSlides(fileName).SlideList.Count;
for (var slideNumber = 1; slideNumber <= slideCount; slideNumber++)
{
// Get notes from the slide.
var notesSlide = slidesApi.GetNotesSlide(fileName, slideNumber);
Console.WriteLine(notesSlide.Text);
}
This is also a paid product, but you can make 150 free API calls per month for your purposes. I work as a Support Developer at Aspose.
I am sending an adaptive card to teams with the bot framework. That is working fine. The card should contain an action that opens a task module like explained here.
My code for the card looks like this:
AdaptiveCard card = new AdaptiveCard(new AdaptiveSchemaVersion(1, 3))
{
Body = new List<AdaptiveElement>() {
new AdaptiveTextBlock() {
Wrap = true,
Text = "test",
IsSubtle = false,
Size = AdaptiveTextSize.Large,
Weight = AdaptiveTextWeight.Bolder
}
},
Actions = new List<AdaptiveAction>() {
new AdaptiveSubmitAction()
{
Title = "In Teams",
DataJson = $"{{\"msteams\":{{\"type\":\"task/fetch\"}},\"Url\":\"{url}\",\"Title\": \"{title}\"}}"
}
}
};
The card is showing in teams, but the button is not working in the desktop client. It is just showing this message in red:
Something went wrong. Please try again.
In the web version the task module is just opening fine. Do I have to change something for the desktop version of teams? Tried to change my code a bit like in this example but that isn't working either.
Update:
So I tried the example and it did work one time. After that I had the same error message and no task module is showing. But when I pop out the App in a new window, everything is working fine. So it looks to me like a bug in teams.
I had the same problem with the message “Something went wrong. Try again.", when called Task Module from adaptive card. I installed the bot through a local upload of the manifest, but then I found out that it was also added to the list of applications for our organization, and apparently there was some kind of collision between them. After I uninstalled the application from my desktop Teams and installed it from the application pool - the error disappeared.
This might relate to how the platform is reading your json - the "" characters for example might not be handled properly on the desktop. To solve this, rather leave the json conversion up to the platform and, for your example in C#, create a strong type instead. The example you link to does exactly that - see this line:
new TaskModuleAction(cardType.ButtonTitle, new CardTaskFetchValue<string>() { Data = cardType.Id }
inside https://github.com/microsoft/BotBuilder-Samples/blob/448c5535cb6d6be8d7a61f78ef1902b55c1f0edb/samples/csharp_dotnetcore/54.teams-task-module/Bots/TeamsTaskModuleBot.cs, which is referencing this class: https://github.com/microsoft/BotBuilder-Samples/blob/901bc140f5aa300fbfa852e64afd7c65fceebff9/samples/csharp_dotnetcore/54.teams-task-module/Models/AdaptiveCardTaskFetchValue.cs
I have successfully set up push notification using firebase and linked it up Azure notification hub using this guide from the Microsoft docs:
https://learn.microsoft.com/en-us/azure/notification-hubs/xamarin-notification-hubs-push-notifications-android-gcm
However I am now trying to push notification to specific devices using tags. There isn't currently a xamarin c# document. I have done some research around the area and found people solving what seems to be the same problem using dependency injection (which feels a little complex?). I have also found these two questions/answers:
How to push notification to specific users in Xamarin.Forms Android?
https://forums.xamarin.com/discussion/85935/how-to-push-notification-to-specific-users-in-xamarin-forms-android
Both of which point to the method "OnRegistered" which i don't seem to have? i've had another look through the documentation I followed to set up notifications in the first place and I seem to have followed it correctly?
I have the following code for android:
private void SendRegistrationToServer(string token)
{
// Register with Notification Hubs
hub = new NotificationHub(ApplicationConstants.NotificationHubName,
ApplicationConstants.ListenConnectionString, this);
var tags = new List<string>() { };
var regID = hub.Register(token, tags.ToArray()).RegistrationId;
}
I can obviously set the tags manually there, however how do i 'call' this Method again if the tags need to be changed?
So bottom line, my question is how do i set up push notification to specific devices on xamarin.forms android/ios?
Thanks.
How can I use the new authentification feature in Bot Builder with MS Teams?
There seems to be an issue with Teams (see Login user with MS Teams bot or https://github.com/Microsoft/BotBuilder/issues/2104), seems if this is not considered in GetTokenDialog?
Is there any chance to get around this?
Just found the reason why it won't work with Teams. In method Microsoft.Bot.Connector.Activity.CreateOAuthReplyAsync(), Parameter asSignInCard has to be set to True for MSTeams, then, the line new CardAction() { Title = buttonLabel, Value = link, Type = ActionTypes.Signin } has to be changed to new CardAction() { Title = buttonLabel, Value = link, Type = ActionTypes.OpenUrl } because MS Teams can obviously not deal with Action type Signin. Hope, the MS developers will fix that method soon.
There are a few things you need to do to get this to work. First you need to create a manifest file for your bot in teams and whitelist token.botframework.com. That is the first problem.
From teams itself in AppStudio you create a Manifest. I had to play around with this a little bit. In AppDetails... Let it generate a new ID. Just hit the button. The URLs really don't matter much for testing. The package name just needs to be unique so something like com.ilonatag.teams.test
In the bots section you plug in your MS AppId and a bot name. This is a the real MSAPPID from your bots MicrosoftAppId" value=" from web.config in your code.
Ok now in "finish->valid domains" I added token.botframework.com and also the URL for my bot just in case. so something like franktest.azurewebsites.net
This part is done but you are not quite done... in your messages controller you need to add this since Teams sends a different verification than the other clients.
if (message.Type == ActivityTypes.Invoke)
{
// Send teams Invoke along to the Dialog stack
if (message.IsTeamsVerificationInvoke())
{
await Conversation.SendAsync(message, () => new Dialogs.RootDialog());
}
}
It took me a bunch of going back and forth with Microsoft to get this sorted out.
This is a known problem using OAuthCard in MS Teams. To solve it, you can change the Button ActionType from signIn to openUrl using this solution on github
I have an task to implement an chat based application to access private data available at server using web service api call.Show all available users from web server and to chat with those persons.Is't possible with titanium development to support on iPhone/Android chat application. If possible let me guide to implement the same.
Yes, of course it's possible. And there are a million ways to do this, your question is not very clear.
If its totally web services based then just use this.
Heres a quick example of posting to a webservice and sending a JSON object:
var getChatMessages = Ti.Network.createHTTPClient({
onload : function(e) {
var doSomethignWithThis = this.responseText;
},
onerror : function(e) {
Ti.API.info(this.responseText);
Ti.API.info('SelectActivityStepsByKeyList webservice failed with message : ' + e.error);
}
});
getChatMessages.open('POST', 'http://yourchatserver/GetChats');
getChatMessages.setRequestHeader("Content-Type", "application/json");
getChatMessages.send({"message" : "How is everyone today?", "user" : "me#me.com});
This is not difficult with titanium, the hard part is on the server side.
Here is an example project that accomplishes chat through the use of the socket.io library. This may be a better approach for you. The link has a video of how it works as well as the full source code.