OSX / Using Google Apps as a SMTP server

Scenario: You’re working from a home ISP connection or traveling, but would like to have your Mac send emails for jobs that have completed or other misc. notices without having to reconfigure each time. Since many ISPs block outbound SMTP servers on standard ports, forcing you to use their servers, this can be a headache.

I decided to use Google’s App/SMTP server to get around this as it uses a non-standard SMTP port and requires authentication. There are tons of guides on how to do this online, but none of them seemed to work for my setup. So, without further ado, here’s how to setup your mac, leveraging Google servers as a relay via Postfix:

First edit /etc/postfix/main.cf:

$ sudo vi /etc/postfix/main.cf

Add this to the end of the file:

myhostname = _HOSTNAME_
relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_use_tls = yes
smtp_sasl_mechanism_filter = plain

Also, edit this line and adjust it to your preference, default is 1MB. I changed mine to 100MB since I send large logfiles:

message_size_limit = 100000000

Edit/create /etc/postfix/sasl_passwd. You’ll need to login to your Google account and create an app password. Spaces from this password are not required in this file:

$ sudo vi/etc/postfix/sasl_passwd

The format of the file should look like this:

[smtp.gmail.com]:587 user@domain:app_password

Modify the permissions of the password file to protect the contents:

$ sudo chmod 600 /etc/postfix/sasl_passwd

Next, hash the password. This will create a sasl_passwd.db file:

$ sudo postmap /etc/postfix/sasl_passwd

Restart the postfix services for the change to take effect:

$ sudo launchctl stop org.postfix.master
$ sudo launchctl start org.postfix.master

And finally, run a test:

$ date | mail -s "test 1 again” you@yourdomain.com

Check the queue for errors. Should report “Mail queue is empty” if everything went well.

$ date && postqueue -p

If you received the message, then you’re all set. Your OS can now send mail from anywhere in the world without having to worry about reconfiguring for local SMTP servers due to blocked ports.

Happy mailing!

Update to yesterdays post

Yesterday, I wrote about making your own reminder service using Google Sheets. Today I made some improvements to that code to look for a date as well, so it’s more viable.

A couple of notes:

  • The timzone function in google scripts seems to be off by an hour, not sure why. So you may have to adjust that.
  • If there’s no date in the spreadsheet, that item is repeated daily.
  • Make sure you’re the date field is set to plain text, and that the date you enter will match the format of the date inside the script: 04-18-2014
  • If you run into trouble, the Logger function is invaluable.  “View > Execution Transcript” will show you everything about the last run.

I think that’s about it. So without much ado, here’s the updated script, basic as it may be:

function sendEmails() {
 var sheet = SpreadsheetApp.getActiveSheet();
 var startRow = 2; // Start on row 2, row 1 is the legend
 var numRows = 100; // How many rows to check? Set high.
 var dataRange = sheet.getRange(startRow, 1, numRows, 5)
 var data = dataRange.getValues();
 var todaysDate = Utilities.formatDate(new Date(), "GMT-4", "MM-dd-yyyy");
 // This works but the TZ is off by an hour, looking into this
 var currentTime = Utilities.formatDate(new Date(), "GMT-4", "HH:mm");
 for (i in data) {
 var row = data[i];
 var emailAddress = row[0];
 var subject = row[1];
 var date = row[2];
 var time = row[3];
 var message = row[4];
 if ((date == '') && (time == currentTime)) {
 MailApp.sendEmail(emailAddress, subject, message);
 }
 if ((date == todaysDate) && (time == currentTime)) {
 MailApp.sendEmail(emailAddress, subject, message);
 }
}
}

Creating your own reminder service

Yesterday, a colleague of mine posted about a service called IFTTT (If this then that) which can create relationships between different services like Facebook, Gmail and Twitter.  Through the use of triggers, you can do some cool stuff.  Be sure to check out Dan’s writeup, it’s probably much more interesting than what you’re about to read.

For me, IFTTT is a little overkill, I usually stick with Google Calendar to remind me about stuff I’m planning on ignoring, but it got me thinking about creating my own very basic version of a crontab in the cloud for some notifications. Like submitting expense reports etc.

Enter Google Sheets and time-driven triggers.  Oh, and before you ask what the point is, the answer is just a little fun.  And if you’re wondering why my idea of fun is working on spreadsheets… ummm… data. mmmmmmm.

So first, we create a new Google Sheets document with some basic details: email address to notify, subject, date, time and message body:

Screen Shot 2014-04-17 at 11.20.31 PM

Once you have a few entries in there (notice the date is blank, I haven’t worked on that just yet – future post) click on Tools > Script Editor

Screen Shot 2014-04-17 at 10.17.57 PM

Here’s the code to add:

function sendEmails() {
 var sheet = SpreadsheetApp.getActiveSheet();
 var startRow = 2; // Start on row 2, row 1 is the legend
 var numRows = 100; // How many rows to check? Set high.
 var dataRange = sheet.getRange(startRow, 1, numRows, 5)
 var data = dataRange.getValues();
 var todaysDate = Utilities.formatDate(new Date(), "GMT", "yyyy-MM-dd");
 // This works but the TZ is off by an hour, looking into this
 var currentTime = Utilities.formatDate(new Date(), "GMT-4", "HH:mm");
 for (i in data) {
 var row = data[i];
 var emailAddress = row[0];
 var subject = row[1];
 var date = row[2];
 var time = row[3];
 var message = row[4];
 if (time == currentTime)
 {
 // Function to send email, lets wrap it.
 MailApp.sendEmail(emailAddress, subject, message);
 }
 }
}

What does this do?  Right now nothing unless you run it manually using the play button in the toolbar.  For the automation magic, you need to add a trigger.  Click on ‘Resources’ in the toolbar, then ‘All your triggers’:

Screen Shot 2014-04-17 at 10.55.51 PM

Now click on the ‘Add a new trigger’ link and fill it out:

Screen Shot 2014-04-17 at 10.56.05 PM

You’ve now scheduled your app to run every 60 seconds, checking for upcoming events.  If the time in your spreadsheet matches the current time, emails get sent out.  I’ll probably make some changes and add date support as well.

So, is this better than a commercial service like IFTTT, Google Calendar or a plain old crontab entry set to send an email? Probably not.  Was it more fun to work on? You betcha!