diff --git a/.gitignore b/.gitignore index add4ce7..7e27fa6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules .idea -secrets.json \ No newline at end of file +secrets.json +templates-output.json diff --git a/Gruntfile.js b/Gruntfile.js index 89c8ebb..45a90d0 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -6,7 +6,7 @@ module.exports = function(grunt) { grunt.initConfig({ - secrets: grunt.file.readJSON('secrets.json'), + secrets: grunt.file.exists('secrets.json') ? grunt.file.readJSON('secrets.json') : {}, /* Postmark ------------------------------------------------- */ @@ -15,23 +15,42 @@ module.exports = function(grunt) { serverToken: '<%= secrets.serverToken %>' }, email: { - from: 'you@youremail.com', - to: 'you@youremail.com', + from: '<%= secrets.testSender %>', + to: '<%= secrets.testRecipient %>', subject: 'Yo', src: ['test/email.html'] }, bulk: { - from: 'you@youremail.com', - to: 'you@youremail.com', + from: '<%= secrets.testSender %>', + to: '<%= secrets.testRecipient %>', subject: 'Hey', src: ['test/*.html'] } + }, + + // you can either specify the template configuration here, or in templates.json + 'postmark-templates': grunt.file.exists('templates.json') ? grunt.file.readJSON('templates.json') : { + test_email: { + name: 'testing-postmark-templates-js1-' + new Date().valueOf(), + subject: 'Testing grunt-postmark-templates', + htmlBody: 'test/email.html', + textBody: 'test/email.txt', + }, + test_email_again: { + name: 'testing-postmark-templates-js2-' + new Date().valueOf(), + subject: 'Testing grunt-postmark-templates', + htmlBody: 'test/email.html', + textBody: 'test/email.txt', + } } }); grunt.loadTasks('tasks'); - grunt.registerTask('default', ['postmark']); + // you can also get a JSON report of uploaded templates (default filename: templates-output.json) + grunt.registerTask('templates-logged', ['postmark-templates', 'postmark-templates-output']); + + grunt.registerTask('default', ['postmark', 'postmark-templates']); }; diff --git a/secrets_example.json b/secrets_example.json index a108905..1cc375a 100644 --- a/secrets_example.json +++ b/secrets_example.json @@ -1,3 +1,5 @@ { - "server_token": "POSTMARK_API_TEST" -} \ No newline at end of file + "serverToken": "POSTMARK_API_TEST", + "testSender": "you@youremail.com", + "testRecipient": "you@youremail.com" +} diff --git a/tasks/grunt-postmark-templates.js b/tasks/grunt-postmark-templates.js new file mode 100644 index 0000000..471e98f --- /dev/null +++ b/tasks/grunt-postmark-templates.js @@ -0,0 +1,138 @@ +/* + * grunt-postmark-templates + * push templates to a Postmark server for use with SendTemplatedEmail + * + * https://github.com/wildbit/grunt-postmark.git + */ + +module.exports = function(grunt) { + + 'use strict'; + + grunt.registerMultiTask('postmark-templates', 'Create or update Postmark templates', function() { + + var done = this.async(); + var options = this.options(); + var template = this.data; + + var defaultLocale = 'en'; + + var serverToken = options.serverToken || grunt.config('secrets.serverToken') || grunt.config('secret.postmark.server_token'); + + if (!serverToken) { + grunt.fail.warn('Missing required option "serverToken" \n'); + } + + template.name = template.name || this.target; + + if (!template.name) { + grunt.fail.warn('Missing required template property "name" \n'); + } + + if (!template.subject) { + grunt.fail.warn('Missing required template property "subject" \n'); + } + + if (!template.htmlBody && !template.htmlSrc) { + grunt.log.error('Missing template property "htmlBody" or "htmlSrc"\n'); + } + + if (!template.textBody && !template.textSrc) { + grunt.log.error('Missing template property "textBody" or "textSrc"\n'); + } + + var postmark = require('postmark'); + var client = new postmark.Client(serverToken); + + var locale = template.locale || defaultLocale; + + // read the referenced files, but hold on to the original filenames + var expanded = { + Name: template.name, + Subject: template.subject, + HtmlBody: template.htmlBody || grunt.file.read(template.htmlSrc), + TextBody: template.textBody || grunt.file.read(template.textSrc), + TemplateId: template.templateId + }; + + if (template.templateId) { + client.editTemplate(template.templateId, expanded, function(err, response) { + if (err && err.code === 1101) { + grunt.log.warn('Template ' + template.templateId + ' not found, so attempting create'); + delete template.templateId; + delete expanded.TemplateId; + client.createTemplate(expanded, function(err, response) { + if (err == null) { + grunt.log.writeln('Template ' + JSON.stringify(template.name) + ' created: ' + JSON.stringify(response.TemplateId)); + } else { + grunt.log.writeln('Error creating template ' + template.name + ': ' + JSON.stringify(err)); + } + }); + } else if (!err && response.TemplateId) { + grunt.log.writeln('Template ' + template.name + ' updated: ' + JSON.stringify(response.TemplateId)); + } else { + grunt.log.writeln('Error on createTemplate(' + template.name + '): ' + JSON.stringify(err) + JSON.stringify(response)); + } + + handleResponse(err, response, done, template); + + }); + } else { + client.createTemplate(expanded, function(err, response) { + if (!err && response.TemplateId) { + grunt.log.writeln('Template ' + expanded.Name + ' created: ' + JSON.stringify(response.TemplateId)); + } else { + grunt.log.writeln('Error on createTemplate(' + expanded.name + '): ' + JSON.stringify(err) + JSON.stringify(response)); + + } + handleResponse(err, response, done, template); + + }); + } + + }); + + function handleResponse(err, response, done, template) { + if (err){ + errorMessage(err); + done(); + } else { + + template.templateId = response.TemplateId; + // append this record to the result array, used by postmark-templates-output task + var upd = grunt.config.get('updatedTemplates') || {}; + var tname = template.name; + delete template.name; + upd[tname] = template; + grunt.config.set('updatedTemplates', upd); + + done(template); + } + } + + function errorMessage(err) { + if (err.message) { + grunt.log.warn('Error: ' + err.message); + } else { + grunt.log.warn('Error: ' + JSON.stringify(err)); + } + } + + // invoke this task after postmark-templates to get an output file containing the resulting template IDs + // this is in the same format as the postmark-templates config. + + grunt.registerTask('postmark-templates-output', 'writes out the resulting template IDs', function() { + + var options = this.options({ + filename: "templates-output.json" + }); + + var results = grunt.config('updatedTemplates'); + + grunt.file.write(options.filename, JSON.stringify(results, null, 2)); + + grunt.log.writeln("Updated template information written to " + options.filename); + + }); + +}; diff --git a/tasks/grunt-postmark.js b/tasks/grunt-postmark.js index ccf7f8b..e29e81a 100644 --- a/tasks/grunt-postmark.js +++ b/tasks/grunt-postmark.js @@ -3,10 +3,10 @@ * https://github.com/wildbit/grunt-postmark.git */ -'use strict'; - module.exports = function(grunt) { + 'use strict'; + grunt.registerMultiTask('postmark', 'Send emails through Postmark', function() { var done = this.async(); @@ -14,7 +14,7 @@ module.exports = function(grunt) { var _data = this.data; // Check for server token - if (!options.serverToken && !_data.serverToken) { + if (!options.serverToken && !_data.serverToken) { grunt.fail.warn('Missing Postmark server token \n'); } @@ -25,8 +25,8 @@ module.exports = function(grunt) { if (this.files.length > 0) { var message = { - 'From': _data.from || options.from, - 'To': _data.to || options.to, + 'From': _data.from || options.from, + 'To': _data.to || options.to, 'Subject': _data.subject || options.subject }; @@ -56,7 +56,7 @@ module.exports = function(grunt) { handleResponse(err, response, done); }); } - + } else { // Warn about no files being passed to task grunt.log.warn('No src file found \n'); @@ -66,7 +66,7 @@ module.exports = function(grunt) { function handleResponse(err, response, done) { - err ? errorMessage(err) : successMessage(response); + var _ = err ? errorMessage(err) : successMessage(response); done(); } diff --git a/test/email.txt b/test/email.txt new file mode 100644 index 0000000..e5494a8 --- /dev/null +++ b/test/email.txt @@ -0,0 +1 @@ +Hello from grunt-postmark-templates