Send queued e-mail using Beanstalkd
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

SMTP Worker

Send queued e-mail in separate process through a JSON abstraction.

Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.


  • Security, SMTP credentials are isolated from the website
  • Simplicity, the website creates JSON and all SMTP logic is isolated here
  • Scalable, things need to go faster? Start a second..third..fourth.. worker!
  • Cleaner, no more ugly timeouts in the browser if trouble and no more lost emails/customers!


  • Use Beanstalkd ( to add jobs in a queue.
  • One or more SMTPw-instances read the queue and try to send
  • Failure? Wait 5sec on SMTPw error or wait for Beanstalk deadline (if process got killed) and try again!


	"beanstalk": "",             // Hostname:port to Beanstalkd
	"from": {
		"support": {                            // From in JSON matches to this from
			"user": "usr",                      // SMTP username
			"pass": "ps",                       // SMTP password
			"host": "",        // SMTP hostname
			"port": 113,                        // SMTP port
			"from": "",     // From-address (used in mail header)
			"display": "Usenet.Farm Support",   // Display-name added before From-address
			"bcc": [
				""            // Send a secret copy (for your own administration)
			"bounce": ""

Bounce sets the From-header to the bounce-address and sets Reply-To for human replies.


./smtpw -h
Usage of ./smtpw:
  -c="./config.json": Path to config.json
  -s=false: Delete e-mail on deverr
  -v=false: Verbose-mode
  • Path config.json, where to find the config.json file
  • Delete on deverr, delete and flush the e-mail content if JSON is invalid.
  • Verbose-mode, log what we're doing


type Email struct {
	From        string          // Key that MUST match From in config
	To          []string
	Subject     string
	Html        string
	Text        string
	HtmlEmbed   map[string]string // file.png => base64(bytes)
	Attachments map[string]string // file.png => base64(bytes)

WARN: I like my parsers strict. Every HtmlEmbed key is scanned with Html.contains(cid:key) and if not found it will throw an error.

WARN: Invalid supplied email-address will fail with errors like mail: no angle-addr, please use a descent email RFC validator, i.e. for PHP


panic: dial tcp connection refused Install Beanstalkd and update config if Beanstalkd is running elsewhere?

x509: certificate signed by unknown authority Your SMTP-server has a self-signed certificate? Time to get a signed one!

Job never received by SMTPw? Is the job sent to the email tube? As smtpw only listenes to this tube.

telnet 11300
use email
peek-ready << should show your JSON here


# User + systemd
useradd -r smtpw
mkdir -p /home/smtpw
vi /etc/systemd/system/smtpw@.service
vi /etc/systemd/system/

chmod 644 /etc/systemd/system/smtpw@.service
chmod 644 /etc/systemd/system/

systemctl daemon-reload
systemctl enable smtpw@1
systemctl enable smtpw@2

systemctl start smtpw@1
systemctl start smtpw@2

External deps