Beispiel #1
0
        public async Task TimeStayUser()
        {
            try
            {
                while (true)
                {
                    Thread.Sleep(1000);

                    if (userDic.Count <= 0)
                    {
                        continue;
                    }
                    foreach (var item in userDic.ToList())
                    {
                        userDic[item.Key] -= 1;
                        var a   = userDic[item.Key];
                        int Key = userDic.Select(x => x.Key).FirstOrDefault();
                        Debug.WriteLine(userDic[item.Key].ToString());
                        if (userDic[item.Key] <= 0)
                        {
                            WebhookController d = new WebhookController();
                            d.LogOut(Key, 0);



                            RemoveUser(Key);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Performs a dialog with user to delete webhooks for a user specified endpoint
        /// </summary>
        /// <param name="webhookController">Controller to use for deleting webhooks</param>
        /// <param name="existingWebhooks">Current webhooks</param>
        private static void DeleteWebhooks(WebhookController webhookController, IEnumerable <Webhook> existingWebhooks)
        {
            bool   delete    = true;
            bool   confirmed = false;
            string deleteUrl = String.Empty;

            while (delete && !confirmed)
            {
                Console.WriteLine("Delete webhooks for a url? Enter URL to delete or \'n\'");
                deleteUrl = Console.ReadLine();
                delete    = deleteUrl != "n";

                if (delete)
                {
                    Console.WriteLine("\"{0}\", confirm?(y/n)", deleteUrl);
                    confirmed = (Console.ReadLine() == "y");
                }
            }

            //Delete any webhook that matches user input
            foreach (var existingWebhook in existingWebhooks.Where(x => x.address == deleteUrl))
            {
                Console.WriteLine("Deleting webhook for {0} with topic {1}", existingWebhook.address, existingWebhook.topic);
                webhookController.DeleteWebhook(existingWebhook);
            }
            Console.WriteLine("Done deleting webhooks");
        }
        public void MandrillContentWebhookDoesntHaveEmailInRepository()
        {
            var leadRepository = new LocalRepository <Contact>();

            var emailLead = ModelHelper.EmailLead;

            leadRepository.Add(emailLead);
            var serverTime       = new Mock <IServerTime>();
            var clientRepository = new LocalRepository <Client>();

            clientRepository.Add(ModelHelper.TestClient1AllDataNoReferences);
            var xDataProvider     = new Mock <IExternalDataProvider>();
            var contactAutoRating = new Mock <IContactAutoRating>();

            var contactService = new Mock <IContactService>();

            serverTime.Setup(st => st.RequestStarted).Returns(new DateTime(2013, 01, 01, 9, 0, 0));
            var emailController = new WebhookController(leadRepository, clientRepository, contactService.Object, serverTime.Object, xDataProvider.Object, contactAutoRating.Object);

            emailController.MandrillContentWebhook(new MadrillContentPost {
                id = "2", html = "<p>New Sample Text</p>", text = "New Sample Text", to = "*****@*****.**"
            });
            Assert.AreEqual(2, leadRepository.All().Count());
            Assert.AreEqual("New Sample Text", leadRepository.Where(e => e.Property.Any(lp => lp.Type == "MandrillId" && lp.Value == "2")).First().Property.First(lp => lp.Type == "Text").Value);
            Assert.AreEqual("<p>New Sample Text</p>", leadRepository.Where(e => e.Property.Any(lp => lp.Type == "MandrillId" && lp.Value == "2")).First().Property.First(lp => lp.Type == "Html").Value);
            contactAutoRating.Verify(ar => ar.SetAutoRating(It.IsAny <Contact>()), Times.Once());

            contactService.Verify(cs => cs.NotifyClientsForNewContactWithEmail(It.IsAny <int>()), Times.Once());
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithPhoneNotification(It.IsAny <int>()), Times.Once());
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithSmsNotification(It.IsAny <int>()), Times.Once());
        }
        public void CallTrackingMetricWebhookThrowsExceptionTest()
        {
            var request           = new Mock <HttpRequestBase>();
            var serverTime        = new Mock <IServerTime>();
            var xDataProvider     = new Mock <IExternalDataProvider>();
            var contactAutoRating = new Mock <IContactAutoRating>();

            string sampleInvalidJsonData =
                "{\"invalid\":Data\"}";
            var serializeObject =
                new MemoryStream(
                    Encoding.UTF8.GetBytes(
                        sampleInvalidJsonData));

            request.SetupGet(x => x.InputStream).Returns(serializeObject);

            var context = new Mock <HttpContextBase>();

            context.SetupGet(x => x.Request).Returns(request.Object);

            var leadsRepository  = new Mock <IRepository <Contact> >();
            var clientRepository = new Mock <IRepository <Client> >();
            var contactService   = new Mock <IContactService>();

            var controller = new WebhookController(leadsRepository.Object, clientRepository.Object, contactService.Object, serverTime.Object, xDataProvider.Object, contactAutoRating.Object);

            controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
            controller.CallTrackingMetricWebhook();

            contactAutoRating.Verify(ar => ar.SetAutoRating(It.IsAny <Contact>()), Times.Never);

            contactService.Verify(cs => cs.NotifyClientsForNewContactWithEmail(It.IsAny <int>()), Times.Never);
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithPhoneNotification(It.IsAny <int>()), Times.Never);
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithSmsNotification(It.IsAny <int>()), Times.Never);
        }
Beispiel #5
0
 private void AutoUpdateDiscordBatch()
 {
     if (!Properties.Settings.Default.AutoDiscordBatch)
     {
         return;
     }
     AddTraceMessage("Discord: Auto update Discord Batch");
     ChkAutoDiscordBatch.Enabled = false;
     foreach (ulong id in _currentDiscordMessageIDs)
     {
         AddTraceMessage("Discord: deleting existing message " + id);
         try
         {
             WebhookController.DeleteMessage(Properties.Settings.Default.WebhookURL, id, out string message);
             AddTraceMessage("Discord: deleted existing message " + message);
         }
         catch (Exception ex)
         {
             AddTraceMessage("Discord: couldn't deleted existing message " + ex.Message);
         }
     }
     _currentDiscordMessageIDs.Clear();
     DiscordBatch(out _currentDiscordMessageIDs);
     ChkAutoDiscordBatch.Enabled = true;
 }
        public void ThrowsExceptionWhenAddingTheSameEmailUpdatesExistingDataWithNewDataAndOnRetryFails()
        {
            var leadRepository = new Mock <LocalRepository <Contact> > {
                CallBase = true
            };
            var serverTime        = new Mock <IServerTime>();
            var emailLead         = ModelHelper.EmailLead;
            var xDataProvider     = new Mock <IExternalDataProvider>();
            var contactAutoRating = new Mock <IContactAutoRating>();

            leadRepository.Setup(er => er.SaveChanges()).Throws(new Exception());
            leadRepository.Object.Add(emailLead);

            var clientRepository = new LocalRepository <Client>();
            var client           = ModelHelper.TestClient1AllDataNoReferences;

            clientRepository.Add(client);

            var contactService = new Mock <IContactService>();

            var emailController = new WebhookController(leadRepository.Object, clientRepository, contactService.Object, serverTime.Object, xDataProvider.Object, contactAutoRating.Object);

            emailController.MandrillContentWebhook(new MadrillContentPost {
                id = "1", html = "<p>Very New Sample Text</p>", text = "Very New Sample Text", to = "*****@*****.**"
            });

            Assert.AreEqual(0, leadRepository.Object.Where(er => er.Property.Any(lp => lp.Type == "Html" && lp.Value == "<p>Very New Sample Text</p>")).Count());
            Assert.AreEqual(0, leadRepository.Object.Where(er => er.Property.Any(lp => lp.Type == "Text" && lp.Value == "Very New Sample Text")).Count());
            Assert.AreEqual(1, leadRepository.Object.Where(er => er.Property.Any(lp => lp.Type == "Text" && lp.Value == "New Sample Text")).Count());
            contactAutoRating.Verify(ar => ar.SetAutoRating(It.IsAny <Contact>()), Times.Exactly(2));

            contactService.Verify(cs => cs.NotifyClientsForNewContactWithEmail(It.IsAny <int>()), Times.Never);
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithPhoneNotification(It.IsAny <int>()), Times.Never);
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithSmsNotification(It.IsAny <int>()), Times.Never);
        }
        public void GetOneMandrillEventsAndThrowsExceptionFailsOnBothTries()
        {
            var leadRepository = new Mock <LocalRepository <Contact> >()
            {
                CallBase = true
            };
            var xDataProvider     = new Mock <IExternalDataProvider>();
            var contactAutoRating = new Mock <IContactAutoRating>();

            var mandrill_event =
                "[{\"event\":\"send\",\"msg\":{\"ts\":1365109999,\"subject\":\"This an example webhook message\",\"email\":\"[email protected]\"," +
                "\"sender\":\"[email protected]\",\"tags\":[\"webhook-example\"],\"opens\":[],\"clicks\":[],\"state\":\"sent\",\"metadata\":{\"user_id\":111}," +
                "\"_id\":\"1\",\"_version\":\"exampleaaaaaaaaaaaaaaa1\"},\"_id\":\"1\",\"ts\":1385020180}]";

            leadRepository.Setup(er => er.SaveChanges()).Throws(new Exception());

            var clientRepository = new LocalRepository <Client>();
            var client           = ModelHelper.TestClient1AllDataNoReferences;

            client.EmailAddress = "*****@*****.**";
            clientRepository.Add(client);
            var serverTime     = new Mock <IServerTime>();
            var contactService = new Mock <IContactService>();

            var emailController = new WebhookController(leadRepository.Object, clientRepository, contactService.Object, serverTime.Object, xDataProvider.Object, contactAutoRating.Object);
            var result          = emailController.ManrillWebhook(mandrill_event);

            Assert.AreEqual(0, leadRepository.Object.All().Count());
            contactAutoRating.Verify(ar => ar.SetAutoRating(It.IsAny <Contact>()), Times.Exactly(2));

            contactService.Verify(cs => cs.NotifyClientsForNewContactWithEmail(It.IsAny <int>()), Times.Never);
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithPhoneNotification(It.IsAny <int>()), Times.Never);
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithSmsNotification(It.IsAny <int>()), Times.Never);
        }
        public static void DoWork(OperationController operation)
        {
            System.Globalization.CultureInfo before = Thread.CurrentThread.CurrentCulture;
            Thread.CurrentThread.CurrentCulture =
                new System.Globalization.CultureInfo("en-US");
            operation.Reset();
            var sw = new Stopwatch();

            try
            {
                sw.Start();
                var fInfo = new FileInfo(operation.InputFile);

                var parser = new EvtcParser(new EvtcParserSettings(Properties.Settings.Default.Anonymous,
                                                                   Properties.Settings.Default.SkipFailedTries,
                                                                   Properties.Settings.Default.ParsePhases,
                                                                   Properties.Settings.Default.ParseCombatReplay,
                                                                   Properties.Settings.Default.ComputeDamageModifiers,
                                                                   Properties.Settings.Default.CustomTooShort,
                                                                   Properties.Settings.Default.DetailledWvW),
                                            APIController);

                //Process evtc here
                ParsedEvtcLog log = parser.ParseLog(operation, fInfo, out GW2EIEvtcParser.ParserHelpers.ParsingFailureReason failureReason);
                if (failureReason != null)
                {
                    failureReason.Throw();
                }
                var      externalTraces = new List <string>();
                string[] uploadresult   = UploadOperation(externalTraces, fInfo);
                if (Properties.Settings.Default.SendEmbedToWebhook && Properties.Settings.Default.UploadToDPSReports)
                {
                    var webhookSettings = new WebhookSettings(Properties.Settings.Default.WebhookURL, !Properties.Settings.Default.SendSimpleMessageToWebhook ? BuildEmbed(log, uploadresult[0]) : null);
                    WebhookController.SendMessage(externalTraces, uploadresult[0], webhookSettings);
                }
                foreach (string trace in externalTraces)
                {
                    operation.UpdateProgress(trace);
                }
                if (uploadresult[0].Contains("https"))
                {
                    operation.DPSReportLink = uploadresult[0];
                }
                //Creating File
                GenerateFiles(log, operation, uploadresult, fInfo);
            }
            catch (Exception ex)
            {
                throw new ProgramException(ex);
            }
            finally
            {
                sw.Stop();
                GC.Collect();
                Thread.CurrentThread.CurrentCulture = before;
                operation.Elapsed = ("Elapsed " + sw.ElapsedMilliseconds + " ms");
            }
        }
Beispiel #9
0
 public Dependencies(InteractivityModule interactivity, WebhookController whm, SubscriptionProcessor subProcessor, WhConfigHolder whConfig, StripeService stripe)
 {
     Interactivity         = interactivity;
     Whm                   = whm;
     SubscriptionProcessor = subProcessor;
     _configHolder         = whConfig;
     Stripe                = stripe;
     OsmManager            = new OsmManager();
 }
        public void GetOneMandrillEventsAndThrowsExceptionAndRetriesSuccessfully()
        {
            var leadRepository = new Mock <LocalRepository <Contact> >()
            {
                CallBase = true
            };
            var xDataProvider     = new Mock <IExternalDataProvider>();
            var contactAutoRating = new Mock <IContactAutoRating>();

            var mandrill_event =
                "[{\"event\":\"send\",\"msg\":{\"ts\":1365109999,\"subject\":\"This an example webhook message\",\"email\":\"[email protected]\"," +
                "\"sender\":\"[email protected]\",\"tags\":[\"webhook-example\"],\"opens\":[],\"clicks\":[],\"state\":\"sent\",\"metadata\":{\"user_id\":111}," +
                "\"_id\":\"1\",\"_version\":\"exampleaaaaaaaaaaaaaaa1\"},\"_id\":\"1\",\"ts\":1385020180}]";


            var    numCalls = 0;
            Action throwExceptionOnFirstCall = () =>
            {
                if (numCalls == 0)
                {
                    numCalls++;
                    throw new Exception();
                }
                else
                {
                    numCalls++;
                }
            };

            leadRepository.Setup(er => er.SaveChanges())
            .Callback(throwExceptionOnFirstCall);

            var clientRepository = new LocalRepository <Client>();
            var client           = ModelHelper.TestClient1AllDataNoReferences;

            client.EmailAddress = "*****@*****.**";
            clientRepository.Add(client);

            var contactService = new Mock <IContactService>();
            var serverTime     = new Mock <IServerTime>();

            serverTime.Setup(st => st.RequestStarted).Returns(new DateTime(2013, 11, 21, 8, 50, 0)); //2013-11-21 08:49:40 on email date

            var emailController = new WebhookController(leadRepository.Object, clientRepository, contactService.Object, serverTime.Object, xDataProvider.Object, contactAutoRating.Object);
            var result          = emailController.ManrillWebhook(mandrill_event);

            Assert.AreEqual(1, leadRepository.Object.All().Count());
            string propertyValue = leadRepository.Object.Where(l => l.Property.Any(lp => lp.Type == "MandrillId" && lp.Value == "1")).Single().Property.First(lp => lp.Type == "Subject").Value;

            Assert.AreEqual("This an example webhook message", propertyValue);
            contactAutoRating.Verify(ar => ar.SetAutoRating(It.IsAny <Contact>()), Times.Exactly(2));

            contactService.Verify(cs => cs.NotifyClientsForNewContactWithEmail(It.IsAny <int>()), Times.Once);
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithPhoneNotification(It.IsAny <int>()), Times.Once);
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithSmsNotification(It.IsAny <int>()), Times.Once());
        }
        public void CallTrackingMetricWebhookCreatesLeadWithValidData()
        {
            var serverTime = new Mock <IServerTime>();

            serverTime.Setup(st => st.RequestStarted).Returns(new DateTime(2013, 01, 01, 8, 20, 0));
            var xDataProvider     = new Mock <IExternalDataProvider>();
            var contactAutoRating = new Mock <IContactAutoRating>();

            var request = new Mock <HttpRequestBase>();

            string sampleJsonData =
                "{\"id\":3158334,\"account_id\":9724,\"name\":\"Restricted\",\"search\":null,\"referrer\":null,\"location\":null,\"source\":\"Website\",\"source_id\":14932,\"tgid\":28622,\"likelihood\":null,\"duration\":107,\"talk_time\":101,\"ring_time\":6,\"parent_id\":null,\"email\":null,\"street\":null,\"city\":\"\",\"state\":\"Stockholm\",\"country\":\"SE\",\"postal_code\":\"\",\"called_at\":\"2013-10-01 10:17 AM +02:00\",\"tracking_number_id\":28938,\"tracking_number\":\"+46844680390\",\"tracking_label\":null,\"business_number\":\"+4687541040\",\"business_label\":\"Winassist Växel\",\"receiving_number_id\":14464,\"dial_status\":\"completed\",\"billed_amount\":1080.0,\"billed_at\":\"2013-10-01T08:19:09\",\"caller_number_split\":[\"46\",\"8\",\"890443\"],\"excluded\":false,\"tracking_number_format\":\"+46-8-44680390\",\"business_number_format\":\"+46-8-7541040\",\"caller_number_format\":\"(+46) 889-0443\",\"alternative_number\":\"+468890443\",\"caller_number_complete\":\"+468890443\",\"caller_number\":\"+468890443\",\"visitor\":false,\"audio\":\"https://ct4.s3.amazonaws.com/accounts/AC31fe87364641848e5d08c041cac16c84/recordings/REef08b869be099e8c7aeb0d85b04a99d2\",\"tag_list\":[],\"notes\":null,\"latitude\":59.3323,\"longitude\":18.0629,\"extended_lookup_on\":false}";

            var serializeObject =
                new MemoryStream(
                    Encoding.UTF8.GetBytes(
                        sampleJsonData));

            request.SetupGet(x => x.InputStream).Returns(serializeObject);

            var context = new Mock <HttpContextBase>();

            context.SetupGet(x => x.Request).Returns(request.Object);

            var leadsRepository = new LocalRepository <Contact>();

            var clientRepository = new LocalRepository <Client>();
            var client           = ModelHelper.TestClient1AllDataNoReferences;

            client.CallTrackingMetricId = 9724;
            clientRepository.Add(client);

            var contactService = new Mock <IContactService>();

            var returnContact = new Contact()
            {
                Id   = 1,
                Date = new DateTime(2013, 01, 01, 08, 17, 0)
            };

            xDataProvider.Setup(x => x.MapPhoneDataToContact(It.Is <CallTrackingMetricsWebhookData>(ctm => ctm.id == 3158334)))
            .Returns(returnContact);

            var controller = new WebhookController(leadsRepository, clientRepository, contactService.Object, serverTime.Object, xDataProvider.Object, contactAutoRating.Object);

            controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
            controller.CallTrackingMetricWebhook();

            Assert.AreEqual(1, leadsRepository.All().Count());

            contactAutoRating.Verify(ar => ar.SetAutoRating(It.Is <Contact>(c => c.Id == returnContact.Id)), Times.Once());

            contactService.Verify(cs => cs.NotifyClientsForNewContactWithEmail(It.IsAny <int>()), Times.Once());
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithPhoneNotification(It.IsAny <int>()), Times.Once());
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithSmsNotification(It.IsAny <int>()), Times.Once());
        }
        public void CallTrackingMetricLeadsOlderThanTenMinutesSaveLeadInDataBaseAndDontSendNotifications()
        {
            var request           = new Mock <HttpRequestBase>();
            var serverTime        = new Mock <IServerTime>();
            var xDataProvider     = new Mock <IExternalDataProvider>();
            var contactAutoRating = new Mock <IContactAutoRating>();

            serverTime.Setup(st => st.RequestStarted).Returns(new DateTime(2013, 01, 01, 8, 30, 0));
            string sampleJsonData =
                "{\"id\":1,\"account_id\":1,\"caller_number\":\"08123456\", \"called_at\":\"2013-01-01 10:00 AM +02:00\"}";

            var serializeObject =
                new MemoryStream(
                    Encoding.UTF8.GetBytes(
                        sampleJsonData));

            request.SetupGet(x => x.InputStream).Returns(serializeObject);

            var context = new Mock <HttpContextBase>();

            context.SetupGet(x => x.Request).Returns(request.Object);

            var leadsRepository = new Mock <IRepository <Contact> >();

            var clientRepository = new LocalRepository <Client>();
            var client           = ModelHelper.TestClient1AllDataNoReferences;

            clientRepository.Add(client);

            var contactService = new Mock <IContactService>();


            var returnContact = new Contact()
            {
                Id   = 1,
                Date = new DateTime(2013, 01, 01, 08, 0, 0)
            };

            xDataProvider.Setup(x => x.MapPhoneDataToContact(It.Is <CallTrackingMetricsWebhookData>(ctm => ctm.id == 1)))
            .Returns(returnContact);

            var controller = new WebhookController(leadsRepository.Object, clientRepository, contactService.Object, serverTime.Object, xDataProvider.Object, contactAutoRating.Object);

            controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
            controller.CallTrackingMetricWebhook();

            leadsRepository.Verify(pc => pc.Add(It.IsAny <Contact>()), Times.Once());
            leadsRepository.Verify(pc => pc.SaveChanges(), Times.Once());
            contactAutoRating.Verify(ar => ar.SetAutoRating(It.Is <Contact>(c => c.Id == returnContact.Id)), Times.Once());

            contactService.Verify(cs => cs.NotifyClientsForNewContactWithEmail(It.IsAny <int>()), Times.Never);
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithPhoneNotification(It.IsAny <int>()), Times.Never);
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithSmsNotification(It.IsAny <int>()), Times.Never);
        }
        public void CanConstruct()
        {
            var leadsRepository   = new Mock <IRepository <Contact> >();;
            var clientRepository  = new Mock <IRepository <Client> >();
            var contactService    = new Mock <IContactService>();
            var serverTime        = new Mock <IServerTime>();
            var xDataProvider     = new Mock <IExternalDataProvider>();
            var contactAutoRating = new Mock <IContactAutoRating>();

            var controller = new WebhookController(leadsRepository.Object, clientRepository.Object, contactService.Object, serverTime.Object, xDataProvider.Object, contactAutoRating.Object);
        }
Beispiel #14
0
        /// <summary>
        /// Instantiate a new <see cref="SubscriptionProcessor"/> class.
        /// </summary>
        /// <param name="servers">Discord servers dictionary</param>
        /// <param name="config">Configuration file</param>
        /// <param name="whm">Webhook controller class</param>
        public SubscriptionProcessor(Dictionary <ulong, DiscordClient> servers, WhConfig config, WebhookController whm)
        {
            _logger.Trace($"SubscriptionProcessor::SubscriptionProcessor");

            _servers  = servers;
            _whConfig = config;
            _whm      = whm;
            _queue    = new NotificationQueue();

            Manager = new SubscriptionManager(_whConfig);

            ProcessQueue();
        }
        public void MultiMandrilleventsWithSameIdIsNotDuplicatedInRepository()
        {
            var leadRepository    = new LocalRepository <Contact>();
            var xDataProvider     = new Mock <IExternalDataProvider>();
            var contactAutoRating = new Mock <IContactAutoRating>();
            var mandrill_event    =
                "[{\"event\":\"send\",\"msg\":{\"ts\":1365109999,\"subject\":\"This an example webhook message\",\"email\":\"[email protected]\"," +
                "\"sender\":\"[email protected]\",\"tags\":[\"webhook-example\"],\"opens\":[],\"clicks\":[],\"state\":\"sent\",\"metadata\":{\"user_id\":111}," +
                "\"_id\":\"1\",\"_version\":\"exampleaaaaaaaaaaaaaaa1\"},\"_id\":\"1\",\"ts\":1385020180}," +

                "{\"event\":\"send\",\"msg\":{\"ts\":1365109999,\"subject\":\"This an example webhook message\",\"email\":\"[email protected]\"," +
                "\"sender\":\"[email protected]\",\"tags\":[\"webhook-example\"],\"opens\":[],\"clicks\":[],\"state\":\"sent\",\"metadata\":{\"user_id\":111}," +
                "\"_id\":\"1\",\"_version\":\"exampleaaaaaaaaaaaaaaa1\"},\"_id\":\"1\",\"ts\":1385020180}," +

                "{\"event\":\"send\",\"msg\":{\"ts\":1365109999,\"subject\":\"This an example webhook message2\",\"email\":\"[email protected]\"," +
                "\"sender\":\"[email protected]\",\"tags\":[\"webhook-example\"],\"opens\":[],\"clicks\":[],\"state\":\"sent\",\"metadata\":{\"user_id\":222}," +
                "\"_id\":\"2\",\"_version\":\"exampleaaaaaaaaaaaaaaa2\"},\"_id\":\"2\",\"ts\":1385020180}]";

            var clientRepository = new LocalRepository <Client>();
            var client           = ModelHelper.TestClient1AllDataNoReferences;

            client.EmailAddress = "*****@*****.**";
            clientRepository.Add(client);

            var client2 = ModelHelper.TestClient1AllDataNoReferences;

            client2.EmailAddress = "*****@*****.**";
            client2.Id           = 2;
            clientRepository.Add(client2);

            var serverTime = new Mock <IServerTime>();

            serverTime.Setup(st => st.RequestStarted).Returns(new DateTime(2013, 11, 21, 8, 50, 0)); //2013-11-21 08:49:40 on email date

            var contactService = new Mock <IContactService>();

            var emailController = new WebhookController(leadRepository, clientRepository, contactService.Object, serverTime.Object, xDataProvider.Object, contactAutoRating.Object);
            var result          = emailController.ManrillWebhook(mandrill_event);

            Assert.AreEqual(2, leadRepository.All().Count());

            Assert.AreEqual("This an example webhook message", leadRepository.Where(l => l.Property.Any(lp => lp.Type == "MandrillId" && lp.Value == "1")).First().Property.First(lp => lp.Type == "Subject").Value);
            Assert.AreEqual("This an example webhook message2", leadRepository.Where(l => l.Property.Any(lp => lp.Type == "MandrillId" && lp.Value == "2")).First().Property.First(lp => lp.Type == "Subject").Value);
            contactAutoRating.Verify(ar => ar.SetAutoRating(It.IsAny <Contact>()), Times.Exactly(3));

            contactService.Verify(cs => cs.NotifyClientsForNewContactWithEmail(It.IsAny <int>()), Times.Exactly(2));
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithPhoneNotification(It.IsAny <int>()), Times.Exactly(2));
            contactService.Verify(cs => cs.NotifyClientsForNewContactWithSmsNotification(It.IsAny <int>()), Times.Exactly(2));
        }
 private void AutoUpdateDiscordBatch()
 {
     if (!Properties.Settings.Default.AutoDiscordBatch)
     {
         return;
     }
     AddTraceMessage("Auto update Discord Batch");
     ChkAutoDiscordBatch.Enabled = false;
     foreach (ulong id in _currentDiscordMessageIDs)
     {
         WebhookController.DeleteMessage(Properties.Settings.Default.WebhookURL, id, out _);
     }
     DiscordBatch(out _currentDiscordMessageIDs);
     ChkAutoDiscordBatch.Enabled = true;
 }
Beispiel #17
0
        private static async Task Raiser <TEvent>(TEvent @event) where TEvent : Event <TPayload>
        {
            if (!RESTarConfig.Initialized)
            {
                return;
            }
            if (Meta.EventResource <TEvent, TPayload> .SafeGet == null)
            {
                throw new UnknownEventTypeException(@event);
            }
            var hookTask = WebhookController.Post(@event);

            Events.Custom <TEvent> .OnRaise(@event);

            await hookTask;
        }
Beispiel #18
0
        public void Test()
        {
            const string text = @"
Did stuff!

:cl: Ev1__l P-JB2323
- add: Did the thing
- remove: Removed the thing
- fix: A
- bugfix: B
- bug: C
";

            var time   = new DateTimeOffset(2021, 1, 1, 1, 1, 1, TimeSpan.Zero);
            var pr     = new GHPullRequest(true, text, new GHUser("PJB"), time, new GHPullRequestBase("master"), 123);
            var parsed = WebhookController.ParsePRBody(pr);

            Assert.That(parsed, Is.Not.Null);
            Assert.That(parsed.Author, Is.EqualTo("Ev1__l P-JB2323"));
            Assert.That(parsed.Time, Is.EqualTo(time));
            Assert.That(parsed.Changes, Is.EquivalentTo(new[]
Beispiel #19
0
        /// <summary>
        /// Performs a dialog with user to create webhooks at a user specified endpoint
        /// </summary>
        /// <param name="webhookController">Controller to use for creating webhooks</param>
        private static void CreateNewWebhooks(WebhookController webhookController)
        {
            bool   confirmed = false;
            string newUrl    = string.Empty;

            while (!confirmed)
            {
                Console.WriteLine("Enter the new URL to set for webhooks.");
                newUrl = Console.ReadLine();
                Console.WriteLine("\"{0}\", confirm?(y/n)", newUrl);
                confirmed = (Console.ReadLine() == "y");
            }

            var            topics          = TopicReader.ReadTopics();
            List <Webhook> createdWebhooks = new List <Webhook>();

            //Create webhooks from selected file's topics
            foreach (string topic in topics)
            {
                try
                {
                    createdWebhooks.Add(webhookController.CreateWebhook(new Webhook()
                    {
                        address = newUrl,
                        topic   = topic
                    }));
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error creating webhook: {0}", ex.Message);
                }
            }

            foreach (var createdWebhook in createdWebhooks)
            {
                Console.WriteLine("Webhook for {0} created with ID {1}", createdWebhook.topic, createdWebhook.id);
            }
        }
Beispiel #20
0
        static void Main(string[] args)
        {
            //Display configuration
            try
            {
                var appSettings = ConfigurationManager.AppSettings;

                if (appSettings.Count == 0)
                {
                    Console.WriteLine("AppSettings is empty.");
                }
                else
                {
                    foreach (var key in appSettings.AllKeys)
                    {
                        Console.WriteLine("Key: {0} Value: {1}", key, appSettings[key]);
                    }
                }
            }
            catch (ConfigurationErrorsException)
            {
                Console.WriteLine("Error reading app settings");
            }


            string storeName = ConfigurationManager.AppSettings["StoreName"];

            //Initialize controller and get existing webhooks
            var webhookController = new WebhookController(storeName);
            var webhooks          = webhookController.GetWebhooks();

            CreateNewWebhooks(webhookController);
            DeleteWebhooks(webhookController, webhooks);

            Console.ReadKey();
        }
Beispiel #21
0
        private string DiscordBatch(out List <ulong> ids)
        {
            ids = new List <ulong>();
            AddTraceMessage("Discord: Sending batch to Discord");
            if (Properties.Settings.Default.WebhookURL == null)
            {
                AddTraceMessage("Discord: No webhook url given");
                return("Set a discord webhook url in settings first");
            }
            var fullDpsReportLogs = new List <FormOperationController>();

            foreach (FormOperationController operation in OperatorBindingSource)
            {
                if (operation.DPSReportLink != null && operation.DPSReportLink.Contains("https"))
                {
                    fullDpsReportLogs.Add(operation);
                }
            }
            if (!fullDpsReportLogs.Any())
            {
                AddTraceMessage("Discord: Nothing to send");
                return("Nothing to send");
            }
            // first sort by time
            AddTraceMessage("Discord: Sorting logs by time");
            fullDpsReportLogs.Sort((x, y) =>
            {
                return(DateTime.Parse(x.BasicMetaData.LogStart).CompareTo(DateTime.Parse(y.BasicMetaData.LogStart)));
            });
            AddTraceMessage("Discord: Splitting logs by start day");
            var fullDpsReportsLogsByDate = fullDpsReportLogs.GroupBy(x => DateTime.Parse(x.BasicMetaData.LogStart).Date).ToDictionary(x => x.Key, x => x.ToList());
            // split the logs so that a single embed does not reach the discord embed limit and also keep a reasonable size by embed
            string message = "";
            bool   start   = true;

            foreach (KeyValuePair <DateTime, List <FormOperationController> > pair in fullDpsReportsLogsByDate)
            {
                if (!start)
                {
                    message += "\r\n";
                }
                start = false;
                var splitDpsReportLogs = new List <List <FormOperationController> >()
                {
                    new List <FormOperationController>()
                };
                message += pair.Key.ToString("yyyy-MM-dd") + " - ";
                List <FormOperationController> curListToFill = splitDpsReportLogs.First();
                AddTraceMessage("Discord: Splitting message to avoid reaching discord's character limit");
                foreach (FormOperationController controller in pair.Value)
                {
                    if (curListToFill.Count < 40)
                    {
                        curListToFill.Add(controller);
                    }
                    else
                    {
                        curListToFill = new List <FormOperationController>()
                        {
                            controller
                        };
                        splitDpsReportLogs.Add(curListToFill);
                    }
                }
                foreach (List <FormOperationController> dpsReportLogs in splitDpsReportLogs)
                {
                    EmbedBuilder embedBuilder = ProgramHelper.GetEmbedBuilder();
                    AddTraceMessage("Discord: Creating embed for " + dpsReportLogs.Count + " logs");
                    var first = DateTime.Parse(dpsReportLogs.First().BasicMetaData.LogStart);
                    var last  = DateTime.Parse(dpsReportLogs.Last().BasicMetaData.LogEnd);
                    embedBuilder.WithFooter(pair.Key.ToString("dd/MM/yyyy") + " - " + first.ToString("T") + " - " + last.ToString("T"));
                    AddTraceMessage("Discord: Sorting logs by category");
                    dpsReportLogs.Sort((x, y) =>
                    {
                        int categoryCompare = x.BasicMetaData.FightCategory.CompareTo(y.BasicMetaData.FightCategory);
                        if (categoryCompare == 0)
                        {
                            return(DateTime.Parse(x.BasicMetaData.LogStart).CompareTo(DateTime.Parse(y.BasicMetaData.LogStart)));
                        }
                        return(categoryCompare);
                    });
                    string currentSubCategory = "";
                    var    embedFieldBuilder  = new EmbedFieldBuilder();
                    string fieldValue         = "I can not be empty";
                    AddTraceMessage("Discord: Building embed body");
                    foreach (FormOperationController controller in dpsReportLogs)
                    {
                        string subCategory = controller.BasicMetaData.FightCategory.GetSubCategoryName();
                        string toAdd       = "[" + controller.BasicMetaData.FightName + "](" + controller.DPSReportLink + ") " + (controller.BasicMetaData.FightSuccess ? " :white_check_mark: " : " :x: ") + ": " + controller.BasicMetaData.FightDuration;
                        if (subCategory != currentSubCategory)
                        {
                            embedFieldBuilder.WithValue(fieldValue);
                            embedFieldBuilder = new EmbedFieldBuilder();
                            fieldValue        = "";
                            embedBuilder.AddField(embedFieldBuilder);
                            embedFieldBuilder.WithName(subCategory);
                            currentSubCategory = subCategory;
                        }
                        else if (fieldValue.Length + toAdd.Length > 1024)
                        {
                            embedFieldBuilder.WithValue(fieldValue);
                            embedFieldBuilder = new EmbedFieldBuilder();
                            fieldValue        = "";
                            embedBuilder.AddField(embedFieldBuilder);
                            embedFieldBuilder.WithName(subCategory);
                        }
                        else
                        {
                            fieldValue += "\r\n";
                        }
                        fieldValue += toAdd;
                    }
                    embedFieldBuilder.WithValue(fieldValue);
                    AddTraceMessage("Discord: Sending embed");
                    try
                    {
                        ids.Add(WebhookController.SendMessage(Properties.Settings.Default.WebhookURL, embedBuilder.Build(), out string curMessage));
                        AddTraceMessage("Discord: embed sent " + curMessage);
                        message += curMessage + " - ";
                    }
                    catch (Exception ex)
                    {
                        AddTraceMessage("Discord: couldn't send embed " + ex.Message);
                        message += ex.Message + " - ";
                    }
                }
            }
            return(message);
        }
        private static void GenerateFiles(ParsedLog log, OperationController operation, string[] uploadresult, FileInfo fInfo)
        {
            operation.UpdateProgressWithCancellationCheck("Creating File(s)");

            DirectoryInfo saveDirectory = GetSaveDirectory(fInfo);

            string result = log.FightData.Success ? "kill" : "fail";
            string encounterLengthTerm = Properties.Settings.Default.AddDuration ? "_" + (log.FightData.FightEnd / 1000).ToString() + "s" : "";
            string PoVClassTerm        = Properties.Settings.Default.AddPoVProf ? "_" + log.LogData.PoV.Prof.ToLower() : "";
            string fName = fInfo.Name.Split('.')[0];

            fName = $"{fName}{PoVClassTerm}_{log.FightData.Logic.Extension}{encounterLengthTerm}_{result}";

            // parallel stuff
            if (log.ParserSettings.MultiTasks)
            {
                log.FightData.GetPhases(log);
                operation.UpdateProgressWithCancellationCheck("Multi threading");
                var playersAndTargets = new List <AbstractSingleActor>(log.PlayerList);
                playersAndTargets.AddRange(log.FightData.Logic.Targets);
                foreach (AbstractSingleActor actor in playersAndTargets)
                {
                    // that part can't be //
                    actor.ComputeBuffMap(log);
                }
                if (log.CanCombatReplay)
                {
                    var playersAndTargetsAndMobs = new List <AbstractSingleActor>(log.FightData.Logic.TrashMobs);
                    playersAndTargetsAndMobs.AddRange(playersAndTargets);
                    // init all positions
                    Parallel.ForEach(playersAndTargetsAndMobs, actor => actor.GetCombatReplayPolledPositions(log));
                }
                else if (log.CombatData.HasMovementData)
                {
                    Parallel.ForEach(log.PlayerList, player => player.GetCombatReplayPolledPositions(log));
                }
                Parallel.ForEach(playersAndTargets, actor => actor.GetBuffGraphs(log));
                //
                Parallel.ForEach(log.PlayerList, player => player.GetDamageModifierStats(log, null));
                // once simulation is done, computing buff stats is thread safe
                Parallel.ForEach(log.PlayerList, player => player.GetBuffs(log, BuffEnum.Self));
                Parallel.ForEach(log.FightData.Logic.Targets, target => target.GetBuffs(log));
            }
            if (Properties.Settings.Default.SaveOutHTML)
            {
                operation.UpdateProgressWithCancellationCheck("Creating HTML");
                string outputFile = Path.Combine(
                    saveDirectory.FullName,
                    $"{fName}.html"
                    );
                operation.GeneratedFiles.Add(outputFile);
                operation.PathsToOpen.Add(outputFile);
                using (var fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write))
                    using (var sw = new StreamWriter(fs))
                    {
                        var builder = new HTMLBuilder(log, uploadresult, Properties.Settings.Default.LightTheme, Properties.Settings.Default.HtmlExternalScripts);
                        builder.CreateHTML(sw, saveDirectory.FullName);
                    }
                operation.UpdateProgressWithCancellationCheck("HTML created");
            }
            if (Properties.Settings.Default.SaveOutCSV)
            {
                operation.UpdateProgressWithCancellationCheck("Creating CSV");
                string outputFile = Path.Combine(
                    saveDirectory.FullName,
                    $"{fName}.csv"
                    );
                operation.GeneratedFiles.Add(outputFile);
                operation.PathsToOpen.Add(outputFile);
                using (var fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write))
                    using (var sw = new StreamWriter(fs, Encoding.GetEncoding(1252)))
                    {
                        var builder = new CSVBuilder(sw, ",", log, uploadresult);
                        builder.CreateCSV();
                    }
                operation.UpdateProgressWithCancellationCheck("CSV created");
            }
            if (Properties.Settings.Default.SaveOutJSON || Properties.Settings.Default.SaveOutXML)
            {
                var builder = new RawFormatBuilder(log, uploadresult);
                if (Properties.Settings.Default.SaveOutJSON)
                {
                    operation.UpdateProgressWithCancellationCheck("Creating JSON");
                    string outputFile = Path.Combine(
                        saveDirectory.FullName,
                        $"{fName}.json"
                        );
                    operation.PathsToOpen.Add(saveDirectory.FullName);
                    Stream str;
                    if (Properties.Settings.Default.CompressRaw)
                    {
                        str = new MemoryStream();
                    }
                    else
                    {
                        str = new FileStream(outputFile, FileMode.Create, FileAccess.Write);
                    }
                    using (var sw = new StreamWriter(str, GeneralHelper.NoBOMEncodingUTF8))
                    {
                        builder.CreateJSON(sw, Properties.Settings.Default.IndentJSON);
                    }
                    if (str is MemoryStream msr)
                    {
                        CompressFile(outputFile, msr, operation);
                        operation.UpdateProgressWithCancellationCheck("JSON compressed");
                    }
                    else
                    {
                        operation.GeneratedFiles.Add(outputFile);
                    }
                    operation.UpdateProgressWithCancellationCheck("JSON created");
                }
                if (Properties.Settings.Default.SaveOutXML)
                {
                    operation.UpdateProgressWithCancellationCheck("Creating XML");
                    string outputFile = Path.Combine(
                        saveDirectory.FullName,
                        $"{fName}.xml"
                        );
                    operation.PathsToOpen.Add(saveDirectory.FullName);
                    Stream str;
                    if (Properties.Settings.Default.CompressRaw)
                    {
                        str = new MemoryStream();
                    }
                    else
                    {
                        str = new FileStream(outputFile, FileMode.Create, FileAccess.Write);
                    }
                    using (var sw = new StreamWriter(str, GeneralHelper.NoBOMEncodingUTF8))
                    {
                        builder.CreateXML(sw, Properties.Settings.Default.IndentXML);
                    }
                    if (str is MemoryStream msr)
                    {
                        CompressFile(outputFile, msr, operation);
                        operation.UpdateProgressWithCancellationCheck("XML compressed");
                    }
                    else
                    {
                        operation.GeneratedFiles.Add(outputFile);
                    }
                    operation.UpdateProgressWithCancellationCheck("XML created");
                }
            }

            if (Properties.Settings.Default.SendEmbedToWebhook && Properties.Settings.Default.UploadToDPSReports && !Properties.Settings.Default.ParseMultipleLogs)
            {
                WebhookController.SendMessage(log, uploadresult);
            }
            operation.UpdateProgress($"Completed parsing for {result}ed {log.FightData.Logic.Extension}");
        }
Beispiel #23
0
        /// <summary>
        /// Discord bot class
        /// </summary>
        /// <param name="whConfig">Configuration settings</param>
        public Bot(WhConfigHolder whConfig)
        {
            _logger.Trace($"WhConfig [Servers={whConfig.Instance.Servers.Count}, Port={whConfig.Instance.WebhookPort}]");
            _servers  = new Dictionary <ulong, DiscordClient>();
            _whConfig = whConfig;
            _whm      = new WebhookController(_whConfig);

            // Build form lists for icons
            IconFetcher.Instance.SetIconStyles(_whConfig.Instance.IconStyles);

            // Set translation language
            Translator.Instance.SetLocale(_whConfig.Instance.Locale);

            // Set database connection strings to static properties so we can access within our extension classes
            DataAccessLayer.ConnectionString        = _whConfig.Instance.Database.Main.ToString();
            DataAccessLayer.ScannerConnectionString = _whConfig.Instance.Database.Scanner.ToString();

            // Set unhandled exception event handler
            AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;

            // Initialize and start midnight reset timer
            var midnight = new DandTSoftware.Timers.MidnightTimer();

            midnight.TimeReached += async(e) => await OnMidnightTimer();

            midnight.Start();

            // Initialize the subscription processor if at least one Discord server wants custom notifications
            // and start database migrator
            if (_whConfig.Instance.Servers.Values.ToList().Exists(x => x.Subscriptions.Enabled))
            {
                // Start database migrator
                var migrator = new DatabaseMigrator();
                while (!migrator.Finished)
                {
                    Thread.Sleep(50);
                }

                _subProcessor = new SubscriptionProcessor(_servers, _whConfig, _whm);
            }

            // Create a DiscordClient object per Discord server in config
            foreach (var(guildId, serverConfig) in _whConfig.Instance.Servers)
            {
                serverConfig.LoadDmAlerts();
                var client = new DiscordClient(new DiscordConfiguration
                {
                    AutomaticGuildSync = true,
                    AutoReconnect      = true,
                    EnableCompression  = true,
                    Token                 = serverConfig.Token,
                    TokenType             = TokenType.Bot,
                    UseInternalLogHandler = true
                });

                // If you are on Windows 7 and using .NETFX, install
                // DSharpPlus.WebSocket.WebSocket4Net from NuGet,
                // add appropriate usings, and uncomment the following
                // line
                //client.SetWebSocketClient<WebSocket4NetClient>();

                // If you are on Windows 7 and using .NET Core, install
                // DSharpPlus.WebSocket.WebSocket4NetCore from NuGet,
                // add appropriate usings, and uncomment the following
                // line
                //client.SetWebSocketClient<WebSocket4NetCoreClient>();

                // If you are using Mono, install
                // DSharpPlus.WebSocket.WebSocketSharp from NuGet,
                // add appropriate usings, and uncomment the following
                // line
                //client.SetWebSocketClient<WebSocketSharpClient>();

                client.Ready              += Client_Ready;
                client.GuildAvailable     += Client_GuildAvailable;
                client.GuildMemberUpdated += Client_GuildMemberUpdated;
                //_client.MessageCreated += Client_MessageCreated;
                client.ClientErrored += Client_ClientErrored;
                client.DebugLogger.LogMessageReceived += DebugLogger_LogMessageReceived;

                // Configure Discord interactivity module
                var interactivity = client.UseInteractivity
                                    (
                    new InteractivityConfiguration
                {
                    // default pagination behaviour to just ignore the reactions
                    PaginationBehaviour = TimeoutBehaviour.Ignore,

                    // default pagination timeout to 5 minutes
                    PaginationTimeout = TimeSpan.FromMinutes(5),

                    // default timeout for other actions to 2 minutes
                    Timeout = TimeSpan.FromMinutes(2)
                }
                                    );

                // Build the dependency collection which will contain our objects that can be globally used within each command module
                DependencyCollection dep;
                using (var d = new DependencyCollectionBuilder())
                {
                    d.AddInstance(new Dependencies(interactivity, _whm, _subProcessor, _whConfig, new StripeService(_whConfig.Instance.StripeApiKey)));
                    dep = d.Build();
                }

                // Discord commands configuration
                var commands = client.UseCommandsNext
                               (
                    new CommandsNextConfiguration
                {
                    StringPrefix = serverConfig.CommandPrefix?.ToString(),
                    EnableDms    = true,
                    // If command prefix is null, allow for mention prefix
                    EnableMentionPrefix = string.IsNullOrEmpty(serverConfig.CommandPrefix),
                    // Use DSharpPlus's built-in help formatter
                    EnableDefaultHelp    = true,
                    CaseSensitive        = false,
                    IgnoreExtraArguments = true,
                    Dependencies         = dep
                }
                               );
                commands.CommandExecuted += Commands_CommandExecuted;
                commands.CommandErrored  += Commands_CommandErrored;
                // Register Discord command handler classes
                commands.RegisterCommands <Owner>();
                commands.RegisterCommands <Event>();
                commands.RegisterCommands <Nests>();
                commands.RegisterCommands <ShinyStats>();
                commands.RegisterCommands <Gyms>();
                commands.RegisterCommands <Quests>();
                commands.RegisterCommands <Settings>();
                if (serverConfig.Subscriptions.Enabled)
                {
                    commands.RegisterCommands <Notifications>();
                }
                if (serverConfig.EnableCities)
                {
                    commands.RegisterCommands <Feeds>();
                }

                _logger.Info($"Configured Discord server {guildId}");
                if (!_servers.ContainsKey(guildId))
                {
                    _servers.Add(guildId, client);
                }

                // Wait 3 seconds between initializing Discord clients
                Task.Delay(3000).GetAwaiter().GetResult();
            }

            RegisterConfigMonitor();
        }
Beispiel #24
0
        private async Task CheckForVenmoDeposits()
        {
            while (true)
            {
                foreach (var workspace in Settings.SettingsObject.Workspaces.Workspaces)
                {
                    WorkspaceInfo workspaceInfo = workspace.Value.ToObject <WorkspaceInfo>() !;
                    logger.LogDebug($"Processing workspace ${workspace.Key}");
                    MongoDatabase database   = new MongoDatabase(workspace.Key, mongoDatabaseLogger);
                    SlackCore     slackApi   = new SlackCore(workspaceInfo.BotToken);
                    var           slackUsers = await slackApi.UsersList();

                    List <Database.Models.VenmoUser> users = database.GetAllUsers();
                    foreach (var user in users)
                    {
                        if (user.YNAB != null && user.YNAB.DefaultAccount != null)
                        {
                            // Get YNAB access token
                            Configuration config          = helperMethods.CreateConfiguration(user.YNAB.Auth !.AccessToken !);
                            string?       ynabAccessToken = await helperMethods.CheckIfYNABAccessTokenIsExpired(user, database, new ApiClient(config));

                            if (ynabAccessToken == null)
                            {
                                logger.LogError($"Unable to refresh YNAB access token for {user.UserId}");
                                await WebhookController.SendSlackMessage(workspaceInfo, "Unable to import your Venmo deposits into YNAB because your YNAB authentication information is invalid. Please refresh it.",
                                                                         user.UserId, httpClient);

                                continue;
                            }
                            config = helperMethods.CreateConfiguration(ynabAccessToken);

                            // Get Venmo access token
                            VenmoApi venmoApi         = new VenmoApi(venmoApiLogger);
                            string?  venmoAccessToken = await helperMethods.CheckIfVenmoAccessTokenIsExpired(user, venmoApi, database);

                            if (string.IsNullOrEmpty(venmoAccessToken))
                            {
                                logger.LogError($"Unable to refresh Venmo access token for {user.UserId}");
                                await WebhookController.SendSlackMessage(workspaceInfo,
                                                                         "Unable to process scheduled Venmos as your token has expired. Please refresh it.",
                                                                         user.UserId, httpClient);

                                continue;
                            }
                            venmoApi.AccessToken = venmoAccessToken;

                            logger.LogDebug($"Processing slack user {user.UserId}");

                            List <TransactionDetail> venmoDeposits = await GetVenmoDeposits(user, config);

                            if (!ShouldProcessLatestVenmoDeposit(venmoDeposits))
                            {
                                continue;
                            }

                            // (fromDate - toDate]. We can adjust which transactions get included after if the
                            // subtransactions total doesn't match the deposit total
                            DateOnly toDate = DateOnly.FromDateTime(venmoDeposits[0].Date !.Value);
                            DateOnly fromDate;
                            // if multiple deposits were made on the same day (due to Venmo transfer limits) then
                            // make sure we get the first deposit not on the same day
                            foreach (var deposit in venmoDeposits)
                            {
                                fromDate = DateOnly.FromDateTime(deposit.Date !.Value);
                                if (fromDate != toDate)
                                {
                                    break;
                                }
                            }
                            fromDate = fromDate.AddDays(1);

                            var venmoTransactions = await GetVenmoTransactionsBetweenDates(fromDate, toDate, venmoApi, user);

                            TransactionDetail         ynabDeposit         = venmoDeposits[0];
                            SaveTransaction?          newTransaction      = null;
                            List <SaveSubTransaction> subTransactions     = new List <SaveSubTransaction>();
                            VenmoTransaction?         previousTransaction = null;
                            decimal originalDepositAmount = 0;
                            decimal depositAmount         = 0;
                            bool    multipleTransfers     = false;
                            foreach (VenmoTransaction transaction in venmoTransactions)
                            {
                                if (previousTransaction == null)
                                {
                                    depositAmount         = transaction.Transfer !.Amount;
                                    originalDepositAmount = depositAmount;
                                }
                                else
                                {
                                    if (previousTransaction.Type == "transfer" && transaction.Type == "transfer")
                                    {
                                        multipleTransfers     = true;
                                        depositAmount        += transaction.Transfer !.Amount;
                                        originalDepositAmount = depositAmount;
                                    }

                                    if (transaction.Type == "payment")
                                    {
                                        if (previousTransaction.Type == "transfer" && multipleTransfers)
                                        {
                                            long   milliunitAmount = (long)(depositAmount * 1000m);
                                            string importId        = $"YNAB:{milliunitAmount}:{ynabDeposit.Date:yyyy-MM-dd}";
                                            newTransaction = new SaveTransaction(ynabDeposit.AccountId, ynabDeposit.Date,
                                                                                 amount: milliunitAmount, ynabDeposit.PayeeId, ynabDeposit.PayeeName,
                                                                                 ynabDeposit.CategoryId, memo: null, golf1052.YNABAPI.HelperMethods.ClearedEnum.Uncleared,
                                                                                 ynabDeposit.Approved, ynabDeposit.FlagColor, importId: importId,
                                                                                 subTransactions);
                                        }

                                        if (depositAmount - transaction.Payment !.Amount > 0)
                                        {
                                            string?memo       = transaction.Payment.Note;
                                            Guid?  categoryId = null;
                                            if (user.YNAB.Mapping != null && user.YNAB.Mapping.Count > 0 && memo != null)
                                            {
                                                foreach (var mapping in user.YNAB.Mapping)
                                                {
                                                    if (mapping.VenmoNote.Equals(memo, StringComparison.InvariantCultureIgnoreCase))
                                                    {
                                                        categoryId = new Guid(mapping.CategoryId);
                                                        break;
                                                    }
                                                }
                                            }
                                            var subTransaction = new SaveSubTransaction(amount: (long)(transaction.Payment.Amount * 1000),
                                                                                        payeeId: null, payeeName: null, categoryId: categoryId, memo);
                                            subTransactions.Add(subTransaction);
                                            depositAmount -= transaction.Payment.Amount;
                                        }
                                    }
                                }
                                previousTransaction = transaction;
                            }

                            if (depositAmount > 0)
                            {
                                var unknownSubTransaction = new SaveSubTransaction(amount: (long)(depositAmount * 1000),
                                                                                   payeeId: null, payeeName: null, categoryId: null, memo: "UNKNOWN");
                                subTransactions.Add(unknownSubTransaction);
                            }

                            TransactionsApi transactionsApi = new TransactionsApi(config);
                            if (multipleTransfers)
                            {
                                // we created a new transaction so POST it
                                var createTransactionsResponse = await transactionsApi.CreateTransactionAsync(Default,
                                                                                                              new SaveTransactionsWrapper(newTransaction));

                                // then "delete" the other transfers
                                List <UpdateTransaction> transactionsToDelete = new List <UpdateTransaction>();
                                for (int i = 0; i < venmoDeposits.Count; i++)
                                {
                                    TransactionDetail transactionDetail = venmoDeposits[i];
                                    VenmoTransaction  venmoTransaction  = venmoTransactions[i];
                                    if (venmoTransaction.Type != "transfer")
                                    {
                                        break;
                                    }

                                    UpdateTransaction updateTransaction = new UpdateTransaction(transactionDetail.AccountId,
                                                                                                transactionDetail.Date, transactionDetail.Amount, transactionDetail.PayeeId,
                                                                                                transactionDetail.PayeeName, transactionDetail.CategoryId,
                                                                                                memo: $"<DELETE ME: Combined into ${originalDepositAmount:F2} Transfer from Venmo> {transactionDetail.Memo}",
                                                                                                golf1052.YNABAPI.HelperMethods.ClearedEnum.Uncleared,
                                                                                                transactionDetail.Approved, transactionDetail.FlagColor, transactionDetail.ImportId,
                                                                                                new List <SaveSubTransaction>());
                                    transactionsToDelete.Add(updateTransaction);
                                }

                                var updateTransactionsResponse = await transactionsApi.UpdateTransactionsAsync(Default, new UpdateTransactionsWrapper(transactionsToDelete));

                                await WebhookController.SendSlackMessage(workspaceInfo,
                                                                         $"Imported and created a new YNAB Venmo transaction totaling ${originalDepositAmount:F2} with " +
                                                                         $"{subTransactions.Count} Venmo subtransactions combining {transactionsToDelete.Count} " +
                                                                         $"transactions which occured on {newTransaction!.Date:d}. " +
                                                                         $"Please go into YNAB, confirm the new transaction and delete the old transactions.",
                                                                         user.UserId, httpClient);
                            }
                            else
                            {
                                // we didn't create a new transaction so just PUT the existing transaction
                                newTransaction = new SaveTransaction(ynabDeposit.AccountId, ynabDeposit.Date,
                                                                     ynabDeposit.Amount, ynabDeposit.PayeeId, ynabDeposit.PayeeName, ynabDeposit.CategoryId,
                                                                     ynabDeposit.Memo, golf1052.YNABAPI.HelperMethods.ClearedEnum.Uncleared, ynabDeposit.Approved,
                                                                     ynabDeposit.FlagColor, ynabDeposit.ImportId, subTransactions);
                                var response = await transactionsApi.UpdateTransactionAsync(Default, ynabDeposit.Id,
                                                                                            new SaveTransactionWrapper(newTransaction));

                                await WebhookController.SendSlackMessage(workspaceInfo,
                                                                         $"Updated a YNAB Venmo transaction with {subTransactions.Count} Venmo subtransactions which occured" +
                                                                         $"on {newTransaction.Date:d}. Please go into YNAB and confirm the updated transaction.",
                                                                         user.UserId, httpClient);
                            }
                        }
                    }
                }
                await Task.Delay(CheckDuration.ToTimeSpan());
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnDiscordBatchClick(object sender, EventArgs e)
        {
            AddTraceMessage("Sending batch to Discord");
            if (Properties.Settings.Default.WebhookURL == null)
            {
                MessageBox.Show("Set a discord webhook url in settings first");
                return;
            }
            var fullDpsReportLogs = new List <FormOperationController>();

            foreach (FormOperationController operation in OperatorBindingSource)
            {
                if (operation.DPSReportLink != null && operation.DPSReportLink.Contains("https"))
                {
                    fullDpsReportLogs.Add(operation);
                }
            }
            if (!fullDpsReportLogs.Any())
            {
                MessageBox.Show("Nothing to send");
                return;
            }
            BtnDiscordBatch.Enabled = false;
            BtnParse.Enabled        = false;
            // first sort by time
            fullDpsReportLogs.Sort((x, y) =>
            {
                return(DateTime.Parse(x.BasicMetaData.LogStart).CompareTo(DateTime.Parse(y.BasicMetaData.LogStart)));
            });
            var fullDpsReportsLogsByDate = fullDpsReportLogs.GroupBy(x => DateTime.Parse(x.BasicMetaData.LogStart).Date).ToDictionary(x => x.Key, x => x.ToList());
            // split the logs so that a single embed does not reach the discord embed limit and also keep a reasonable size by embed
            string message = "";
            bool   start   = true;

            foreach (KeyValuePair <DateTime, List <FormOperationController> > pair in fullDpsReportsLogsByDate)
            {
                if (!start)
                {
                    message += "\r\n";
                }
                start = false;
                var splitDpsReportLogs = new List <List <FormOperationController> >()
                {
                    new List <FormOperationController>()
                };
                message += pair.Key.ToString("yyyy-MM-dd") + " - ";
                List <FormOperationController> curListToFill = splitDpsReportLogs.First();
                foreach (FormOperationController controller in pair.Value)
                {
                    if (curListToFill.Count < 40)
                    {
                        curListToFill.Add(controller);
                    }
                    else
                    {
                        curListToFill = new List <FormOperationController>()
                        {
                            controller
                        };
                        splitDpsReportLogs.Add(curListToFill);
                    }
                }
                foreach (List <FormOperationController> dpsReportLogs in splitDpsReportLogs)
                {
                    EmbedBuilder embedBuilder = ProgramHelper.GetEmbedBuilder();
                    embedBuilder.WithCurrentTimestamp();
                    embedBuilder.WithFooter(pair.Key.ToString("yyyy-MM-dd"));
                    dpsReportLogs.Sort((x, y) =>
                    {
                        var categoryCompare = x.BasicMetaData.FightCategory.CompareTo(y.BasicMetaData.FightCategory);
                        if (categoryCompare == 0)
                        {
                            return(DateTime.Parse(x.BasicMetaData.LogStart).CompareTo(DateTime.Parse(y.BasicMetaData.LogStart)));
                        }
                        return(categoryCompare);
                    });
                    string currentSubCategory = "";
                    var    embedFieldBuilder  = new EmbedFieldBuilder();
                    var    fieldValue         = "I can not be empty";
                    foreach (FormOperationController controller in dpsReportLogs)
                    {
                        string subCategory = controller.BasicMetaData.FightCategory.GetSubCategoryName();
                        string toAdd       = "[" + controller.BasicMetaData.FightName + "](" + controller.DPSReportLink + ") " + (controller.BasicMetaData.FightSuccess ? " :white_check_mark: " : " :x: ") + ": " + controller.BasicMetaData.FightDuration;
                        if (subCategory != currentSubCategory)
                        {
                            embedFieldBuilder.WithValue(fieldValue);
                            embedFieldBuilder = new EmbedFieldBuilder();
                            fieldValue        = "";
                            embedBuilder.AddField(embedFieldBuilder);
                            embedFieldBuilder.WithName(subCategory);
                            currentSubCategory = subCategory;
                        }
                        else if (fieldValue.Length + toAdd.Length > 1024)
                        {
                            embedFieldBuilder.WithValue(fieldValue);
                            embedFieldBuilder = new EmbedFieldBuilder();
                            fieldValue        = "";
                            embedBuilder.AddField(embedFieldBuilder);
                        }
                        else
                        {
                            fieldValue += "\r\n";
                        }
                        fieldValue += toAdd;
                    }
                    embedFieldBuilder.WithValue(fieldValue);
                    message += new WebhookController(Properties.Settings.Default.WebhookURL, embedBuilder.Build()).SendMessage() + " - ";
                }
            }

            MessageBox.Show(message);
            //
            BtnDiscordBatch.Enabled = !_anyRunning;
            BtnParse.Enabled        = !_anyRunning;
        }
        private async Task CheckSchedules()
        {
            while (true)
            {
                foreach (var workspace in Settings.SettingsObject.Workspaces.Workspaces)
                {
                    WorkspaceInfo workspaceInfo = workspace.Value.ToObject <WorkspaceInfo>() !;
                    MongoDatabase database      = new MongoDatabase(workspace.Key, mongoDatabaseLogger);
                    SlackCore     slackApi      = new SlackCore(workspaceInfo.BotToken);
                    var           slackUsers    = await slackApi.UsersList();

                    List <Database.Models.VenmoUser> users = database.GetAllUsers();
                    foreach (var user in users)
                    {
                        if (user.Schedule != null && user.Schedule.Count > 0)
                        {
                            VenmoApi venmoApi    = new VenmoApi(venmoApiLogger);
                            string?  accessToken = await helperMethods.CheckIfVenmoAccessTokenIsExpired(user, venmoApi, database);

                            if (string.IsNullOrEmpty(accessToken))
                            {
                                logger.LogError($"Unable to refresh Venmo access token for {user.UserId}");
                                await WebhookController.SendSlackMessage(workspaceInfo,
                                                                         "Unable to process scheduled Venmos as your token has expired. Please refresh it.",
                                                                         user.UserId, httpClient);

                                continue;
                            }

                            venmoApi.AccessToken = accessToken;
                            bool saveNeeded = false;
                            for (int i = 0; i < user.Schedule.Count; i++)
                            {
                                VenmoSchedule schedule       = user.Schedule[i];
                                Instant       now            = clock.GetCurrentInstant();
                                Instant       scheduledTime  = Instant.FromDateTimeUtc(schedule.NextExecution);
                                bool          deleteSchedule = false;
                                if (now > scheduledTime)
                                {
                                    saveNeeded = true;
                                    await WebhookController.SendSlackMessage(workspaceInfo,
                                                                             $"Processing {schedule.Command}",
                                                                             user.UserId,
                                                                             httpClient);

                                    string[] splitPaymentMessage = helperMethods.ConvertScheduleMessageIntoPaymentMessage(schedule.Command.Split(' '));

                                    ParsedVenmoPayment parsedVenmoPayment;
                                    try
                                    {
                                        parsedVenmoPayment = helperMethods.ParseVenmoPaymentMessage(splitPaymentMessage);
                                    }
                                    catch (Exception ex)
                                    {
                                        logger.LogWarning(ex, "Failed to parse payment, this shouldn't happen as it was parsed before being saved.");
                                        continue;
                                    }

                                    var response = await helperMethods.VenmoPayment(venmoApi, user, database,
                                                                                    parsedVenmoPayment.Amount, parsedVenmoPayment.Note, parsedVenmoPayment.Recipients,
                                                                                    parsedVenmoPayment.Action, parsedVenmoPayment.Audience);

                                    foreach (var r in response.responses)
                                    {
                                        if (!string.IsNullOrEmpty(r.Error))
                                        {
                                            await WebhookController.SendSlackMessage(workspaceInfo,
                                                                                     $"Venmo error: {r.Error}",
                                                                                     user.UserId, httpClient);

                                            continue;
                                        }

                                        if (parsedVenmoPayment.Action == VenmoAction.Charge)
                                        {
                                            await WebhookController.SendSlackMessage(workspaceInfo,
                                                                                     $"Successfully charged {r.Data!.Payment.Target!.User.Username} ${r.Data.Payment.Amount} for {r.Data.Payment.Note}. Audience is {r.Data.Payment.Audience}",
                                                                                     user.UserId, httpClient);
                                        }
                                        else
                                        {
                                            await WebhookController.SendSlackMessage(workspaceInfo,
                                                                                     $"Successfully paid {r.Data!.Payment.Target!.User.Username} ${r.Data.Payment.Amount} for {r.Data.Payment.Note}. Audience is {r.Data.Payment.Audience}",
                                                                                     user.UserId, httpClient);
                                        }
                                    }

                                    foreach (var u in response.unprocessedRecipients)
                                    {
                                        await WebhookController.SendSlackMessage(workspaceInfo,
                                                                                 $"You are not friends with {u}.",
                                                                                 user.UserId, httpClient);
                                    }

                                    if (schedule.Verb == "at" || schedule.Verb == "on")
                                    {
                                        deleteSchedule = true;
                                    }
                                    else if (schedule.Verb == "every")
                                    {
                                        SlackUser?slackUser = helperMethods.GetSlackUser(user.UserId, slackUsers);
                                        if (slackUser == null)
                                        {
                                            // user somehow doesn't exist?
                                            logger.LogError($"While trying to process schedule for a slack user they disappeared? {user.UserId}");
                                            deleteSchedule = true;
                                        }
                                        else
                                        {
                                            ZonedDateTime nextExecution = helperMethods.ConvertScheduleMessageIntoDateTime(
                                                schedule.Command.Split(' '),
                                                slackUser.TimeZone,
                                                clock);
                                            await WebhookController.SendSlackMessage(workspaceInfo,
                                                                                     $"Next execution is {nextExecution.GetFriendlyZonedDateTimeString()}",
                                                                                     user.UserId,
                                                                                     httpClient);

                                            schedule.NextExecution = nextExecution.ToDateTimeUtc();
                                        }
                                    }
                                }

                                if (deleteSchedule)
                                {
                                    user.Schedule.RemoveAt(i);
                                    i--;
                                }
                            }

                            if (saveNeeded)
                            {
                                database.SaveUser(user);
                            }
                        }
                    }
                }

                await Task.Delay(CheckDuration.ToTimeSpan());
            }
        }