public static void Main() { callGraphServiceTimer.Start(); callGraphServiceTimer.Elapsed += (sender, e) => HandleTimer(sender, e); ViaNettSMS viaNettSMS = new ViaNettSMS(_SMSServiceUserName, _SMSServicePassword); try { // ADAL: https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-libraries authenticationContext = new AuthenticationContext(GraphService.DefaultAadInstance, TokenCache.DefaultShared); authenticationResult = authenticationContext.AcquireTokenAsync( GraphService.ResourceId, _ApplicationAppId, _ApplicationRedirectUri, new PlatformParameters(PromptBehavior.RefreshSession)).Result; } catch (Exception e) { Console.WriteLine(e); } // This BookingsContainer is generated by the ODATA v4 Client Code Generator // See https://odata.github.io and https://github.com/odata/odata.net for usage. // Note that the code generator customizes the entity and property names to PascalCase // so they match C# guidelines, while the EDM uses lower case camelCase, as per Graph guidelies. // Since the application is short lived, the delegate is simply returning the authorization // header obtained above; a long lived application would likely need to refresh the token // when it expires, so it would have a slightly more complex delegate. var graphService = new GraphService( GraphService.DefaultV1ServiceRoot, () => { // Hvis Token timedout // Forny Token if (authenticationResult.ExpiresOn.ToLocalTime() >= DateTime.Now) { //refresh // Har mulighet til å refreshe i 5 minutter etter token har utgått authenticationResult = authenticationContext.AcquireTokenSilentAsync(GraphService.ResourceId, _ApplicationAppId).Result; string _header = authenticationResult.CreateAuthorizationHeader(); return(_header); } else { string _header = authenticationResult.CreateAuthorizationHeader(); return(_header); } }); // Fiddler makes it easy to look at the request/response payloads. Use it automatically if it is running. // https://www.telerik.com/download/fiddler if (System.Diagnostics.Process.GetProcessesByName("fiddler").Any()) { graphService.WebProxy = new WebProxy(new Uri("http://*****:*****@"[^\d+]", ""), customerNotes = oDataAppointment.CustomerNotes, Id = oDataAppointment.Id, staffMemberIds = oDataAppointment.StaffMemberIds.FirstOrDefault(), Start = System.DateTime.Parse(oDataAppointment.Start.DateTime).ToLocalTime(), End = System.DateTime.Parse(oDataAppointment.End.DateTime).ToLocalTime(), serviceId = oDataAppointment.ServiceId, serviceName = oDataAppointment.ServiceName.ToLower(), json = JsonConvert.SerializeObject(oDataAppointment), md5 = Convert.ToBase64String(md5.ComputeHash(Encoding.UTF8.GetBytes(oDataAppointment.Id + oDataAppointment.Start.DateTime.ToString() + oDataAppointment.End.DateTime.ToString()))), md5hash = md5.ComputeHash(Encoding.Unicode.GetBytes(oDataAppointment.Id)) }; Debug.WriteLine(appointment.json); List <BookingAppointment> _list = new List <BookingAppointment> { oDataAppointment }; switch (InsertOrUpdate(appointment, db)) { case EntityState.Detached: break; case EntityState.Unchanged: break; case EntityState.Added: // Ny Avtale SendSMS(viaNettSMS, _business, _list, SMSTemplate.SMSConfirmation); break; case EntityState.Deleted: break; case EntityState.Modified: // Avtalen er endret SendSMS(viaNettSMS, _business, _list, SMSTemplate.SMSUpdate); break; default: break; } } //Create a list of Cancelled Appointments (Appointments in database not occuring from the graphservice.business.appointments ) List <byte[]> odataIDs; try { odataIDs = bookingAppointments.Select(x => md5.ComputeHash(Encoding.Unicode.GetBytes(x.Id))).ToList <byte[]>(); } catch (Exception e) { Console.WriteLine($"ExceptionCount: {exceptionCount} , exception: {e.InnerException.ToString()}"); exceptionCount++; continue; } /* * */ var deleteAppointments = from a in db.Appointment where !odataIDs.Contains(a.md5hash) && a.Start > DateTime.Now && a.appointmentIsActive == true select a; var bookingAppointmentList = new List <BookingAppointment>(); //Update database for every Cancelled appointment and create a list of those Appointments foreach (var appoint in deleteAppointments) { appoint.appointmentIsActive = false; appoint.appointmentChangedDate = DateTime.Now; var bappoint = JsonConvert.DeserializeObject <BookingAppointment>(appoint.json); bookingAppointmentList.Add(bappoint); } try { db.SaveChanges(); } catch (Exception e) { Console.WriteLine($"ExceptionCount: {exceptionCount} , exception: {e.InnerException.ToString()}"); exceptionCount++; continue; } /* Send SMS for every Cancelled Appointments in the AppointmentList*/ SendSMS(viaNettSMS, _business, bookingAppointmentList, SMSTemplate.SMSCancellation); // Send Reminder SMS DateTime rm1DateTimeMax = DateTime.Now.Add(SMSReminder1TimeSpanBefore); DateTime rm2DateTimeMax = DateTime.Now.Add(SMSReminder2TimeSpanBefore); //DateTime rm3DateTimeMax = DateTime.Now.Add(SMSReminder3TimeSpanBefore); DateTime rm1DateTimeMin = rm1DateTimeMax.AddHours(-2); DateTime rm2DateTimeMin = rm2DateTimeMax.AddHours(-2); //DateTime rm3DateTimeMin = rm3DateTimeMax.AddHours(-2); DateTime surveyDateTimeMin = DateTime.Now.Add(SMSSurveyTimeSpanBefore); // 7 Dager var reminder1Appointments = from a in db.Appointment where a.SMSLog.Where(s => s.smsTemplate == SMSTemplate.SMSReminder1.ToString() && s.smsIsSent == true).Count() < 1 && a.Start <rm1DateTimeMax && a.Start> rm1DateTimeMin && !(a.appointmentCreatedDate <rm1DateTimeMax && a.appointmentCreatedDate> rm1DateTimeMin) && !string.IsNullOrEmpty(a.customerId) && !string.IsNullOrEmpty(a.customerPhone) && a.appointmentIsActive == true select a; // 2 Dager var reminder2Appointments = from a in db.Appointment where a.SMSLog.Where(s => s.smsTemplate == SMSTemplate.SMSReminder2.ToString() && s.smsIsSent == true).Count() < 1 && a.Start <rm2DateTimeMax && a.Start> rm2DateTimeMin && !(a.appointmentCreatedDate <rm2DateTimeMax && a.appointmentCreatedDate> rm2DateTimeMin) && !string.IsNullOrEmpty(a.customerId) && !string.IsNullOrEmpty(a.customerPhone) && a.appointmentIsActive == true select a; //// 1 Dag //var reminder3Appointments = from a in db.Appointment // where a.SMSLog.Where(s => s.smsTemplate == SMSTemplate.SMSReminder3.ToString() && s.smsIsSent == true).Count() < 1 // && a.Start < rm3DateTimeMax // && a.Start > rm3DateTimeMin // && !(a.appointmentCreatedDate < rm3DateTimeMax && a.appointmentCreatedDate > rm3DateTimeMin) // select a; var surveyAppointments = from a in db.Appointment where a.SMSLog.Where(s => s.smsTemplate == SMSTemplate.SMSSurvey.ToString() && s.smsIsSent == true).Count() < 1 && a.Start < surveyDateTimeMin && !string.IsNullOrEmpty(a.customerId) && !string.IsNullOrEmpty(a.customerPhone) && a.appointmentIsActive == true select a; List <BookingAppointment> reminder1List = new List <BookingAppointment>(); List <BookingAppointment> reminder2List = new List <BookingAppointment>(); List <BookingAppointment> surveyList = new List <BookingAppointment>(); //List<BookingAppointment> reminder3List = new List<BookingAppointment>(); foreach (var item in reminder1Appointments) { reminder1List.Add( new BookingAppointment { Id = item.Id , CustomerName = item.customerName , CustomerPhone = item.customerPhone , ServiceName = item.serviceName , Start = new DateTimeTimeZone { DateTime = DateTime.Parse(item.Start.ToString()).ToUniversalTime().ToString("o"), TimeZone = "UTC" } , CustomerEmailAddress = item.customerEmailAddress , End = new DateTimeTimeZone { DateTime = DateTime.Parse(item.End.ToString()).ToUniversalTime().ToString("o"), TimeZone = "UTC" } , Duration = new TimeSpan(1, 0, 0) , ServiceLocation = new Location { Address = new PhysicalAddress() , Coordinates = new OutlookGeoCoordinates() } } ); } foreach (var item in reminder2Appointments) { reminder2List.Add( new BookingAppointment { Id = item.Id , CustomerName = item.customerName , CustomerPhone = item.customerPhone , ServiceName = item.serviceName , Start = new DateTimeTimeZone { DateTime = DateTime.Parse(item.Start.ToString()).ToUniversalTime().ToString("o"), TimeZone = "UTC" } , CustomerEmailAddress = item.customerEmailAddress , End = new DateTimeTimeZone { DateTime = DateTime.Parse(item.End.ToString()).ToUniversalTime().ToString("o"), TimeZone = "UTC" } , Duration = new TimeSpan(1, 0, 0) , ServiceLocation = new Location { Address = new PhysicalAddress() , Coordinates = new OutlookGeoCoordinates() } } ); } foreach (var item in surveyAppointments) { surveyList.Add( new BookingAppointment { Id = item.Id , CustomerName = item.customerName , CustomerPhone = item.customerPhone , ServiceName = item.serviceName , Start = new DateTimeTimeZone { DateTime = DateTime.Parse(item.Start.ToString()).ToUniversalTime().ToString("o"), TimeZone = "UTC" } , CustomerEmailAddress = item.customerEmailAddress , End = new DateTimeTimeZone { DateTime = DateTime.Parse(item.End.ToString()).ToUniversalTime().ToString("o"), TimeZone = "UTC" } , Duration = new TimeSpan(1, 0, 0) , ServiceLocation = new Location { Address = new PhysicalAddress() , Coordinates = new OutlookGeoCoordinates() } } ); } //foreach (var item in reminder3Appointments) //{ // reminder3List.Add( // new BookingAppointment { // Id = item.Id // ,CustomerName = item.customerName // ,CustomerPhone = item.customerPhone // ,ServiceName = item.serviceName // ,Start = new DateTimeTimeZone { DateTime = DateTime.Parse(item.Start.ToString()).ToUniversalTime().ToString("o"), TimeZone = "UTC" } // ,CustomerEmailAddress = item.customerEmailAddress // ,End = new DateTimeTimeZone { DateTime = DateTime.Parse(item.End.ToString()).ToUniversalTime().ToString("o"), TimeZone = "UTC" } // ,Duration = new TimeSpan(1,0,0) // ,ServiceLocation = new Location { // Address = new PhysicalAddress() // ,Coordinates = new OutlookGeoCoordinates() // } // } // ); //} SendSMS(viaNettSMS, _business, reminder1List, SMSTemplate.SMSReminder1); SendSMS(viaNettSMS, _business, reminder2List, SMSTemplate.SMSReminder2); SendSMS(viaNettSMS, _business, surveyList, SMSTemplate.SMSSurvey); //SendSMS(viaNettSMS, _business, reminder3List, SMSTemplate.SMSReminder3); } System.Threading.Thread.Sleep(60000); } // End While }
private static void SendSMS(ViaNettSMS viaNettSMS, BookingBusiness _business, IEnumerable <BookingAppointment> _appointments, SMSTemplate sMSTemplate) { MD5 md5 = MD5.Create(); foreach (BookingAppointment appointment in _appointments) { // Send SMS to Customer Console.WriteLine("Sending SMS to CustomerName: {0}, CustomerPhone: {1}", appointment.CustomerName, appointment.CustomerPhone); ViaNettSMS.Result result; string _appointmentDateString = DateTime.Parse(appointment.Start.DateTime).ToString("dd.MM.yyyy HH:mm"); string message = RenderSMSTemplate(_business, appointment, _appointmentDateString, sMSTemplate); try { // Send SMS through HTTP API Console.WriteLine("{0} SendingSMS: {1} {2} {3}", Date.Now.ToString(), _SMSSenderFrom, appointment.CustomerPhone, message); result = viaNettSMS.SendSMS(_SMSSenderFrom, appointment.CustomerPhone, message); //result = viaNettSMS.SendSMS(_SMSSenderFrom, "40453626", message); // Show Send SMS response if (result.Success) { Debug.WriteLine("Message successfully sent"); using (BookingEntities context = new BookingEntities()) { context.SMSLog.Add(new SMSLog { appointmentId = appointment.Id , message = message , recipientPhone = appointment.CustomerPhone , sentDate = DateTime.Now , smsIsSent = true , sentResult = "OK" , smsTemplate = sMSTemplate.ToString() , md5hash = md5.ComputeHash(Encoding.Unicode.GetBytes(appointment.Id)) }); context.SaveChanges(); } } else { using (BookingEntities context = new BookingEntities()) { context.SMSLog.Add(new SMSLog { appointmentId = appointment.Id , message = message , recipientPhone = appointment.CustomerPhone , sentDate = DateTime.Now , smsIsSent = false , sentResult = $"Received error: {result.ErrorCode} {result.ErrorMessage}" , smsTemplate = sMSTemplate.ToString() , md5hash = md5.ComputeHash(Encoding.Unicode.GetBytes(appointment.Id)) }); context.SaveChanges(); } Debug.WriteLine($"Received error: {result.ErrorCode} {result.ErrorMessage}"); } } catch (System.Net.WebException ex) { //Catch error occurred while connecting to server. Debug.WriteLine(ex.Message); } } md5.Dispose(); }