How to use ActionMailbox in Rails 6

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what's up guys this episode we're going to be talking about Rails sixes new action mailbox functionality that allows you to accept inbound emails into your rails app and then process them so action mailbox is really cool and an example of what you can use it for is github reply it by email for issues and pull requests so whenever you get notifications from github it says reply to this email directly and it allows you to add a comment from your email without ever logging into github so how does that work well the magic happens when you hit reply it goes to this email address that you see right here where did that come from you might ask well the reply to header is actually what defines that and you'll see this email address as rail slash rails so it makes a friendly name and then the email address right here is where the magic really kind of happened so this is reply plus an ID which represents that pull request at reply github calm so that reply github calm is a subdomain used entirely for processing emails for replies and that's basically what you'll have to set up in send grid or postmark or whatever tool that you're going to use you'll use a subdomain for processing these and we'll talk about that a little bit in the future then in action mailbox you will be able to go and match those email addresses find whoever sent it look up their user account then pull out the ID from the email that they sent it to and then you can look up the pull request or issue or whatever your model might be to go and add that content to your database so it's pretty straightforward but let's dive into building an example so let's create a new rail 6 app we're gonna call it mailbox err very creatively and this is going to be setting up everything for us but we are going to install action mailbox next which will also install active storage so the thing that happens behind the scenes for us that we don't really have to pay attention to is that active storage is the storage for these emails that come in so whenever an email comes into rails it will save it and keep track of it and whether or not it's been processed then it will load an active job to go process it and then delete that email when it's done but it will keep track of the ID and the checksum so that this is a way for it to deduplicate so if you ever got the same email twice it would not process it two times and create duplicates it would only process it once so that's pretty handy so let's go in and run rails action mailbox colon install to go ahead and install it and this is going to generate our two migrations for active storage action mailbox and it's going to go and create an application mailbox so while we're here let's rails generate a scaffold for user which will have a name in an email let's generate a scaffold for discussion as well which will have a title and this will be kind of like an issue or a pull request or something with comments then then we'll generate a scaffold for comment which is a user references and discussion references and some body text and that will be what will take the email content and put it into the content the comment body so with that we can run rails DB migrate to create all of that and we can open up our application now if we pull up our schema you can see the model for action mailbox this is basically the status whether or not it's pending processing we're finished and then the message ID and the check sum for the deduplication stuff and then active storage of course and our other user models that we just created now the other file that it created for us is under App mailboxes application mailbox and this file is where you define your routes for the emails they're gonna match against the email address and determine which processing method you want which is called a mailbox so here you can set up a routing for all the messages to go to say like a replies mailbox but you can also use a regex here and say routing and define how you want that to work so maybe you want the reply plus dot plus like a bunch of characters at least one and then reply dot github.com if you wrote this reg X it would match the one that we saw there on the github email and one of the tools that I find really useful for this is Rube Euler you'll see here that I have it set up with that regular expression that I just wrote and the example from github and then I have another one that has a Save maybe more like Basecamp save forwarding and this doesn't match so that's one of the things that you can do is just change the format of the email address people reply to and then put it in different buckets for processing so it's really handy to have an action mailbox so let's comment these out because we're not going to use them but let's create a mailbox so we'll run rails generate mailbox replies and we'll use this one to add replies to a discussion so this is where we're going to be defining that and inside of here we have a process method and basically we have access to the mail object the actual email that was given to us and the inbound email which is the active storage record so that the action mailbox record rather this is the action mailbox inbound email record out of the database so if you ever need access to that you can use inbound email or you can use this which is a mail object to actually grab say the subject line out of the email itself so we'll leave these as comments here for your reference because I found myself forgiving them it's probably gonna be handy to just have those those notes in here now once you're in here you can go since that email so what do you need to do first thing is you need to load up the user record from the database so one thing you can do to make this a little bit more organized is to find the user and we'll have at user and this will be a user not find by email and we want to grab the email from address so whoever sent the email we want to look that user up because we are trying to create a record for them they replied by email and if we don't find the user we don't want to really process this and so we can immediately return from this if user dot nil so we can make sure that there is a user you could also do unless user is present however you want to do that works for you and another option you have here for handling things is you have before processing callbacks you can set up so you can say ensure user and define a method here like ensure user where you can say if user is nil then we want to bounce with an email so the way that you would do this is you would create like a user mailer and say there was a missing user inbound email you can pass in that database record for the inbound email and then send that email a response so this is something you might find useful where you can go ahead and send an email back to whoever sent the email in and say hey we're sorry but it doesn't look like you have an account make sure that you're sending us you know an email from an account that does exist whatever email you use to sign up for our service use that one so this is a cool way of handling things and this bounce with will handle the stop processing and all of that and send an email as a response so that's pretty cool and a good option but we're gonna leave it as simple like this because we're not going to bother setting up the user mailer so we got plenty of other things to do to process this the next thing is we need to actually find our discussion from that email so we're gonna look up the discussion at discussion discussion not find and we need to grab that ID somehow and let's just say it's a discussion ID variable or method and I will define discussion ID right here and we need to pull this out of the email address that was matched so if we go to our application mailbox remember that we have this right here so we have our routing lines so we need to set one of those up so let's get this one and we'll do the same format but maybe maybe let's make it a - and we'll organize this a little bit differently so we'll say reply - and this capture group at example.com and those emails will be the only ones that we process so currently one of the design flaws maybe that I noticed was that when you're writing this there's no way to figure out this capture group which is often going to be used to look up the database record in your process here so what we're going to do is actually take this regex line here and we're going to say replies mailbox matcher and we're gonna define that here so we're gonna say matcher equals that regex that way we can reuse the same reg X in both places and we're gonna use it to find that discussion ID so mail dot recipients will give us a list of an array of email addresses that that user set to in our case it probably is just one email address but we have to loop through it because it is an array and we want to just look and see if matcher dot match on that's email recipient address and if it does we can say we have the recipient and we then need to find the ID out of that so we found the right one but we need to get that capture group out of it and we can do that by saying recipient matcher comma 1 and now run the regex against that and give us the first capture group back so this should return to us the database ID from that URL so for example we would send an email to reply one at replied example.com and that should pull out this number one from there so before we go down the tracks too far I want to mention that the mail gem is this mail object that you have to work with the action mailbox stuff is built on top of this and if you scroll down to reading an email in the docs here you'll see what a mail object has access to so you'll see all these different things like from addresses sender and to and so on and this is the content of the email and you can go and ask for different things and you can also do multi-part emails so if you have an HTML email usually it comes with a plain text version as well you might have images attached underneath and then referenced in the HTML and it gets pretty complicated so typically what happens is that applications like github and at Basecamp and so on we'll just take the plain text version of that email and embed that so they don't worry about the HTML version because that can have CSS and all this extra stuff and really they're trying to add comments that need to be just plain text and so they strip all the HTML stuff out if they can and just go with the the plain text version so that's what we're going to do here in our example so what we need to do now that we have the discussion is go to the comments array and we don't have the has many comments set up just yet so let's do that now and we'll create the user as user and the body of this will be a male dot d code and that's one of the methods that is mentioned here or decoded that is mentioned there you can also check and see if it's multi-part and grab like the plain text version this example shows that there's a PDF version in that example there's two different ways to go and do this so we're just gonna keep this very simple for now but we'll talk more about that in a future episode on how to pull out content from emails because it can be pretty complicated so with this comment created we should be good to go so we need to go and test this out so let's boot up our rails app let's go into a mailbox or run our rails server and in users let's go ahead and create an account for myself Krista Corral's calm let's go to discussions and create a new discussion like action mailbox hello world create that and on this page we're going to display any of the comments so let's go ahead and update our discussion show HTML yarby and we'll go in here and let's do it underneath this let's say H for comments and at discussion comments let's just render those out and we'll go to the comments comment dot HTML ER be file app use comments comment HTML European in here we'll just create a div let's have a strong that prints out the comment dot username strong commented and a br and we'll do a simple format for the comment dot body and close the div so these would be really really basic comments but we will have some on the page and know if our code worked so we're ready to test this out and the easiest way to do this is to use the new rails conductor for action mailbox these are developing URLs that are available in development of course and you can access these and actually run things against your rails app without having to go to the console or do anything like that so this is really cool and we'll simulate sending an email to your rails app and you can say rails you know reply one at reply decks imple calm let's just put in some sort of subject and we'll say hello world from this and we'll deliver that inbound email now it also allows us to route this again it says the status of it is pending and the full email source is included here for us so we can see the content type of it and so on and all of this is available and you can do more complex things like actually view the other inbound emails in your app so if you have one that comes in from another service like you've set up send grid and end grok and local tunnel or something you can go and test that out so if we pop into our discussions tab again and refresh we don't see any new comments and we can take a look at the rails logs in here you'll see where it begins processing the action mailbox routing job and that is the job that is going to process these emails and here you'll see that it updated to the pending State or the processing state it went ahead and found the user found the discussion and it created the comment for us so we know that is good and it just processed our email correctly so if we go back to our discussion show maybe we missed something here and it looks like we did we forgot to add the equals on our comment and we can refresh and we see that it's now available so we have now processed an email by writing this action mailbox and that has gone ahead routed it correctly and done everything that we need to make that work now one of the cool things that you can do is if you want you can use a tool like end Rock to expose your rails app to the public Internet and then you can go set up send grid to actually send emails to your development environment then you could go to like Gmail send emails to your actual email address and route them to your local rails app for testing that's gonna be really nice because you can test more complex things and forward real emails that are like HTML and images embedded and all of that make sure that your mail processing code like we're right now just using mail dot decoded very simply this may not be the best thing for your location but it works for us in these simple plain text examples so you can fiddle with this I would highly encourage you to throw like a by bug in here and just test it out and poke around the emails and the mail object because they're pretty complicated and we're going to talk more about processing HTML emails and storing them in rich text action text fields and uploading attachments and that sort of thing as well but we'll do that in a future episode so the last thing I want to mention is the instructions here for setting up your email provider so for example with postmark you would set your ingress to postmark you would want to do this in development if you want to test it out locally setup and rock or local tunnels so it's available and then the action mailbox ingress password is a secret password that postmark and your rails app would know so that if any attacker tried to send over emails and send out her or like post spam or something it would not be possible because I wouldn't know the secret password then you just simply drop in the example URL here to postmark for the inbound web hook and you're good to go and all of that is set up some of these you do need to tell it to include the raw email because that is what's processed by the mail gem it needs to know the raw email and that's what makes it kind of generic across all of these providers if you can process the raw email similarly for all of them you don't have to have a whole lot of different code to process each one of these providers so that is a basic introduction to action mailbox you can use it fairly easily to send out email notifications and then receive replies to those and put them in your app so it's pretty cool and something we're going to dive way more into depth with in future episodes so if you guys want to see more stuff let me know in the comments below if you have ideas on good use cases for this I'd love to see those in the comments until then I will talk to you guys later peace [Music]
Info
Channel: GoRails
Views: 9,594
Rating: undefined out of 5
Keywords: Ruby, Ruby on Rails, Rails, Javascript, HTML, CSS, Servers, Databases, Screencast, Tutorial, Rails 6 action mailbox, Action mailbox, actionmailbox rails 6, action mailbox rails 6
Id: cQtmwrm93XA
Channel Id: undefined
Length: 19min 51sec (1191 seconds)
Published: Tue May 14 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.