I want to develop a mail notification service to send order approval to customer. The order data is in the denormalized view (query side) and it should be filled to the mail template. Then, we send the email in html string format via mail notification service. But, the order status should be changed to "order approval email sent".
I also try to implement the CQRS, ES, and DDD concept in microservices architecture.
Is this procedure correct and still align with the concept?
Develop HTTP POST API in order command to send approval mail so the order status could be changed in command-side.
The command side generate the event "order approval mail processed"
The event processor process the event. It should get the order data from query-side / denormalized view.
The event processor generates the approval mail from the data and fill the data to the template.
The event processor call HTTP POST to the mail notification service with mail body (html format) in the payload.
The event processor call HTTP PUT to the order service (command-side) to change the order status to "order approval mail sent".
But, if this procedure is applied, the user can't get the response "mail sent" in real-time. How to trigger the client / front-end side that the mail is successfully sent? So, the client side don't have a need to refresh or retry many calls to the API.
Thanks.
I've written a post on this subject a while ago, you can find it here: How to Send Emails the Right Way in a CQRS System
The short version is that I would use a process manager. A process manager listens to events and can issue commands as a result of these events. Just make sure you have a mechanism to not re-send emails if you ever re-run your events.
Regarding the UI. I have another post dealing with this question. You can find it here: 4 Ways to Handle Eventual Consistency on the UI
Here is a short answer. How often do you think once the code is run to send the email, that the email fails to send? Assuming you have a reasonably robust system, I would hope the vast majority of the time it would work. So fake it. And only if there is a problem find some way to notify the user and or admin users. If you want to get fancy you can use things like Signalr or some pub-sub framework for sending messages to the UI.
Anyway - hope that helps.
Related
I am receiving chart data in JSON format to my email address and my goal is to convert it to chart/chart img and resend it to my email address.
I have been looking for several methods:
Google App script used for gmail. I failed to find trigger on newly received message.
Email client, that supports adding actions based on scripts to new incoming message trigger. Only one I know about is MS Outlook with VBA scripts, but creating chart image with lack of libraries available in VBA is not very elegant solution.
Open source email client with possibility to alter the code and so directly process data and resend message. The more robust email client, the harder is to change the code to do relatively simple job, I believe.
I really donĀ“t know what kind of solution this simple problem needs.
Thank you in advance.
Sounds like you are interested in some kind of gateway on the server side, not client-side. Take a closer look at your server-side implementation. For example, you may start from the Mail flow rules (transport rules) in Exchange Online page.
I am trying to figure out how can I make it possible to send an email from my
application to Sendgrid and have it come back.
I want to use coldfusion to send an email using X-SMTP API. I found a documentation
online here but still wondering if there's any documentation available other
than the web API one?
http://thehatrack.net/blog/integrating-sendgrid-with-your-coldfusion-application/
SendGrid's Event Webhook is the only way to get email reads on an individual basis. This will POST an event to your server every time an email is read (among several other events).
The only "pull" based solution to get individual email events from SendGrid is the bounces endpoint, which will tell you when an email bounces (and is certainly not read), but nothing else.
If you want to retrieve individual read events from SendGrid, you'll need to connect the Event Webhook to an external service like Keen.io, and then leveraging their API to get individual events.
With regards an OMS, what is the best method to send a confirmation email? The 2 options I have so far are;
A script on the order page sends an email once the record is written to the database.
A scheduled task on the server, send the email, polling the database every-so-often to find new entries.
Which method do systems currently use?
For e-commerce websites, it might be better to think about the best user experience.
Given that, you would want to send the email as soon as the order is received so the user knows that they have purchased the item. The sooner it gets into their inbox, the sooner they will be happy that they have made their purchase.
I agree with Digbyswift that sending the confirmation email once the record is written to the database is the least scalable. But I would argue that if your system has gotten to the point that you are taking so many orders that your system cannot keep up, you have a wonderful problem on your hands that you now probably have resources to handle.
At PostageApp, we handle the emails of a few e-commerce websites, so perhaps you would benefit from an arrangement with an email service provider to off-load this task so that all of your resources can be spent on keeping your site up and your databases running.
Here are some great alternatives if PostageApp is not your style:
Sendgrid
Postmark
Mailjet
This is a question of scalability. Sending a confirmation email once the record is written to the database is the least scalable. The more orders that are taken , the more emails are sent potentially tying up resources.
A scheduled task is certainly better as emails can be queued up and can be sent in a separate process.
A further option which you could consider is using neither and delegating the responsibility of sending emails to a 3rd party dedicated emailing service, i.e. via an API. This is much better since your hosting does not have to consider the load and you can utilise any reporting offered by the 3rd party. Plus many services offer a free quota up to a certain threshold. This will allow you OMS and business to scale appropriately.
If you apply a message based architecture; you could just publish an order created message and have any number of subscribers respond to that event. You could create a listener that sends the email in house (bespoke option) or another listener that called the API of a 3rd party emailer to send the email on your behalf (as per #Digbyswift)
What I've always liked about this approach is
You can have any number of listeners live at any one time.
You can create a new listener and change how you send the email without needing to change/redeploy the OMS application itself.
You can take the listener(s) off line and stop / delay the sending of the email without losing any notifications or affecting the OMS itself.
At this moment we are building a new architecture that is based on the principles of CQRS and domain-driven-design. We are now having some discussions about how we should deal with external communication. To make the question more concrete I use the example of sending a SMS notification when a customer creates a order.
The client creates a NewOrderCommand that is handled by the associated command handler. The handler creates a new Order object in the domain model, that generates a NewcustomerCreatedEvent. The object is saved in the event store and the event is published to all the listeners.
So far so good but now the question. Where should we sent out the SMS notification?
Our first instinct told us we should send it out by using a event listener that listens for the NewCustomerCreatedEvent and sends out the message. The problem with this approach is that the sending of the SMS is also part of our business logic. We are selling hosted services so our clients should be able to see all the SMS messages that are sent on their behalf. Because the sending of the message takes place outside of the domain we are not able to do that.
So we created an SMS domain and now when the event listener receives the NewCustomerCreatedEvent the event handler creates a new command SendSmsMessageCommand that will create a new SMSMessage object in our domain, sends out the SMS notification and creates a SmsSent event that we use to create the view.
At first we were sending the SMS message in the domain model, but we realized that this could give some problems. Let's say that after sending the SMS something happens (an exception is thrown) and the transaction is rolled back. Our domain supports this completely so data wise we are ok, but the SMS message is already sent, so when the command is resent the SMS notification will be sent again.
We were thinking about sending out the SMS on the SmSSent event but that would be a little bit strange, because the event says the message is already sent but is isn't.
The example above brings us to the question how to deal with external communication in the CQRS and domain-driven-design concept? We are not only talking about sending an SMS notification but also about sending an invoice to and external billing system and all other sort of communication to the outside world. Should we do this in the domain because it business logic or should we always do that based on events in our event handlers? And if we do so, is it acceptable to use events that say that the message is sent when it's not actually done yet?
Hope you guys have already dealt with this situation and can give us some advice on this subject.
I would think a domain object for the SMS message is not necessary. You just need to report the SMS's sent to the customer, correct? The SMS messages are not used in any domain logic, correct?
So I would have the handler send an SMS and then publish another event that says an SMS was sent and have an event handler listen for the SMS sent message and materialize that info in a read model so that the customer can view them.
You could use a Saga, or a Process Manager as Microsoft calls it. This basically listens to events, which change the saga's state, and issues commands based on the state logic implemented in the saga.
In your case it would be a two state saga, that waits for both CustomerCreatedEvent and OrderCreatedEvent, and, either issue a command to send an sms, if you have a specialised bounded context for communication, or call an infrastructure service, through an interface, to send the sms.
Here you can find Microsoft's article on the saga/process manager pattern:
https://msdn.microsoft.com/en-us/library/jj591569.aspx
And two articles containing implementations:
http://danielwhittaker.me/2015/03/31/how-to-send-emails-the-right-way-in-a-cqrs-system/
http://blog.jonathanoliver.com/cqrs-sagas-with-event-sourcing-part-ii-of-ii/
I have an application that sends emails when a user creates/modifies a record. I would like my users to be able to reply to the email that was sent to them and have the web application receive the email, parse it and update the record automatically. I have seen this done in web apps like Basecamp. The email usually says "Reply above this line", and if you simply reply to the email, you don't have to log in to the web application in order to update your ticket/conversation.
How can I go about implementing this sort of functionaly? (I'm not looking for a particular language implementation, but rather a language agnostic solution).
There are 2 ways you can do this:
You could use a Procmail filter to pipe the incoming email to your script. This would need some 'nix knowhow to setup - but it's certainly possible to do what you described via this method.
Use a service like MailGun - they do all the hard work of setting up and configuring the mail server stuff and expose it to you via a nice programmable web API. I've been evaluating it this week to solve a similar problem like the one you are having and I can tell you: it is really cool and I highly recommend you check it out yourself.
You'll need to implement a service/daemon that polls an email inbox for new messages. To relate an incoming email to the corresponding data, you can include an id in the outgoing email's subject.
I agree you should created a system to receive the incoming email but I don't necessarily agree that polling for it is the correct solution. Take a look at a blog post I wrote on the subject here. It relates to Rails but the concepts should work in any language. That's why we wrote the CloudMailin system to provide a better way of receiving the email.
Also you can use a unique from address for each email that would prevent the user from altering the subject line being a problem. The disposable part of an email address is useful for that. reply+user123#example.com for example.