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; } }
/// <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); }
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"); } }
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); }
/// <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; }
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; }
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[]
/// <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); } }
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(); }
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}"); }
/// <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(); }
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()); } }