/// <summary> /// Processes the subscriber queue message. /// </summary> /// <param name="message">The message.</param> /// <param name="subscriberTable">The subscriber table.</param> public static void ProcessSubscriberQueueMessage( [QueueTrigger(NewSubscriberQueue)] string message, [Table(SubscriberTable)] CloudTable subscriberTable) { try { lock (LockingObject) { var isUnsubsribeMessage = false; Console.Out.WriteLine("New subscriber message captured {0}", message); var sendgridUserName = ConfigurationManager.AppSettings[ApplicationConstants.SendgridUserName]; var sendgridPassword = ConfigurationManager.AppSettings[ApplicationConstants.SendgridPassword]; mailSystem = new SendgridMailClient(sendgridUserName, sendgridPassword); if (message.StartsWith("unsubscribe:", StringComparison.OrdinalIgnoreCase)) { message = message.Split(':')[1]; isUnsubsribeMessage = true; } var operation = TableOperation.Retrieve(ApplicationConstants.SubscriberListKey, message); var result = subscriberTable.Execute(operation, TableRequestOptions).Result as DynamicTableEntity; if (null == result) { Console.Error.WriteLine("There was no record found for {0}", message); return; } Console.Out.WriteLine("Going to send mail to {0}", message); if (isUnsubsribeMessage) { // ReSharper disable once PossibleInvalidOperationException SendUnsubscribeMailToUser( new Tuple <string, string, string, DateTime>( result.Properties["FirstName"].StringValue, result.Properties["UnsubscribeString"].StringValue, message, result.Properties["CreatedDate"].DateTime.Value)); } else { // ReSharper disable once PossibleInvalidOperationException SendNewSubscriberMailToUser( new Tuple <string, string, string, DateTime>( result.Properties["FirstName"].StringValue, result.Properties["VerificationString"].StringValue, message, result.Properties["CreatedDate"].DateTime.Value)); } Console.Out.WriteLine("Mail sent to {0}", message); } } catch (Exception exception) { Console.Error.WriteLine("Error at Time:{0} Exception:{1}", DateTime.UtcNow, exception); throw; } }
/// <summary> /// Processes the queue message. /// </summary> /// <param name="message">The message.</param> /// <param name="blogTable">The blog table.</param> /// <param name="subscriberTable">The subscriber table.</param> public static void ProcessNewPostQueueMessage( [QueueTrigger(NewPostQueue)] string message, [Table(BlogTable)] CloudTable blogTable, [Table(SubscriberTable)] CloudTable subscriberTable) { try { Console.Out.WriteLine("New post message captured {0}", message); var sendgridUserName = ConfigurationManager.AppSettings[ApplicationConstants.SendgridUserName]; var sendgridPassword = ConfigurationManager.AppSettings[ApplicationConstants.SendgridPassword]; mailSystem = new SendgridMailClient(sendgridUserName, sendgridPassword); var operation = TableOperation.Retrieve(ApplicationConstants.BlogKey, message); var result = blogTable.Execute(operation, TableRequestOptions).Result as DynamicTableEntity; if (null == result) { Console.Error.WriteLine("Could not find record corresponding to RK {0}", message); return; } var title = result.Properties["Title"].StringValue; var postedDate = result.Properties["PostedDate"].DateTime; var bodySnippet = Routines.GeneratePreview(result.Properties["AutoIndexedElement_0_Body"].StringValue); var formattedUri = result.Properties["FormattedUri"].StringValue; //// Run paged queries to get subscribers. Console.Out.WriteLine("Going to get list of subscribers"); var query = (from record in subscriberTable.CreateQuery <DynamicTableEntity>() where record.PartitionKey == ApplicationConstants.SubscriberListKey && record.Properties["LastEmailIdentifier"].StringValue != result.RowKey && record.Properties["LastEmailIdentifier"].StringValue != string.Format("Faulted {0}", DateTime.UtcNow.Date) && record.Properties["IsVerified"].BooleanValue == true select record).Take(50).AsTableQuery(); TableContinuationToken token = null; do { var segment = subscriberTable.ExecuteQuerySegmented(query, token, TableRequestOptions); var batchUpdate = new TableBatchOperation(); if (null == segment || !segment.Any()) { Console.Out.WriteLine("No users found. Aborting current call."); return; } //// Compose Tuple of records of users. var userDetails = segment.Select( record => new Tuple <string, string, string>( record.Properties["FirstName"].StringValue, record.RowKey, record.Properties["VerificationString"].StringValue)).ToList(); Console.Out.WriteLine("Going to send mails to users"); if (SendNewPostMailsToUsers(userDetails, title, postedDate, formattedUri, bodySnippet)) { foreach (var record in segment) { record.Properties["LastEmailIdentifier"].StringValue = result.RowKey; batchUpdate.Add(TableOperation.InsertOrReplace(record)); } } else { foreach (var record in segment) { record.Properties["LastEmailIdentifier"].StringValue = string.Format( "Faulted {0}", DateTime.UtcNow.Date); batchUpdate.Add(TableOperation.InsertOrReplace(record)); } } subscriberTable.ExecuteBatch(batchUpdate, TableRequestOptions); token = segment.ContinuationToken; }while (token != null); Console.Out.WriteLine("Mails sent"); } catch (Exception exception) { Console.Error.WriteLine("Error at Time:{0} Message:{1}", DateTime.UtcNow, exception); throw; } }
/// <summary> /// Cleanups the old subscribers. /// </summary> /// <param name="subscriberTable">The subscriber table.</param> public static void CleanupOldSubscribers(CloudTable subscriberTable) { try { var query = (from record in subscriberTable.CreateQuery <DynamicTableEntity>() where record.PartitionKey == ApplicationConstants.SubscriberListKey && record.Properties["CreatedDate"].DateTime < (DateTime.UtcNow - TimeSpan.FromDays(7)) && record.Properties["IsVerified"].BooleanValue == false select record).Take(100).AsTableQuery(); TableContinuationToken token = null; do { var segment = subscriberTable.ExecuteQuerySegmented(query, token, TableRequestOptions); var batchDelete = new TableBatchOperation(); if (null == segment || !segment.Any()) { Console.Out.WriteLine("No users found. Aborting current call."); } else { //// Log users we are going to delete. foreach (var user in segment) { Console.Out.WriteLine("Deleting {0}", user.Properties["Email"].StringValue); batchDelete.Add(TableOperation.Delete(user)); } Console.Out.WriteLine("Going to delete inactive users"); subscriberTable.ExecuteBatch(batchDelete, TableRequestOptions); token = segment.ContinuationToken; } }while (token != null); //// Send a friendly reminder everyday for the last 5 days before deleting a subscription. var sendgridUserName = ConfigurationManager.AppSettings[ApplicationConstants.SendgridUserName]; var sendgridPassword = ConfigurationManager.AppSettings[ApplicationConstants.SendgridPassword]; mailSystem = new SendgridMailClient(sendgridUserName, sendgridPassword); var reminderQuery = (from record in subscriberTable.CreateQuery <DynamicTableEntity>() where record.PartitionKey == ApplicationConstants.SubscriberListKey && record.Properties["CreatedDate"].DateTime <= (DateTime.UtcNow - TimeSpan.FromDays(3)) && record.Properties["IsVerified"].BooleanValue == false select record).Take(10).AsTableQuery(); TableContinuationToken reminderContinuationToken = null; do { var segment = subscriberTable.ExecuteQuerySegmented( reminderQuery, reminderContinuationToken, TableRequestOptions); if (null == segment || !segment.Any()) { Console.Out.WriteLine("No user found for reminder. Aborting current call."); } else { //// Log users we are going to remind. foreach (var user in segment) { Console.Out.WriteLine("Reminding {0}", user.Properties["Email"].StringValue); var reminderStatus = SendReminderMail( new Tuple <string, string, string, DateTime>( user.Properties["FirstName"].StringValue, user.Properties["VerificationString"].StringValue, user.Properties["Email"].StringValue, // ReSharper disable once PossibleInvalidOperationException user.Properties["CreatedDate"].DateTime.Value)); Console.Out.WriteLine( "Reminded {0} with state {1}", user.Properties["Email"].StringValue, reminderStatus); } Console.Out.WriteLine("All users reminded"); reminderContinuationToken = segment.ContinuationToken; } }while (reminderContinuationToken != null); } catch (Exception exception) { Console.Error.WriteLine("Error at Time:{0} Exception:{1}", DateTime.UtcNow, exception); throw; } }