public MultiProviderAuthDialog(List <OAuthConnection> authenticationConnections, MicrosoftAppCredentials appCredentials = null) : base(nameof(MultiProviderAuthDialog)) { _authenticationConnections = authenticationConnections; _appCredentials = appCredentials; _responseManager = new ResponseManager( new string[] { "en", "de", "es", "fr", "it", "zh" }, new AuthenticationResponses()); var firstStep = new WaterfallStep[] { FirstStepAsync, }; var remoteAuth = new WaterfallStep[] { SendRemoteEventAsync, ReceiveRemoteEventAsync, }; var localAuth = new WaterfallStep[] { PromptForProviderAsync, PromptForAuthAsync, HandleTokenResponseAsync, }; AddDialog(new WaterfallDialog(DialogIds.FirstStepPrompt, firstStep)); // Add remote authentication support AddDialog(new WaterfallDialog(DialogIds.RemoteAuthPrompt, remoteAuth)); AddDialog(new EventPrompt(DialogIds.RemoteAuthEventPrompt, TokenEvents.TokenResponseEventName, TokenResponseValidatorAsync)); // If authentication connections are provided locally then we enable "local auth" otherwise we only enable remote auth where the calling Bot handles this for us. if (_authenticationConnections != null && _authenticationConnections.Any()) { bool authDialogAdded = false; foreach (var connection in _authenticationConnections) { // We ignore placeholder connections in config that don't have a Name if (!string.IsNullOrEmpty(connection.Name)) { AddDialog(new OAuthPrompt( connection.Name, new OAuthPromptSettings { ConnectionName = connection.Name, Title = "Login", Text = string.Format("Login with {0}", connection.Name), }, AuthPromptValidatorAsync)); authDialogAdded = true; } } // Only add Auth supporting local auth dialogs if we found valid authentication connections to use otherwise it will just work in remote mode. if (authDialogAdded) { AddDialog(new WaterfallDialog(DialogIds.LocalAuthPrompt, localAuth)); AddDialog(new ChoicePrompt(DialogIds.ProviderPrompt)); localAuthConfigured = true; } } else { throw new ArgumentNullException(nameof(authenticationConnections)); } }
// This method creates a MultiProviderAuthDialog based on a skill manifest. private MultiProviderAuthDialog BuildAuthDialog(SkillManifest skill, BotSettings settings, MicrosoftAppCredentials appCredentials) { if (skill.AuthenticationConnections?.Count() > 0) { if (settings.OAuthConnections.Any() && settings.OAuthConnections.Any(o => skill.AuthenticationConnections.Any(s => s.ServiceProviderId == o.Provider))) { var oauthConnections = settings.OAuthConnections.Where(o => skill.AuthenticationConnections.Any(s => s.ServiceProviderId == o.Provider)).ToList(); return(new MultiProviderAuthDialog(oauthConnections, appCredentials)); } else { throw new Exception($"You must configure at least one supported OAuth connection to use this skill: {skill.Name}."); } } return(null); }
public ShowToDoItemDialog( BotSettings settings, BotServices services, ConversationState conversationState, UserState userState, LocaleTemplateEngineManager localeTemplateEngineManager, IServiceManager serviceManager, IBotTelemetryClient telemetryClient, MicrosoftAppCredentials appCredentials, IHttpContextAccessor httpContext) : base(nameof(ShowToDoItemDialog), settings, services, conversationState, userState, localeTemplateEngineManager, serviceManager, telemetryClient, appCredentials, httpContext) { TelemetryClient = telemetryClient; var showTasks = new WaterfallStep[] { GetAuthToken, AfterGetAuthToken, ClearContext, DoShowTasks, }; var doShowTasks = new WaterfallStep[] { GetAuthToken, AfterGetAuthToken, ShowTasks, FirstReadMoreTasks, SecondReadMoreTasks, CollectGoBackToStartConfirmation, }; var firstReadMoreTasks = new WaterfallStep[] { CollectFirstReadMoreConfirmation, FirstReadMore, }; var secondReadMoreTasks = new WaterfallStep[] { CollectSecondReadMoreConfirmation, SecondReadMore, }; var collectFirstReadMoreConfirmation = new WaterfallStep[] { AskFirstReadMoreConfirmation, AfterAskFirstReadMoreConfirmation, }; var collectSecondReadMoreConfirmation = new WaterfallStep[] { AskSecondReadMoreConfirmation, AfterAskSecondReadMoreConfirmation, }; var collectGoBackToStartConfirmation = new WaterfallStep[] { AskGoBackToStartConfirmation, AfterAskGoBackToStartConfirmation, }; var collectRepeatFirstPageConfirmation = new WaterfallStep[] { AskRepeatFirstPageConfirmation, AfterAskRepeatFirstPageConfirmation, }; // Define the conversation flow using a waterfall model. AddDialog(new WaterfallDialog(Actions.ShowTasks, showTasks) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.DoShowTasks, doShowTasks) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.FirstReadMoreTasks, firstReadMoreTasks) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.SecondReadMoreTasks, secondReadMoreTasks) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.CollectFirstReadMoreConfirmation, collectFirstReadMoreConfirmation) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.CollectSecondReadMoreConfirmation, collectSecondReadMoreConfirmation) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.CollectGoBackToStartConfirmation, collectGoBackToStartConfirmation) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.CollectRepeatFirstPageConfirmation, collectRepeatFirstPageConfirmation) { TelemetryClient = telemetryClient }); // Set starting dialog for component InitialDialogId = Actions.ShowTasks; }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => options.EnableEndpointRouting = false).SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddSingleton <IConfiguration>(this.Configuration); // Create the credential provider to be used with the Bot Framework Adapter. services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>(); services.AddSingleton <InspectionMiddleware>(); // Load settings var settings = new BotSettings(); Configuration.Bind(settings); IStorage storage = null; // Configure storage for deployment if (!string.IsNullOrEmpty(settings.CosmosDb.AuthKey)) { storage = new CosmosDbStorage(settings.CosmosDb); } else { Console.WriteLine("The settings of CosmosDbStorage is incomplete, please check following settings: settings.CosmosDb"); storage = new MemoryStorage(); } services.AddSingleton(storage); var userState = new UserState(storage); var conversationState = new ConversationState(storage); var inspectionState = new InspectionState(storage); // Configure telemetry services.AddApplicationInsightsTelemetry(); var telemetryClient = new BotTelemetryClient(new TelemetryClient()); services.AddSingleton <IBotTelemetryClient>(telemetryClient); services.AddBotApplicationInsights(telemetryClient); var botFile = Configuration.GetSection("bot").Get <string>(); TypeFactory.Configuration = this.Configuration; // manage all bot resources var resourceExplorer = new ResourceExplorer().AddFolder(botFile); var credentials = new MicrosoftAppCredentials(this.Configuration["MicrosoftAppId"], this.Configuration["MicrosoftAppPassword"]); services.AddSingleton <IBotFrameworkHttpAdapter, BotFrameworkHttpAdapter>((s) => { var adapter = new BotFrameworkHttpAdapter(new ConfigurationCredentialProvider(this.Configuration)); adapter .UseStorage(storage) .UseState(userState, conversationState) .UseAdaptiveDialogs() .UseResourceExplorer(resourceExplorer) .UseLanguageGeneration(resourceExplorer, "common.lg") .Use(new RegisterClassMiddleware <IConfiguration>(Configuration)) .Use(new InspectionMiddleware(inspectionState, userState, conversationState, credentials)); if (!string.IsNullOrEmpty(settings.BlobStorage.ConnectionString) && !string.IsNullOrEmpty(settings.BlobStorage.Container)) { adapter.Use(new TranscriptLoggerMiddleware(new AzureBlobTranscriptStore(settings.BlobStorage.ConnectionString, settings.BlobStorage.Container))); } else { Console.WriteLine("The settings of TranscriptLoggerMiddleware is incomplete, please check following settings: settings.BlobStorage.ConnectionString, settings.BlobStorage.Container"); } adapter.OnTurnError = async(turnContext, exception) => { await turnContext.SendActivityAsync(exception.Message).ConfigureAwait(false); telemetryClient.TrackException(new Exception("Exceptions: " + exception.Message)); await conversationState.ClearStateAsync(turnContext).ConfigureAwait(false); await conversationState.SaveChangesAsync(turnContext).ConfigureAwait(false); }; return(adapter); }); services.AddSingleton <IBot, ComposerBot>((sp) => new ComposerBot("Main.dialog", conversationState, userState, resourceExplorer, DebugSupport.SourceMap, telemetryClient)); }
/// <summary> /// 送出透過Bot Framework所連接的訊息 /// </summary> /// <param name="data"></param> /// <returns></returns> private async Task SendBotFrameworkMessage(ConversationFile data) { var userAccount = new ChannelAccount(data.FromId, data.FromName); var botAccount = new ChannelAccount(data.RecipientId, data.RecipientName); var connector = new ConnectorClient(new Uri(data.ServiceUrl)); MicrosoftAppCredentials.TrustServiceUrl(data.ServiceUrl); // 取得要送出的訊息內容物件 List <PushObj.GetPushFileResult> push = new PushObj().GetPushFile(); for (int p = 0; p < push.Count; p++) { IMessageActivity message = Activity.CreateMessageActivity(); message.ChannelId = data.ChannelId; message.From = botAccount; message.Recipient = userAccount; message.Conversation = new ConversationAccount(id: data.ConversationId); message.Locale = "zh-tw"; // 放入推送訊息內容 message.Text = push[p].MainMessage; // 放入card for (int t = 0; t < push[p].cards.Count; t++) { List <CardImage> cardImages = new List <CardImage>(); List <CardAction> cardButtons = new List <CardAction>(); // 放入圖片 cardImages.Add(new CardImage(url: push[p].cards[t].ImageUrl)); // 放入Button for (int b = 0; b < push[p].cards[t].buttons.Count; b++) { CardAction plButton = new CardAction() { Value = push[p].cards[t].buttons[b].Url, Type = push[p].cards[t].buttons[b].ActionType, Title = push[p].cards[t].buttons[b].Title, }; cardButtons.Add(plButton); } if (push[p].PushType == "Thumbnail") { // 放入ThumbnailCard ThumbnailCard plCard = new ThumbnailCard() { Title = push[p].cards[t].Title, Subtitle = push[p].cards[t].SubTitle, Images = cardImages, Buttons = cardButtons }; Attachment plAttachment = plCard.ToAttachment(); message.Attachments.Add(plAttachment); } else if (push[p].PushType == "Hero") { HeroCard plCard = new HeroCard() { Title = push[p].cards[t].Title, Subtitle = push[p].cards[t].SubTitle, Images = cardImages, Buttons = cardButtons, }; Attachment plAttachment = plCard.ToAttachment(); message.Attachments.Add(plAttachment); } } message.AttachmentLayout = push[p].Layout; // 送出訊息 await connector.Conversations.SendToConversationAsync((Activity)message); } }
public async Task SendReminderChat(IBotFrameworkHttpAdapter adapter) { try { TelemetryClient.TrackTrace("Sending reminder from Bot", Severity.Information, null); var team = await this.tableService.getDailyChallengeTeamInfo(); var dailyChallenge = await tableService.GetDailyChallenge(); // If no photo selected, send update if (dailyChallenge.winnerName == null) { MicrosoftAppCredentials.TrustServiceUrl(team.ServiceUrl); TelemetryClient.TrackTrace("Sending MicrosoftAppId: " + Configuration["MicrosoftAppId"], Severity.Information, null); ConnectorClient connectorClient = new ConnectorClient(new Uri(team.ServiceUrl), Configuration["MicrosoftAppId"], Configuration["MicrosoftAppPassword"]); var teamName = await this.GetTeamNameAsync(connectorClient, team.TeamId); var bot = new ChannelAccount(team.BotId); string replyText = $"<at>@{teamName}</at> "; var activity = MessageFactory.Text(replyText); var mentioned = JObject.FromObject(new { id = team.TeamId, name = teamName }); var mentionedEntity = new Entity("mention") { Properties = JObject.FromObject(new { mentioned = mentioned, text = replyText }), }; activity.Entities = new[] { mentionedEntity }; activity.Text = "It's reminder time, " + replyText; var convParams = new ConversationParameters() { TenantId = team.TenantId, Bot = bot, IsGroup = true, ChannelData = team.ChannelData, Activity = (Activity)activity }; TelemetryClient.TrackTrace("ConvParams: " + JsonConvert.SerializeObject(convParams), Severity.Information, null); var conversation = await connectorClient.Conversations.CreateConversationAsync(convParams); BotAdapter ba = (BotAdapter)adapter; var conversationReference = new ConversationReference(conversation.ActivityId); conversationReference.Bot = bot; conversationReference.ChannelId = team.ChannelId; conversationReference.Conversation = new ConversationAccount(); var convAccount = new ConversationAccount(true, null, conversation.Id); convAccount.TenantId = team.TenantId; conversationReference.Conversation = convAccount; conversationReference.ServiceUrl = team.ServiceUrl; TelemetryClient.TrackTrace("Sending to Conversation", Severity.Information, null); await ba.ContinueConversationAsync(Configuration["MicrosoftAppId"], conversationReference, ReminderBotCallback, default(CancellationToken)); } } catch (Exception ex) { TelemetryClient.TrackTrace("Error sending reminder: " + ex.Message + ex.StackTrace, Severity.Error, null); Logger.LogError(ex, $"Error making pairups: {ex.Message}"); } }
/// <summary> /// Creates a conversation on the specified channel. /// </summary> /// <param name="channelId">The ID for the channel.</param> /// <param name="serviceUrl">The channel's service URL endpoint.</param> /// <param name="credentials">The application credentials for the bot.</param> /// <param name="conversationParameters">The conversation information to use to /// create the conversation.</param> /// <param name="callback">The method to call for the resulting bot turn.</param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A task that represents the work queued to execute.</returns> /// <remarks>To start a conversation, your bot must know its account information /// and the user's account information on that channel. /// Most _channels only support initiating a direct message (non-group) conversation. /// <para>The adapter attempts to create a new conversation on the channel, and /// then sends a <c>conversationUpdate</c> activity through its middleware pipeline /// to the <paramref name="callback"/> method.</para> /// <para>If the conversation is established with the /// specified users, the ID of the activity's <see cref="IActivity.Conversation"/> /// will contain the ID of the new conversation.</para> /// </remarks> public virtual async Task CreateConversationAsync(string channelId, string serviceUrl, MicrosoftAppCredentials credentials, ConversationParameters conversationParameters, BotCallbackHandler callback, CancellationToken cancellationToken) { var connectorClient = CreateConnectorClient(serviceUrl, credentials); var result = await connectorClient.Conversations.CreateConversationAsync(conversationParameters, cancellationToken).ConfigureAwait(false); // Create a conversation update activity to represent the result. var eventActivity = Activity.CreateEventActivity(); eventActivity.Name = "CreateConversation"; eventActivity.ChannelId = channelId; eventActivity.ServiceUrl = serviceUrl; eventActivity.Id = result.ActivityId ?? Guid.NewGuid().ToString("n"); eventActivity.Conversation = new ConversationAccount(id: result.Id); eventActivity.Recipient = conversationParameters.Bot; using (TurnContext context = new TurnContext(this, (Activity)eventActivity)) { ClaimsIdentity claimsIdentity = new ClaimsIdentity(); claimsIdentity.AddClaim(new Claim(AuthenticationConstants.AudienceClaim, credentials.MicrosoftAppId)); claimsIdentity.AddClaim(new Claim(AuthenticationConstants.AppIdClaim, credentials.MicrosoftAppId)); claimsIdentity.AddClaim(new Claim(AuthenticationConstants.ServiceUrlClaim, serviceUrl)); context.Services.Add <IIdentity>(BotIdentityKey, claimsIdentity); context.Services.Add(connectorClient); await RunPipelineAsync(context, callback, cancellationToken).ConfigureAwait(false); } }
public InspectionMiddleware(InspectionState inspectionState, UserState userState = null, ConversationState conversationState = null, MicrosoftAppCredentials credentials = null, ILogger <InspectionMiddleware> logger = null) : base(logger) { _inspectionState = inspectionState ?? throw new ArgumentNullException(nameof(inspectionState)); _userState = userState; _conversationState = conversationState; _credentials = credentials ?? MicrosoftAppCredentials.Empty; _httpClient = new Lazy <HttpClient>(() => new HttpClient()); }
public async static void SendThreadMessage(DataRow dr, DataTable dtWiadomosci, IList <Attachment> items) { try { // BaseDB.AddToLog("Wywołanie metody SendThreadMessage"); string uzytkownik = ""; if (items.Count > 0) { try { MicrosoftAppCredentials.TrustServiceUrl(@"https://facebook.botframework.com", DateTime.MaxValue); IMessageActivity message = Activity.CreateMessageActivity(); message.ChannelData = JObject.FromObject(new { notification_type = "REGULAR", quick_replies = new dynamic[] { new { content_type = "text", title = "Aktualności", payload = "DEVELOPER_DEFINED_PAYLOAD_Aktualnosci", // image_url = "https://cdn3.iconfinder.com/data/icons/developperss/PNG/Green%20Ball.png" // image_url = "http://archiwum.koluszki.pl/zdjecia/naglowki_nowe/listopad%202013/pi%C5%82ka[1].png" }, // new // { // content_type = "text", // title = "Galeria", // payload = "DEVELOPER_DEFINED_PAYLOAD_Galeria", //// image_url = "https://gim7bytom.edupage.org/global/pics/iconspro/sport/volleyball.png" // }, new { content_type = "text", title = "Sklep", payload = "DEVELOPER_DEFINED_PAYLOAD_Sklep", // image_url = "https://gim7bytom.edupage.org/global/pics/iconspro/sport/volleyball.png" }, new { content_type = "text", title = "Video", payload = "DEVELOPER_DEFINED_PAYLOAD_Video", // image_url = "https://www.samo-lepky.sk/data/11/hokej5.png" }, } }); message.AttachmentLayout = AttachmentLayoutTypes.Carousel; message.Attachments = items; try { var userAccount = new ChannelAccount(name: dr["UserName"].ToString(), id: dr["UserId"].ToString()); uzytkownik = userAccount.Name; var botAccount = new ChannelAccount(name: dr["BotName"].ToString(), id: dr["BotId"].ToString()); var connector = new ConnectorClient(new Uri(dr["Url"].ToString()), "8fa14720-e758-4cc7-82fd-fd6ad145ec90", "oExpuWnvj4oDAQnYHSpVrCJ"); var conversationId = await connector.Conversations.CreateDirectConversationAsync(botAccount, userAccount); message.From = botAccount; message.Recipient = userAccount; message.Conversation = new ConversationAccount(id: conversationId.Id, isGroup: false); await connector.Conversations.SendToConversationAsync((Activity)message).ConfigureAwait(false); } catch (Exception ex) { BaseDB.AddToLog("Błąd wysyłania wiadomości do: " + uzytkownik + " " + ex.ToString()); } } catch (Exception ex) { BaseDB.AddToLog("Błąd wysyłania wiadomości do: " + uzytkownik + " " + ex.ToString()); } } } catch (Exception ex) { BaseDB.AddToLog("Błąd wysłania wiadomosci: " + ex.ToString()); } }
public static IContainer Build(bool isDebugging) { var builder = new ContainerBuilder(); builder .RegisterType <DialogInvoker>() .As <IDialogInvoker>(); builder .RegisterModule <AttributedMetadataModule>(); // Using a Telemetry Client per request, so user context, etc is unique per request. builder .RegisterType <TelemetryClient>() .SingleInstance(); var microsoftAppCredentials = new MicrosoftAppCredentials(Config.MicrosoftApplicationId, Config.MicrosoftAppPassword); // When debugging with the bot emulator we need to use the listening url from the emulator. if (isDebugging && !string.IsNullOrEmpty(Config.EmulatorListeningUrl)) { builder.Register(c => new StateClient(new Uri(Config.EmulatorListeningUrl), microsoftAppCredentials)); } else { builder.Register(c => new StateClient(microsoftAppCredentials)); } builder .RegisterType <BotState>() .AsImplementedInterfaces(); builder .RegisterType <AuthenticationService>() .WithParameter("appSecret", Config.ApplicationSecret) .WithParameter("authorizeUrl", Config.AuthorizeUrl) .AsImplementedInterfaces(); builder .RegisterType <BotService>() .AsImplementedInterfaces(); builder .RegisterType <VstsService>() .AsImplementedInterfaces(); builder .RegisterControllers(typeof(Bootstrap).Assembly); builder .RegisterApiControllers(typeof(Bootstrap).Assembly); builder .RegisterAssemblyTypes(typeof(Bootstrap).Assembly) .Where(t => t.GetInterfaces().Any(i => i.IsAssignableFrom(typeof(IDialog <object>)))) .Except <ConnectDialog>() .Except <RootDialog>() .AsImplementedInterfaces(); builder .RegisterType <ConnectDialog>() .WithParameter("appId", Config.ApplicationId) .WithParameter("appScope", Config.ApplicationScope) .WithParameter("authorizeUrl", Config.AuthorizeUrl) .AsImplementedInterfaces(); builder .RegisterType <RootDialog>() .AsSelf(); return(builder.Build()); }
/// <summary> /// Initializes a new instance of the <see cref="ProcessNowController"/> class. /// </summary> /// <param name="bot">The Icebreaker bot instance</param> /// <param name="botCredentials">The bot AAD credentials</param> public ProcessNowController(IcebreakerBot bot, MicrosoftAppCredentials botCredentials) { this.bot = bot; this.botCredentials = botCredentials; }
/// <summary> /// Initializes a new instance of the <see cref="MessagesController"/> class. /// </summary> /// <param name="configuration">The configuration.</param> public MessagesController(IConfiguration configuration) { appCredentials = new MicrosoftAppCredentials(configuration); }
public static async Task <bool> DoExport() { // REPLACE with REAL APPID and PASSWORD var credentials = new MicrosoftAppCredentials("MsAppId", "MsAppPassword"); StringBuilder outputMessage = new StringBuilder(); string continuationToken = ""; // REPLACE with bot framework API var stateUrl = new Uri("https://intercom-api-scratch.azurewebsites.net"); MicrosoftAppCredentials.TrustServiceUrl(stateUrl.AbsoluteUri); var client = new StateClient(stateUrl, credentials); var state = client.BotState; BotStateDataResult stateResult = null; do { try { // should work with "directline", "facebook", or "kik" stateResult = await BotStateExtensions.ExportBotStateDataAsync(state, "directline", continuationToken).ConfigureAwait(false); foreach (var datum in stateResult.BotStateData) { outputMessage.Append($"conversationID: {datum.ConversationId}\tuserId: {datum.UserId}\tdata:{datum.Data}\n"); // If you were exporting into a new bot state store, here is where you would write the data //if (string.IsNullOrEmpty(datum.ConversationId)) //{ // // use SetUserData(datum.UserId, data.Data); //} //else //{ // SetPrivateConversationData(datum.UserId, datum.ConversationId, datum.Data); //} } continuationToken = stateResult.ContinuationToken; } catch (Exception e) { Console.WriteLine(e); } } while (!string.IsNullOrEmpty(continuationToken)); Console.WriteLine(outputMessage.ToString()); continuationToken = null; outputMessage = new StringBuilder(); // REPLACE with channel's URL. var connectionsUrl = new Uri("http://ic-directline-scratch.azurewebsites.net"); MicrosoftAppCredentials.TrustServiceUrl(connectionsUrl.AbsoluteUri); var connectorClient = new ConnectorClient(connectionsUrl, credentials); var conversations = connectorClient.Conversations; ConversationsResult conversationResults = null; do { try { conversationResults = await conversations.GetConversationsAsync(continuationToken).ConfigureAwait(false); if (conversationResults == null) { outputMessage.Append("Internal error, conversation results was empty"); } else if (conversationResults.Conversations == null) { outputMessage.Append("No conversations found for this bot in this channel"); } else { outputMessage.Append($"Here is a batch of {conversationResults.Conversations.Count} conversations:\n"); foreach (var conversationMembers in conversationResults.Conversations) { string members = string.Join(", ", conversationMembers.Members.Select(member => member.Id)); outputMessage.Append($"Conversation: {conversationMembers.Id} members: {members}\n"); } } } catch (Exception e) { Console.WriteLine(e); } continuationToken = conversationResults?.Skip; // should be ContinuationToken (this version is built on an old library } while (!string.IsNullOrEmpty(continuationToken)); Console.WriteLine(outputMessage.ToString()); return(true); }
public AppBotConfig(string app, string appPassword) { Console.WriteLine("appId: " + app); Console.WriteLine("appPwd: " + appPassword); _creds = new MicrosoftAppCredentials(app, appPassword); }
/// <inheritdoc/> public async Task <CreateConversationResponse> CreateConversationAsync( string teamsUserId, string tenantId, string serviceUrl, int maxAttempts, ILogger log) { if (string.IsNullOrEmpty(teamsUserId)) { throw new ArgumentException($"'{nameof(teamsUserId)}' cannot be null or empty", nameof(teamsUserId)); } if (string.IsNullOrEmpty(tenantId)) { throw new ArgumentException($"'{nameof(tenantId)}' cannot be null or empty", nameof(tenantId)); } if (string.IsNullOrEmpty(serviceUrl)) { throw new ArgumentException($"'{nameof(serviceUrl)}' cannot be null or empty", nameof(serviceUrl)); } if (log is null) { throw new ArgumentNullException(nameof(log)); } // Set the service URL in the trusted list to ensure the SDK includes the token in the request. MicrosoftAppCredentials.TrustServiceUrl(serviceUrl); var conversationParameters = new ConversationParameters { TenantId = tenantId, Members = new ChannelAccount[] { new ChannelAccount { Id = teamsUserId, }, }, }; var response = new CreateConversationResponse(); try { var retryPolicy = this.GetRetryPolicy(maxAttempts, log); await retryPolicy.ExecuteAsync(async() => await this.botAdapter.CreateConversationAsync( channelId: ConversationService.MicrosoftTeamsChannelId, serviceUrl: serviceUrl, credentials: this.appCredentials, conversationParameters: conversationParameters, callback: (turnContext, cancellationToken) => { // Success. response.Result = Result.Succeeded; response.StatusCode = (int)HttpStatusCode.Created; response.ConversationId = turnContext.Activity.Conversation.Id; return(Task.CompletedTask); }, cancellationToken: CancellationToken.None)); } catch (ErrorResponseException e) { var errorMessage = $"{e.GetType()}: {e.Message}"; log.LogError(e, $"Failed to create conversation. Exception message: {errorMessage}"); var statusCode = e.Response.StatusCode; response.StatusCode = (int)statusCode; response.ErrorMessage = e.Response.Content; response.Result = statusCode == HttpStatusCode.TooManyRequests ? Result.Throttled : Result.Failed; } return(response); }
public static async Task <Tuple <ConversationReference, string> > SendMessageToTeamsChannelAsync(ITurnContext turnContext, IActivity activity, string teamsChannelId, MicrosoftAppCredentials credentials, CancellationToken cancellationToken = default) { if (turnContext == null) { throw new ArgumentNullException(nameof(turnContext)); } if (turnContext.Activity == null) { throw new InvalidOperationException(nameof(turnContext.Activity)); } if (string.IsNullOrEmpty(teamsChannelId)) { throw new ArgumentNullException(nameof(teamsChannelId)); } if (credentials == null) { throw new ArgumentNullException(nameof(credentials)); } ConversationReference conversationReference = null; var newActivityId = string.Empty; var serviceUrl = turnContext.Activity.ServiceUrl; var conversationParameters = new ConversationParameters { IsGroup = true, ChannelData = new { channel = new { id = teamsChannelId } }, Activity = (Activity)activity, }; await((BotFrameworkAdapter)turnContext.Adapter).CreateConversationAsync( teamsChannelId, serviceUrl, credentials, conversationParameters, (t, ct) => { conversationReference = t.Activity.GetConversationReference(); newActivityId = t.Activity.Id; return(Task.CompletedTask); }, cancellationToken).ConfigureAwait(false); return(new Tuple <ConversationReference, string>(conversationReference, newActivityId)); }
/// <summary> /// Generate pairups and send pairup notifications. /// </summary> /// <returns>The number of pairups that were made</returns> public async Task <int> MakePairsAndNotify() { this.telemetryClient.TrackTrace("Making pairups"); // Recall all the teams where we have been added // For each team where bot has been added: // Pull the roster of the team // Remove the members who have opted out of pairups // Match each member with someone else // Save this pair // Now notify each pair found in 1:1 and ask them to reach out to the other person // When contacting the user in 1:1, give them the button to opt-out var installedTeamsCount = 0; var pairsNotifiedCount = 0; var usersNotifiedCount = 0; try { var teams = await this.dataProvider.GetInstalledTeamsAsync(); installedTeamsCount = teams.Count; this.telemetryClient.TrackTrace($"Generating pairs for {installedTeamsCount} teams"); foreach (var team in teams) { this.telemetryClient.TrackTrace($"Pairing members of team {team.Id}"); try { MicrosoftAppCredentials.TrustServiceUrl(team.ServiceUrl); var connectorClient = new ConnectorClient(new Uri(team.ServiceUrl)); var teamName = await this.GetTeamNameAsync(connectorClient, team.TeamId); var optedInUsers = await this.GetOptedInUsers(connectorClient, team); foreach (var pair in this.MakePairs(optedInUsers).Take(this.maxPairUpsPerTeam)) { usersNotifiedCount += await this.NotifyPair(connectorClient, team.TenantId, teamName, pair); pairsNotifiedCount++; } } catch (Exception ex) { this.telemetryClient.TrackTrace($"Error pairing up team members: {ex.Message}", SeverityLevel.Warning); this.telemetryClient.TrackException(ex); } } } catch (Exception ex) { this.telemetryClient.TrackTrace($"Error making pairups: {ex.Message}", SeverityLevel.Warning); this.telemetryClient.TrackException(ex); } // Log telemetry about the pairups var properties = new Dictionary <string, string> { { "InstalledTeamsCount", installedTeamsCount.ToString() }, { "PairsNotifiedCount", pairsNotifiedCount.ToString() }, { "UsersNotifiedCount", usersNotifiedCount.ToString() }, }; this.telemetryClient.TrackEvent("ProcessedPairups", properties); this.telemetryClient.TrackTrace($"Made {pairsNotifiedCount} pairups, {usersNotifiedCount} notifications sent"); return(pairsNotifiedCount); }
/// <summary> /// Create Connector client. /// </summary> /// <param name="serviceUrl">Service URL to initiate the connection.</param> private IConnectorClient CreateConnectorClient(string serviceUrl) { MicrosoftAppCredentials.TrustServiceUrl(serviceUrl, DateTime.MaxValue); return(new ConnectorClient(new Uri(serviceUrl))); }
/// <summary> /// Lists the Conversations in which this bot has participated for a given channel server. The /// channel server returns results in pages and each page will include a `continuationToken` /// that can be used to fetch the next page of results from the server. /// </summary> /// <param name="serviceUrl">The URL of the channel server to query. This can be retrieved /// from `context.activity.serviceUrl`. </param> /// <param name="credentials">The credentials needed for the Bot to connect to the services.</param> /// <param name="continuationToken"></param> /// <param name="cancellationToken">A cancellation token that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A task that represents the work queued to execute.</returns> /// <remarks>If the task completes successfully, the result contains the members of the current conversation. /// This overload may be called from outside the context of a conversation, as only the /// bot's service URL and credentials are required. /// </remarks> public async Task <ConversationsResult> GetConversationsAsync(string serviceUrl, MicrosoftAppCredentials credentials, string continuationToken, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(serviceUrl)) { throw new ArgumentNullException(nameof(serviceUrl)); } if (credentials == null) { throw new ArgumentNullException(nameof(credentials)); } var connectorClient = CreateConnectorClient(serviceUrl, credentials); var results = await connectorClient.Conversations.GetConversationsAsync(continuationToken, cancellationToken).ConfigureAwait(false); return(results); }
public MarkToDoItemDialog( BotSettings settings, BotServices services, ConversationState conversationState, UserState userState, LocaleTemplateEngineManager localeTemplateEngineManager, IServiceManager serviceManager, IBotTelemetryClient telemetryClient, MicrosoftAppCredentials appCredentials, IHttpContextAccessor httpContext) : base(nameof(MarkToDoItemDialog), settings, services, conversationState, userState, localeTemplateEngineManager, serviceManager, telemetryClient, appCredentials, httpContext) { TelemetryClient = telemetryClient; var markTask = new WaterfallStep[] { GetAuthToken, AfterGetAuthToken, ClearContext, CollectListTypeForComplete, GetAuthToken, AfterGetAuthToken, InitAllTasks, DoMarkTask, }; var doMarkTask = new WaterfallStep[] { CollectTaskIndexForComplete, GetAuthToken, AfterGetAuthToken, MarkTaskCompleted, ContinueMarkTask, }; var collectListTypeForComplete = new WaterfallStep[] { AskListType, AfterAskListType, }; var collectTaskIndexForComplete = new WaterfallStep[] { AskTaskIndex, AfterAskTaskIndex, }; var continueMarkTask = new WaterfallStep[] { AskContinueMarkTask, AfterAskContinueMarkTask, }; // Define the conversation flow using a waterfall model. AddDialog(new WaterfallDialog(Actions.DoMarkTask, doMarkTask) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.MarkTaskCompleted, markTask) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.CollectListTypeForComplete, collectListTypeForComplete) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.CollectTaskIndexForComplete, collectTaskIndexForComplete) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.ContinueMarkTask, continueMarkTask) { TelemetryClient = telemetryClient }); // Set starting dialog for component InitialDialogId = Actions.MarkTaskCompleted; }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); // Load settings var settings = new BotSettings(); Configuration.Bind(settings); services.AddSingleton(settings); // Configure credentials services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>(); var appCredentials = new MicrosoftAppCredentials(settings.MicrosoftAppId, settings.MicrosoftAppPassword); services.AddSingleton(appCredentials); // Configure telemetry services.AddApplicationInsightsTelemetry(); services.AddSingleton <IBotTelemetryClient, BotTelemetryClient>(); services.AddSingleton <ITelemetryInitializer, OperationCorrelationTelemetryInitializer>(); services.AddSingleton <ITelemetryInitializer, TelemetryBotIdInitializer>(); services.AddSingleton <TelemetryInitializerMiddleware>(); services.AddSingleton <TelemetryLoggerMiddleware>(); // Configure bot services var botservices = new BotServices(settings, new BotTelemetryClient(new Microsoft.ApplicationInsights.TelemetryClient())); services.AddSingleton(botservices); // Configure storage // Uncomment the following line for local development without Cosmos Db // services.AddSingleton<IStorage, MemoryStorage>(); services.AddSingleton <IStorage>(new CosmosDbStorage(settings.CosmosDb)); services.AddSingleton <UserState>(); services.AddSingleton <ConversationState>(); // Configure localized responses var localizedTemplates = new Dictionary <string, List <string> >(); var templateFiles = new List <string>() { "MainResponses", "OnboardingResponses" }; var supportedLocales = new List <string>() { "en-us", "de-de", "es-es", "fr-fr", "it-it", "zh-cn" }; foreach (var locale in supportedLocales) { var localeTemplateFiles = new List <string>(); foreach (var template in templateFiles) { // LG template for default locale should not include locale in file extension. if (locale.Equals(settings.DefaultLocale ?? "en-us")) { localeTemplateFiles.Add(Path.Combine(".", "Responses", $"{template}.lg")); } else { localeTemplateFiles.Add(Path.Combine(".", "Responses", $"{template}.{locale}.lg")); } } localizedTemplates.Add(locale, localeTemplateFiles); } services.AddSingleton(new LocaleTemplateEngineManager(localizedTemplates, settings.DefaultLocale ?? "en-us")); // Register dialogs services.AddTransient <MainDialog>(); services.AddTransient <OnboardingDialog>(); // SAMPLE: Multi-turn QnA dialog var currentLocale = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName; services.AddTransient(s => new QnADialog(botservices.CognitiveModelSets[currentLocale].QnAServices["HRBenefits"])); // SAMPLE: Proactive notifications services.AddSingleton <ProactiveState>(); // Register skill dialogs foreach (var skill in settings.Skills) { var authDialog = BuildAuthDialog(skill, settings, appCredentials); var credentials = new MicrosoftAppCredentialsEx(settings.MicrosoftAppId, settings.MicrosoftAppPassword, skill.MSAappId); services.AddTransient(sp => { var userState = sp.GetService <UserState>(); var telemetryClient = sp.GetService <IBotTelemetryClient>(); return(new SkillDialog(skill, credentials, telemetryClient, userState, authDialog)); }); } // IBotFrameworkHttpAdapter now supports both http and websocket transport services.AddSingleton <IBotFrameworkHttpAdapter, DefaultAdapter>(); // Configure bot services.AddTransient <IBot, DefaultActivityHandler <MainDialog> >(); }
public async static Task <IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, TraceWriter log) { var account = CloudStorageAccount.Parse("<Please insert your storage account key>"); client = account.CreateCloudTableClient(); CloudTable table = client.GetTableReference("ConversationInformation"); await table.CreateIfNotExistsAsync(); TableOperation getOperation = TableOperation.Retrieve <ConversationInformation>(partitionKey: "ConversationInformation", rowkey: "default-user"); var info = await table.ExecuteAsync(getOperation); var conversationInformation = info.Result as ConversationInformation; var reference = JsonConvert.DeserializeObject <ConversationReference>(conversationInformation.ConversationReference); //TODO: Need to refactor. log.Info("C# HTTP trigger function processed a request."); //Parse body from ChatPlus' webhook //string requestBody = new StreamReader(req.Body).ReadToEnd(); //var data = body["data"]; //var res = JsonConvert.DeserializeObject<WebhookSendMessageResponse>(data); var body = await req.ReadFormAsync(); body.TryGetValue("data", out StringValues bodydata); string test = bodydata; string decodedContent = WebUtility.UrlDecode(test); var res = JsonConvert.DeserializeObject <ChatPlusInformation>(test); //ChatPlusInformation webhookResponse = JsonConvert.DeserializeObject<ChatPlusInformation>(requestBody); //string name = webhookResponse.visitor.visitor_id; string name = "default user"; //Get conversation reference from input binding //ConversationReference reference = JsonConvert.DeserializeObject<ConversationReference>(conversationInformationList.OrderByDescending(r => r.Timestamp).First().ConversationReference); //ConversationReference reference = JsonConvert.DeserializeObject<ConversationReference>(conversationInformation.ConversationReference); //Create Connector Client var appCredential = new MicrosoftAppCredentials("<Microsoft App Id>", "Microsoft App Password"); //string MicrosoftAppId = configuration["MicrosoftAppId"]; //string MicrosoftAppPassword = configuration["MicrosoftAppPassword"]; //var appCredential = new MicrosoftAppCredentials(MicrosoftAppId, MicrosoftAppPassword); MicrosoftAppCredentials.TrustServiceUrl(reference.ServiceUrl); var connector = new ConnectorClient(new Uri(reference.ServiceUrl), appCredential); //Compose activity if (res.type != "chat_start") { var proactiveMessage = Activity.CreateMessageActivity(); proactiveMessage.From = reference.Bot; proactiveMessage.Conversation = reference.Conversation; proactiveMessage.Text = res.message.text; try { await connector.Conversations.SendToConversationAsync((Activity)proactiveMessage); } catch (Exception e) { Console.Write(e.Message); } } //Return 200 or 400 to web client return(name != null ? (ActionResult) new OkObjectResult($"Hello, {name} (id:{reference.User.Id})") : new BadRequestObjectResult("Please pass a name on the query string or in the request body")); }
public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequestMessage req, TraceWriter log) { log.Info("SendToConversation C# HTTP trigger function processed a request."); // parse query parameters string messageText = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "message", true) == 0) .Value; string toName = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "toname", true) == 0) .Value; string toId = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "toid", true) == 0) .Value; string fromId = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "fromid", true) == 0) .Value; string fromName = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "fromname", true) == 0) .Value; string serviceUrl = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "serviceurl", true) == 0) .Value; string appId = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "appid", true) == 0) .Value; string appPassword = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "apppassword", true) == 0) .Value; // Get request body dynamic data = await req.Content.ReadAsAsync <object>(); // Set name to query string or body data messageText = messageText ?? data?.messagetext; toName = toName ?? data?.toname; toId = toId ?? data?.toid; fromId = fromId ?? data?.fromid; fromName = fromName ?? data?.fromname; serviceUrl = serviceUrl ?? data?.serviceurl; appId = appId ?? data?.appid; appPassword = appPassword ?? data?.apppassword; try { var userAccount = new ChannelAccount(toId, toName); var botAccount = new ChannelAccount(fromId, fromName); MicrosoftAppCredentials.TrustServiceUrl(serviceUrl); MicrosoftAppCredentials creds = new MicrosoftAppCredentials(appId, appPassword); var connector = new ConnectorClient(new Uri(serviceUrl), creds); IMessageActivity message = Activity.CreateMessageActivity(); var conversationId = (await connector.Conversations.CreateDirectConversationAsync(botAccount, userAccount)).Id; message.From = botAccount; message.Recipient = userAccount; message.Conversation = new ConversationAccount(id: conversationId); message.Text = messageText; message.Locale = "en-Us"; await connector.Conversations.SendToConversationAsync((Activity)message); return(req.CreateResponse(HttpStatusCode.OK)); } catch (Exception ex) { return(req.CreateResponse(HttpStatusCode.InternalServerError, ex.ToString())); } }
public async Task CreateConversationOverloadProperlySetsTenantId() { // Arrange const string activityIdName = "ActivityId"; const string activityIdValue = "SendActivityId"; const string conversationIdName = "Id"; const string conversationIdValue = "NewConversationId"; const string tenantIdValue = "theTenantId"; const string eventActivityName = "CreateConversation"; Func <Task <HttpResponseMessage> > createResponseMessage = () => { var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK); response.Content = new StringContent(new JObject { { activityIdName, activityIdValue }, { conversationIdName, conversationIdValue } }.ToString()); return(Task.FromResult(response)); }; var mockCredentialProvider = new Mock <ICredentialProvider>(); var mockHttpMessageHandler = new Mock <HttpMessageHandler>(); mockHttpMessageHandler.Protected() .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>()) .Returns((HttpRequestMessage request, CancellationToken cancellationToken) => createResponseMessage()); var httpClient = new HttpClient(mockHttpMessageHandler.Object); var adapter = new BotFrameworkAdapter(mockCredentialProvider.Object, customHttpClient: httpClient); var activity = new Activity("test") { ChannelId = Channels.Msteams, ServiceUrl = "https://fake.service.url", ChannelData = new JObject { ["tenant"] = new JObject { ["id"] = tenantIdValue }, }, Conversation = new ConversationAccount { TenantId = tenantIdValue }, }; var parameters = new ConversationParameters() { Activity = new Activity() { ChannelData = activity.ChannelData, }, }; var reference = activity.GetConversationReference(); var credentials = new MicrosoftAppCredentials(string.Empty, string.Empty, httpClient); Activity newActivity = null; Task UpdateParameters(ITurnContext turnContext, CancellationToken cancellationToken) { newActivity = turnContext.Activity; return(Task.CompletedTask); } // Act await adapter.CreateConversationAsync(activity.ChannelId, activity.ServiceUrl, credentials, parameters, UpdateParameters, reference, new CancellationToken()); // Assert - all values set correctly Assert.AreEqual(tenantIdValue, JObject.FromObject(newActivity.ChannelData)["tenant"]["tenantId"]); Assert.AreEqual(activityIdValue, newActivity.Id); Assert.AreEqual(conversationIdValue, newActivity.Conversation.Id); Assert.AreEqual(tenantIdValue, newActivity.Conversation.TenantId); Assert.AreEqual(eventActivityName, newActivity.Name); }
public ShowEventsDialog( BotSettings settings, BotServices services, ResponseManager responseManager, ConversationState conversationState, UpdateEventDialog updateEventDialog, ChangeEventStatusDialog changeEventStatusDialog, IServiceManager serviceManager, IBotTelemetryClient telemetryClient, MicrosoftAppCredentials appCredentials) : base(nameof(ShowEventsDialog), settings, services, responseManager, conversationState, serviceManager, telemetryClient, appCredentials) { TelemetryClient = telemetryClient; var showMeetings = new WaterfallStep[] { GetAuthToken, AfterGetAuthToken, SetSearchCondition, }; var searchEvents = new WaterfallStep[] { SearchEventsWithEntities, FilterTodayEvent, AddConflictFlag, ShowAskParameterDetails, ShowEventsList }; var showNextMeeting = new WaterfallStep[] { ShowNextMeeting, }; var showEventsOverview = new WaterfallStep[] { ShowEventsOverview, PromptForNextAction, HandleNextAction }; var showEventsOverviewAgain = new WaterfallStep[] { ShowEventsOverviewAgain, PromptForNextAction, HandleNextAction }; var showFilteredEvents = new WaterfallStep[] { ShowFilteredEvents, PromptForNextAction, HandleNextAction }; var readEvent = new WaterfallStep[] { GetAuthToken, AfterGetAuthToken, ReadEvent, PromptForNextActionAfterRead, HandleNextActionAfterRead, }; var updateEvent = new WaterfallStep[] { UpdateEvent, ReShow }; var changeEventStatus = new WaterfallStep[] { ChangeEventStatus, ReShow }; var reshow = new WaterfallStep[] { AskForShowOverview, AfterAskForShowOverview }; // Define the conversation flow using a waterfall model. AddDialog(new WaterfallDialog(Actions.ShowEvents, showMeetings) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.SearchEvents, searchEvents) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.ShowNextEvent, showNextMeeting) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.ShowEventsOverview, showEventsOverview) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.ShowEventsOverviewAgain, showEventsOverviewAgain) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.ShowFilteredEvents, showFilteredEvents) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.ChangeEventStatus, changeEventStatus) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.UpdateEvent, updateEvent) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.Read, readEvent) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.Reshow, reshow) { TelemetryClient = telemetryClient }); AddDialog(updateEventDialog ?? throw new ArgumentNullException(nameof(updateEventDialog))); AddDialog(changeEventStatusDialog ?? throw new ArgumentNullException(nameof(changeEventStatusDialog))); // Set starting dialog for component InitialDialogId = Actions.ShowEvents; }
/// <summary> /// Registers dependencies with the <paramref name="builder"/>. /// </summary> /// <param name="builder"> The container builder.</param> protected override void Load(ContainerBuilder builder) { builder.RegisterType <ConnectorStore>() .AsSelf() .InstancePerLifetimeScope(); // if application settings indicate that bot should use the table storage, // TableBotDataStore will be registered as underlying storage // otherwise bot connector state service will be used. if (ShouldUseTableStorage()) { builder.Register(c => MakeTableBotDataStore()) .Keyed <IBotDataStore <BotData> >(Key_DataStore) .AsSelf() .SingleInstance(); } else { builder.Register(c => new ConnectorStore(c.Resolve <IStateClient>())) .Keyed <IBotDataStore <BotData> >(Key_DataStore) .AsSelf() .InstancePerLifetimeScope(); } // register the data store with caching data store // and set the consistency policy to be "Last write wins". builder.Register(c => new CachingBotDataStore(c.ResolveKeyed <IBotDataStore <BotData> >(Key_DataStore), CachingBotDataStoreConsistencyPolicy.LastWriteWins)) .As <IBotDataStore <BotData> >() .AsSelf() .InstancePerLifetimeScope(); // register the appropriate StateClient based on the state api url. builder.Register(c => { var activity = c.Resolve <IActivity>(); if (activity.ChannelId == "emulator") { // for emulator we should use serviceUri of the emulator for storage return(new StateClient(new Uri(activity.ServiceUrl))); } MicrosoftAppCredentials.TrustServiceUrl(BotService.stateApi.Value, DateTime.MaxValue); return(new StateClient(new Uri(BotService.stateApi.Value))); }) .As <IStateClient>() .InstancePerLifetimeScope(); // register the bot service serialization binder for type mapping to current assembly builder.Register(c => new BotServiceSerializationBinder(assembly)) .AsSelf() .As <SerializationBinder>() .InstancePerLifetimeScope(); // register the Delegate surrogate provide to map delegate to current assembly during deserialization builder .Register(c => new BotServiceDelegateSurrogate(assembly)) .AsSelf() .InstancePerLifetimeScope(); // extend surrogate providers with bot service delegate surrogate provider and register the surrogate selector builder .Register(c => { var providers = c.ResolveKeyed <IEnumerable <Serialization.ISurrogateProvider> >(FiberModule.Key_SurrogateProvider).ToList(); // need to add the latest delegate surrogate to make sure that surrogate selector // can deal with latest assembly providers.Add(c.Resolve <BotServiceDelegateSurrogate>()); return(new Serialization.SurrogateSelector(providers)); }) .As <ISurrogateSelector>() .InstancePerLifetimeScope(); // register binary formatter used for binary serialization operation builder .Register((c, p) => new BinaryFormatter(c.Resolve <ISurrogateSelector>(), new StreamingContext(StreamingContextStates.All, c.Resolve <Serialization.StoreInstanceByTypeSurrogate.IResolver>(p))) { AssemblyFormat = FormatterAssemblyStyle.Simple, Binder = c.Resolve <SerializationBinder>() }) .As <IFormatter>() .InstancePerLifetimeScope(); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); var provider = services.BuildServiceProvider(); // Load settings var settings = new BotSettings(); Configuration.Bind(settings); services.AddSingleton(settings); // Configure credentials services.AddSingleton <ICredentialProvider, ConfigurationCredentialProvider>(); var appCredentials = new MicrosoftAppCredentials(settings.MicrosoftAppId, settings.MicrosoftAppPassword); services.AddSingleton(appCredentials); // Configure telemetry services.AddApplicationInsightsTelemetry(); var telemetryClient = new BotTelemetryClient(new TelemetryClient()); services.AddSingleton <IBotTelemetryClient>(telemetryClient); services.AddBotApplicationInsights(telemetryClient); // Configure bot services services.AddSingleton <BotServices>(); // Configure storage // Uncomment the following line for local development without Cosmos Db // services.AddSingleton<IStorage, MemoryStorage>(); services.AddSingleton <IStorage>(new CosmosDbStorage(settings.CosmosDb)); services.AddSingleton <UserState>(); services.AddSingleton <ConversationState>(); services.AddSingleton(sp => { var userState = sp.GetService <UserState>(); var conversationState = sp.GetService <ConversationState>(); return(new BotStateSet(userState, conversationState)); }); // Register dialogs services.AddTransient <CancelDialog>(); services.AddTransient <EscalateDialog>(); services.AddTransient <MainDialog>(); services.AddTransient <OnboardingDialog>(); // Register skill dialogs services.AddTransient(sp => { var userState = sp.GetService <UserState>(); var skillDialogs = new List <SkillDialog>(); foreach (var skill in settings.Skills) { var authDialog = BuildAuthDialog(skill, settings, appCredentials); var credentials = new MicrosoftAppCredentialsEx(settings.MicrosoftAppId, settings.MicrosoftAppPassword, skill.MSAappId); skillDialogs.Add(new SkillDialog(skill, credentials, telemetryClient, userState, authDialog)); } return(skillDialogs); }); // Configure adapters // DefaultAdapter is for all regular channels that use Http transport services.AddSingleton <IBotFrameworkHttpAdapter, DefaultAdapter>(); // DefaultWebSocketAdapter is for directline speech channel // This adapter implementation is currently a workaround as // later on we'll have a WebSocketEnabledHttpAdapter implementation that handles // both Http for regular channels and websocket for directline speech channel services.AddSingleton <WebSocketEnabledHttpAdapter, DefaultWebSocketAdapter>(); // Configure bot services.AddTransient <IBot, DialogBot <MainDialog> >(); }
public DeleteToDoItemDialog( BotSettings settings, BotServices services, ResponseManager responseManager, ConversationState conversationState, UserState userState, IServiceManager serviceManager, IBotTelemetryClient telemetryClient, MicrosoftAppCredentials appCredentials) : base(nameof(DeleteToDoItemDialog), settings, services, responseManager, conversationState, userState, serviceManager, telemetryClient, appCredentials) { TelemetryClient = telemetryClient; var deleteTask = new WaterfallStep[] { GetAuthToken, AfterGetAuthToken, ClearContext, CollectListTypeForDelete, InitAllTasks, DoDeleteTask, }; var doDeleteTask = new WaterfallStep[] { CollectTaskIndexForDelete, CollectAskDeletionConfirmation, DeleteTask, ContinueDeleteTask, }; var collectListTypeForDelete = new WaterfallStep[] { AskListType, AfterAskListType, }; var collectTaskIndexForDelete = new WaterfallStep[] { AskTaskIndex, AfterAskTaskIndex, }; var collectDeleteTaskConfirmation = new WaterfallStep[] { AskDeletionConfirmation, AfterAskDeletionConfirmation, }; var continueDeleteTask = new WaterfallStep[] { AskContinueDeleteTask, AfterAskContinueDeleteTask, }; // Define the conversation flow using a waterfall model. AddDialog(new WaterfallDialog(Actions.DoDeleteTask, doDeleteTask) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.DeleteTask, deleteTask) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.CollectListTypeForDelete, collectListTypeForDelete) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.CollectTaskIndexForDelete, collectTaskIndexForDelete) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.CollectDeleteTaskConfirmation, collectDeleteTaskConfirmation) { TelemetryClient = telemetryClient }); AddDialog(new WaterfallDialog(Actions.ContinueDeleteTask, continueDeleteTask) { TelemetryClient = telemetryClient }); // Set starting dialog for component InitialDialogId = Actions.DeleteTask; }
/// <summary> /// POST: api/Messages /// Receive a message from a user and reply to it /// </summary> public async Task <HttpResponseMessage> Post([FromBody] Activity activity) { Switches[] switches = null; MicrosoftAppCredentials creds = new MicrosoftAppCredentials(ConfigurationManager.AppSettings["MicrosoftappID"], ConfigurationManager.AppSettings["MicrosoftappPassword"]); ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl)); //making sure to create on instance of the HTTPclient with its headers if (j == 0) { string accessToken = ConfigurationManager.AppSettings["accessToken"]; client.BaseAddress = new Uri($"https://graph-na02-useast1.api.smartthings.com:443/api/smartapps/installations/" + ConfigurationManager.AppSettings["SmartThingsSubscription"] + "/switches"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken); j++; } if (activity.Type == ActivityTypes.Message) { Activity reply1; string caseInput; //Parsing String into individual words var parseForSpaces = activity.Text.Where(Char.IsPunctuation).Distinct().ToArray(); var individualInputWords = activity.Text.Split().Select(x => x.Trim(parseForSpaces)); //Checking if one word or multiple words were sent in the message if (individualInputWords.ToArray().Length > 1) { caseInput = individualInputWords.ToArray()[0] + " " + individualInputWords.ToArray()[1]; } else { caseInput = individualInputWords.ToArray()[0]; } //Case for responses back to client switch (caseInput.ToLower()) { case "turn on": calltoSmartThings(client, activity, individualInputWords.ToArray(), responsemain, switches, connector); break; //if the first two words are turn off, turn off case "turn off": calltoSmartThings(client, activity, individualInputWords.ToArray(), responsemain, switches, connector); break; //Default will return the current status of all the resources connected to the app default: //"What lights are on?": try { switches = await GetSwitchesAsync(""); for (int i = switches.Length - 1; i >= 0; i--) { reply1 = activity.CreateReply($"Light/Device: {switches[i].name}\tStatus: {switches[i].value}\tDimmerLevel: {switches[i].dimmer}"); responsemain.EnsureSuccessStatusCode(); await connector.Conversations.ReplyToActivityAsync(reply1); } break; } catch { } break; } } else { HandleSystemMessage(activity); } return(responsemain); }
public static async Task NotifySubscribers(UserScubaData userScubaData, BotAdapter adapter, MicrosoftAppCredentials workingCredentials, ConversationReference reserverReference = null) { if (reserverReference != null) { var scubaReservation = new Tuple <ConversationReference, UserScubaData>(reserverReference, userScubaData); _recentReservations.AddOrUpdate(reserverReference.User.Id, scubaReservation, (key, oldValue) => scubaReservation); //todo: this should not be a hard coded url userScubaData.ChatWithUserUrl = "https://contososcubademo.azurewebsites.net?chatWithId=" + reserverReference.User.Id; //chatWithUserIdUrl = "Use this URL to chat with them: http://localhost:3979?chatWithId=" + reserverReference.User.Id; } string message = $"New scuba booking for {userScubaData.PersonalInfo.Name}"; var replaceInfo = new Dictionary <string, string>(); replaceInfo.Add("{{destination}}", userScubaData.Destination); replaceInfo.Add("{{school}}", userScubaData.School); replaceInfo.Add("{{longdate}}", Convert.ToDateTime(userScubaData.Date).ToString("dddd, MMMM dd")); replaceInfo.Add("{{number_of_people}}", userScubaData.NumberOfPeople); replaceInfo.Add("{{phone}}", userScubaData.PersonalInfo.Phone); replaceInfo.Add("{{email}}", userScubaData.PersonalInfo.Email); replaceInfo.Add("{{name}}", userScubaData.PersonalInfo.Name); replaceInfo.Add("{{protein_preference}}", userScubaData.MealOptions.ProteinPreference); replaceInfo.Add("{{vegan}}", userScubaData.MealOptions.Vegan ? "Yes" : "No"); replaceInfo.Add("{{allergy}}", userScubaData.MealOptions.Alergy); if (!string.IsNullOrEmpty(userScubaData.ChatWithUserUrl)) { replaceInfo.Add("{{url}}", userScubaData.ChatWithUserUrl); } var subscriberCardText = await CardProvider.GetCardText("SubscriberNotification", replaceInfo); var conversationCallback = GetConversationCallback(message, workingCredentials, subscriberCardText); await SendActionableMessage(userScubaData); foreach (var subscriber in _reservationSubscribers.Values) { await adapter.ContinueConversation(subscriber.Bot.Id, subscriber, conversationCallback); } }