July 5, 2020
TAGS: COMMENTS | EMAIL | MAILGUN

Get Notified by Email When Someone Comments on Your Website

As I was building out functionality of Railscoder and other projects I was working on, I realized that without checking each article every day, I would have no idea if someone commented, but more importantly, had a question about something that I could answer. So I needed a to add functionality to my app that would automatically send me an email if anyone submitted a comment.

A couple of things I needed/wanted... one, to be notified that someone had commented. Two, I wanted a direct link to the article/post/item they were commenting on so I could get to it quickly.

Rails 6

This article pertains to projects using Action Mailer on Rails 6. Although, it should work for Rails 5.2 and up without issue.

Mail Service

Please note, I am using Mailgun as the service to actually send my emails for my app. You can read about setting up Mailgun on your site in this article. I found Mailgun to be super easy and they provide excellent documentation on how to set your mailing domain up.

Generate Comment Mailer

You have generate the comment mailer first:

$ rails generate mailer CommentMailer

This will create all the necessary files you will need.

Edit The Mailer

This will appear at app/mailers/comment_mailer.rb. You need add a method. In my case, I called comment_email and defined the attributes of the method as such.

class CommentMailer < ApplicationMailer

  def comment_email
    @post = params[:post]
    @user = params[:user]
    @url = "https://your_site.com/articles/"+@post.slug
    mail(to: "[email protected]", subject: 'Comment added to Your_site.com')
  end

end

A couple of things I am doing here. First getting params from the post and user, which you will see where they are coming from when we modify the comment controller. But these variables allow you to pass data into the email that will be sent to you. Also take note of the url where I use the @post.slug. I am using the friendly_id gem for pretty URLs. If you were not using something similar, you would just use @post.id there.

You may have also recognized that I don't have a from email defined in here. That's because in my application_mailer.rb file, I have a the default from set there.

class ApplicationMailer < ActionMailer::Base
  default from: '[email protected]_site.com'
  layout 'mailer'
end

You could override the from and place it in your comment_mailer.rb file just like it is above.

Create The Mailer View

Under your views folder, you will see a folder called comment_mailer which was generated when you originally ran the Rails mailer generator. That's where you can create the view. You need to name it the same as your method defined in the model above. In my case it will be comment_email.html.erb.

Now, we will create what gets sent to us in the email body.

<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Comment added to Your_site.com</h1>
    <p>
      A new comment was added to Your_site.com by <%= @user.username %>.
    </p>
    <p>
      To see the comment, just follow this link: <%= link_to @post.title, @url %>.
    </p>

  </body>
</html>

Simple enough. Now we have to complete the circle and create the action when someone submits a comment.

Add The Comment Mailer To The Comments Controller

This is the final step. Your comments controller will likely be similar to this. But during the creation of a comment, you will need to put your Comment Mailer in before the final action of the create method. Changes to comments controller in bold.

class CommentsController < ApplicationController
    before_action :is_admin?, only: [:destroy]
    before_action :is_user?, only: [:create]

    def create
        @post = Post.friendly.find(params[:post_id])
        @comment = @post.comments.create(params[:comment].permit(:content).merge(user_id: current_user.id))
        # Mail me a notice of comment
        CommentMailer.with(post: @post, user: current_user).comment_email.deliver_later
        # Then redirect
        redirect_to post_path(@post)
    end

    def destroy
        @post = Post.friendly.find(params[:post_id])
        @comment = @post.comments.find(params[:id])
        @comment.destroy
        redirect_to post_path(@post)
    end


end

I am sending the data from the current post and current user over to the Comment Mailer model which will then generate the email.

After you set everything up, be sure to restart your server if you have been running it in development mode. After that, you should be good to go in production after you push the new code.


Comments

Sign Up or Login to comment.