courier

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: May 18, 2017 License: AGPL-3.0 Imports: 25 Imported by: 87

README

Courier Build Status Coverage Status Go Report Card

Install Courier in your workspace with:

go get github.com/nyaruka/courier

Build Courier with:

go install github.com/nyaruka/courier/cmd/...

This will create a new executable in $GOPATH/bin called courier.

To run the tests you need to create the test database:

$ createdb courier_test
$ createuser -P -E courier
$ psql -d courier_test -f backends/rapidpro/schema.sql
$ psql -d courier_test -c "GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO courier;"
$ psql -d courier_test -c "GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO courier;"

To run all of the tests including benchmarks:

go test $(go list ./... | grep -v /vendor/) -cover -bench=.

Documentation

Index

Constants

View Source
const (
	// FacebookScheme is the scheme used for Facebook identifiers
	FacebookScheme string = "facebook"

	// TelegramScheme is the scheme used for telegram identifier
	TelegramScheme string = "telegram"

	// TelScheme is the scheme used for telephone numbers
	TelScheme string = "tel"

	// TwitterScheme is the scheme used for Twitter identifiers
	TwitterScheme string = "twitter"
)
View Source
const (
	// ConfigAuthToken is our constant key used in channel configs for auth tokens
	ConfigAuthToken = "auth_token"
)

Variables

View Source
var ErrChannelExpired = errors.New("channel expired")

ErrChannelExpired is returned when our cached channel has outlived it's TTL

View Source
var ErrChannelNotFound = errors.New("channel not found")

ErrChannelNotFound is returned when we fail to find a channel in the db

View Source
var ErrChannelWrongType = errors.New("channel type wrong")

ErrChannelWrongType is returned when we find a channel with the set UUID but with a different type

View Source
var ErrMsgNotFound = errors.New("message not found")

ErrMsgNotFound is returned when trying to queue the status for a Msg that doesn't exit

View Source
var NilChannelUUID = ChannelUUID{uuid.Nil}

NilChannelUUID is our nil value for channel UUIDs

View Source
var NilMsgID = MsgID{sql.NullInt64{Int64: 0, Valid: false}}

NilMsgID is our nil value for MsgID

View Source
var NilMsgUUID = MsgUUID{uuid.Nil}

NilMsgUUID is a "zero value" message UUID

View Source
var NilURN = URN("")

NilURN is our constant for nil URNs

Functions

func EnsureSpoolDirPresent

func EnsureSpoolDirPresent(spoolDir string, subdir string) (err error)

EnsureSpoolDirPresent checks that the passed in spool directory is present and writable

func RegisterBackend

func RegisterBackend(backendType string, constructorFunc BackendConstructorFunc)

RegisterBackend adds a new backend, called by individual backends in their init() func

func RegisterFlusher

func RegisterFlusher(directory string, flusherFunc FlusherFunc)

RegisterFlusher creates a new walker which we will use to flush files from the passed in directory

func RegisterHandler

func RegisterHandler(handler ChannelHandler)

RegisterHandler adds a new handler for a channel type, this is called by individual handlers when they are initialized

func WriteError

func WriteError(w http.ResponseWriter, err error) error

WriteError writes a JSON response for the passed in error

func WriteIgnored

func WriteIgnored(w http.ResponseWriter, message string) error

WriteIgnored writes a JSON response for the passed in message

func WriteReceiveSuccess

func WriteReceiveSuccess(w http.ResponseWriter, msg *Msg) error

WriteReceiveSuccess writes a JSON response for the passed in msg indicating we handled it

func WriteStatusSuccess

func WriteStatusSuccess(w http.ResponseWriter, status *MsgStatusUpdate) error

WriteStatusSuccess writes a JSON response for the passed in status update indicating we handled it

func WriteToSpool

func WriteToSpool(spoolDir string, subdir string, contents interface{}) error

WriteToSpool writes the passed in object to the passed in subdir

Types

type Backend

type Backend interface {
	Start() error
	Stop() error

	GetChannel(ChannelType, ChannelUUID) (Channel, error)
	WriteMsg(*Msg) error
	WriteMsgStatus(*MsgStatusUpdate) error

	Health() string
}

Backend represents the part of Courier that deals with looking up and writing channels and results

func NewBackend

func NewBackend(config *config.Courier) (Backend, error)

NewBackend creates the type of backend passed in

type BackendConstructorFunc

type BackendConstructorFunc func(*config.Courier) Backend

BackendConstructorFunc defines a function to create a particular backend type

type Channel

type Channel interface {
	UUID() ChannelUUID
	ChannelType() ChannelType
	Country() string
	Address() string
	ConfigForKey(key string, defaultValue interface{}) interface{}
}

Channel defines the general interface backend Channel implementations must adhere to

func NewMockChannel

func NewMockChannel(uuid string, channelType string, address string, country string, config map[string]interface{}) Channel

NewMockChannel creates a new mock channel for the passed in type, address, country and config

type ChannelActionHandlerFunc

type ChannelActionHandlerFunc func(Channel, http.ResponseWriter, *http.Request) error

ChannelActionHandlerFunc is the interface ChannelHandler functions must satisfy to handle various requests. The Server will take care of looking up the channel by UUID before passing it to this function.

type ChannelHandler

type ChannelHandler interface {
	Initialize(Server) error
	ChannelType() ChannelType
	ChannelName() string
}

ChannelHandler is the interface all handlers must satisfy

type ChannelType

type ChannelType string

ChannelType is our typing of the two char channel types

type ChannelUUID

type ChannelUUID struct {
	uuid.UUID
}

ChannelUUID is our typing of a channel's UUID

func NewChannelUUID

func NewChannelUUID(u string) (ChannelUUID, error)

NewChannelUUID creates a new ChannelUUID for the passed in string

type FlusherFunc

type FlusherFunc func(filename string, contents []byte) error

FlusherFunc defines our interface for flushers, they are handed a filename and byte blob and are expected to try to flush that to the db, returning an error if the db is still down

type MockBackend

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

MockBackend is a mocked version of a backend which doesn't require a real database or cache

func NewMockBackend

func NewMockBackend() *MockBackend

NewMockBackend returns a new mock backend suitable for testing

func (*MockBackend) AddChannel

func (mb *MockBackend) AddChannel(channel Channel)

AddChannel adds a test channel to the test server

func (*MockBackend) ClearChannels

func (mb *MockBackend) ClearChannels()

ClearChannels is a utility function on our mock server to clear all added channels

func (*MockBackend) ClearQueueMsgs

func (mb *MockBackend) ClearQueueMsgs()

ClearQueueMsgs clears our mock msg queue

func (*MockBackend) GetChannel

func (mb *MockBackend) GetChannel(cType ChannelType, uuid ChannelUUID) (Channel, error)

GetChannel returns the channel with the passed in type and channel uuid

func (*MockBackend) GetLastQueueMsg

func (mb *MockBackend) GetLastQueueMsg() (*Msg, error)

GetLastQueueMsg returns the last message queued to the server

func (*MockBackend) Health

func (mb *MockBackend) Health() string

Health gives a string representing our health, empty for our mock

func (*MockBackend) SetErrorOnQueue

func (mb *MockBackend) SetErrorOnQueue(shouldError bool)

SetErrorOnQueue is a mock method which makes the QueueMsg call throw the passed in error on next call

func (*MockBackend) Start

func (mb *MockBackend) Start() error

Start starts our mock backend

func (*MockBackend) Stop

func (mb *MockBackend) Stop() error

Stop stops our mock backend

func (*MockBackend) WriteMsg

func (mb *MockBackend) WriteMsg(m *Msg) error

WriteMsg queues the passed in message internally

func (*MockBackend) WriteMsgStatus

func (mb *MockBackend) WriteMsgStatus(status *MsgStatusUpdate) error

WriteMsgStatus writes the status update to our queue

type Msg

type Msg struct {
	Channel     Channel
	ID          MsgID
	UUID        MsgUUID
	Text        string
	Attachments []string
	ExternalID  string
	URN         URN
	ContactName string
	ReceivedOn  time.Time
}

Msg is our base struct to represent an incoming or outgoing message

func NewIncomingMsg

func NewIncomingMsg(channel Channel, urn URN, text string) *Msg

NewIncomingMsg creates a new message from the given params

func (*Msg) AddAttachment

func (m *Msg) AddAttachment(url string) *Msg

AddAttachment can be used to append to the media urls for a message

func (*Msg) WithContactName

func (m *Msg) WithContactName(name string) *Msg

WithContactName can be used to set the contact name on a msg

func (*Msg) WithExternalID

func (m *Msg) WithExternalID(id string) *Msg

WithExternalID can be used to set the external id on a msg in a chained call

func (*Msg) WithReceivedOn

func (m *Msg) WithReceivedOn(date time.Time) *Msg

WithReceivedOn can be used to set sent_on on a msg in a chained call

type MsgID

type MsgID struct {
	sql.NullInt64
}

MsgID is our typing of the db int type

func NewMsgID

func NewMsgID(id int64) MsgID

NewMsgID creates a new MsgID for the passed in int64

func (*MsgID) String

func (i *MsgID) String() string

String satisfies the Stringer interface

func (*MsgID) UnmarshalJSON

func (i *MsgID) UnmarshalJSON(bytes []byte) (err error)

UnmarshalJSON satisfies json unmarshalling so ids can be decoded from JSON

func (*MsgID) UnmarshalText

func (i *MsgID) UnmarshalText(text []byte) (err error)

UnmarshalText satisfies text unmarshalling so ids can be decoded from forms

type MsgStatus

type MsgStatus string

MsgStatus is the status of a message

const (
	MsgPending   MsgStatus = "P"
	MsgQueued    MsgStatus = "Q"
	MsgSent      MsgStatus = "S"
	MsgDelivered MsgStatus = "D"
	MsgFailed    MsgStatus = "F"
	NilMsgStatus MsgStatus = ""
)

Possible values for MsgStatus

type MsgStatusUpdate

type MsgStatusUpdate struct {
	Channel    Channel
	ID         MsgID
	ExternalID string
	Status     MsgStatus
	CreatedOn  time.Time
}

MsgStatusUpdate represents a status update on a message

func NewStatusUpdateForExternalID

func NewStatusUpdateForExternalID(channel Channel, externalID string, status MsgStatus) *MsgStatusUpdate

NewStatusUpdateForExternalID creates a new status update for a message identified by its external ID

func NewStatusUpdateForID

func NewStatusUpdateForID(channel Channel, id MsgID, status MsgStatus) *MsgStatusUpdate

NewStatusUpdateForID creates a new status update for a message identified by its primary key

func (*MsgStatusUpdate) Release

func (m *MsgStatusUpdate) Release()

Release releases this status and assigns it back to our pool for reuse

type MsgUUID

type MsgUUID struct {
	uuid.UUID
}

MsgUUID is the UUID of a message which has been received

func NewMsgUUID

func NewMsgUUID() MsgUUID

NewMsgUUID creates a new unique message UUID

type Server

type Server interface {
	Config() *config.Courier
	AddChannelRoute(handler ChannelHandler, method string, action string, handlerFunc ChannelActionHandlerFunc) *mux.Route

	GetChannel(ChannelType, ChannelUUID) (Channel, error)
	WriteMsg(*Msg) error
	WriteMsgStatus(*MsgStatusUpdate) error

	WaitGroup() *sync.WaitGroup
	StopChan() chan bool
	Stopped() bool

	Router() *mux.Router

	Start() error
	Stop() error
}

Server is the main interface ChannelHandlers use to interact with the database and redis. It provides an abstraction that makes mocking easier for isolated unit tests

func NewServer

func NewServer(config *config.Courier, backend Backend) Server

NewServer creates a new Server for the passed in configuration. The server will have to be started afterwards, which is when configuration options are checked.

type URN

type URN string

URN represents a Universal Resource Name, we use this for contact identifiers like phone numbers etc..

func NewTelURNForChannel

func NewTelURNForChannel(number string, channel Channel) URN

NewTelURNForChannel returns a URN for the passed in telephone number and channel

func NewTelURNForCountry

func NewTelURNForCountry(number string, country string) URN

NewTelURNForCountry returns a URN for the passed in telephone number and country code ("US")

func NewTelegramURN

func NewTelegramURN(identifier int64) URN

NewTelegramURN returns a URN for the passed in telegram identifier

func NewURNFromParts

func NewURNFromParts(scheme string, path string) (URN, error)

NewURNFromParts returns a new URN for the given scheme and path

Jump to

Keyboard shortcuts

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