项目作者: defndaines

项目描述 :
E-Mail Service (using Mailgun) with API endpoint for direct mailing or queued messages using Kafka.
高级语言: Clojure
项目地址: git://github.com/defndaines/yuubin.git
创建时间: 2016-12-18T23:28:47Z
项目社区:https://github.com/defndaines/yuubin

开源协议:Eclipse Public License 1.0

下载


Yūbin

Small application to integrate with Mailgun.

The service can take individual requests via a POST endpoint, or can monitor a
Kafka topic for incoming requests.

Installation

Download from https://github.com/defndaines/yuubin/releases

Usage

To run as a standalone service:

  1. $ java -jar yuubin-0.1.0-standalone.jar config.edn

Configuration

In order to run the service from the standalone JAR, an EDN configuration file must
be passed with the following values provided (if “port” is not provided, will
default to 3000):

  1. {:port 3030
  2. :mailbox "mailgun-api-mailbox"
  3. :api-key "mailgun-api-key"
  4. :template-dir "/etc/yuubin/templates"
  5. :bootstrap-servers "localhost:9092"
  6. :incoming-topic "yuubin.horyuu.json"
  7. :receipt-topic "yuubin.ryoushuu.json"}

API

The service expects POST requests passing JSON data about the mail message to
send. At this time, the service does not authenticate the incoming request, so
the service will send out valid messages using the configured mailbox and API
key. If a “from” field is not provided, it uses the “postmaster”
account of the configured “mailbox”.

Examples

The examples below assume you have configured the service to listen on the
default port ({ :port 3000 }).

To send a simple message providing the message body:

  1. curl -X POST -H "Content-Type: application/json" localhost:3000 -d '{"to": "mikan@e-mail.com", "subject": "Welcome to Yūbin", "body": "<h1>Hey Mikan!</h1><p>We are really happy to have you here at Yūbin. If you have any questions, please contact us."}'

To send a request using a template:

  1. curl -X POST -H "Content-Type: application/json" localhost:3000 -d '{"to": "mikan@e-mail.com", "subject": "Welcome to Yūbin", "template": "welcome.html", "t:name": "Mikan"}'

Templates

The service can send e-mails using a template body. Some sample templates are
defined under resources/templates/. Use the “template” key with the name of
the template file as the value to use this feature.

To use templates, provide a template directory in the configuration file
({ :template-dir "/etc/yuubin/templates" }).

This example sends the Password Reset template to the user:

  1. { "to": "user@mail.com"
  2. , "subject": "Password Reset"
  3. , "template": "password-reset.html"
  4. }

Templates can contain attributes to replace. Template attributes must be
prefixed with “t:”. In the HTML document, they must be surrounded with
double-percent signs, like “%%t:attr%%”. If a template includes attributes
but the request does not define them, they will be stripped from the outgoing
message to avoid leaving the template identifiers in the message.
This example replaces the “name” attribute in the “Welcome” template:

  1. { "to": "user@mail.com"
  2. , "subject": "Welcome to Yūbin"
  3. , "template": "welcome.html"
  4. , "t:name": "Mikan"
  5. }

Queuing Mail

The service can also read from a Kafka topic which acts as a queue for messages.
The incoming topic expects JSON messages in the same format as defined in the
API above.

To use the queuing feature, be sure to set the following configuration
values:

  1. {:bootstrap-servers "localhost:9092"
  2. :incoming-topic "yuubin.horyuu.json"
  3. :receipt-topic "yuubin.ryoushuu.json"}

The incoming-topic will be monitored for incoming JSON messages.
The receipt-topic will contain the response from the
Mailgun request for each processed message.

The service hard-codes the Kafka group ID and syncs messages once they’ve been
handled. This means that if the service crashes and is restarted, it should not
resend messages which have already been sent.

At this time, the service does not provide an explicit way to track queued
requests and receipts. It could be changed to require incoming messages to
provide an ID and then include that ID in the receipt.

Development

Use of this project requires an API key from Mailgun. See their
Sign Up page to get a key.
The .gitignore file is set to
ignore the “mailgun-api.key” file, so you can store a personal key there for
development to avoid accidentally committing it. Additionally, if you have
git-secrets installed, run a command
like the following to prevent you from committing a file containing the key:

  1. git secrets --add '<your-key-here>'

Send Mail from the REPL

You can test that everything is wired up correctly to send messages via Mailgun
with the following:

  1. (require '[yuubin.mail :as mail])
  2. (def my-key (clojure.string/trim-newline (slurp "resources/mailgun-api.key")))
  3. (def my-mailbox (clojure.string/trim-newline (slurp "resources/mailgun-api.mailbox")))
  4. (def template-dir "resources/templates")
  5. (def my-message {"to" "your.name@e-mail.com"
  6. "subject" "Hello World"
  7. "body" "<html><body><h1>Hello World!</h1></body></html>"})
  8. (mail/post-message my-mailbox my-key my-message)

If this returns a 400, check the full exception, which can do a good job of
pointing out what is missing from the call.

Ring Server

For development, you can run the service using:

  1. lein ring server 3000

This will run the server locally on port 3000. It will also pick up many code
changes dynamically so that the service can be tweaked and tested.

Setting up Kafka

The service can read from and write to Kafka topics to track message requests.
Follow the instructions below to install a local instance of
Kafka. If using Docker or a preexisting Kafka
installation, you can skip most of this, provided you configure topics.

Download the
Kafka 0.10.1.0
tar ball and extract to a location which makes sense for your environment.

Start zookeeper.

  1. cd kafka_2.11-0.10.1.0
  2. bin/zookeeper-server-start.sh config/zookeeper.properties

Start the Kafka server. You may need to add the line
advertised.host.name=localhost to the server.properties file in order to
publish and consume from a local Kafka instance.

  1. bin/kafka-server-start.sh config/server.properties

Create a couple topics to publish messages to.

  1. bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic yuubin.horyuu.json
  2. bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic yuubin.ryoushuu.json

Check that the topics are present.

  1. bin/kafka-topics.sh --list --zookeeper localhost:2181

Write messages into the sending topic. Any content written or pasted into this
session this creates, per line, will publish into the topic. Use Ctrl-C to exit.

  1. bin/kafka-console-producer.sh --broker-list localhost:9092 --topic yuubin.horyuu.json

To test from the command line that the messages are in the topic:

  1. bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic yuubin.horyuu.json --from-beginning

License

Copyright © 2016 Michael S. Daines

Distributed under the Eclipse Public License either version 1.0 or (at
your option) any later version.