From ede0fda29949a92b0f8c64e27c87b93bbcb96650 Mon Sep 17 00:00:00 2001 From: Markus Johansson Date: Tue, 10 Dec 2024 20:33:04 +0100 Subject: [PATCH] v14 example for Recipient List Provider --- .../Extensions-Demos/Demo.Web/.editorconfig | 2 + .../InMemoryRecipient.cs | 11 + .../InMemoryRecipientListProvider.cs | 218 ++++++++++++++++++ .../InMemoryRecipientListProviderComposer.cs | 13 ++ 4 files changed, 244 insertions(+) create mode 100644 Newsletter Studio V14/Extensions-Demos/Demo.Web/.editorconfig create mode 100644 Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipient.cs create mode 100644 Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipientListProvider.cs create mode 100644 Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipientListProviderComposer.cs diff --git a/Newsletter Studio V14/Extensions-Demos/Demo.Web/.editorconfig b/Newsletter Studio V14/Extensions-Demos/Demo.Web/.editorconfig new file mode 100644 index 0000000..d9e95b6 --- /dev/null +++ b/Newsletter Studio V14/Extensions-Demos/Demo.Web/.editorconfig @@ -0,0 +1,2 @@ +[*.{cs,ts,js,html}] +max_line_length = 85 \ No newline at end of file diff --git a/Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipient.cs b/Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipient.cs new file mode 100644 index 0000000..4bbf372 --- /dev/null +++ b/Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipient.cs @@ -0,0 +1,11 @@ +namespace Demo.Web.Extensions.RecipientListProvider; + +/// +/// A model to recipient data about an In Memory Recipient +/// +public class InMemoryRecipient +{ + public int BirthYear { get; set; } + public string City { get; set; } + public string CompanyName { get; set; } +} \ No newline at end of file diff --git a/Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipientListProvider.cs b/Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipientListProvider.cs new file mode 100644 index 0000000..b48e60d --- /dev/null +++ b/Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipientListProvider.cs @@ -0,0 +1,218 @@ +using NewsletterStudio.Core.Infrastructure.MailingLists; +using NewsletterStudio.Core.Rendering; +using Umbraco.Cms.Core.Web; + +namespace Demo.Web.Extensions.RecipientListProvider; + +/// +/// A Demo provider that uses in memory recipients. +/// +public class InMemoryRecipientListProvider : IRecipientListProvider +{ + private readonly IUmbracoContextFactory _umbracoContextFactory; + + public string DisplayName => "In Memory Provider"; + + /// + /// Enter a name or a localization key like ex_my_key. You need to make + /// sure that these translations are loaded in to the backoffice. + /// + public string DisplayNameLocalizationKey => "In Memory Provider"; + + public string Prefix => "ex"; + + public InMemoryRecipientListProvider( + IUmbracoContextFactory umbracoContextFactory + ) + { + // You can inject dependencies in the constructor if needed. + // Providers are created as Singletons, keep this in mind when + // injecting your dependencies. + _umbracoContextFactory = umbracoContextFactory; + } + + /// + /// Called when we present available lists to the users, e.g. in the + /// last step before sending a campaign. + /// + /// Should return a list of available lists that this provider exposes. + /// Examples: + /// Built in provider = Mailing Lists, + /// Umbraco Members = List of groups + /// + /// + /// + public List GetLists(Guid workspaceKey) + { + /* + * Note here that each item in the list has a RecipientListIdentifier + * This identifier is used to uniquely identify the list and will be + * passed to other methods in this class to retrieve details. + */ + return new List() + { + new RecipientList() + { + // Replace 1 with a unique identifier (int, guid etc.) of your list. + Identifier = new RecipientListIdentifier(Prefix, 1), + Name = "Demo list 1", + Subscribers = 25 + }, + new RecipientList() + { + Identifier = new RecipientListIdentifier(Prefix, 2), + Name = "Demo list 2", + Subscribers = 21 + } + }; + } + + /// + /// This method is called bu Newsletter Studio to build a for a campaign based + /// on the lists that the user selected. The package will handle duplicates if + /// the same email is present in more than one list. + /// + /// Notice that the from the + /// -method is passed here and will contain your + /// unique identifier. + /// + /// This method should return a list of that will + /// be used to build the queue. + /// + /// + /// + /// + public List GetReceiversForList( + RecipientListIdentifier listId, + GetReceiversForListParams parameters + ) + { + var list = new List(); + list.Add(new EmailReceiver( + new EmailReceiverIdentifier(Prefix, 1), + "foo@bar123.com", + "Foo Bar") + ); + + if (listId.Identifier == "2") + list.Add(new EmailReceiver( + new EmailReceiverIdentifier(Prefix, 2), + "foo2@bar123.com", + "Foo Bar") + ); + + return list; + } + + /// + /// This method is called by the package during the send out. I will be + /// called one time for each recipient to get the details based on the + /// created in the + /// -method. + /// + /// These details are used to render the email and to provide values + /// for any . + /// + /// + /// + public RecipientProviderRecipientDataModel GetDataModel( + EmailReceiverIdentifier receiverId + ) + { + var model = new RecipientProviderRecipientDataModel(); + model.Email = "foo@bar.com"; + model.ProviderRecipientId = receiverId.ToString(); + + // The optional "Model"-property is used to pass a custom model that + // can be used inside a IMergeFieldProvider to translate properties + // into Merge Fields. Leave this as null if you do not need to pass + // any detailed data. + model.Model = new InMemoryRecipient() + { + BirthYear = 1975, + City = "London", + CompanyName = "Test Company Inc." + }; + + return model; + } + + /// + /// This method is used when matching transactional recipients to existing + /// recipients in the system. Return a based on + /// the email passed in. This method can return null if you data source + /// does not support to query by email. + /// + /// + /// + /// + /// + public EmailReceiver GetByEmail(string email, Guid? workspaceKey = null) + { + throw new NotImplementedException(); + } + + /// + /// This method is called to unsubscribe a recipient from a given list. + /// + /// + /// + /// + public bool Unsubscribe( + EmailReceiverIdentifier receiverId, + RecipientListIdentifier listId + ) + { + //TODO: Change status + return true; + } + + /// + /// This method is called to unsubscribe a recipient from all + /// lists in the provider. + /// + /// + /// + public bool UnsubscribeAll(EmailReceiverIdentifier receiverId) + { + //TODO: Change status + return true; + } + + /// + /// Should return information on how to open details for the recipient. + /// Could be a link to another part of the Umbraco backoffice or external link + /// + /// + /// + public RecipientEditInformation? GetEditInformation( + EmailReceiverIdentifier receiverId + ) + { + return new RecipientEditInformation() + { + Type = RecipientEditInformationType.Link, + OpenInNewWindow = true, + Url = "https://www.newsletterstudio.org" + }; + } + + /// + public void ReportSoftBounce(EmailReceiverIdentifier receiverId) + { + // If you're data source supports keeping track of delivery issues you + // can use this method to append new issues. The build in provider uses + // a "ErrorCount" column that will increment. After too many soft bounces + // (set by NewsletterStudioConstants.Recipient.MaxErrorsBeforeInvalid) the + // recipient is considered invalid. + } + + /// + public void ReportHardBounce(EmailReceiverIdentifier receiverId) + { + // If you're data source supports "turning off" a recipient due to + // delivery issues you should use this method. A hard bounce means that + // we're sure that the recipient should never get any more emails, + // it should be permanently disabled. + } +} \ No newline at end of file diff --git a/Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipientListProviderComposer.cs b/Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipientListProviderComposer.cs new file mode 100644 index 0000000..6c718c4 --- /dev/null +++ b/Newsletter Studio V14/Extensions-Demos/Demo.Web/Extensions/RecipientListProvider/InMemoryRecipientListProviderComposer.cs @@ -0,0 +1,13 @@ +using NewsletterStudio.Core.Composing; + +namespace Demo.Web.Extensions.RecipientListProvider; + +public class InMemoryRecipientListProviderComposer +{ + public void Compose(IUmbracoBuilder builder) + { + builder.NewsletterStudio() + .RecipientListProviders + .Append(); + } +} \ No newline at end of file