maillist

package module
v0.0.0-...-ad90ac9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2017 License: Apache-2.0 Imports: 22 Imported by: 0

README

maillist

godoc v1

A Go based mailing list manager.

This package allows lists of email addresses to be managed, and schedules e-mail campaigns to be sent to them.

It is currently tied to the Sendgrid API, and probably only used internally at Attendly.

Please see the API docs for usage information.

License

Apache License version 2.0 (see LICENSE file)

Documentation

Overview

Package maillist sends bulk e-mail to lists of addresses using the Sendgrid API.

All functionality is implemented as methods on a session object, which should be closed when finished with it.

The script 'init-db.sh' should be run to initialize the database for this package.

Usage

Open a new session.

config := maillist.Config{
	DatabaseAddress: "username:password@unix(/run/mysqld/mysqld.sock)/attendly_email_service"
	JustPrint:       true,
	Logger:          os.Stdout,
	UnsubscribeURL:  "https://localhost/unsubscribe",

	SendGridUsername: "sendgrid@example.com"
	SendGridPassword: "asdf1234"
	SendGridAPIKey:   "SG.0x145597e70x13313b210x49fd869f"
}
s, _ := maillist.OpenSession(&config)
defer s.Close()

Create or retrieve an Account.

a := maillist.Account{
	FirstName: "Joe",
	LastName:  "Bloggs",
	Email:     "sendgrid@example.com",
}
s.InsertAccount(&a)

Create or retrive a List (which contains subscribers).

l := maillist.List{
	AccountID: a.ID,
	Name:      "My Awesome Mailing List",
}
s.InsertList(&l)

Optionally add more subscribers to the list.

sub := maillist.Subscriber{
	AccountID: a.ID,
	FirstName: "Tommy",
	LastName:  "Barker",
	Email:     "tom@example.com",
}
s.InsertSubscriber(&sub)
s.AddSubscriberToList(l.ID, sub.ID)

Create and schedule a campaign for that list.

c := maillist.Campaign{
	AccountID: a.ID,
	Subject:   "Awesome Event 2016",
	Body:      "Hi {{.FirstName}} {{.LastName}},\nThis is a test of attendly email list service",
	Scheduled: time.Now().Unix(),
}
s.InsertCampaign(&c, []int64{l.ID}, nil)

This package will ensure the emails are sent out when the scheduled time is reached as long as at least one session remains open.

Example

Example session of sending a single test email. Configuration here is read from the environment.

package main

import (
	"os"
	"time"

	"github.com/Attendly/maillist"
	_ "github.com/go-sql-driver/mysql"
)

func main() {

	config := maillist.Config{
		DatabaseAddress: os.Getenv("MAILLIST_DATABASE"),
		JustPrint:       true,
		UnsubscribeURL:  "https://myeventarc.localhost/unsubscribe",

		SendGridUsername: os.Getenv("SENDGRID_USERNAME"),
		SendGridPassword: os.Getenv("SENDGRID_PASSWORD"),
		SendGridAPIKey:   os.Getenv("SENDGRID_APIKEY"),
	}

	s, _ := maillist.OpenSession(&config)
	defer s.Close()

	a := maillist.Account{
		ApplicationID: 0xdeadbeef,
		FirstName:     "Joe",
		LastName:      "Bloggs",
		Email:         "sendgrid@example.com",
	}

	s.InsertAccount(&a)
	defer s.DeleteAccount(a.ID)

	l := maillist.List{
		AccountID: a.ID,
		Name:      "My Awesome Mailing List",
	}
	s.InsertList(&l)

	sub := maillist.Subscriber{
		AccountID: a.ID,
		FirstName: "Tommy",
		LastName:  "Barker",
		Email:     "tom@example.com",
	}

	s.InsertSubscriber(&sub)
	defer s.DeleteSubscriber(sub.ID)

	s.AddSubscriberToList(l.ID, sub.ID)

	c := maillist.Campaign{
		AccountID: a.ID,
		Subject:   "Awesome Event 2016",
		Body:      "Hi {{.FirstName}} {{.LastName}},\nThis is a test of attendly email list service",
		Address:   "123 fake st",
		Scheduled: time.Now().Unix(),
	}
	s.InsertCampaign(&c, []int64{l.ID}, nil)
	time.Sleep(5 * time.Second)

}
Output:

Email to send
To: tom@example.com (Tommy Barker)
From: sendgrid@example.com (Joe Bloggs)
Subject: Awesome Event 2016
Body: Hi Tommy Barker,
This is a test of attendly email list service

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrNotFound = &errNotFound{}

ErrNotFound returned when an entity is not present in the database

Functions

This section is empty.

Types

type Account

type Account struct {
	ID            int64  `db:"id"`
	ApplicationID int64  `db:"application_id" validate:"required"`
	FirstName     string `db:"first_name" validate:"required"`
	LastName      string `db:"last_name" validate:"required"`
	Email         string `db:"email" validate:"required"`
	Status        string `db:"status" validate:"eq=active|eq=deleted"`
	CreateTime    int64  `db:"create_time" validate:"required"`
}

Account is equivalent to a user. All lists, messages, and subscribers must have an associated account

type Campaign

type Campaign struct {
	ID         int64  `db:"id"`
	AccountID  int64  `db:"account_id" validate:"required"`
	Subject    string `db:"subject" validate:"required"`
	Body       string `db:"body" validate:"required"`
	Address    string `db:"address" validate:"required"`
	Status     string `db:"status" validate:"eq=scheduled|eq=pending|eq=sent|eq=cancelled|eq=failed|eq=draft"`
	ListIDs    string `db:"list_ids" validate:"-"`
	EventIDs   string `db:"event_ids" validate:"-"`
	Scheduled  int64  `db:"scheduled" validate:"required"`
	CreateTime int64  `db:"create_time" validate:"required"`
}

Campaign is a message template sent at a particular time to one or more mailing lists

type Config

type Config struct {
	DatabaseAddress      string
	JustPrint            bool
	Logger               Logger
	GetAttendeesCallback getAttendeeFunc
	UnsubscribeURL       string

	SendGridAPIKey   string
	SendGridUsername string
	SendGridPassword string
}

Config stores application defined options

type List

type List struct {
	ID         int64  `db:"id"`
	AccountID  int64  `db:"account_id" validate:"required"`
	Name       string `db:"name" validate:"required"`
	Status     string `db:"status" validate:"eq=active|eq=deleted"`
	CreateTime int64  `db:"create_time" validate:"required"`
}

List represents a user defined mailing list, these are seperate from event-associated lists

type ListSubscriber

type ListSubscriber struct {
	ListID       int64 `db:"list_id" validate:"required"`
	SubscriberID int64 `db:"subscriber_id" validate:"required"`
	CreateTime   int64 `db:"create_time" validate:"required"`
}

ListSubscriber represents a joining table for list and subscribers

type Logger

type Logger interface {
	Error(a ...interface{})
	Info(a ...interface{})
}

Logger interface

type Message

type Message struct {
	SubscriberID int64  `db:"subscriber_id" validate:"required"`
	CampaignID   int64  `db:"campaign_id" validate:"required"`
	Status       string `db:"status" validate:"eq=pending|eq=sent|eq=failed|eq=cancelled"`
	CreateTime   int64  `db:"create_time" validate:"required"`
}

Message is a single email. It keeps track of whether the message has been sent or not.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session is an opaque type holding database connections and other implementation details

func OpenSession

func OpenSession(config *Config) (*Session, error)

OpenSession initialises a connection with the mailing list system. A call to Session.Close() should follow to ensure a clean exit.

func (*Session) AddSubscriberToList

func (s *Session) AddSubscriberToList(listID, subscriberID int64) error

AddSubscriberToList adds a subscriber to a mailing list. Internally it is added to the list_subscriber joining table

func (*Session) CancelCampaign

func (s *Session) CancelCampaign(campaignID int64) error

CancelCampaign will cancel the given campaign from sending

func (*Session) Close

func (c *Session) Close() error

Close closes the session. It blocks until the session is cleanly exited

func (*Session) DeleteAccount

func (s *Session) DeleteAccount(accountID int64) error

DeleteAccount removes an account

func (*Session) DeleteList

func (s *Session) DeleteList(listID int64) error

DeleteList removes a mailing list from the database (actually just marks it as `deleted` so we can a log of it)

func (*Session) DeleteSubscriber

func (s *Session) DeleteSubscriber(id int64) error

DeleteSubscriber from the db

func (*Session) GetAccount

func (s *Session) GetAccount(accountID int64) (*Account, error)

GetAccount retrieves an account with a given ID. Returns nil,nil if that ID does not exist (or has been deleted)

func (*Session) GetAccountByApplicationID

func (s *Session) GetAccountByApplicationID(applicationID int64) (*Account, error)

GetAccountByApplicationID retrieves an account with a given application ID. Returns nil,nil if that ID does not exist (or has been deleted)

func (*Session) GetAccountByEmail

func (s *Session) GetAccountByEmail(email string) (*Account, error)

GetAccountByEmail retrieves an account with a given email address. Returns nil,nil if that email address does not exist (or has been deleted)

func (*Session) GetCampaign

func (s *Session) GetCampaign(campaignID int64) (*Campaign, error)

GetCampaign retrieves a campaign with a given ID

func (*Session) GetCampaignsInAccount

func (s *Session) GetCampaignsInAccount(accountID int64) ([]*Campaign, error)

GetCampaignsInAccount returns the campaigns for the given account

func (*Session) GetList

func (s *Session) GetList(listID int64) (*List, error)

GetList retrieves a mailing list with a given ID

func (*Session) GetLists

func (s *Session) GetLists(accountID int64) ([]*List, error)

GetLists retrieves all the mailing lists associated with an account.

func (*Session) GetSubscriber

func (s *Session) GetSubscriber(subscriberID int64) (*Subscriber, error)

GetSubscriber retrieves a subscriber with a given ID. Returns nil,nil if no such subscriber exists

func (*Session) GetSubscriberByEmail

func (s *Session) GetSubscriberByEmail(email string, accountID int64) (*Subscriber, error)

GetSubscriberByEmail retrieves a subscriber with a given email address. Returns nil,nil if no such subscriber exists

func (*Session) GetSubscriberByToken

func (s *Session) GetSubscriberByToken(token string) (*Subscriber, error)

GetSubscriberByToken retrieves the subscriber associated with a token. Returns an error if the token doesn't match any in the database

func (*Session) GetSubscribers

func (s *Session) GetSubscribers(listID int64) ([]*Subscriber, error)

GetSubscribers retrieves all the subscribers in a mailing list

func (*Session) HasReportedSpam

func (s *Session) HasReportedSpam(email string) (bool, error)

HasReportedSpam checks whether an email address has made a spam report against us. Mail should not be sent to such an address.

func (*Session) InsertAccount

func (s *Session) InsertAccount(a *Account) error

InsertAccount adds the database to the account. The ID field will be updated. It is an error to have duplicate email addresses for the account table

func (*Session) InsertCampaign

func (s *Session) InsertCampaign(c *Campaign, listIDs []int64, eventIDs []int64) error

InsertCampaign adds the campaign to the scheduler to be sent to all its subscribers

func (*Session) InsertList

func (s *Session) InsertList(l *List) error

InsertList adds a new mailing list to the database.

func (*Session) InsertMessage

func (s *Session) InsertMessage(m *Message) error

InsertMessage inserts a message into the database. It's ID field will be updated.

func (*Session) InsertSubscriber

func (s *Session) InsertSubscriber(sub *Subscriber) error

InsertSubscriber into the db

func (*Session) RemoveSubscriberFromList

func (s *Session) RemoveSubscriberFromList(listID, subscriberID int64) error

RemoveSubscriberFromList removes a subscriber from a list. Note this is distinct from unsubscribing which is done on an account basis

func (*Session) Unsubscribe

func (s *Session) Unsubscribe(sub *Subscriber) error

Unsubscribe marks a subscriber as not wanting to recieve any more marketting emails

func (*Session) UnsubscribeToken

func (s *Session) UnsubscribeToken(sub *Subscriber) (string, error)

UnsubscribeToken gets a crypographically secure token which represents a subscriber. Using such a token means that only the recepiant of an email can unsubscribe from that mailing list.

func (*Session) UpdateAccount

func (s *Session) UpdateAccount(a *Account) error

UpdateAccount updates an account (identified by it's ID)

func (*Session) UpdateList

func (s *Session) UpdateList(l *List) error

UpdateList updates a mailing list in the database, identified by it's ID

type Subscriber

type Subscriber struct {
	ID         int64  `db:"id"`
	AccountID  int64  `db:"account_id" validate:"required"`
	FirstName  string `db:"first_name" validate:"required"`
	LastName   string `db:"last_name" validate:"required"`
	Email      string `db:"email" validate:"required,email"`
	Status     string `db:"status" validate:"eq=active|eq=deleted|eq=unsubscribed"`
	CreateTime int64  `db:"create_time" validate:"required"`
}

Subscriber stores a single email address and some associated parameters. Each subscriber must have an associated account, and a given email address will have one subscriber for each account

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL