internal void SyncContact(Entity target, Entity postImage, Entity preImage, bool isUpdate) { if (target == null || postImage == null) { tracer.Trace("Invalid target or postImage entity."); return; } if (campaignMonitorConfig == null) { tracer.Trace("Missing or invalid campaign monitor configuration."); return; } string emailField = SharedLogic.GetPrimaryEmailField(campaignMonitorConfig.SubscriberEmail); if (string.IsNullOrWhiteSpace(emailField) || !postImage.Contains(emailField) || string.IsNullOrWhiteSpace(postImage[emailField].ToString())) { tracer.Trace("The email field to sync is missing or contains invalid data."); return; } if (campaignMonitorConfig.SyncViewId != Guid.Empty) { tracer.Trace("Testing the contact against the filter."); // Retrieve the view specified in the campmon_syncviewid field of the configuration record. var filterQuery = SharedLogic.GetConfigFilterQuery(orgService, campaignMonitorConfig.SyncViewId); // Modify the sync view fetch query to include a filter condition for the current contact id.Execute the modified query and check if the contact is returned.If it is, exit the plugin. if (!TestContactFitsFilter(filterQuery, target.Id)) { tracer.Trace("Contact does not fit the filter."); return; } } else { if (target.Contains("statecode") && (target["statecode"] as OptionSetValue).Value == 1) { tracer.Trace("Contact was not synced: no view is selected and this contact is deactivated."); return; } } tracer.Trace("Contact fits the filter, or no filter is selected."); /* * Create a campmon_message record with the following data: * • campmon_sdkmessage = Plugin message (create or update) * • campmon_data = JSON serialized sync data */ var syncMessage = new Entity("campmon_message"); var fields = SharedLogic.ContactAttributesToSubscriberFields(orgService, tracer, target, campaignMonitorConfig.SyncFields.ToList()); // Check that the plugin target has modified attributes that are included in the campmon_syncfields data. If there are not any sync fields in the target, exit the plugin. if (fields.Count <= 0) { tracer.Trace("There are no fields in the target that match the current fields being synced with Campaign Monitor."); return; } if (isUpdate && !target.Attributes.Contains(emailField)) { fields.Add(new SubscriberCustomField { Key = emailField, Value = postImage[emailField].ToString() }); } else if (isUpdate && target.Attributes.Contains(emailField) && preImage[emailField].ToString() != postImage[emailField].ToString()) { // if it contains primary email and isUpdate, then the primary email was changed and we need to do something to handle that var auth = Authenticator.GetAuthentication(campaignMonitorConfig, orgService); var subscriber = new Subscriber(auth, campaignMonitorConfig.ListId); try { subscriber.Update(preImage[emailField].ToString(), postImage[emailField].ToString(), postImage["fullname"].ToString(), null, false); } catch (CreatesendException csEx) { if (csEx.Error.Code == "203") { subscriber.Add(postImage[emailField].ToString(), postImage["fullname"].ToString(), null, false); } } catch (Exception ex) { tracer.Trace("Exception type: {0}", ex.GetType().Name); throw; } } if (isUpdate && !target.Attributes.Contains("fullname")) { fields.Add(new SubscriberCustomField { Key = "fullname", Value = postImage["fullname"].ToString() }); } var syncData = JsonConvert.SerializeObject(fields); syncMessage["campmon_name"] = isUpdate ? "update" : "create"; syncMessage["campmon_data"] = syncData; syncMessage["campmon_email"] = emailField; orgService.Create(syncMessage); }
public bool Run() { trace.Trace("Deserializing bulk sync data."); BulkSyncData syncData = config.BulkSyncData != null ? syncData = JsonConvert.DeserializeObject <BulkSyncData>(config.BulkSyncData) : new BulkSyncData(); string primaryEmail = SharedLogic.GetPrimaryEmailField(config.SubscriberEmail); QueryExpression viewFilter = GetBulkSyncFilter(config, syncData, primaryEmail); var auth = Authenticator.GetAuthentication(config, orgService); var sub = new Subscriber(auth, config.ListId); var mdh = new MetadataHelper(orgService, trace); trace.Trace("Beginning the sync process."); do { viewFilter.PageInfo.PageNumber = syncData.PageNumber > 1 ? syncData.PageNumber : 1; if (!string.IsNullOrWhiteSpace(syncData.PagingCookie)) { viewFilter.PageInfo.PagingCookie = syncData.PagingCookie; } trace.Trace("Processing page number {0}.", viewFilter.PageInfo.PagingCookie); // sync batch of 1000 contacts to CM list as subscribers EntityCollection contacts = orgService.RetrieveMultiple(viewFilter); syncData.PagingCookie = contacts.PagingCookie; syncData.PageNumber++; IEnumerable <Entity> invalidEmail = contacts.Entities.Where(e => !e.Attributes.Contains(primaryEmail) || string.IsNullOrWhiteSpace(e[primaryEmail].ToString())); syncData.NumberInvalidEmails += invalidEmail.Count(); BulkImportResults importResults = null; var subscribers = GenerateSubscribersList(contacts.Entities.Except(invalidEmail), primaryEmail, mdh); if (!subscribers.Any()) { trace.Trace("No subscribers to import from contact page."); continue; } trace.Trace("Starting subscriber import. {0} subscribers.", subscribers.Count()); try { importResults = sub.Import(subscribers, false, // resubscribe false, // queueSubscriptionBasedAutoResponders false); // restartSubscriptionBasedAutoResponders } catch (CreatesendException ex) { trace.Trace("CreatesendException Error on subscriber import: " + ex.Error.Message); trace.Trace("Exception Error on subscriber import: " + ex.Message); syncData.BulkSyncErrors.Add(new BulkSyncError("import", ex.Error.Message, "")); syncData.BulkSyncErrors.Add(new BulkSyncError("import", ex.Message, "")); trace.Trace("CreatesendException error occurred: Subscriber import ended."); } trace.Trace("Subscriber import ended."); if (importResults.FailureDetails.Count > 0) { if (syncData.BulkSyncErrors == null) { syncData.BulkSyncErrors = new List <BulkSyncError>(); } // log the errors back into bulk sync data foreach (var failure in importResults.FailureDetails) { syncData.BulkSyncErrors.Add(new BulkSyncError(failure.Code, failure.Message, failure.EmailAddress)); } } syncData.NumberSuccesses += importResults.TotalNewSubscribers; trace.Trace("Page: {0}", syncData.PageNumber); trace.Trace("More Records? {0}", contacts.MoreRecords); if (!contacts.MoreRecords) { trace.Trace("No more records."); trace.Trace("Sending email."); try { var account = new Account(auth); var emailPayload = String.Format("{{ \"ToEmail\": \"{0}\", \"SubscriberCount\": \"{1}\", \"ListName\": \"{2}\" }}", account.GetPrimaryContact(), syncData.NumberSuccesses, config.ListName); SuccessEmailSender.SendEmail(config.AccessToken, emailPayload); } catch (Exception ex) { trace.Trace(ex.Message); trace.Trace(ex.StackTrace); } trace.Trace("Clearing the sync data."); syncData.PageNumber = 1; syncData.PagingCookie = string.Empty; syncData.UpdatedFields = null; syncData.BulkSyncErrors.Clear(); syncData.NumberInvalidEmails = 0; break; } }while (timer.ElapsedMilliseconds <= 90000); trace.Trace("Saving bulk data."); string bulkData = JsonConvert.SerializeObject(syncData); config.BulkSyncData = bulkData; config.BulkSyncInProgress = syncData.PageNumber > 1; configService.SaveConfig(config); return(syncData.PageNumber <= 1); // if we're done return true }