Services.AddTransient() Vs Services.AddBot() - botframework

In the latest bot samples, we can see that bot is being added to services collection as below
services.AddTransient<IBot, MyBot>();
but in older samples, we saw below approach
services.AddBot<MyBot>(options => { });
Here I am trying to understand the benefits of adding bot using AddTransient() over using AddBot().
What I know is that internally AddBot uses AddTransient only, then why use AddTransient. Referred remarks section from this link.

You can see in the source code that the AddBot methods are used for automatically adding a bot adapter to DI in addition to the bot and for configuring bot-related options like credentials and error handling. The conventions for using the Bot Builder v4 SDK were very different when those samples were made, and the bot's configuration along with its credentials were loaded from something called a bot file. The current convention for using the SDK is much easier because it takes advantage of ASP.NET Core automatically loading the app's configuration from appsettings.json. Since we're not using AddBot anymore you'll notice that the adapter is added to DI explicitly, and you can configure things like error handling and middleware either by accessing the properties and methods of the adapter directly or by deriving your own adapter class, as seen in the samples.

Related

Cannot AzureBlobStorage initialization in Bot Framework 4.9

I am implementing "AzureBlobStorage" by referencing "Microsoft.Bot.Builder.Azure", but when I initialize I get an error with "CloudStorageAccount".
Error CS7069 Reference to type 'CloudStorageAccount' claims it is defined in 'Microsoft.Azure.Storage.Common', but it could not be found QBotSolution
Solution Explorer:
It looks like Visual Studio can't determine which package you're trying to use. If you're just looking to do traditional bot state management, you should remove these packages:
Azure.Storage.Blobs
Microsoft.Azure.Cosmos.Table
Microsoft.Azure.Storage.Blob
Microsoft.Azure.Storage.Common
For bot Blob storage, you should only need Microsoft.Bot.Builder.Azure, so be sure to include using Microsoft.Bot.Builder.Azure; at the top of whatever file you're trying to use this in.
Here's a few good references:
State Management Sample
Write Directly to Storage - Using Blob Storage Docs
State Management Docs

Clear explanation of Dialog implementation on bot framework V4

Is there someone who can explain how to code dialog from bot framework properly?
I'm trying to code from scratch using the empty bot template to understand every pieces of code and why and how they piece together. But even after reading so many times I don't how it is properly implemented or coding for dialogs in Microsoft Bot Framework. I've read the documentation from microsoft many times and many version or doc from microsoft but still can't comprehend how it link together every piece of code. Even blogs or website i found did not explain why such pieces of code is needed but just ask you to add this and that. I understand concept but not the mechanics. The code seems to span from startup.cs, yourMainBotLogic.cs, dialogClassName.cs, BotAccessors.cs which confuse me which are the steps the program is run on and how.
Please explain in detail why the pieces of code/components is needed/what use it has and why it has to be there in such files (e.g. Startup.cs). For example;
var accessors = new BotAccessors(conversationState) { ConversationDialogState = conversationState.CreateProperty<DialogState>("DialogState"), }; return accessors;
Create a accessor for the DialogState and then return it. This is just example and my description of the code might not be right.
Your question about how everything fits together is a bit broad, but I will attempt some explanation:
startup.cs: bot configuration should be loaded here, and singletons created. Including IStatePropertyAccessors. Many of the samples contain a BotConfig file with bot specific setup code, and call it from startup. Many samples also contain a bot file. Bot files can make loading some bot services easier. But, they aren't necessary. Ids and passwords can still be retrieved from App Settings, or web.config and your code can create the services.
Some things usually initialized in startup are:
ICredentialProvider is used by the sdk to create the BotAdapter and provide JWT Token Auth. For single appid/password bots, the SDK provides a SimpleCredentialProvider. If your bot is using the integration libraries, you can create one during the IBot initialization, or just supply the botConfig with appid/pass:
webapi:
public static void Register(HttpConfiguration config)
{
config.MapBotFramework(botConfig =>
{
var appId = ConfigurationManager.AppSettings[MicrosoftAppCredentials.MicrosoftAppIdKey];
var pass = ConfigurationManager.AppSettings[MicrosoftAppCredentials.MicrosoftAppPasswordKey];
botConfig.UseMicrosoftApplicationIdentity(appId, pass);
}
}
netcore:
public void ConfigureServices(IServiceCollection services)
{
services.AddBot(options =>
{
options.CredentialProvider = new SimpleCredentialProvider(appId, appPassword);
});
}
IStorage is an implementation for interacting with a state store. The sdk provides MemoryStorage CosmosDbStorage and AzureBlobStorage These are each just using JsonSerializer to store and retrieve objects from the underlying storage.
BotState are objects that provide keys into the IStorage implementation. The SDK provides three examples:
ConversationState scoped by {channelId}/conversations/{conversationId}
UserState scoped by {channelId}/users/{userId}
PrivateConversationState scoped by {channelId}/conversations/{conversationId}/users/{userId}
IStatePropertyAccessors These are an implementation layer providing for typed access into the scoped BotState explained above. When a get/set is performed, the actual state store is queried and persisted (through an internal cache provided by the sdk).
BotAccessors.cs is just a container to hold the state classes and IStatePropertyAccessors. This isn't needed, but is for convenience.
yourMainBotLogic.cs: this is where the adapter's OnTurn implementation exists, and should load the dialog stack and process the user's message. The dialog stack is managed by a dialog set that contains an IStatePropertyAccessor of DialogData type. When a get is performed on this property accessor by calling create context, the state store is queried to fill the dialog stack of the DialogContext.
dialogClassName.cs is a dialog implementation. The specific dialog types are delineated here: Dialog types Examples of how to use them are in the samples on github and documentation.
As with other asp.net applications, startup is run when the application first loads (see aspnet-web-api-poster or lifecycle-of-an-aspnet-mvc-5-application and note that the Microsoft.Bot.Builder.Integration.AspNet.Core uses an IApplicationBuilder extension to add the message handler to the request pipeline ApplicationBuilderExtensions and Microsoft.Bot.Builder.Integration.AspNet.WebApi uses an HttpMessageHandler implementation). However, you can choose to not use the integration libraries, and create your own controllers. Like this sample: MVC-Bot
V4 additional references
Implement sequential conversation flow
Create advanced conversation flow using branches and loops
Gather user input using a dialog prompt
Managing state
Save user and conversation data
Implement custom storage for your bot

Click-To-Call feature for Dynamics CRM (like Lync/Skype)

Advance warning: Im an absolute newbie to Dynamics CRM!
Intention
I want to have a feature like Lync/Skype integration but use my own URL. (Click on any telephone number inside CRM and call it).
For eg. assuming I have a web service which can initiate a call per URL: http://telephony.com/call?nr=012345678. Now, whenever a CRM user clicks onto a telephone number field (in forms and views) inside the CRM my web service should be called instead of Skype/Lync.
In fact I'm trying to reproduce sth. like the InGenius Connecter.
Attempts
I already tried to inject a JS web resource to a specific formular (in my case it was the default contact form) and override the Mscrm.ReadFormUtilities.openPhoneClient callback (which seems to handle the Lync/Skype integration).
function load() {
// override integrated CTC (Lync/Skype)
Mscrm.ReadFormUtilities.openPhoneClient = function (telephoneNr) {
// redirect user to my web service
window.location.replace("http://telephony.com/call?nr="+telephoneNr);
return;
}
}
Found this method at: Disable Lync completely
This does work well in forms of Dynamics 2015 (my custom link pops up instead of Skype/Lync). However, this does only work on entity forms since I can't inject web resources into an entity view.
My other ideas how to implement such a feature are:
Inject global JS resource which disables Lync/Skype and encapsulate every telephone number with link to my custom URL.
Extend/Manipulate Lync/Skype integration to use my custom URL instead of Lync/Skype.
Write plugin which encapsulate telephone numbers server side.
Question
Since I have a grasp understanding of Dynamics and no experience in plugin/resource development, I'm left a bit confused with these questions.
Is it possible to achieve any of the three ideas above ?
If not, any idea how InGenius solved this problem ?
Do you have any other idea/resources about this topic ?
Currently I found two options available to achieve a custom CTC feature. (Both has the downside of not being officialy supported by the dynamics crm.)
Global Ribbon
Pretty simple: Add a Click-To-Call button to global ribbon which is only enabled on specific grids when one row is selected.
This button refers to an JS-Action which retrieves the telephone number via ODATA and then launches the dial process.
Global Ribbon CustomRule injection
Add a global button to ribbon which refers to a JS resource per <CustomRule>. The JScript then unbinds all actions from links with .ms-crm-Phone classes and replaces its href-attribute.
This would be useful if one want to override the integrated "Skype / Lync - Click to Dial" feature with his own logic.
I didn't test this method until now, so I can't guarentee it's working !
Note: I will include example scripts as soon I got the time.

Is it possible to create External user profiles in IBM Connections using the ProfileAdminService?

I've been able to create new profiles in IBM Connections 5 using the ProfileAdminService but can't find any documentation on how to flag them as External.
The Social business toolkit doesn't expose the isExternal flag via the Profile object. I've tried to set it manually by
profile.setAsString("snx:isExternal","true");
or
profile.setAsString("isExternal","true");
but the created profile always end up being a normal/internal one.
Is this possible yet via the API?
Thanks
I figured this out over the weekend.
You CAN add external users using the connections ProfileAdminService but you CAN't do it yet using Social Business Toolkit (functionality not there yet)
To make it work I created my own build of SBT and added "userMode" to the ProfileAttributes. Caught me out initially as was looking for isExternal. Should have guessed it was mode as that's the name in the TDI assembly
com.ibm.sbt.services.client.connections.profiles.utils.ProfilesConstants
public enum ProfileAttribute {
GUID("guid", "com.ibm.snx_profiles.base.guid"),
EMAIL("email", "com.ibm.snx_profiles.base.email"),
UID("uid", "com.ibm.snx_profiles.base.uid"),
DISTINGUISHED_NAME("distinguishedName", "com.ibm.snx_profiles.base.distinguishedName"),
DISPLAY_NAME("displayName", "com.ibm.snx_profiles.base.displayName"),
GIVEN_NAMES("givenNames", "com.ibm.snx_profiles.base.givenNames"),
SURNAME("surname", "com.ibm.snx_profiles.base.surname"),
USER_STATE("userState", "com.ibm.snx_profiles.base.userState"),
USER_MODE("userMode","com.ibm.snx_profiles.base.userMode") // <<<added this line
;
`

Right way to consume a Web Service in WP7

I have a Web Service like ServiceA.asmx. What is the right way to consume it?
I have two ways to consume a service:
1)adding Service Refernce:
I have added Service Refernce of ServiceA.asmx ( Like in http://microsoftfeed.com/2011/part-14-how-to-consume-a-web-service-in-windows-phone-7) and i am able to call the Functions in Service like in the link i have given. If we use this way there is no need to parse the Result, Result returned in Objects(easy to use).
2)Hitting the URL and Calling asynchronously:
Here we can hit the URL, that function will call the asynchronous function that asynchronous function will return the response. But here response will be in XML here we have to parse that XML in to an Object.(not easy if any Big XML is there)
Please Guide me on this
Personally I would use the 'Add service reference' option. It's easy to use, and this option is added to Visual Studio especially for consuming web services. You can still use MVVM to build up your models/viewmodels.
I don't have the option to check it right now, but from my head the classes generated when adding the service reference also implement INotifyPropertyChanged. So you could probably use the object directly (if they are in the structure as you want to use it.) as your Model. Based on that model you can create your own ViewModel which you can bind to the UI.
To see how this works have a look at the code samples on MSDN:
Implementing the Model-View-ViewModel Pattern in a Windows Phone Application
Weather Forecast Sample

Resources