dt

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2016 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package dt offers a collection of commonly used datatypes. These datatypes are shared and used by Abot's core and shared packages as well as plugins themselves.

Index

Constants

This section is empty.

Variables

View Source
var ErrInvalidFlexIDType = errors.New("invalid flexid type")

ErrInvalidFlexIDType is returned when a FlexIDType is invalid not matching one of the pre-defined FlexIDTypes for email (1) or phone (2).

View Source
var ErrMissingFlexID = errors.New("missing flexid")

ErrMissingFlexID is returned when a FlexID is expected, but none found.

View Source
var ErrMissingFlexIDType = errors.New("missing flexidtype")

ErrMissingFlexIDType is returned when a FlexIDType is expected, but none found.

View Source
var ErrMissingUser = errors.New("missing user")

ErrMissingUser is returned when a user expected, but none found.

View Source
var ErrNoAddress = errors.New("no address")

ErrNoAddress signals that no address could be found when one was expected.

Functions

func GetAddress

func GetAddress(dest *Address, db *sqlx.DB, id uint64) error

GetAddress searches the database for a specific address by its ID.

Types

type Address

type Address struct {
	ID             uint64
	Name           string
	Line1          string
	Line2          string
	City           string
	State          string
	Zip            string
	Zip5           string
	Zip4           string
	Country        string
	DisplayAddress string
}

Address holds all relevant information in an address for presentation to the user and communication to external services, including the USPS address validation tool. Right now, an effort is only made to support US-based addresses.

type Admin

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

Admin is a special type of user that has access to Abot's admin panel.

func NewAdmin

func NewAdmin() *Admin

NewAdmin returns a singleton that represents the current admin running the deployed service. Its name and email are set through the environment variables ADMIN_NAME and ADMIN_EMAIL.

func (*Admin) GetEmail

func (a *Admin) GetEmail() string

GetEmail satisfies the Contactable interface, making it possible to email the admin.

func (*Admin) GetName

func (a *Admin) GetName() string

GetName satisfies the Contactable interface, making it possible to email the admin.

type AtomicSet

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

AtomicSet is a thread-safe map that acts as a Set of strings (no duplicates are possible). To initialize this struct, use NewAtomicSet().

func NewAtomicSet

func NewAtomicSet() AtomicSet

NewAtomicSet returns an AtomicSet to track whether string values have been set or not in an efficient and thread-safe way.

func (AtomicSet) Get

func (as AtomicSet) Get(k string) (exists bool)

Get returns whether a string exists in a given Set in a thread-safe way.

func (AtomicSet) Set

func (as AtomicSet) Set(k string)

Set a given string as existing within the AtomicSet.

type AuthMethod

type AuthMethod int

AuthMethod allows you as the plugin developer to control the level of security required in an authentication. Select an appropriate security level depending upon your risk tolerance for fraud compared against the quality and ease of the user experience.

NOTE this is just a stub and isn't implemented TODO build the constants defining the types of AuthMethods

type Card

type Card struct {
	ID             int
	AddressID      sql.NullInt64
	Last4          string
	CardholderName string
	ExpMonth       int
	ExpYear        int
	Brand          string
	ServiceToken   string
	Zip5Hash       []byte `sql:"zip5hash"`
}

Card represents a credit card. Note that information such as the card number, security code and zip code are not present in this struct, since that data should never hit the server and thus can never be stored. Storage of that sensitive data is outsourced to a payment provider (initially Stripe) and is sent directly from the client to that payment provider, bypassing the server entirely.

type CardParams

type CardParams struct {
	ServiceToken   string
	CardholderName string
	Last4          string
	Brand          string
	ExpMonth       int
	ExpYear        int
	AddressZip     string
}

CardParams is used when saving a new card.

type City

type City struct {
	Name        string
	CountryCode string
}

City represents a city within a specific country.

type Contactable

type Contactable interface {
	GetName() string
	GetEmail() string
}

Contactable defines an interface used by dt.MailClient to send customized emails to users, vendors and admins

type EventRequest

type EventRequest int

EventRequest is sent to the state machine to request safely jumping between states (directly to a specific Label) with guards checking that each new state is valid.

type FlexIDType

type FlexIDType int

FlexIDType is used to identify a user when only an email, phone, or other "flexible" ID is available.

type HTTPRoute

type HTTPRoute struct {
	Method string
	Path   string
}

HTTPRoute defines a route to be used within a HandlerMap.

type HandlerMap

type HandlerMap map[HTTPRoute]echo.Handler

HandlerMap maps HTTPRoutes (the method and URL path) to a echo router handler.

func NewHandlerMap

func NewHandlerMap(rhs []RouteHandler) HandlerMap

NewHandlerMap builds a HandlerMap from a slice of RouteHandlers. This is a convenience function, since RouteHandlers directly is very verbose for plugins.

func (HandlerMap) AddRoutes

func (hm HandlerMap) AddRoutes(prefix string, e *echo.Echo)

AddRoutes to the Echo router dynamically, enabling drivers to add routes to an application at runtime usually as part of their initialization. AddRoutes panics if the HTTP method in the HandlerMap is unknown (i.e. not GET, POST, PUT, PATCH, or DELETE).

type Location

type Location struct {
	Name      string
	Lat       float64
	Lon       float64
	CreatedAt time.Time
}

Location represents some location saved for a user or plugin. This is used by itsabot.org/abot/shared/knowledge to quickly retrieve either the user's last location (if recent) or request another location using the previous as a hint, e.g. "Are you still in Los Angeles?"

func (Location) IsRecent

func (l Location) IsRecent() bool

IsRecent is a helper function to determine if the user's location was last recorded in the past day. Beyond that, itsabot.org/abot/shared/knowledge will request an updated location.

type Memory

type Memory struct {
	Key string
	Val []byte
	// contains filtered or unexported fields
}

Memory holds a generic "memory" of Ava's usually set by a plugin, such as the current state of a plugin, selected products, results of a search, current offset in those search results, etc. Since the value is returned as a a []byte (and stored in the database in the same way), it can represent any datatype, and it's up to the plugin developer to recall which memories correspond to which datatypes.

func (Memory) Bool

func (m Memory) Bool() bool

Bool is a helper method making it easier to perform a common use-case, converting a memory's []byte Val into bool and protecting against a common error.

func (Memory) Int64

func (m Memory) Int64() int64

Int64 is a helper method making it easier to perform a common use-case, converting a memory's []byte Val into an int64 and protecting against a common error.

func (Memory) String

func (m Memory) String() string

String is a helper method making it easier to perform a common use-case, converting a memory's []byte Val into a string.

type Msg

type Msg struct {
	ID              uint64
	FlexID          string
	FlexIDType      int
	Sentence        string
	User            *User
	StructuredInput *nlp.StructuredInput
	Stems           []string
	Plugin          string
	State           map[string]interface{}
	CreatedAt       *time.Time
	// AbotSent determines if msg is from the user or Ava
	AbotSent      bool
	NeedsTraining bool
	// Tokens breaks the sentence into words. Tokens like ,.' are treated as
	// individual words.
	Tokens []string
	Route  string
}

Msg is a message received by a user. It holds various fields that are useful for plugins which are populated by Abot core in core/process.

func GetMsg

func GetMsg(db *sqlx.DB, id uint64) (*Msg, error)

GetMsg returns a message for a given message ID.

func (*Msg) GetLastRoute

func (m *Msg) GetLastRoute(db *sqlx.DB) (string, error)

GetLastRoute for a given user so the previous plugin can be called again if no new trigger is detected.

func (*Msg) Save

func (m *Msg) Save(db *sqlx.DB) error

Save a message to the database, updating the message ID.

func (*Msg) Update

func (m *Msg) Update(db *sqlx.DB) error

Update a message as needing training.

type Phone

type Phone struct {
	ID     uint64
	Number string `db:"flexid"`
}

Phone represents a phone as a flexid from the database.

type Product

type Product struct {
	ID        string
	Name      string
	Size      string
	Stock     uint
	Price     uint64
	VendorID  uint64
	Category  string
	Varietals []string
	Reviews   []struct {
		Score uint
		Body  string
	}
}

Product represents a product result returned from ElasticSearch. Note that because it's an ElasticSearch result, it has a string ID.

type ProductSel

type ProductSel struct {
	*Product
	Count uint
}

ProductSel is a user's product selection, keeping track of both the product selected and the quantity desired.

type ProductSels

type ProductSels []ProductSel

ProductSels represents a slice of product selections, adding a helper method that makes it easy to calculate the prices (subtotal, tax, shipping, and total).

func (ProductSels) Prices

func (prods ProductSels) Prices(addr *Address) map[string]uint64

Prices calculates the various prices for a given product selection. This includes a product subtotal, tax, shipping, and a total combining all the above.

type Purchase

type Purchase struct {
	ID                 uint64
	UserID             uint64
	User               *User
	VendorID           uint64
	Vendor             *Vendor
	ShippingAddress    *Address
	ShippingAddressID  sql.NullInt64
	Products           []string // product names
	ProductSels        ProductSels
	Tax                uint64
	Shipping           uint64
	Total              uint64
	AvaFee             uint64
	CreditCardFee      uint64
	TransferFee        uint64
	VendorPayout       uint64
	VendorPaidAt       *time.Time
	DeliveryExpectedAt *time.Time
	EmailsSentAt       *time.Time
	CreatedAt          *time.Time
	// contains filtered or unexported fields
}

Purchase represents a user purchase and associated useful information such as a breakdown of pricing, products purchased and the time a delivery is expected.

func NewPurchase

func NewPurchase(db *sqlx.DB, pc *PurchaseConfig) (*Purchase, error)

NewPurchase creates a Purchase and fills in information like a pricing breakdown automatically based on a provided PurchaseConfig.

func (*Purchase) Create

func (p *Purchase) Create() error

Create saves a new Purchase to the database and returns an error, if any.

func (*Purchase) DisplayID

func (p *Purchase) DisplayID() string

DisplayID returns a user-facing identifier for a purchase made that can be referenced in future communications, such as if purchased items arrive damaged.

func (*Purchase) Subtotal

func (p *Purchase) Subtotal() uint64

Subtotal is a helper function to return the purchase price before tax and shipping, i.e. only the cost of the products purchased.

func (*Purchase) UpdateEmailsSent

func (p *Purchase) UpdateEmailsSent() error

UpdateEmailsSent records the time at which a purchase confirmation and vendor request were sent. See itsabot.org/abot/shared/task/request_auth.go:makePurchase for an example.

type PurchaseConfig

type PurchaseConfig struct {
	*User
	Prices          []uint64
	VendorID        uint64
	ShippingAddress *Address
	ProductSels     ProductSels
}

PurchaseConfig is a smaller set of purchase information that plugins can use to more easily build a full Purchase.

type RouteHandler

type RouteHandler struct {
	Method  string
	Path    string
	Handler echo.Handler
}

RouteHandler is a complete struct containing both an HTTPRoute and a handler.

type State

type State struct {
	// OnEntry preprocesses and asks the user for information. If you need
	// to do something when the state begins, like run a search or hit an
	// endpoint, do that within the OnEntry function, since it's only called
	// once.
	OnEntry func(*Msg) string

	// OnInput sets the category in the cache/DB. Note that if invalid, this
	// state's Complete function will return false, preventing the user from
	// continuing. User messages will continue to hit this OnInput func
	// until Complete returns true.
	//
	// A note on error handling: errors should be logged but are not
	// propogated up to the user. Due to the preferred style of thin
	// States, you should generally avoid logging errors directly in
	// the OnInput function and instead log them within any called functions
	// (e.g. setPreference).
	OnInput func(*Msg)

	// Complete will determine if the state machine continues. If true,
	// it'll move to the next state. If false, the user's next response will
	// hit this state's OnInput function again.
	Complete func(*Msg) (bool, string)

	// SkipIfComplete will run Complete() on entry. If Complete() == true,
	// then it'll skip to the next state.
	SkipIfComplete bool

	// Label enables jumping directly to a State with stateMachine.SetState.
	// Think of it as enabling a safe goto statement. This is especially
	// useful when combined with a KeywordHandler, enabling a user to jump
	// straight to something like a "checkout" state. The state machine
	// checks before jumping that it has all required information before
	// jumping ensuring Complete() == true at all skipped states, so the
	// developer can be sure, for example, that the user has selected some
	// products and picked a shipping address before arriving at the
	// checkout step. In the case where one of the jumped Complete()
	// functions returns false, the state machine will stop at that state,
	// i.e. as close to the desired state as possible.
	Label string
}

State is a collection of pre-defined functions that are run when a user reaches the appropriate state within a stateMachine.

type StateMachine

type StateMachine struct {
	Handlers []State
	// contains filtered or unexported fields
}

StateMachine enables plugin developers to easily build complex state machines given the constraints and use-cases of an A.I. bot. It primarily holds a slice of function Handlers, which is all possible states for a given stateMachine. The unexported variables are useful internally in keeping track of state automatically for developers and make an easy API like stateMachine.Next() possible.

func NewStateMachine

func NewStateMachine(pluginName string) *StateMachine

NewStateMachine initializes a stateMachine to its starting state.

func (*StateMachine) GetDBConn

func (sm *StateMachine) GetDBConn() *sqlx.DB

GetDBConn allows for accessing a stateMachine's provided database connection.

func (*StateMachine) GetMemory

func (sm *StateMachine) GetMemory(in *Msg, k string) Memory

GetMemory retrieves a memory for a given key. Accessing that Memory's value is described in itsabot.org/abot/shared/datatypes/memory.go.

func (*StateMachine) HasMemory

func (sm *StateMachine) HasMemory(in *Msg, k string) bool

HasMemory is a helper function to simply a common use-case, determing if some key/value has been set in Ava, i.e. if the memory exists.

func (*StateMachine) LoadState

func (sm *StateMachine) LoadState(in *Msg)

LoadState upserts state into the database. If there is an existing state for a given user and plugin, the stateMachine will load it. If not, the stateMachine will insert a starting state into the database.

func (*StateMachine) Next

func (sm *StateMachine) Next(in *Msg) (response string)

Next moves a stateMachine from its current state to its next state. Next handles a variety of corner cases such as reaching the end of the states, ensuring that the current state's Complete() == true, etc. It directly returns the next response of the stateMachine, whether that's the Complete() failed string or the OnEntry() string.

func (*StateMachine) OnInput

func (sm *StateMachine) OnInput(in *Msg)

OnInput runs the stateMachine's current OnInput function. Most of the time this is not used directly, since Next() will automatically run this function when appropriate. It's an exported function to provide users more control over their

func (*StateMachine) Reset

func (sm *StateMachine) Reset(in *Msg)

Reset the stateMachine both in memory and in the database. This also runs the programmer-defined reset function (SetOnReset) to reset memories to some starting state for running the same plugin multiple times. This is usually called from a plugin's Run() function. See plugins/ava_purchase/ava_purchase.go for an example.

func (*StateMachine) SetDBConn

func (sm *StateMachine) SetDBConn(s *sqlx.DB)

SetDBConn gives a stateMachine itsabot.org/abot/shared access to a plugin's database connection. This is required even if no states require database access, since the stateMachine's current state (among other things) are peristed to the database between user requests.

func (*StateMachine) SetLogger

func (sm *StateMachine) SetLogger(l *log.Logger)

SetLogger enables the logger with any plugin-defined settings to be used internally by the stateMachine. This ensures consistency in the logs of a plugin.

func (*StateMachine) SetMemory

func (sm *StateMachine) SetMemory(in *Msg, k string, v interface{})

SetMemory saves to some key to some value in Ava's memory, which can be accessed by any state or plugin. Memories are stored in a key-value format, and any marshalable/unmarshalable datatype can be stored and retrieved. Note that Ava's memory is global, peristed across plugins. This enables plugins that subscribe to an agreed-upon memory API to communicate between themselves. Thus, if it's absolutely necessary that no some other plugins modify or access a memory, use a long key unlikely to collide with any other plugin's.

func (*StateMachine) SetOnReset

func (sm *StateMachine) SetOnReset(reset func(in *Msg))

SetOnReset sets the OnReset function for the stateMachine, which should be called from a plugin's Run() function. See plugins/ava_purchase/ava_purchase.go for an example.

func (*StateMachine) SetState

func (sm *StateMachine) SetState(in *Msg, label string) string

SetState jumps from one state to another by its label. It will safely jump forward but NO safety checks are performed on backward jumps. It's therefore up to the developer to ensure that data is still OK when jumping backward. Any forward jump will check the Complete() function of each state and get as close as it can to the desired state as long as each Complete() == true at each state.

func (*StateMachine) SetStates

func (sm *StateMachine) SetStates(sss ...[]State)

SetStates takes [][]State as an argument. Note that it's a slice of a slice, which is used to enable tasks like requesting a user's shipping address, which themselves are []Slice, to be included inline when defining the states of a stateMachine. See plugins/ava_purchase/ava_purchase.go as an example.

func (*StateMachine) State

func (sm *StateMachine) State() int

State returns the current state of a stateMachine. state is an unexported field to protect programmers from directly editing it. While reading state can be done through this function, changing state should happen only through the provided stateMachine API (stateMachine.Next(), stateMachine.SetState()), which allows for safely moving between states.

type TimeRange

type TimeRange struct {
	Start *time.Time
	End   *time.Time
}

TimeRange defines a range of time.

type User

type User struct {
	Name                     string
	Email                    string
	Password                 string // temp storage prior to hashing
	PaymentServiceID         string
	LocationID               int
	ID                       uint64
	AuthorizationID          sql.NullInt64
	LastAuthenticationMethod AuthMethod
	LastAuthenticated        *time.Time
	Admin                    bool

	// Trainer determines whether the user has access to the training
	// interface and will be notified via email when new training is
	// required
	Trainer bool
}

User represents a user, which is usually the user that sent a message to Abot.

func GetUser

func GetUser(db *sqlx.DB, c *echo.Context) (*User, error)

GetUser from an HTTP request.

func (*User) CheckActiveAuthorization

func (u *User) CheckActiveAuthorization(db *sqlx.DB) (bool, error)

CheckActiveAuthorization determines if a message to Ava was fulfilling an authorization request. RequestAuth nulls out the authorizationid once auth has been completed.

func (*User) Create

func (u *User) Create(db *sqlx.DB, fidT FlexIDType, fid string) error

Create a new user in the database.

func (*User) DeleteSessions

func (u *User) DeleteSessions(db *sqlx.DB) error

DeleteSessions removes any open sessions by the user. This enables "logging out" of the web-based client.

func (*User) GetAddress

func (u *User) GetAddress(db *sqlx.DB, text string) (*Address, error)

GetAddress standardizes the name of addresses for faster searching and consistent responses.

func (*User) GetCards

func (u *User) GetCards(db *sqlx.DB) ([]Card, error)

GetCards retrieves credit cards for a specific user.

func (*User) GetEmail

func (u *User) GetEmail() string

GetEmail satisfies the Contactable interface

func (*User) GetName

func (u *User) GetName() string

GetName satisfies the Contactable interface

func (*User) GetPrimaryCard

func (u *User) GetPrimaryCard(db *sqlx.DB) (*Card, error)

GetPrimaryCard retrieves the primary credit card for a specific user.

func (*User) IsAuthenticated

func (u *User) IsAuthenticated(m AuthMethod) (bool, error)

IsAuthenticated confirms that the user is authenticated for a particular AuthMethod.

func (*User) SaveAddress

func (u *User) SaveAddress(db *sqlx.DB, addr *Address) (uint64, error)

SaveAddress of a specific user to the database.

func (*User) UpdateAddressName

func (u *User) UpdateAddressName(db *sqlx.DB, id uint64, name string) (*Address,
	error)

UpdateAddressName such as "home" or "office" when learned.

type Vendor

type Vendor struct {
	ID           uint64
	BusinessName string `sql:"businessname"`
	ContactName  string `sql:"contactname"`
	ContactEmail string `sql:"contactemail"`
}

Vendor represents some seller of a product or service Ava provides that is contactable via email to notify them of a new user purchase or transaction.

func (*Vendor) GetEmail

func (v *Vendor) GetEmail() string

GetEmail satisfies the Contactable interface enabling a vendor to be emailed.

func (*Vendor) GetName

func (v *Vendor) GetName() string

GetName satisfies the Contactable interface enabling a vendor to be emailed.

type Vocab

type Vocab struct {
	Commands map[string]struct{}
	Objects  map[string]struct{}
	// contains filtered or unexported fields
}

Vocab maintains sets of Commands and Objects recognized by plugins as well as the functions to be performed when such Commands or Objects are found.

func NewVocab

func NewVocab(vhs ...VocabHandler) *Vocab

NewVocab returns Vocab with all Commands and Objects stemmed using the Porter2 Snowball algorithm.

func (*Vocab) HandleKeywords

func (v *Vocab) HandleKeywords(m *Msg) string

HandleKeywords is a runs the first matching VocabFn in the sentence. For an example, see github.com/itsabot/plugin_purchase/plugin_purchase.go.

type VocabFn

type VocabFn func(m *Msg, mod int) (response string)

VocabFn is a function run when the user sends a matched vocab word as defined by a plugin. For an example, see github.com/itsabot/plugin_purchase/plugin_purchase.go. The response returned is a user-presentable string from the VocabFn.

type VocabHandler

type VocabHandler struct {
	Fn      VocabFn
	Trigger *nlp.StructuredInput
}

VocabHandler maintains sets of Commands and Objects recognized by plugins as well as the functions to be performed when such Commands or Objects are found.

Jump to

Keyboard shortcuts

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