Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Tonny Schou 3 posts 73 karma points
    1 week ago
    Tonny Schou
    0

    Custom EmailServiceProvider - returning results

    We're looking to use NewsletterStudio to handle outgoing mail (mostly transactional) on the Umbraco side of our projects and it is looking very promising.

    We have our own system for sending out email on the backend side of our projects, which does a better job of handling throttling and status tracing than plain SMTP, so we would like to continue to use this as our provider. I've build an IEmailServiceProvider for NewsletterStudio and set this up as our default in the configuration and it is working, with just one issue: I cannot seem to get any results back when sending transactional email through it.

    Our backend provider generates a TransactionId, which I would like to store with the Umbraco Member the email was sent to, but whenever I call INewsletterStudioService.SendTransactional, the model returned is empty. I've set the ExternalId property on the SendEmailJob to our TransactionId in the provider and tried setting the SendTransactionalEmailRequest to NotAsync() but nothing is returned to the caller regardless.

    How do we set the send results in the EmailServiceProvider so we can read them in the caller?

  • Markus Johansson 1771 posts 5182 karma points c-trib
    4 days ago
    Markus Johansson
    0

    Hi Tonny!

    Thanks for looking at the package and for your kind words! I'm really excited that we're extending the package to your needs - let's see if we can narrow down your issues and solve them.

    So if I understand things right here: You have some other system that takes care of sending the emails, this system basically works as a API or SMTP so you're implementing a custom "Email Service Provider" (https://www.newsletterstudio.org/documentation/package/4.0.0/develop/email-service-providers/) that you're using to send the emails from using your email backend?

    And if I understand you right you are looking for a way to see all of your "TransactionIds" (returned by you're service and set as ExternalId on the batch) related to a given Umbraco Member?

    I'll try to outline the process here so that we have a common understanding of how the Email Service Provider is used when sending emails in Newsletter Studio.

    In the context of Transactional Emails, depending on the settings, one call to ´SendTransactionalEmailRequest´ could result in one or many individual emails beening sent (depending on the settings for the recipient(s), CC, BCC). Also, we will send individual emails to each recipient if not explicitly configured on the transactional email.

    This means that one call to ´SendTransactionalEmailRequest´ could result in one or many SendEmailJob being passed to your Email Service Provider´. Each individual job represents an individual email. We store the "ExternalId" in the database (nsTrackingTransactionalEmail-table) to be used e.g when a Email Service provides callbacks (webhooks) or APIs to check for delivery status. This way anEmail Service Provider´ can be implemented together with a scheduled job or a webhook-listener to update information about delivery status (bounces etc). Here is an example of this: https://github.com/enkelmedia/NewsletterStudio.Plugins.Mailjet/

    The calling code will not get the details from the SendEmailJob back at the moment, as far as I can see the SendTransactionalEmailResponse only handles validation and does not return any information. Since there is a "async" behavior, where a background thread will perform the work, the information needed might not be available for the calling code when the method returns. With that said, it might be possible for us to provide changes that would returns this information in the future.

    Depending on why you need this it might be an option to use the information in the nsTrackingTransactionalEmail-table since we will store the "ExternalId" here and the Umbraco Members unique key (part of the providerRecipientId). Or maybe you could store this information from the Email Service Provider that you're implementing.

    No sure if this provided any answers that can help you move forward? Please feel free to ask more questions if you need to details.

    Cheers!

  • Tonny Schou 3 posts 73 karma points
    3 days ago
    Tonny Schou
    0

    Thank you for the added information. The github link to the MailJet example was particularly useful and would be a good addition to the documentation page for the Email Service Providers.

    So if I understand things right here: You have some other system that takes care of sending the emails, this system basically works as a API or SMTP so you're implementing a custom "Email Service Provider" (https://www.newsletterstudio.org/documentation/package/4.0.0/develop/email-service-providers/) that you're using to send the emails from using your email backend?

    Correct. We send single emails or batches through a REST API and the system behind it handles all the technical matters of sending the email through an external service, including error handling and collecting status information, receiving webhooks etc. This allows for more reliability than basic "fire-and-forget" SMTP and lets us off-load those tasks to another server, so the website isn't impacted by all the email-related traffic.

    The external system also handles other background tasks, such as invoicing. These tasks can generate emails of their own, so we would prefer to send all emails through this system to keep all the resulting status information in one place.

    And if I understand you right you are looking for a way to see all of your "TransactionIds" (returned by you're service and set as ExternalId on the batch) related to a given Umbraco Member?

    Yes. We are currently working on a site for an industry association and the recipients of their emails will be their paying members. The content of the emails will be the usual innocuous stuff (newsletters, action receipts etc) but also more important things, like invoice reminders and notifications of updates to individual legal matters. In the past, there have been disputes between the association and their members regarding these matters and the notifications, so it's important to our client that we give them the ability to track individual emails and look up their detailed status information.

    We would like to build a dashboard in Umbraco that lets the client admin choose a member and show a list of all emails and other communication sent to them and a button for each email that requests and displays the status information stored for it in our external system. To do that, we need to somehow tie together the Umbraco MemberId and the TransactionId of each individual email.

    This could be accomplished by returning the TransactionId from the EmailServiceProvider after sending the email, so we can store it ourselves. We could also make it work the other way, by having a field for the MemberId on the SendTransactionalEmailRequest and having this be stored in the nsTrackingTransactionalEmail table along with the externalId. Either way is fine for us. As long we can do this:

    SELECT TransactionId FROM someTable WHERE MemberId = @parameter
    

    ...our objective will be met.

  • Markus Johansson 1771 posts 5182 karma points c-trib
    3 days ago
    Markus Johansson
    0

    Hi!

    Thanks for the feedback! The documentation would totally benefit from this link, I'll add it.

    Okey, as far as I understand it we should be able to solve this without any changes to the core.

    So first of all, you need to enable the "Keep log of sent emails"-setting on the Transactional Email that you want to send and probably use the "Never"-setting for expiry (otherwise history will automatically be cleaned up).

    If you're using Umbraco Members we will automatically store the receiving members key as part the providerRecipientId in the nsTrackingTransactionalEmail.

    It might look something like this:

    umb_r_c5d9fd9628dd45d2980f47387fe534a8
    

    This is a special identifier that we create/use in the package (called EmailReceiverIdentifier) it's basically:

    • umb = Prefix for the Umbraco Member Recipient List Provider
    • r = Indicates that the identifier represents a recipient (there is other types of identifiers as well)
    • [guid] = Any string identifier. In the case of Umbraco Members, it's the unique key for the member, in other cases it could be a int or something else.

    You can get the key for a member via the "Key"-property on a IMember-instance:

    var member = _memberService.GetByEmail("[email protected]");
    var guidKey = member.Key;
    

    or look in the database:

    SELECT m.[nodeId]
          ,m.[Email]
          ,m.[LoginName]
          ,n.uniqueId
      FROM [cmsMember] AS m
      INNER JOIN umbracoNode AS n ON n.id = m.nodeId
    

    When you have the key you can then create the "providerRecipientId"-string like this:

    var identifier = new EmailReceiverIdentifier(NewsletterStudioConstants.RecipientListProvider.UmbracoRecipientListProviderPrefix, member.Key);
    identifier.ToString(); // Outputs eg: umb_r_c5d9fd9628dd45d2980f47387fe534a8
    

    Then use this to fetch a list of emails with your "TransactionId" as the value of the "ExternalId":

    SELECT [externalId] FROM [nsTrackingTransactionalEmail] WHERE [providerRecipientId] = 'umb_r_c5d9fd9628dd45d2980f47387fe534a8'
    

    Maybe you could try this as a solution?

    If you find that this approach is not sufficient I could consider adding more return-information from the call to SendTransactionalEmail-call but this might take some time.

    Let me know what you think.

    Cheers!

Please Sign in or register to post replies

Write your reply to:

Draft