Simple tool to send bulk email. Written in go for higher throughput. Supports multiple dispatcher (sparkpost) and can read from multiple sources (csv)

go get



v0.1 beta Its an application written in go to send bulk email.

"Somebody please contribute unit test cases, so that I can remove beta tag."

  • Rahul Prasad

You can choose source from following options

  1. csv (working on it)
  2. json (todo)

And mail user following services

  1. Sparkpost (working on it)
  2. sendgrid (todo)
  3. SMTP (todo)


  1. High throughput because of Go's concurrency model
  2. Throttle number of emails send in specific amount of time
  3. Modular structure. Its easy to add your service provider such as sendgrid.
  4. Interactive CLI mode which can be overridden to be used dynamically
  5. Support for overriding csv.source using flag


Building from source

  1. You must have go environment setup first. Learn more at
  2. Run go get
  3. Goto $GOPATH/src/ and run go build
  4. It should create an executable of name go-bulk-mailer


For help use ./go-bulk-mailer -h
To send mail, create config.json file and run ./go-bulk-mailer --config=config.json


  "campaign": {
    "###title": "Title of the campaign",
    "title": "reinstall mailer",

    "###subject": "Subject which will be sent as mail. You can use variable like {$name} within subject if name column comes after subject column in csv.",
    "subject": "{$name} Please come back",

    "from_email": "",
    "from_name": "Bobble App"
  "source": {
    "###use": "which source will be used for reading recipient information. Currently only csv is supported",
    "use": "csv",

    "csv": {
      "###src": "Path of csv file which contains recipient information",
      "src": "dump.csv",

      "###variables": "Array of strings, It must be in same order as csv file. 'email' is a mandatory variable, 'name', 'from_email', 'from_name', 'subject' (If subject if first column, other vaiables may be used within its value) are another static optional variable.",
      "variables": ["subject", "email", "gender", "from_name"]
  "###template": "variables can be used inside template files in this format {$name}. It will be replaced by data found in source",
  "template": {
    "html_src": "template.html",
    "text_src": "template.txt"
  "dispatcher": {
    "###use": "which dispatcher service to use? Currently only sparkpost is available",
    "use": "sparkpost",

    "sparkpost": {
      "API_KEY": "xxx",
      "base_url": "",
      "api_version": 1
    "###workers_count": "Workers will be working concurrently, it can be increased for better throughput.",
    "workers_count": 1,

    "worker": {
      "###wait_for_x_milliseconds": "Number seconds each worker will wait after dispatching certain message. If set to 0 messages will be dispatched continuously. This might cause heavy load on dispatcher.",
      "wait_for_x_milliseconds": 1,

      "###after_dispatching_y_msgs": "Number of messages which has to be dispatched by single worker before sleeping for certain seconds. If set to 0 messages will be dispatched continuously.",
      "after_dispatching_y_msgs": 10
  "logger": {
    "###folder_path": "Path of the folder where logs will be stored. If folder does not exists, it will be created.",
    "folder_path": "logs",

    "###log_success": "true/false To log successful requests",
    "log_success": true


Pull request are most welcome.

Currently I have implemented support for csv as source and sparkpost as service. You are most welcome to add more services and sources.


  1. Create test mode flag to send test email
  2. Implement support for sending attachment
  3. Daemon mode
  4. Generate sample config file
  5. create go get cli just like
  6. Make config modular, each module should be responsible for loading its config

Folder structure

main.go contains bootstapping code
init folder contains business logic
config folder contains configuration management
source contains logic to process email data sources
dispatcher contains service providers
common folder contains Models, Logger, Error Handler

Creating new dispatcher say sendgrid

  1. Create folder under dispatcher called sendgrid
  2. Update dispatcher/init.go and code to initiate sendgrid's worker
  3. Pass channel for receiving msgs to sendgrid's worker
  4. Worker can range over channel and send emails
  5. Source will close channel if all the messages are processed.
  6. Detect if channel is closed and shut down workers accordingly


v0.1 beta This is first version