A mass mailer script for SMTP services.
353
A mass mailer script for SMTP services. If the service imposes a sending quota, then this script pauses and resumes automatically as needed.
Containers derived from this image are supposed to be bind-mounted to the user's home directory. If you want to restrict access any further, then I recommend that you create another user on your machine just for mass mailing purposes.
Usage:
docker run --volume "$HOME:/workspace:ro" --rm dogaar/mass-mailer [options]
Options:
-c, --config PATH Absolute path to config file inside $HOME. Default value is "~/config.yaml".
Use ~ for the home directory, and enclose the config filename with ""
to ensure ~ expansion by the container.
-q, --quota-spent QUOTA_SPENT Mail-sending quota that has already been spent for current period.
This option is useful if the online mailing service imposes quotas,
and if this script is being called more than once for the same
sending period. Default value is 0.
-v, --[no-]verbose Run verbosely.
-h, --help Display this help message and exit.
Usage example:
docker run --volume "$HOME:/workspace:ro" --rm dogaar/mass-mailer --config "~/config.yaml" --quota-spent 110 --verbose
config.yaml:
------------
mailer_config_file: ~/path/to/mailer-config.yaml
mailing_list_file: ./mailinglist.json
mail:
subject: Test mail
body_file: ./email.html # If the file extension is not HTML then the file type is assumed to be plain text.
mailinglist.json:
-----------------
[
[
"name",
"email"
],
[
"Recipient name",
"[email protected]"
],
[
"2nd recipient name",
"[email protected]"
]
]
mailer-config.yaml:
------------------
name: Mail Bridge
# Required
smtp:
address: 127.0.0.1
port: 1025
domain: example.com
authentication: plain
enable_starttls_auto: true
user_name: [email protected]
password: a_password
# Optional
constraints:
max_mails_per_period: 300
period_length_in_seconds: 86400.0 # 1 day
The container script tries to behave like a native script, notably in terms of file name resolution. But there are restrictions for file name arguments:
Although you can call docker run directly, to make this image even more practical you can write a small local frontend script that allows relative filenames as arguments as well, and then formulates the docker run command behind the scenes. Using this image then becomes exactly like calling a local script when working inside the home directory, and this is the recommended way of using this image.
Here is a sample frontend script:
#! /usr/bin/env ruby
# require 'fileutils'
require 'pathname'
# A mass mailer script
APP_VERSION = "1.0.0"
# MODE = :development
MODE = :production
# read the yaml data at the end of this file
require "yaml"; TEXT = YAML.load DATA.read
def log message
$stderr.puts "#{message}" if OPTIONS[:verbose]
end
########################################################################
# Command line options and arguments
OPTIONS = {
config: nil, # Path relative to home directory
quota_spent: 0, # Emails already sent for current period
verbose: false,
}
require "optparse"
def format_helptext text
# TODO
end
OptionParser.new do |c|
c.banner = TEXT[:cli][:description].gsub('$script', $0)
c.separator ""
c.separator "Options:"
c.on("-c", "--config PATH", String,
*(TEXT[:cli][:options][:config].split("\n").map{|line| line.chomp})) do |e|
absolute_path = (Pathname.pwd + e).to_s
home_path = "#{ENV['HOME']}"
unless absolute_path.index(home_path) == 0
$stderr.puts "File is outside of home directory"
exit 1
end
home_relative_path =
OPTIONS[:config] = absolute_path[home_path.size + 1, absolute_path.size - home_path.size - 1]
log "Config file: #{OPTIONS[:config]}"
end
c.on("-q", "--quota-spent QUOTA_SPENT", Fixnum,
*(TEXT[:cli][:options][:quota_spent].split("\n").map{|line| line.chomp})) do |e|
e = 0 unless e > 0
OPTIONS[:quota_spent] = e
end
c.on("-v", "--[no-]verbose",
*(TEXT[:cli][:options][:verbose].split("\n").map{|line| line.chomp})) do |e|
OPTIONS[:verbose] = e
end
c.on("-h", "--help",
*(TEXT[:cli][:options][:help].split("\n").map{|line| line.chomp})) do
puts c.to_s
exit
end
c.separator ""
c.separator "Usage example:"
c.separator " #{TEXT[:cli][:usage_example].gsub '$script', $0 }"
c.separator ""
end.parse!
########################################################################
# Main
status =
system "docker run --volume \"$HOME:/workspace:ro\" --rm dogaar/mass-mailer --config \"~/#{OPTIONS[:config]}\" --quota-spent #{OPTIONS[:quota_spent]} --verbose"
unless status
$stderr.puts "Call returned an error."
end
__END__
# YAML data
#
# Notes:
# * if keys start with ':', then they are read as ruby symbols
# * uses spaces for indentation; tabs are not allowed
# * "|" preserves line breaks in multiline text
# * ">" concatenates adjascent non-empty lines in multiline text
:cli:
:description: |
A mass mailer script for SMTP services. If the service imposes a sending quota, then this script pauses and resumes automatically as needed.
Usage:
$script [options]
:options:
:config: |
Path to config file.
:quota_spent: |
Mail-sending quota that has already been spent for current period.
This option is useful if the online mailing service imposes quotas,
and if this script is being called more than once for the same
sending period.
:verbose: |
Run verbosely.
:help: |
Display this help message and exit.
:usage_example: |
$script --config config.yaml --quota-spent 110 --verbose
config.yaml:
------------
mailing_list_file: ./mailinglist.json
mail:
subject: Test mail
body_file: ./email.html
mailer_config_file: ./mailer.yaml
mailinglist.json:
-----------------
[
[
"name",
"email"
],
[
"Recipient name",
"[email protected]"
],
[
"2nd recipient name",
"[email protected]"
]
]
mailer.yaml:
------------
name: Mail Bridge
# Required
smtp:
address: 127.0.0.1
port: 1025
domain: example.com
authentication: plain
enable_starttls_auto: true
user_name: [email protected]
password: a_password
# Optional
constraints:
max_mails_per_period: 300
period_length_in_seconds: 86400.0 # 1 day
Content type
Image
Digest
Size
37.4 MB
Last updated
over 5 years ago
docker pull dogaar/mass-mailer