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);
        }
示例#2
0
        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
        }