Home | About | Blog | Interesting Reads | Tutorials | Skills | Personal Projects | Books | Fun | Connect with me
Published On: Feb 18 2024
Written By: Krishnan Sethuraman
Category: Programming
I am excited to announce that we now have one customer. Though this customer is on a free plan, nevertheless they have started giving some valuable feedback and feature requests.
The first feature request that I received from them was to create a ticket every time an email is sent to their support email address.
I have done similar features before so from an architectural standpoint I was exactly sure on how I should build this feature.
Please note that this is not an how to article so there will not be detailed code samples.
At a very high level I have to come up with a forward email address to which the inbound emails get forwarded.
The inbound email received by this forward email address should be parsed and converted as a json payload and posted to a webhook.
This webhook will then parse the json and create a ticket.
Inbound emails can be either a new ticket or a comment to an existing ticket.
This can be identified from the subject of the inbound email. The format of the subject that we are setting for a comment sent via email is “email subject [Ticket#ticketnumber].
In certain cases the inbound emails will also have attachments. These attachments should be considered as attachments to a ticket or comment.
So the webhook should also be able to handle the attachments to the inbound email.
To start with I had to look out for a service provider who would handle the inbound emails and parse and post it to the provided webhook.
After some research on Google I figured out that Sendgrid under the paid plan had this feature. So all I had to do was to provide a domain name and point the MX of this domain name to Sendgrid.
So I provisioned email.daysupport.co.uk in Sendgrid and updated the MX records of email.daysupport.co.uk so that it points to Sendgrid.
Now if I add something@email.daysupport.co.uk as a forward email to support@daysupport.co.uk then all emails sent to support@daysupport.co.uk will be forwarded to something@email.daysupport.co.uk.
I had to provide a webhook to sendgrid so that it can parse the inbound emails and post them to the webhook in json format.
In Daysupport you can create multiple support channels.
Each support channel has an email, which means that when a user sends email to the email address of a particular support channel then all the tickets are created under that particular support channel.
I modified the create support channel API to accommodate the forward email address.
The subdomain i.e email.daysupport.co.uk was static with all support channels. Only the email address should be unique.
So I simply added a few lines that would generate a random but unique string of alphanumeric characters and concatenate the same with the subdomain to create a unique forward email address.
do {
$bytes = random_bytes(5);
$random_string = bin2hex($bytes);
$forward_email = $random_string.'@email.example.com';
$forward_email_exists = Projects::where('forward_email', $forward_email)->where('status', 'active')->count();
}while($forward_email_exists > 0);
With the logic that I have implemented above it is close to impossible for a similar string to be generated but to be on the safer side I have kept a loop that tries multiple times in case of a duplicate forward email address.
With the forward email ready I created the MX records with my DNS service provider so that it points to the Sendgrid servers.
I am building DaySupport as microservice architecture so I will be building the email parsing and ticket creation module as a standalone application.
Firstly I wanted to use a different framework or programming language but decided to stick with Laravel as I wanted to finish this ASAP.
This webhook module will share the database with the main backend of DaySupport. Just to put things in perspective I have provided a rough architectural diagram of Daysupport.
I will be using a database based queue here heavily.
First I built the webhook to process the json payload posted from Sendgrid and depending on the parameters create a ticket or either a comment.
If the inbound emails have attachments then these attachments are also uploaded by the webhook to an S3 compatible bucket and then indexed along with the created ticket or comment.
I have added the workflow with the architectural diagram below.
I added Jenkinsfile in the source code root directory and configured the project in Jenkins and deployed it to the server.
After creating some virtual hosts and setting up forwards I started testing if the features are working fine. There were some bugs and after I fixed them the emails were getting created as tickets and comments both with and without attachments.
As a next step I need to write content on the Daysupport website for this feature.