Michael Liendo's post Serverless Contact Form Using AWS Amplify reminded me of something I learnt about adding additional "not natively supported" services into Amplify.
When I say "not natively supported", I mean you can't create the resources with the cli. Rather than, Amplify doesn't support them at all. Of course your application will, you've access to the AWS SDK after all...
Sending a simple templated email...
Like Michael's example, I wanted to simply create an email to invite people to an organisation in the slate. The difference was I wanted to use an SES email template, so that I could have different environmental versions.
SES templates?
Rather than have the actual email template like so
await ses
.sendEmail({
Destination: {
ToAddresses: [process.env.SES_EMAIL],
},
Source: process.env.SES_EMAIL,
Message: {
Subject: { Data: 'Candidate Submission' },
Body: {
Text: { Data: `My name is ${candidateName}. You can reach me at ${candidateEmail}` },
},
},
})
.promise()
You can do something like this,
var emailTemplate = {
Destination: {
ToAddresses: []
},
Source: `The Slate <${inviteEmail}>`,
Template: 'SLATE_INVITE',
TemplateData: `{ \"invited_by\":\"${userDetails.name}\", \"invite_url\": \"${url}\" }`, // THIS HAS TO BE A JSON ESCAPED STRING!?
ReplyToAddresses: [
`The Slate <${inviteEmail}>`
],
};
await ses.sendTemplatedEmail(emailTemplate).promise();
SLATE_INVITE
is a reference to an HTML and Text email template held in SES, and it will accept the references and data in TemplateData
to be rendered in the template. To me it's a nice / clearer way of making changes to the template.
Kicking it up a notch
For some reason, I've no idea why, I decided to put the HTML and text templates into /amplify/backend/email
.
Then in my infinite wisdom I wondered, could I make a Cloudformation template for this?
My rational was that I could deploy environmental/versioned templates alongside everything else, and if I had to spin the slate up on a different AWS account, it wouldn't be a problem. The short answer is yes, yes you can.
As you can imagine, it didn't take long to go "If I have a cloudformation template, could add it to the existing Amplify cloudformation set-up?". Again, turns out you can do this too.
Extending your Amplify Cloudformations
You may have never have noticed, but there is a file at /amplify/backend/backend-config.json
that describes your amplify resources, e.g.
"storage": {
"slate": {
"service": "DynamoDB",
"providerPlugin": "awscloudformation"
}
},
The format of the json describes two things;
- "Storage" is both the "Category" you see in the cli and a folder (
/amplify/backend/storage
) - "slate" is "Resource name" you see in the cli and a folder (
/amplify/backend/storage/slate
) holding the cloudformation template
If you were to add something like
"email": {
"invite": {
"service": "SES",
"providerPlugin": "awscloudformation"
}
},
In theory it will be picked up.
In theory you say?
Yes - because you need to have /amplify/#current-cloud-backend/amplify-meta.json
refreshed to see your new service in the cli.
Once that happens, when you will see your new custom service and it will execute as part of the cloudformation stack. If it isn't there, it won't.
Top comments (2)
This is an awesome post! Thanks for taking the time to showcase folks how to extend Amplify. Our team is making some big improvements when it comes to extensibility this year. Stay tuned π
No problem at all - it was an interesting curiosity that snowballed, then I promptly forgot about it. After I read your post I remembered that I had done it!
I figured documenting would be worthwhile as I hadn't come across anyone mentioning it was even possible.