Skip to content
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9dffdfa
configuration for tests
hybernaut Dec 14, 2016
abb4d27
more test config cleanup
hybernaut Dec 14, 2016
86c4d29
basic grunt task implemented
hybernaut Dec 14, 2016
e8ae024
read template files from filesystem
hybernaut Dec 15, 2016
4057b64
remove debug
hybernaut Dec 15, 2016
d988011
TODO for validating htmlBody/htmlFile etc.
hybernaut Dec 15, 2016
aac24c8
pretty good support for creating a server
hybernaut Dec 15, 2016
0873473
make create server task idempotent
hybernaut Dec 16, 2016
bcef316
refactor postmark-servers task using more idiomatic grunt usage
hybernaut Dec 16, 2016
71ccf91
duplicate test requires only one additional iteration, not two
hybernaut Dec 16, 2016
d3331ca
collect serverToken from secrets.json
hybernaut Dec 23, 2016
a48658c
read template config from templates.json
hybernaut Dec 23, 2016
a650a90
clean up example template files
hybernaut Dec 23, 2016
d87365d
simplify configuration
hybernaut Dec 23, 2016
bb51efc
use more canonical htmlBody and textBody
hybernaut Dec 23, 2016
3967d29
read templates.json in the postmark-templates task
hybernaut Dec 23, 2016
82fb13c
checkpoint: making progress toward saving templateID output
hybernaut Jan 3, 2017
a0a6f6d
output template info (including IDs) in templates.json format
hybernaut Jan 4, 2017
8fb62e5
update existing templates if templateID is present
hybernaut Jan 4, 2017
a518367
if update fails with bad Id, then revert to create
hybernaut Jan 4, 2017
6131196
move postmark-servers task to separate PR
hybernaut Jan 4, 2017
ac17e37
remove references to postmark-servers (for another PR)
hybernaut Jan 4, 2017
f3a7f7e
one last comment
hybernaut Jan 4, 2017
4a0b60c
node.js style callback
hybernaut Jan 13, 2017
aa3194b
simplify configuration following suggestions from @derekrushforth
hybernaut Jan 13, 2017
90ec805
log "created" vs "updated"
hybernaut Jan 13, 2017
315fd19
sample Gruntfile reads templates.json or defaults to inline config
hybernaut Jan 13, 2017
19fc6c4
Add the ability for `mailmason` to generate and upload/update templates.
randytarampi Jul 8, 2017
253a587
Further decouple `grunt-postmark` from `mailmason`.
randytarampi Dec 11, 2017
ee632f2
Add `postmark-templates-parse` and `postmark-templates-from-file`.
randytarampi Jan 8, 2018
b7e7a42
Add some documentation around `postmark-templates`.
randytarampi Jan 8, 2018
2cfb716
Bump version to `0.0.8`.
randytarampi Jan 8, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
.idea
secrets.json
config.json
secrets.json
51 changes: 39 additions & 12 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,62 @@
* https://github.com/wildbit/grunt-postmark.git
*/

module.exports = function(grunt) {
module.exports = function (grunt) {
var secret = grunt.file.readJSON('secrets.json');
var config = grunt.file.readJSON('config.json');

grunt.initConfig({
secrets: grunt.file.readJSON('secrets.json'),
secret: secret,
config: config,

/* Postmark
------------------------------------------------- */
------------------------------------------------- */
postmark: {
options: {
serverToken: '<%= secrets.serverToken %>'
serverToken: "<%= secret.postmark.server_token %>",
},
email: {
from: '[email protected]',
to: '[email protected]',
subject: 'Yo',
from: "<%= config.postmark.from %>",
to: "<%= config.postmark.to %>",
subject: "<%= config.postmark.subject %>",
src: ['test/email.html']
},
bulk: {
from: '[email protected]',
to: '[email protected]',
subject: 'Hey',
from: "<%= config.postmark.from %>",
to: "<%= config.postmark.to %>",
subject: "<%= config.postmark.subject %>",
src: ['test/*.html']
}
}
},

// you can either specify the template configuration here, or in templates.json
'postmark-templates-upload': config.templates && config.templates
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optionally storing the template data in a separate JSON file is a good idea, but this might be a roadblock for people who are configuring this for the first time.

example_config.json references templates.json so I ran into issues during setup because it wasn't clear whether the plugin was using the data from the template config or from the target config.

Instead of reading from templates.json we should remove this and document it as an optional step. This would reduce the friction during the initial setup process.

? config.templates.output_file || config.templates.file
: {
test_email: {
name: 'testing-postmark-templates-js1-' + new Date().valueOf(),
subject: 'Testing grunt-postmark-templates',
htmlBody: 'test/email.html',
Copy link
Contributor

@derekrushforth derekrushforth Nov 24, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the upload task is writing the string to the Postmark template instead of reading and posting the contents of the file.

Am I missing something?

screen shot 2017-11-24 at 10 24 21 am

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',
}
},

'postmark-templates-output': {
options: {
outputFile: '<%= config.templates.output_file || config.templates.file %>',
cleanOutput: '<%= config.templates.clean_output %>'
}
}
});

grunt.loadTasks('tasks');

grunt.registerTask('default', ['postmark']);
grunt.registerTask('default', ['postmark', 'postmark-templates']);

};
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ After the plugin is installed, it can be enabled in your Gruntfile:
grunt.loadNpmTasks('grunt-postmark');
```

You'll need to add a [`config.json`](https://github.com/wildbit/mailmason/wiki/Getting-Started#create-configjson-required) and a [`secrets.json`](https://github.com/wildbit/mailmason/wiki/Getting-Started#create-secretsjson-optional) per the `mailmason` configuration.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are several details in this wiki entry that aren't relevant to grunt-postmark so this might confuse people who aren't using MailMason.

We should replace this with setup instructions specific to grunt-postmark. I can create the wiki page and link it once we've merged this PR.


## Postmark task
_Run this task with the `grunt postmark` command._

Expand Down
17 changes: 17 additions & 0 deletions example_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// 1. Copy this file to "config.json" for your own version that won't be
// tracked in source control.
//
// 2. Delete these comments from the configuration so Grunt doesn't get confused
//
// 3. Visit the following page for details:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this step since grunt-postmark isn't dependent on MailMason.

// https://github.com/wildbit/mailmason/wiki/Getting-Started#configjson
{
"postmark": {
"from": "[email protected]",
"to": "[email protected]",
"subject": "Test Email"
},
"templates": {
"file": "templates.json"
}
}
12 changes: 12 additions & 0 deletions example_secrets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// 1. Copy this file to "secrets.json" for your own version that won't be
// tracked in source control.
//
// 2. Delete these comments from the configuration so Grunt doesn't get confused
//
// 3. Visit the following page for details:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove this step since grunt-postmark isn't dependent on MailMason.

// https://github.com/wildbit/mailmason/wiki/Getting-Started#secretsjson
{
"postmark": {
"server_token": "YOUR_POSTMARK_SERVER_TOKEN_HERE"
}
}
3 changes: 0 additions & 3 deletions secrets_example.json

This file was deleted.

118 changes: 118 additions & 0 deletions tasks/grunt-postmark-templates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* grunt-postmark-templates
* push templates to a Postmark server for use with SendTemplatedEmail
*
* https://github.com/wildbit/grunt-postmark.git
*/

module.exports = function (grunt) {
grunt.registerMultiTask('postmark-templates-upload', 'Create or update Postmark templates', function () {
var done = this.async();
var options = this.options();
var template = this.data;

var serverToken = options.serverToken || grunt.config('secret.postmark.server_token');

if (!serverToken) {
grunt.fail.warn('Missing Postmark server token \n');
}

if (!template.Name) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use camel case variables instead of title case. Same goes for subject, htmlBody, and textBody validation.

I was using the default variables specified from the gruntfile and kept running into validation errors because the variables didn't match.

grunt.fail.warn('Missing required template property "Name" \n');
}

if (!template.Subject) {
grunt.fail.warn('Missing required template property "Subject" \n');
}

if (!template.HtmlBody) {
grunt.log.error('Missing template property "HtmlBody" \n');
}

if (!template.TextBody) {
grunt.log.error('Missing template property "TextBody" \n');
}

var postmark = require('postmark');
var client = new postmark.Client(serverToken);

// read the referenced files, but hold on to the original filenames
var expanded = Object.assign({}, template);

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) {
grunt.log.writeln('Template ' + template.Name + ' created: ' + JSON.stringify(response.TemplateId));
handleResponse(err, response, done, template);
});
} else {
grunt.log.writeln('Template ' + template.Name + ' updated: ' + JSON.stringify(response.TemplateId));
handleResponse(err, response, done, template);
}
});
} else {
client.createTemplate(expanded, function (err, response) {
grunt.log.writeln('Template ' + template.Name + ' created: ' + JSON.stringify(response.TemplateId));
handleResponse(err, response, done, template);
});
}

});

function handleResponse(err, response, done, template) {
if (err){
errorMessage(err);
done();
} else {
template.TemplateId = response.TemplateId;
// compile the templates for use by the `postmark-templates-output` task
var updatedTemplates = grunt.config.get('updatedTemplates') || {};
updatedTemplates[template.Name] = template;
grunt.config.set('updatedTemplates', updatedTemplates);

done();
}
}

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', 'Write out the resulting template IDs', function () {
var options = this.options({
cleanOutput: false
});
var updatedTemplates = grunt.config('updatedTemplates');
var oldTemplates = grunt.file.read(options.outputFile);

Object.keys(updatedTemplates).forEach(function (updatedTemplateKey) {
updatedTemplates[updatedTemplateKey] = Object.assign(
oldTemplates[updatedTemplateKey] || {},
updatedTemplates[updatedTemplateKey]
);

if (options.cleanOutput) {
delete updatedTemplates[updatedTemplateKey].HtmlBody;
delete updatedTemplates[updatedTemplateKey].TextBody;
}
});

grunt.file.write(options.outputFile, JSON.stringify(updatedTemplates, null, 2));
grunt.log.writeln("Updated template information written to " + options.outputFile);

});

// you can also get a JSON report of uploaded templates
grunt.registerTask('postmark-templates', ['postmark-templates-upload', 'postmark-templates-output']);
};
20 changes: 13 additions & 7 deletions tasks/grunt-postmark.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@
* 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();
var options = this.options();
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');
}

Expand All @@ -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
};

Expand Down Expand Up @@ -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');
Expand All @@ -66,7 +66,13 @@ module.exports = function(grunt) {


function handleResponse(err, response, done) {
err ? errorMessage(err) : successMessage(response);
if (err) {
errorMessage(err);

} else {
successMessage(response);
}

done();
}

Expand Down
1 change: 1 addition & 0 deletions test/email.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello from grunt-postmark-templates