Example #1
0
        public async Task <object> Post(AuthHelper.AuthorizeArgs args)
        {
            try
            {
                Trace.WriteLine($"Webhook was triggered!");

                // Initialize the azure bot
                using (BotService.Initialize())
                {
                    // BotBuilder insists on getting from the default config - this overrides it
                    Conversation.UpdateContainer(b =>
                    {
                        b.RegisterInstance(new MicrosoftAppCredentials(
                                               Config.GetAppSetting("MicrosoftAppId"),
                                               Config.GetAppSetting("MicrosoftAppPassword")
                                               ));
                    });
                    var message = await AuthHelper.Process(Request.GetRequestUri(), args.state, args.code, args.error, args.error_description);

                    return(Content(message, "text/html"));
                }
            }
            catch (Exception ex)
            {
                MessagesController.TelemetryClient.TrackException(ex);
                throw;
            }
        }
        public static async Task Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer, TraceWriter log)
        {
            using (BotService.Initialize())
            {
                var subscriptionFacade = new SubscriptionFacade();
                var reportsFacade      = new ReportsFacade();
                var unavailableDevices = await reportsFacade.GetUnavailableDeviceReports();

                var subscriptions = (await subscriptionFacade.GetAllSubscriptions()).ToArray();

                foreach (var subscription in subscriptions.Where(t => t.LastActivity != null && DateTime.UtcNow.Subtract(t.LastActivity.Created) > TimeSpan.FromDays(1)))
                {
                    var connector = new ConnectorClient(new Uri(subscription.ServiceUrl), Environment.GetEnvironmentVariable("MicrosoftAppId"), Environment.GetEnvironmentVariable("MicrosoftAppPassword"));
                    await connector.Conversations.DeleteActivityAsync(subscription.LastActivity.ConversationId, subscription.LastActivity.ActitityId);

                    subscription.LastActivity = null;
                    await subscriptionFacade.UpdateBotSubscription(subscription);
                }

                foreach (var deviceGroup in unavailableDevices.GroupBy(t => t.Group))
                {
                    var message    = new DeviceStatusMessage(deviceGroup.ToList());
                    var recipients = subscriptions.Where(t => t.GroupName == deviceGroup.Key);
                    await message.SendMessageToChannel("Found unavailable devices!", recipients);
                }
            }
        }
Example #3
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            try
            {
                using (BotService.Initialize())
                {
                    var activity = JsonConvert.DeserializeObject <Activity>(await req.Content.ReadAsStringAsync());
                    if (!await BotService.Authenticator.TryAuthenticateAsync(req, new[] { activity }, CancellationToken.None))
                    {
                        return(BotAuthenticator.GenerateUnauthorizedResponse(req));
                    }

                    if (activity != null)
                    {
                        switch (activity.GetActivityType())
                        {
                        case ActivityTypes.Message:
                            await Conversation.SendAsync(activity, () => new RootDialog());

                            break;

                        case ActivityTypes.ConversationUpdate:
                            var client = new ConnectorClient(new Uri(activity.ServiceUrl));
                            IConversationUpdateActivity update = activity;
                            if (update.MembersAdded.Any())
                            {
                                var reply      = activity.CreateReply();
                                var newMembers = update.MembersAdded?.Where(t => t.Id != activity.Recipient.Id);
                                foreach (var newMember in newMembers)
                                {
                                    reply.Text = "Welcome";
                                    if (!string.IsNullOrEmpty(newMember.Name))
                                    {
                                        reply.Text += $" {newMember.Name}";
                                    }
                                    reply.Text += "!";
                                    await client.Conversations.ReplyToActivityAsync(reply);
                                }
                            }
                            break;

                        case ActivityTypes.ContactRelationUpdate:
                        case ActivityTypes.Typing:
                        case ActivityTypes.DeleteUserData:
                        case ActivityTypes.Ping:
                        default:
                            log.Error($"Unknown activity type ignored: {activity.GetActivityType()}");
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error("Error", ex);
                throw;
            }

            return(req.CreateResponse(HttpStatusCode.Accepted));
        }
Example #4
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestMessage req, TraceWriter log)
        {
            using (BotService.Initialize())
            {
                // Deserialize the incoming activity
                string jsonContent = await req.Content.ReadAsStringAsync();

                var activity = JsonConvert.DeserializeObject <Activity>(jsonContent);
                // authenticate incoming request and add activity.ServiceUrl to MicrosoftAppCredentials.TrustedHostNames
                // if request is authenticated
                if (!await BotService.Authenticator.TryAuthenticateAsync(req, new[] { activity }, CancellationToken.None))
                {
                    return(BotAuthenticator.GenerateUnauthorizedResponse(req));
                }

                if (activity != null)
                {
                    // one of these will have an interface and process it
                    switch (activity.GetActivityType())
                    {
                    case ActivityTypes.Message:
                        await Conversation.SendAsync(activity, () => new JiraDialog());

                        break;

                    default:
                        log.Error($"Unknown activity type ignored: {activity.GetActivityType()}");
                        break;
                    }
                }
                return(req.CreateResponse(HttpStatusCode.Accepted));
            }
        }
Example #5
0
        public static async Task <object> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "messages")] HttpRequestMessage req, TraceWriter log)
        {
            log.Info($"Webhook was triggered!");

            // Initialize the azure bot
            using (BotService.Initialize())
            {
                // Deserialize the incoming activity
                string jsonContent = await req.Content.ReadAsStringAsync();

                var activity = JsonConvert.DeserializeObject <Activity>(jsonContent);

                // authenticate incoming request and add activity.ServiceUrl to MicrosoftAppCredentials.TrustedHostNames
                // if request is authenticated
                if (!await BotService.Authenticator.TryAuthenticateAsync(req, new[] { activity }, CancellationToken.None))
                {
                    return(BotAuthenticator.GenerateUnauthorizedResponse(req));
                }

                if (activity != null)
                {
                    // one of these will have an interface and process it
                    switch (activity.GetActivityType())
                    {
                    case ActivityTypes.Message:
                        await Conversation.SendAsync(activity, () => new FindMyAgeDialog());

                        break;

                    case ActivityTypes.ConversationUpdate:
                        var client = new ConnectorClient(new Uri(activity.ServiceUrl));
                        IConversationUpdateActivity update = activity;
                        if (update.MembersAdded.Any())
                        {
                            var reply      = activity.CreateReply();
                            var newMembers = update.MembersAdded?.Where(t => t.Id != activity.Recipient.Id);
                            foreach (var newMember in newMembers)
                            {
                                reply.Text = "Hey there. Welcome to Image Recognition Bot. Send me a photo and I will tell you what it contains!";
                                await client.Conversations.ReplyToActivityAsync(reply);
                            }
                        }
                        break;

                    case ActivityTypes.ContactRelationUpdate:
                    case ActivityTypes.Typing:
                    case ActivityTypes.DeleteUserData:
                    case ActivityTypes.Ping:
                    default:
                        log.Error($"Unknown activity type ignored: {activity.GetActivityType()}");
                        break;
                    }
                }
                return(req.CreateResponse(HttpStatusCode.Accepted));
            }
        }
Example #6
0
        public static async Task StartBot()
        {
            BotService service = new BotService();

            bool success = await service.Initialize();

            if (success)
            {
                await Task.Delay(-1);
            }
        }
        public static async Task <object> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestMessage req, TraceWriter log)
        {
            log.Info("PolicyEnquiry was triggered!");

            // Initialize the azure bot
            using (BotService.Initialize())
            {
                ConfigureStateStore();

                // Deserialize the incoming activity
                var activity = JsonConvert.DeserializeObject <Activity>(await req.Content.ReadAsStringAsync());

                // authenticate incoming request and add activity.ServiceUrl to MicrosoftAppCredentials.TrustedHostNames
                // if request is authenticated
                if (!await BotService.Authenticator.TryAuthenticateAsync(req, new[] { activity }, CancellationToken.None))
                {
                    return(BotAuthenticator.GenerateUnauthorizedResponse(req));
                }

                if (activity != null)
                {
                    // one of these will have an interface and process it
                    switch (activity.GetActivityType())
                    {
                    case ActivityTypes.Message:
                        await Conversation.SendAsync(activity, () => new RootDialog());

                        break;

                    case ActivityTypes.ConversationUpdate:
                        var client = new ConnectorClient(new Uri(activity.ServiceUrl));
                        IConversationUpdateActivity update = activity;

                        if (update.MembersAdded.Any())
                        {
                            var reply = activity.CreateReply();
                            reply.Text = "Hey! I am Polen. I can answer quick questions for your policy.";
                            await client.Conversations.ReplyToActivityAsync(reply);
                        }
                        break;

                    default:
                        log.Error($"Unknown activity type ignored: {activity.GetActivityType()}");
                        break;
                    }
                }

                return(req.CreateResponse(HttpStatusCode.Accepted));
            }
        }
Example #8
0
        public static async Task <object> BotMessageHandler([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "bot/messages", WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            // Initialize the azure bot
            using (BotService.Initialize())
            {
                // Deserialize the incoming activity
                string jsonContent = await req.Content.ReadAsStringAsync();

                var activity = JsonConvert.DeserializeObject <Activity> (jsonContent);

                // authenticate incoming request and add activity.ServiceUrl to MicrosoftAppCredentials.TrustedHostNames
                // if request is authenticated
                if (!await BotService.Authenticator.TryAuthenticateAsync(req, new[] { activity }, CancellationToken.None))
                {
                    return(BotAuthenticator.GenerateUnauthorizedResponse(req));
                }

                if (activity != null)
                {
                    if (activity.GetActivityType() == ActivityTypes.Message)
                    {
                        var typing = activity.CreateReply();

                        typing.Type = ActivityTypes.Typing;

                        await activity.ClientForReply().Conversations.ReplyToActivityAsync(typing);

                        if (SimpleQnAMakerDialog.IsQuestion(activity.Text))
                        {
                            await Conversation.SendAsync(activity, () => new SimpleQnAMakerDialog());
                        }
                        else
                        {
                            await Conversation.SendAsync(activity, () => new FaqDialog());
                        }
                    }
                    else
                    {
                        var reply = HandleSystemMessage(activity, log);

                        if (reply != null)
                        {
                            await activity.ClientForReply().Conversations.ReplyToActivityAsync(reply);
                        }
                    }
                }

                return(req.CreateResponse(HttpStatusCode.Accepted));
            }
        }
Example #9
0
        public static async Task <object> Run([HttpTrigger(WebHookType = "genericJson")] HttpRequestMessage req, TraceWriter log)
        {
            // Initialize the azure bot
            using (BotService.Initialize())
            {
                log.Info($"Webhook was triggered! - messages");

                string jsonContent = await req.Content.ReadAsStringAsync();

                var activity = JsonConvert.DeserializeObject <Activity>(jsonContent);

                if (activity != null)
                {
                    // one of these will have an interface and process it
                    switch (activity.GetActivityType())
                    {
                    case ActivityTypes.Message:
                        //here is where we will navigate to root dialogue
                        await Conversation.SendAsync(activity, () => new RootDialog());

                        //var client = new ConnectorClient(new Uri(activity.ServiceUrl));
                        //var triggerReply = activity.CreateReply();

                        //triggerReply.Text = $"Hey you said '{activity.Text}'.";
                        //await client.Conversations.ReplyToActivityAsync(triggerReply);

                        break;

                    case ActivityTypes.ConversationUpdate:

                        if (activity.MembersAdded.Any(o => o.Id == activity.Recipient.Id))
                        {
                            var reply = activity.CreateReply("Welcome to our Bot!");
                            reply.AddHeroCard("Where do you want to go?", MenuHelpers.getMenuOptions("Home"));

                            ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

                            await connector.Conversations.ReplyToActivityAsync(reply);
                        }

                        break;

                    default:
                        log.Error($"Unknown activity type ignored: {activity.GetActivityType()}");
                        break;
                    }
                }
                return(req.CreateResponse(HttpStatusCode.Accepted));
            }
        }
Example #10
0
        // 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);

            services.AddSingleton <IGraphLogger, GraphLogger>(_ => new GraphLogger("AI4Bharat.ISLBot", redirectToTrace: true));
            services.AddSingleton <InMemoryObserver, InMemoryObserver>();
            services.Configure <AzureSettings>(Configuration.GetSection(nameof(AzureSettings)));
            services.PostConfigure <AzureSettings>(az => az.Initialize());
            services.AddSingleton <IBotService, BotService>(provider =>
            {
                var bot = new BotService(
                    provider.GetRequiredService <IGraphLogger>(),
                    provider.GetRequiredService <IOptions <AzureSettings> >());
                bot.Initialize();
                return(bot);
            });
        }
Example #11
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            await _botService.Initialize();

            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);

                var unreadMails = await _mailService.GetUnreadMails();

                if (unreadMails != null)
                {
                    _logger.LogInformation($"{unreadMails.Count} unread mails, sending!");
                    foreach (var unreadMail in unreadMails)
                    {
                        var embed = new EmbedBuilder
                        {
                            Title = unreadMail.Subject, Color = Color.Green
                        };
                        embed.AddField("From", unreadMail.FromMail);
                        if (!unreadMail.IsHtml)
                        {
                            embed.AddField("Message", unreadMail.Message);
                        }
                        embed.Footer =
                            new EmbedFooterBuilder().WithText($"Received at {unreadMail.InboxTime:f}");

                        if (unreadMail.IsHtml)
                        {
                            var    converter = new HtmlConverter();
                            var    bytes     = converter.FromHtmlString(unreadMail.Message);
                            Stream stream    = new MemoryStream(bytes);
                            embed.ImageUrl = $"attachment://html.jpeg";
                            await _botService.UploadImage(stream, "html.jpeg", embed.Build());
                        }
                        else
                        {
                            await _botService.SendEmbed(embed.Build());
                        }
                    }
                }
                await Task.Delay(1000 *30, stoppingToken);
            }
        }
Example #12
0
        public static async Task <HttpResponseMessage> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = "messages")]
            HttpRequestMessage request,
            TraceWriter log
            )
        {
            log.Info("C# HTTP trigger function processed a request.");

            using (BotService.Initialize())
            {
                using (BotService.Initialize())
                {
                    string jsonContent = await request.Content.ReadAsStringAsync();

                    var activity = JsonConvert.DeserializeObject <Activity>(jsonContent);

                    if (!await BotService.Authenticator.TryAuthenticateAsync(request, new[] { activity }, CancellationToken.None))
                    {
                        return(BotAuthenticator.GenerateUnauthorizedResponse(request));
                    }

                    if (activity != null)
                    {
                        switch (activity.GetActivityType())
                        {
                        case ActivityTypes.Message:
                            await Conversation.SendAsync(activity, () => new RootDialog());

                            break;

                        case ActivityTypes.ConversationUpdate:
                        case ActivityTypes.ContactRelationUpdate:
                        case ActivityTypes.Typing:
                        case ActivityTypes.DeleteUserData:
                        case ActivityTypes.Ping:
                        default:
                            break;
                        }
                    }

                    return(request.CreateResponse(HttpStatusCode.Accepted));
                }
            }
        }
        public async Task <object> Post([FromBody] Activity activity)
        {
            try
            {
                // Initialize the azure bot
                using (BotService.Initialize())
                {
                    // BotBuilder insists on getting from the default config - this overrides it
                    Conversation.UpdateContainer(b =>
                    {
                        b.RegisterInstance(new MicrosoftAppCredentials(
                                               Config.GetAppSetting("MicrosoftAppId"),
                                               Config.GetAppSetting("MicrosoftAppPassword")
                                               ));
                    });
                    // use this to check what the registered value is
                    // ((MicrosoftAppCredentials)(Conversation.Container.ComponentRegistry.TryGetRegistration(new Autofac.Core.TypedService(typeof(MicrosoftAppCredentials)), out var xxx) ? Conversation.Container.ResolveComponent(xxx, new Autofac.Core.Parameter[0]) : null)).MicrosoftAppId

                    // Deserialize the incoming activity
                    //string jsonContent = await req.Content.ReadAsStringAsync();
                    //var activity = JsonConvert.DeserializeObject<Activity>(jsonContent);

                    // authenticate incoming request and add activity.ServiceUrl to MicrosoftAppCredentials.TrustedHostNames
                    // if request is authenticated
                    var authHeader    = this.Request.Headers.GetCommaSeparatedValues(HeaderNames.Authorization);
                    var authParts     = authHeader[0].Split(new[] { ' ' }, 2);
                    var identityToken = await BotService.Authenticator.TryAuthenticateAsync(authParts[0], authParts[1], CancellationToken.None);

                    if (null == identityToken || !identityToken.Authenticated)
                    {
                        this.Response.Headers.Add("WWW-Authenticate", $"Bearer realm=\"{Request.Host}\"");
                        return(Unauthorized());
                    }
                    identityToken.ValidateServiceUrlClaim(new[] { activity });
                    MicrosoftAppCredentials.TrustServiceUrl(activity.ServiceUrl);

                    if (activity != null)
                    {
                        // one of these will have an interface and process it
                        switch (activity.GetActivityType())
                        {
                        case ActivityTypes.Message:
                            var text = activity.AsMessageActivity().Text ?? "";
                            Trace.WriteLine($"Recieved message: '{text}' from {activity.From.Id}/{activity.From.Name} on {activity.ChannelId}/{activity.Conversation.IsGroup.GetValueOrDefault()}");
                            Trace.WriteLine($"  ChannelData: {(activity.ChannelData as JObject)}");
                            Trace.WriteLine($"  Conversation: {activity.Conversation.ConversationType}, id: {activity.Conversation.Id}, name: {activity.Conversation.Name}, role: {activity.Conversation.Role}, properties: {activity.Conversation.Properties}");
                            Trace.WriteLine($"  From: {activity.From.Id}/{activity.From.Name}, role: {activity.From.Role}, properties: {activity.From.Properties}");
                            Trace.WriteLine($"  Recipient: {activity.Recipient.Id}/{activity.Recipient.Name}, role: {activity.Recipient.Role}, properties: {activity.Recipient.Properties}");
                            if (text.Contains("</at>") && activity.ChannelId == "msteams")
                            {
                                // ignore the mention of us in the reply
                                text = new Regex("<at>.*</at>").Replace(text, "").Trim();
                            }

                            if (activity.ChannelId == "slack")
                            {
                                var mentions = activity.Entities.Where(i => i.Type == "mention").Select(i =>
                                                                                                        i.Properties.ToAnonymousObject(new
                                {
                                    mentioned = new { id = "", name = "" },
                                    text      = ""
                                }))
                                               .ToList();

                                // ignore any group messages that don't mention us
                                if (activity.Conversation.IsGroup.GetValueOrDefault() &&
                                    !mentions.Any(i => i.mentioned.name == activity.Recipient.Name))
                                {
                                    break;
                                }

                                // filter out any mentions - we don't really care about them...
                                foreach (var mention in mentions)
                                {
                                    if (!string.IsNullOrEmpty(mention.text))
                                    {
                                        text = text.Replace(mention.text, "");
                                    }
                                }

                                // set up the conversation so we'll be in the thread
                                string thread_ts = ((dynamic)activity.ChannelData)?.SlackMessage?.@event?.thread_ts;
                                string ts        = ((dynamic)activity.ChannelData)?.SlackMessage?.@event?.ts;
                                if (string.IsNullOrEmpty(thread_ts) && !string.IsNullOrEmpty(ts) && activity.Conversation.Id.Split(':').Length == 3)
                                {
                                    // this is a main-channel conversation - pretend it came in on a thread
                                    activity.Conversation.Id += $":{ts}";
                                    Trace.WriteLine($"  Modified Conversation: {activity.Conversation.ConversationType}, id: {activity.Conversation.Id}, name: {activity.Conversation.Name}, role: {activity.Conversation.Role}, properties: {activity.Conversation.Properties}");
                                }
                            }

                            activity.AsMessageActivity().Text = text.Trim();

                            Trace.WriteLine($"Processing message: '{text}' from {activity.From.Id}/{activity.From.Name} on {activity.ChannelId}/{activity.Conversation.IsGroup.GetValueOrDefault()}");
                            await Conversation.SendAsync(activity, () => new ExceptionHandlerDialog <object>(new BotDialog(Request.GetRequestUri()), true));

                            break;

                        case ActivityTypes.ConversationUpdate:
                            var client = new ConnectorClient(new Uri(activity.ServiceUrl), new MicrosoftAppCredentials(
                                                                 Config.GetAppSetting("MicrosoftAppId"),
                                                                 Config.GetAppSetting("MicrosoftAppPassword")
                                                                 ));
                            IConversationUpdateActivity update = activity;
                            if (update.MembersAdded?.Any() ?? false)
                            {
                                var reply      = activity.CreateReply();
                                var newMembers = update.MembersAdded?.Where(t => t.Id != activity.Recipient.Id);
                                foreach (var newMember in newMembers)
                                {
                                    reply.Text = "Welcome";
                                    if (!string.IsNullOrEmpty(newMember.Name))
                                    {
                                        reply.Text += $" {newMember.Name}";
                                    }
                                    reply.Text += ", this is a bot from Rightpoint Labs Beta - say 'info' for more.";
                                    await client.Conversations.ReplyToActivityAsync(reply);
                                }
                            }
                            break;

                        case ActivityTypes.ContactRelationUpdate:
                        case ActivityTypes.Typing:
                        case ActivityTypes.DeleteUserData:
                        case ActivityTypes.Ping:
                        default:
                            Trace.WriteLine($"Unknown activity type ignored: {activity.GetActivityType()}");
                            break;
                        }
                    }
                    return(Accepted());
                }
            }
            catch (Exception ex)
            {
                TelemetryClient.TrackException(ex);
                throw;
            }
        }
Example #14
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequestMessage req, TraceWriter log)
        {
            log.Info("Callback was triggered!");

            using (BotService.Initialize())
            {
                ConfigureStateStore();
                GetQueryParams(req, out var code, out var state);

                try
                {
                    // Use the state parameter to get correct IAuthProvider and ResumptionCookie
                    var           decoded      = Encoding.UTF8.GetString(HttpServerUtility.UrlTokenDecode(state) ?? throw new InvalidOperationException());
                    var           queryString  = HttpUtility.ParseQueryString(decoded);
                    var           assembly     = Assembly.Load(queryString["providerassembly"]);
                    var           type         = assembly.GetType(queryString["providertype"]);
                    var           providername = queryString["providername"];
                    IAuthProvider authProvider;

                    if (type.GetConstructor(new[] { typeof(string) }) != null)
                    {
                        authProvider = (IAuthProvider)Activator.CreateInstance(type, providername);
                    }

                    else
                    {
                        authProvider = (IAuthProvider)Activator.CreateInstance(type);
                    }

                    // Get the conversation reference
                    var conversationRef = UrlToken.Decode <ConversationReference>(queryString["conversationRef"]);
                    var message         = conversationRef.GetPostToBotMessage();

                    var  magicNumber     = GenerateRandomNumber();
                    var  writeSuccessful = false;
                    uint writeAttempts   = 0;

                    using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
                    {
                        // Get the UserData from the original conversation
                        var stateStore = scope.Resolve <IBotDataStore <BotData> >();
                        var key        = Address.FromActivity(message);
                        var userData   = await stateStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None);

                        // Get Access Token using authorization code
                        var authOptions = userData.GetProperty <AuthenticationOptions>($"{authProvider.Name}{ContextConstants.AuthOptions}");
                        var token       = await authProvider.GetTokenByAuthCodeAsync(authOptions, code);

                        // Generate magic number and attempt to write to userdata
                        while (!writeSuccessful && writeAttempts++ < MaxWriteAttempts)
                        {
                            try
                            {
                                userData.SetProperty($"{authProvider.Name}{ContextConstants.AuthResultKey}", token);

                                if (authOptions.UseMagicNumber)
                                {
                                    userData.SetProperty($"{authProvider.Name}{ContextConstants.MagicNumberKey}", magicNumber);
                                    userData.SetProperty($"{authProvider.Name}{ContextConstants.MagicNumberValidated}", "false");
                                }

                                await stateStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);

                                await stateStore.FlushAsync(key, CancellationToken.None);

                                writeSuccessful = true;
                            }
                            catch (Exception ex)
                            {
                                log.Error(ex.Message);
                                writeSuccessful = false;
                            }
                        }

                        var resp = new HttpResponseMessage(HttpStatusCode.OK);

                        if (!writeSuccessful)
                        {
                            message.Text = string.Empty; // fail the login process if we can't write UserData
                            await Conversation.ResumeAsync(conversationRef, message);

                            resp.Content = new StringContent("<html><body>Could not log you in at this time, please try again later</body></html>", Encoding.UTF8, @"text/html");

                            return(resp);
                        }

                        await Conversation.ResumeAsync(conversationRef, message);

                        // check if the user has configured an alternate magic number view
                        if (!String.IsNullOrEmpty(authOptions.MagicNumberView))
                        {
                            var redirect = req.CreateResponse(HttpStatusCode.Moved);
                            redirect.Headers.Location = new Uri(String.Format(authOptions.MagicNumberView, magicNumber), UriKind.Relative);

                            return(redirect);
                        }

                        resp.Content = new StringContent($"<html><body>Almost done! Please copy this number and paste it back to your chat so your authentication can complete:<br/> <h1>{magicNumber}</h1>.</body></html>", Encoding.UTF8, @"text/html");

                        return(resp);
                    }
                }
                catch (Exception ex)
                {
                    // Callback is called with no pending message as a result the login flow cannot be resumed.
                    return(req.CreateErrorResponse(HttpStatusCode.BadRequest, ex));
                }
            }
        }
        public static async Task <object> Dispatch <T>(HttpRequestMessage req, IContainer container) where T : ActivityDispatcher
        {
            using (BotService.Initialize())
            {
                var jsonContent = await req.Content.ReadAsStringAsync();

                var activity = JsonConvert.DeserializeObject <Activity>(jsonContent);

                if (!await BotService.Authenticator.TryAuthenticateAsync(req, new[] { activity }, CancellationToken.None))
                {
                    return(BotAuthenticator.GenerateUnauthorizedResponse(req));
                }

                if (activity == null)
                {
                    return(req.CreateResponse(HttpStatusCode.Accepted));
                }

                using (var scope = DialogModule.BeginLifetimeScope(container, activity))
                {
                    var dispatcherTarget = scope.Resolve <T>();

                    switch (activity.GetActivityType())
                    {
                    case ActivityTypes.Message:
                        await dispatcherTarget.OnMessage(activity);

                        break;

                    case ActivityTypes.ConversationUpdate:
                        await dispatcherTarget.OnConversationUpdate(activity);

                        break;

                    case ActivityTypes.Trigger:
                        await dispatcherTarget.OnConversationUpdate(activity);

                        break;

                    case ActivityTypes.ContactRelationUpdate:
                        await dispatcherTarget.OnContactRelationUpdate(activity);

                        break;


                    case ActivityTypes.DeleteUserData:
                        await dispatcherTarget.OnDeleteUserData(activity);

                        break;

                    //case ActivityTypes.Typing:
                    //case ActivityTypes.Ping:
                    default:
                        await dispatcherTarget.OnUnknownActivity(activity);

                        break;
                    }

                    return(req.CreateResponse(HttpStatusCode.Accepted));
                }
            }
        }