You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

129 lines
3.4 KiB

package main
import (
"fmt"
"log"
"os"
"github.com/teris-io/shortid"
"samhofi.us/x/keybase/v2"
"samhofi.us/x/keybase/v2/types/chat1"
"samhofi.us/x/keybase/v2/types/stellar1"
)
// Bot holds the necessary information for the bot to work.
type bot struct {
k *keybase.Keybase
handlers keybase.Handlers
opts keybase.RunOptions
payments map[stellar1.PaymentID]botReply
config botConfig
}
// this allows you to change the command the bot listens to (in additon to its username)
func (b *bot) cmd() string {
return "jitsi"
}
// botConfig hold env and cli flags and options
// fields must be exported for package env (reflect) to work
type botConfig struct {
Debug bool `env:"BOT_DEBUG" envDefault:"false"`
LogConvIDStr string `env:"BOT_LOG_CONVID" envDefault:""`
FeedbackConvIDStr string `env:"BOT_FEEDBACK_CONVID" envDefault:""`
FeedbackTeamAdvert string `env:"BOT_FEEDBACK_TEAM_ADVERT" envDefault:""`
KVStoreTeam string `env:"BOT_KVSTORE_TEAM" envDefault:""`
}
// debug provides printing only when --debug flag is set or BOT_DEBUG env var is set
func (b *bot) debug(s string, a ...interface{}) {
if b.config.Debug {
b.log(s, a...)
}
}
// logError generates an error id and returns it for error reporting, and writes the error to logging locations
func (b *bot) logError(err error) string {
// generate the error id
eid := shortid.MustGenerate()
// send the error to the log
b.log("`%s` - %s", eid, err)
// then return the error id for use
return eid
}
// logToChat will send this message to the keybase chat configured in b.config.LogConvIDStr
func (b *bot) log(s string, a ...interface{}) {
// if the ConvIdStr isn't blank try to log to chat
if b.config.LogConvIDStr != "" {
// if you can't send the message, log the error to stdout
if _, err := b.k.SendMessageByConvID(chat1.ConvIDStr(b.config.LogConvIDStr), s, a...); err != nil {
log.Printf("Unable to log to keybase chat: %s", err)
}
}
// and then log it to stdout
log.Printf(s, a...)
}
// newBot returns a new empty bot
func newBot() *bot {
var b bot
b.k = keybase.NewKeybase()
b.handlers = keybase.Handlers{}
b.opts = keybase.RunOptions{}
b.payments = make(map[stellar1.PaymentID]botReply)
return &b
}
// this handles setting up command advertisements and aliases
func (b *bot) registerCommands() {
opts := keybase.AdvertiseCommandsOptions{
Alias: "Jitsi Meet",
Advertisements: []chat1.AdvertiseCommandAPIParam{
{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "jitsi",
Description: "Starts a meet.jit.si meeting",
Usage: "",
},
{
Name: fmt.Sprintf("%s feedback", b.k.Username),
Description: "Tell us how we're doing!",
Usage: "",
ExtendedDescription: getFeedbackExtendedDescription(b.config),
},
},
},
},
}
b.k.AdvertiseCommands(opts)
}
// run performs a proxy main function
func (b *bot) run(args []string) error {
// parse the arguments
err := b.parseArgs(args)
if err != nil {
return err
}
b.registerHandlers()
// clear the commands and advertise the new commands
b.k.ClearCommands()
b.registerCommands()
log.Println("Starting...")
b.k.Run(b.handlers, &b.opts)
return nil
}
// main is a thin skeleton, proxied to Bot.Run()
func main() {
b := newBot()
if err := b.run(os.Args); err != nil {
log.Printf("%s", err)
os.Exit(1)
}
}