Documentation
¶
Index ¶
- Variables
- func EmojiToNumber(s string) int
- func ErrToOK(err *error) string
- func GetFeedbackCommandAdvertisement(prefix string) chat1.UserBotCommandInput
- func GetLatestCloudwatchLogs(region string, logGroupName string) ([]string, error)
- func GetOAuthClient(tokenIdentifier string, callbackMsg chat1.MsgSummary, kbc *kbchat.API, ...) (*http.Client, error)
- func GetSession(region string) (sess *session.Session, err error)
- func GoWithRecover(debugOutput *DebugOutput, f func())
- func GoWithRecoverErrGroup(eg *errgroup.Group, debugOutput *DebugOutput, f func() error)
- func HandleNewTeam(stats *StatsRegistry, log *DebugOutput, kbc *kbchat.API, ...) error
- func IdentifierFromMsg(msg chat1.MsgSummary) string
- func IsAtLeastWriter(kbc *kbchat.API, senderUsername string, channel chat1.ChatChannel) (bool, error)
- func IsDeletedConvError(err error) bool
- func IsDirectPrivateMessage(botUsername, senderUsername string, channel chat1.ChatChannel) bool
- func MakeOAuthHTML(botName string, title, msg string, logoURL string) []byte
- func MakeRequestID() (string, error)
- func MakeSecret(repo string, convID chat1.ConvIDStr, secret string) string
- func MsgpackDecode(dst interface{}, src []byte) error
- func MsgpackEncode(src interface{}) ([]byte, error)
- func NumberToEmoji(v int) string
- func PanicRecover(debugOutput *DebugOutput)
- func RandBytes(length int) ([]byte, error)
- func RandHexString(length int) string
- func SendByConvNameOrID(kbc *kbchat.API, debugOutput *DebugOutput, name, msg string, ...) (err error)
- func SplitTokens(cmd string) (tokens []string, userErrorMessage string, err error)
- func URLEncoder() *base64.Encoding
- type AWSOptions
- type BaseOAuthDB
- type ChatDebugOutputConfig
- type DB
- type DebugOutput
- func (d *DebugOutput) ChatDebug(convID chat1.ConvIDStr, msg string, args ...interface{})
- func (d *DebugOutput) ChatEcho(convID chat1.ConvIDStr, msg string, args ...interface{})
- func (d *DebugOutput) ChatErrorf(convID chat1.ConvIDStr, msg string, args ...interface{})
- func (d *DebugOutput) Config() *ChatDebugOutputConfig
- func (d *DebugOutput) Debug(format string, args ...interface{})
- func (d *DebugOutput) Errorf(msg string, args ...interface{})
- func (d *DebugOutput) Report(msg string, args ...interface{})
- func (d *DebugOutput) Trace(err *error, format string, args ...interface{}) func()
- type DummyEmailer
- type DummyStatsBackend
- type Emailer
- type GetOAuthOpts
- type HTTPSrv
- type Handler
- type OAuthDB
- type OAuthHTTPSrv
- type OAuthRequest
- type OAuthRequiredError
- type OAuthStorage
- type Options
- type SESEmailer
- type Server
- func (s *Server) AnnounceAndAdvertise(advert kbchat.Advertisement, running string) (err error)
- func (s *Server) GoWithRecover(eg *errgroup.Group, f func() error)
- func (s *Server) HandleSignals(shutdowners ...Shutdowner) (err error)
- func (s *Server) Listen(handler Handler) (err error)
- func (s *Server) Name() string
- func (s *Server) SetBotAdmins(admins []string)
- func (s *Server) Shutdown() (err error)
- func (s *Server) Start(errReportConv string) (kbc *kbchat.API, err error)
- type ShortID
- type Shutdowner
- type StathatBackend
- type StathatConfig
- type StatsBackend
- type StatsBackendType
- type StatsRegistry
- func (r *StatsRegistry) Count(name string)
- func (r *StatsRegistry) CountMult(name string, count int)
- func (r *StatsRegistry) ResetPrefix() *StatsRegistry
- func (r *StatsRegistry) SetPrefix(prefix string) *StatsRegistry
- func (r *StatsRegistry) Shutdown() (err error)
- func (r *StatsRegistry) Value(name string, value float64)
- func (r *StatsRegistry) ValueInt(name string, value int)
Constants ¶
This section is empty.
Variables ¶
View Source
var DefaultBotAdmins = []string{
"01",
"joshblum",
"marceloneil",
"mikem",
}
View Source
var Images = map[string]string{
"logo": "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",
}
Functions ¶
func EmojiToNumber ¶
func GetFeedbackCommandAdvertisement ¶
func GetFeedbackCommandAdvertisement(prefix string) chat1.UserBotCommandInput
func GetLatestCloudwatchLogs ¶
func GetOAuthClient ¶
func GetOAuthClient( tokenIdentifier string, callbackMsg chat1.MsgSummary, kbc *kbchat.API, config *oauth2.Config, storage OAuthStorage, opts GetOAuthOpts, ) (*http.Client, error)
func GoWithRecover ¶
func GoWithRecover(debugOutput *DebugOutput, f func())
func GoWithRecoverErrGroup ¶
func GoWithRecoverErrGroup(eg *errgroup.Group, debugOutput *DebugOutput, f func() error)
func HandleNewTeam ¶
func HandleNewTeam(stats *StatsRegistry, log *DebugOutput, kbc *kbchat.API, conv chat1.ConvSummary, welcomeMsg string) error
func IdentifierFromMsg ¶
func IdentifierFromMsg(msg chat1.MsgSummary) string
identifierFromMsg returns either the team's name or sender's username, which is used to identify the oauth token. This is so we can have a separate oauth token per team (perhaps with a workplace account) and use a personal account for other events.
func IsAtLeastWriter ¶
func IsDeletedConvError ¶
func IsDirectPrivateMessage ¶
func IsDirectPrivateMessage(botUsername, senderUsername string, channel chat1.ChatChannel) bool
func MakeRequestID ¶
func MakeSecret ¶
Secret token given to API's for authentication (after establishing webhooks) We expect them to return this secret token in webhook POST requests for validation
func MsgpackDecode ¶
func MsgpackEncode ¶
func NumberToEmoji ¶
func PanicRecover ¶
func PanicRecover(debugOutput *DebugOutput)
func RandHexString ¶
func SendByConvNameOrID ¶
func SendByConvNameOrID(kbc *kbchat.API, debugOutput *DebugOutput, name, msg string, args ...interface{}) (err error)
func SplitTokens ¶
func URLEncoder ¶
Types ¶
type AWSOptions ¶
func (*AWSOptions) IsEmpty ¶
func (o *AWSOptions) IsEmpty() bool
type BaseOAuthDB ¶
type BaseOAuthDB struct {
*DB
}
func NewBaseOAuthDB ¶
func NewBaseOAuthDB(db *sql.DB) *BaseOAuthDB
func (*BaseOAuthDB) CompleteState ¶
func (d *BaseOAuthDB) CompleteState(state string) error
func (*BaseOAuthDB) GetState ¶
func (d *BaseOAuthDB) GetState(state string) (*OAuthRequest, error)
func (*BaseOAuthDB) PutState ¶
func (d *BaseOAuthDB) PutState(state string, oauthState *OAuthRequest) error
type ChatDebugOutputConfig ¶
func NewChatDebugOutputConfig ¶
func NewChatDebugOutputConfig(kbc *kbchat.API, errReportConv string) *ChatDebugOutputConfig
type DebugOutput ¶
type DebugOutput struct {
// contains filtered or unexported fields
}
func NewDebugOutput ¶
func NewDebugOutput(name string, config *ChatDebugOutputConfig) *DebugOutput
func (*DebugOutput) ChatDebug ¶
func (d *DebugOutput) ChatDebug(convID chat1.ConvIDStr, msg string, args ...interface{})
func (*DebugOutput) ChatEcho ¶
func (d *DebugOutput) ChatEcho(convID chat1.ConvIDStr, msg string, args ...interface{})
func (*DebugOutput) ChatErrorf ¶
func (d *DebugOutput) ChatErrorf(convID chat1.ConvIDStr, msg string, args ...interface{})
func (*DebugOutput) Config ¶
func (d *DebugOutput) Config() *ChatDebugOutputConfig
func (*DebugOutput) Debug ¶
func (d *DebugOutput) Debug(format string, args ...interface{})
func (*DebugOutput) Errorf ¶
func (d *DebugOutput) Errorf(msg string, args ...interface{})
func (*DebugOutput) Report ¶
func (d *DebugOutput) Report(msg string, args ...interface{})
func (*DebugOutput) Trace ¶
func (d *DebugOutput) Trace(err *error, format string, args ...interface{}) func()
type DummyEmailer ¶
type DummyEmailer struct { }
func (DummyEmailer) Send ¶
func (d DummyEmailer) Send(_, subject, _ string) error
type DummyStatsBackend ¶
type DummyStatsBackend struct {
*DebugOutput
}
func NewDummyStatsBackend ¶
func NewDummyStatsBackend(debugConfig *ChatDebugOutputConfig) *DummyStatsBackend
func (*DummyStatsBackend) Count ¶
func (d *DummyStatsBackend) Count(name string) error
func (*DummyStatsBackend) CountMult ¶
func (d *DummyStatsBackend) CountMult(name string, count int) error
func (*DummyStatsBackend) Shutdown ¶
func (d *DummyStatsBackend) Shutdown() error
type GetOAuthOpts ¶
type GetOAuthOpts struct { // set the OAuth2 OfflineAccessType (default: false) OAuthOfflineAccessType bool // template for the auth message (default: "Visit %s\n to authorize me.") AuthMessageTemplate string // optional callback which constructs and sends auth URL (default: disabled) AuthURLCallback func(authUrl string) error }
type HTTPSrv ¶
type HTTPSrv struct { *DebugOutput Stats *StatsRegistry // contains filtered or unexported fields }
func NewHTTPSrv ¶
func NewHTTPSrv(stats *StatsRegistry, debugConfig *ChatDebugOutputConfig) *HTTPSrv
type Handler ¶
type Handler interface { HandleCommand(chat1.MsgSummary) error HandleNewConv(chat1.ConvSummary) error }
type OAuthHTTPSrv ¶
type OAuthHTTPSrv struct { *HTTPSrv // contains filtered or unexported fields }
func NewOAuthHTTPSrv ¶
func NewOAuthHTTPSrv( stats *StatsRegistry, kbc *kbchat.API, debugConfig *ChatDebugOutputConfig, oauth *oauth2.Config, storage OAuthStorage, callback func(msg chat1.MsgSummary, identifier string) error, htmlTitle string, htmlLogoB64 string, urlPrefix string, ) *OAuthHTTPSrv
type OAuthRequest ¶
type OAuthRequiredError ¶
type OAuthRequiredError struct{}
func (OAuthRequiredError) Error ¶
func (e OAuthRequiredError) Error() string
type OAuthStorage ¶
type OAuthStorage interface { GetToken(identifier string) (*oauth2.Token, error) PutToken(identifier string, token *oauth2.Token) error DeleteToken(identifier string) error GetState(state string) (*OAuthRequest, error) PutState(state string, req *OAuthRequest) error CompleteState(state string) error }
type Options ¶
type Options struct { // Location of the keybase binary KeybaseLocation string // Home directory for keybase service Home string // Conversation name or ID to announce when the bot begins Announcement string // Conversation name or ID to report bot errors to ErrReportConv string // Database Source Name DSN string MultiDSN string StathatEZKey string // Allow the bot to read it's own messages (default: false) ReadSelf bool AWSOpts *AWSOptions }
func NewOptions ¶
func NewOptions() *Options
type SESEmailer ¶
type SESEmailer struct { *DebugOutput // contains filtered or unexported fields }
func NewSESEmailer ¶
func NewSESEmailer(sender, region string, debugConfig *ChatDebugOutputConfig) *SESEmailer
func (*SESEmailer) Send ¶
func (e *SESEmailer) Send(address, subject, message string) error
type Server ¶
type Server struct { *DebugOutput sync.Mutex // contains filtered or unexported fields }
func NewServer ¶
func NewServer( name, announcement string, awsOpts *AWSOptions, multiDBDSN string, readSelf bool, runOptions kbchat.RunOptions, ) *Server
func (*Server) AnnounceAndAdvertise ¶
func (s *Server) AnnounceAndAdvertise(advert kbchat.Advertisement, running string) (err error)
func (*Server) HandleSignals ¶
func (s *Server) HandleSignals(shutdowners ...Shutdowner) (err error)
func (*Server) SetBotAdmins ¶
type Shutdowner ¶
type Shutdowner interface {
Shutdown() error
}
type StathatBackend ¶
type StathatBackend struct {
// contains filtered or unexported fields
}
func (*StathatBackend) Count ¶
func (s *StathatBackend) Count(name string) error
func (*StathatBackend) Shutdown ¶
func (s *StathatBackend) Shutdown() error
type StathatConfig ¶
type StathatConfig struct {
// contains filtered or unexported fields
}
func NewStathatConfig ¶
func NewStathatConfig(ezkey string, shutdownTimeout time.Duration) StathatConfig
type StatsBackend ¶
type StatsBackend interface { Count(name string) error CountMult(name string, count int) error Value(name string, value float64) error Shutdown() error }
func NewStatsBackend ¶
func NewStatsBackend(btype StatsBackendType, config interface{}) (StatsBackend, error)
type StatsBackendType ¶
type StatsBackendType int
const ( StathatStatsBackendType StatsBackendType = iota DummyStatsBackendType )
type StatsRegistry ¶
type StatsRegistry struct { *DebugOutput // contains filtered or unexported fields }
func NewStatsRegistry ¶
func NewStatsRegistry(debugConfig *ChatDebugOutputConfig, stathatEZKey string) (reg *StatsRegistry, err error)
func NewStatsRegistryWithBackend ¶
func NewStatsRegistryWithBackend(debugConfig *ChatDebugOutputConfig, backend StatsBackend) *StatsRegistry
func (*StatsRegistry) Count ¶
func (r *StatsRegistry) Count(name string)
func (*StatsRegistry) CountMult ¶
func (r *StatsRegistry) CountMult(name string, count int)
func (*StatsRegistry) ResetPrefix ¶
func (r *StatsRegistry) ResetPrefix() *StatsRegistry
func (*StatsRegistry) SetPrefix ¶
func (r *StatsRegistry) SetPrefix(prefix string) *StatsRegistry
func (*StatsRegistry) Shutdown ¶
func (r *StatsRegistry) Shutdown() (err error)
func (*StatsRegistry) Value ¶
func (r *StatsRegistry) Value(name string, value float64)
func (*StatsRegistry) ValueInt ¶
func (r *StatsRegistry) ValueInt(name string, value int)
Source Files
¶
Click to show internal directories.
Click to hide internal directories.