Provides a uniform method for pushing notifications to users.
- Run as a gem inside your application (with an ActiveRecord backend) or stand alone via AWS Lambda (with DynamoDB).
- Store multiple configurations (each with their own templates) to support a multi-tenant model.
- Templating:
- Adapters for:
Data:
A Request
is injected with Config
and creates one or more Post
records for processing asyncronously.
Each Post
is associated with a Channel
and a Recipient
.
The Channel
will inject the Post
data into a Content
class which optionally uses a Template
to render the output. The result is then passed to an Adapter
to push out to a third-party system.
config = Config.create(
data: {
template_version: 'v1',
channels: {
# implement {{Channels::Mail}}
mail: {
# for use with {{Adapters::Mailing}}
adapter: { name: 'mailgun', domain: 'orgname.org', api_key: '...' },
from: 'Notification<noreply@orgname.org>', reply_to: 'Notification<noreply@orgname.org>'
},
# Other channels Push/Text via Slack, Twillo etc possible.
# push: { ... },
# text: { ... }
},
objects: { org_name: 'Org Name' }
}
)
html_template = Template.create(
config_id: config.id, version: 'v1',
notification: 'welcome', channel: 'mail', format: 'html',
data: <<~HTML
<title>Email Subject</title>
<body>
<p>Welcome {{name}}!</p>
<p>
<a href={{url}}>Go here to start</a>
</p>
<p>- {{org_name}}</p>
</body>
HTML
)
plain_template = Template.create(
config_id: config.id, version: 'v1',
notification: 'welcome', channel: 'mail', format: 'plain',
data: <<~STR
Subject: Welcome!
Welcome {{name}}
Go to {{url}} to get started.
- {{org_name}}
STR
)
result = MakeRequest.call(
api_key: config.api_key, notification: 'welcome',
instant: true, # do not queue the processing, return full response for debug purposes.
debug: false, # would run everything except the {Adapter#call} and return sample payload.
recipients: [
{ uid: 1, email: 'your@email.com', objects: { name: 'Bob' } }
],
objects: {
url: 'https://orgname.org/welcome'
}
)
If deployed to AWS, you can then invoke the function:
aws lambda invoke --function-name service-notifications-make_request-production --payload '{"instant":true,"api_key":"___AWS_KEY___","notification":"inline","recipients":[{"uid":1,"email":"__TEST_EMAIL__"}],"objects":{"plain":"Plain content","html":"\u003cstrong\u003eHTML\u003c/strong\u003e"}}' /dev/stdout
or via AWS Gateway API:
curl -d '{"instant":true,"api_key":"___AWS_KEY___","notification":"inline","recipients":[{"uid":1,"email":"__TEST_EMAIL__"}],"objects":{"plain":"Plain content","html":"\u003cstrong\u003eHTML\u003c/strong\u003e"}}' -H "Content-Type: application/json" -X POST https://__API_GATEWAY_ENDPOINT__.us-east-1.amazonaws.com/production/make_request
- See
Makefile
for setup and deployment. - Use
AWS=1 guard
to run specs against the AWS setup.
- Separate out gems for ActiveRecord and AWS dependencies (eg
service_notifications-active_record
) to remove gem dependencies. - Better environment/configuration setup (mostly ENV or hardcoded).
- Documentation
- DynanmoDB posts table to queue Lamba for backgrounding the processing (currently only works with instant: true processing).