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.
229 lines
5.4 KiB
229 lines
5.4 KiB
package main |
|
|
|
import ( |
|
"fmt" |
|
"log" |
|
"os" |
|
"os/signal" |
|
"syscall" |
|
"time" |
|
|
|
"app/cmd" |
|
|
|
"github.com/kf5grd/keybasebot" |
|
"github.com/kf5grd/keybasebot/pkg/kvstore" |
|
"github.com/urfave/cli/v2" |
|
"samhofi.us/x/keybase/v2" |
|
"samhofi.us/x/keybase/v2/types/chat1" |
|
) |
|
|
|
var version string |
|
|
|
func main() { |
|
app := cli.NewApp() |
|
app.Name = "ssh0le" |
|
app.Version = version |
|
app.HideVersion = false |
|
app.Usage = "A general Keybase chat bot" |
|
app.Writer = os.Stdout |
|
app.HideVersion = false |
|
|
|
app.Flags = []cli.Flag{ |
|
&cli.StringFlag{ |
|
Name: "home", |
|
Aliases: []string{"H"}, |
|
Usage: "Keybase Home Folder", |
|
}, |
|
&cli.BoolFlag{ |
|
Name: "debug", |
|
Usage: "Enables debugging", |
|
EnvVars: []string{"BOT_DEBUG"}, |
|
}, |
|
&cli.BoolFlag{ |
|
Name: "json", |
|
Usage: "Enables JSON logging", |
|
EnvVars: []string{"BOT_LOG_JSON"}, |
|
}, |
|
&cli.StringFlag{ |
|
Name: "log-convid", |
|
Usage: "Set the Keybase log conversation id", |
|
EnvVars: []string{"BOT_LOG_CONVID"}, |
|
}, |
|
&cli.StringFlag{ |
|
Name: "reddit-user", |
|
Usage: "Set the Reddit auth user", |
|
EnvVars: []string{"BOT_REDDIT_USER"}, |
|
}, |
|
&cli.StringFlag{ |
|
Name: "reddit-pass", |
|
Usage: "Set the Reddit auth password", |
|
EnvVars: []string{"BOT_REDDIT_PASS"}, |
|
}, |
|
&cli.StringFlag{ |
|
Name: "owner", |
|
Usage: "Set the Keybase username of the bot owner", |
|
EnvVars: []string{"BOT_OWNER"}, |
|
}, |
|
&cli.StringFlag{ |
|
Name: "kvstore-team", |
|
Usage: "Set the kvstore team if you want to save configs", |
|
EnvVars: []string{"BOT_KVSTORE_TEAM"}, |
|
}, |
|
} |
|
|
|
app.Action = run |
|
|
|
if err := app.Run(os.Args); err != nil { |
|
log.Fatal(err) |
|
} |
|
} |
|
|
|
func run(c *cli.Context) error { |
|
b := keybasebot.New("", keybase.SetHomePath(c.String("home"))) |
|
b.Debug = c.Bool("debug") |
|
b.JSON = c.Bool("json") |
|
b.LogWriter = os.Stdout |
|
//b.LogConv = chat1.ConvIDStr(c.String("log-convid")) |
|
// set the bot owner for private commands |
|
if c.String("owner") != "" { |
|
b.Meta["owner"] = c.String("owner") |
|
} |
|
allowedTeams := make(map[chat1.ConvIDStr]bool) |
|
if c.String("kvstore-team") != "" { |
|
b.Meta["kvstore"] = c.String("kvstore-team") |
|
allowedTeams = loadNsfwAllowed(b) |
|
} |
|
// set reddit login, which enables reddit commands |
|
if c.String("reddit-user") != "" && c.String("reddit-pass") != "" { |
|
b.Meta["reddit-user"] = c.String("reddit-user") |
|
b.Meta["reddit-pass"] = c.String("reddit-pass") |
|
} |
|
|
|
// register the bot commands |
|
b.Commands = append(b.Commands, |
|
keybasebot.BotCommand{ |
|
Name: "ping", |
|
Ad: &cmd.PingAd, |
|
AdType: "public", |
|
Run: keybasebot.Adapt( |
|
cmd.SendPong, |
|
keybasebot.MessageType("text"), |
|
keybasebot.CommandPrefix("!ping"), |
|
), |
|
}, |
|
keybasebot.BotCommand{ |
|
Name: "age", |
|
Ad: &cmd.AgeAd, |
|
AdType: "public", |
|
Run: keybasebot.Adapt( |
|
cmd.Age, |
|
keybasebot.MessageType("text"), |
|
keybasebot.CommandPrefix("!age"), |
|
), |
|
}, |
|
keybasebot.BotCommand{ |
|
Name: "convert", |
|
Ad: &cmd.ConvertAd, |
|
AdType: "public", |
|
Run: keybasebot.Adapt( |
|
cmd.Convert, |
|
keybasebot.MessageType("text"), |
|
keybasebot.CommandPrefix("!convert"), |
|
), |
|
}, |
|
keybasebot.BotCommand{ |
|
Name: "price", |
|
Ad: &cmd.PriceAd, |
|
AdType: "public", |
|
Run: keybasebot.Adapt( |
|
cmd.SendPrice, |
|
keybasebot.MessageType("text"), |
|
keybasebot.CommandPrefix("!price"), |
|
), |
|
}, |
|
keybasebot.BotCommand{ |
|
Name: "nsfw", |
|
Ad: &cmd.NsfwAd, |
|
AdType: "teammembers", |
|
AdTeamName: c.String("kvstore-team"), |
|
Run: keybasebot.Adapt( |
|
cmd.SetNsfw, |
|
keybasebot.MessageType("text"), |
|
keybasebot.CommandPrefix("!nsfw"), |
|
keybasebot.FromUser(c.String("owner")), |
|
), |
|
}, |
|
) |
|
// if there are reddit credentials add the reddit commands |
|
if c.String("reddit-user") != "" && c.String("reddit-pass") != "" { |
|
b.Commands = append(b.Commands, |
|
keybasebot.BotCommand{ |
|
Name: "eyebleach", |
|
Ad: &cmd.EyebleachAd, |
|
Run: keybasebot.Adapt( |
|
cmd.Eyebleach, |
|
keybasebot.MessageType("text"), |
|
keybasebot.CommandPrefix("!eyebleach"), |
|
), |
|
}, |
|
keybasebot.BotCommand{ |
|
Name: "boobs", |
|
Ad: nil, // send nil advertisement and send fake per-convid ones later |
|
Run: keybasebot.Adapt( |
|
cmd.Boobs, |
|
keybasebot.MessageType("text"), |
|
keybasebot.CommandPrefix("!boobs"), |
|
nsfwFilter(), |
|
), |
|
}, |
|
) |
|
for convID, allowed := range allowedTeams { |
|
fmt.Printf("loading NSFW conversations\n") |
|
if allowed { |
|
fmt.Printf("NSFW allowed in %s\n", string(convID)) |
|
b.Commands = append(b.Commands, |
|
keybasebot.BotCommand{ |
|
Name: "boobs", |
|
Ad: &cmd.BoobsAd, |
|
AdType: "conv", |
|
AdTeamName: "", |
|
AdConv: convID, |
|
Run: cmd.FakeNsfwAction, |
|
}, |
|
) |
|
} |
|
} |
|
} |
|
|
|
// catch ctrl-c so we can clean up |
|
ch := make(chan os.Signal) |
|
signal.Notify(ch, os.Interrupt, syscall.SIGTERM) |
|
go func() { |
|
<-ch |
|
b.Logger.Info("Caught SIGINT, cleaning up.") |
|
b.KB.ClearCommands() |
|
b.Logger.Info("Cleared command adverts. Bye.") |
|
time.Sleep(time.Second * 2) |
|
os.Exit(0) |
|
}() |
|
// then run |
|
b.Run() |
|
return nil |
|
} |
|
|
|
func loadNsfwAllowed(b *keybasebot.Bot) (allowedTeams map[chat1.ConvIDStr]bool) { |
|
// get the team from meta |
|
data, ok := b.Meta["kvstore"] |
|
if ok { |
|
// make something to fill |
|
team := data.(string) |
|
kvKey := kvstore.New("nsfwAllowed", &allowedTeams, -1) |
|
err := kvstore.Get(b.KB, team, "ssh0le", &kvKey) |
|
if err != nil { |
|
return |
|
} |
|
// set the allowed teams into meta |
|
b.Meta["nsfwAllowed"] = allowedTeams |
|
} |
|
return |
|
}
|
|
|