Matthew Faltys
3 years ago
16 changed files with 41508 additions and 0 deletions
@ -0,0 +1,53 @@ |
|||||||
|
GOC=go build
|
||||||
|
GOFLAGS=-a -ldflags '-s'
|
||||||
|
CGOR=CGO_ENABLED=0
|
||||||
|
IMAGE_NAME=lorebot
|
||||||
|
|
||||||
|
all: lorebot |
||||||
|
|
||||||
|
depends: |
||||||
|
go get github.com/unixvoid/glogger
|
||||||
|
go get gopkg.in/gcfg.v1
|
||||||
|
go get gopkg.in/redis.v5
|
||||||
|
go get github.com/bwmarrin/discordgo
|
||||||
|
|
||||||
|
lorebot: |
||||||
|
$(GOC) lorebot/lorebot.go
|
||||||
|
|
||||||
|
run: |
||||||
|
go run \
|
||||||
|
lorebot/lorebot.go \
|
||||||
|
lorebot/botfunc.go
|
||||||
|
|
||||||
|
stat: |
||||||
|
mkdir -p bin/
|
||||||
|
$(CGOR) $(GOC) -o bin/lorebot $(GOFLAGS) lorebot/*.go
|
||||||
|
|
||||||
|
docker: stat |
||||||
|
mkdir stage.tmp/
|
||||||
|
cp bin/lorebot stage.tmp/
|
||||||
|
cp deps/rootfs.tar.gz stage.tmp/
|
||||||
|
cp deps/Dockerfile stage.tmp/
|
||||||
|
cp deps/redis.conf stage.tmp/
|
||||||
|
chmod +x deps/run.sh
|
||||||
|
cp deps/run.sh stage.tmp/
|
||||||
|
cp -R deps/fortune stage.tmp/
|
||||||
|
cp config.gcfg stage.tmp/
|
||||||
|
cd stage.tmp/ && \
|
||||||
|
sudo docker build -t $(IMAGE_NAME) .
|
||||||
|
@echo "$(IMAGE_NAME) built"
|
||||||
|
|
||||||
|
test_docker: |
||||||
|
mkdir -p /tmp/lorebot/redis/
|
||||||
|
touch /tmp/lorebot/dump.rdb
|
||||||
|
cp .auth /tmp/lorebot/
|
||||||
|
sudo docker run \
|
||||||
|
-it \
|
||||||
|
-v /tmp/lorebot/redis:/redisbackup:rw \
|
||||||
|
-v /tmp/lorebot/.auth:/.auth:ro \
|
||||||
|
$(IMAGE_NAME)
|
||||||
|
|
||||||
|
clean: |
||||||
|
rm -rf bin/
|
||||||
|
rm -rf stage.tmp/
|
||||||
|
rm -rf lorebot.aci
|
@ -0,0 +1,9 @@ |
|||||||
|
[lorebot] |
||||||
|
loglevel = "debug" |
||||||
|
slackdebug = false |
||||||
|
bootstrapdelay = 1 |
||||||
|
AuthFile = ".auth" |
||||||
|
|
||||||
|
[redis] |
||||||
|
host = "127.0.0.1:6379" |
||||||
|
password = "" |
@ -0,0 +1,19 @@ |
|||||||
|
FROM alpine |
||||||
|
|
||||||
|
RUN apk --update add ca-certificates redis fortune |
||||||
|
RUN mkdir /redisbackup/ |
||||||
|
RUN rm -rf /usr/share/fortune |
||||||
|
COPY fortune/ /usr/share/fortune |
||||||
|
WORKDIR /usr/share/fortune/ |
||||||
|
RUN strfile -c % fortunes fortunes.dat |
||||||
|
RUN strfile -c % kenm kenm.dat |
||||||
|
RUN strfile -c % showerthoughts showerthoughts.dat |
||||||
|
|
||||||
|
#ADD rootfs.tar.gz / |
||||||
|
COPY redis.conf / |
||||||
|
COPY config.gcfg / |
||||||
|
COPY lorebot / |
||||||
|
COPY run.sh / |
||||||
|
WORKDIR / |
||||||
|
|
||||||
|
CMD ["/run.sh"] |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,44 @@ |
|||||||
|
{ |
||||||
|
"acKind": "ImageManifest", |
||||||
|
"acVersion": "0.7.1", |
||||||
|
"name": "unixvoid.com/lorebot", |
||||||
|
"labels": [ |
||||||
|
{ |
||||||
|
"name": "version", |
||||||
|
"value": "latest" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"name": "arch", |
||||||
|
"value": "amd64" |
||||||
|
}, |
||||||
|
{ |
||||||
|
"name": "os", |
||||||
|
"value": "linux" |
||||||
|
} |
||||||
|
], |
||||||
|
"app": { |
||||||
|
"user": "root", |
||||||
|
"group": "root", |
||||||
|
"exec": [ |
||||||
|
"/run.sh" |
||||||
|
], |
||||||
|
"mountPoints": [ |
||||||
|
{ |
||||||
|
"name": "redis", |
||||||
|
"path": "/redisbackup/", |
||||||
|
"readOnly": false |
||||||
|
}, |
||||||
|
{ |
||||||
|
"name": "auth", |
||||||
|
"path": "/.auth", |
||||||
|
"readOnly": false |
||||||
|
} |
||||||
|
] |
||||||
|
}, |
||||||
|
"annotations": [ |
||||||
|
{ |
||||||
|
"name": "authors", |
||||||
|
"value": "Matthew Faltys <mfaltys@gmail.com>" |
||||||
|
} |
||||||
|
] |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
daemonize yes |
||||||
|
dbfilename dump.rdb |
||||||
|
dir /redisbackup/ |
||||||
|
save 30 1 |
Binary file not shown.
@ -0,0 +1,5 @@ |
|||||||
|
#!/bin/sh |
||||||
|
|
||||||
|
redis-server /redis.conf |
||||||
|
|
||||||
|
/lorebot $@ |
@ -0,0 +1,8 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
sudo docker run \ |
||||||
|
-d \ |
||||||
|
-v /home/mfaltys/lorebot-data/redis:/redisbackup:rw \ |
||||||
|
-v /home/mfaltys/lorebot-data/.auth:/.auth:ro \ |
||||||
|
--name lorebot \ |
||||||
|
lorebot |
@ -0,0 +1,14 @@ |
|||||||
|
module git.bitnuke.io/mfaltys/lorebot |
||||||
|
|
||||||
|
go 1.17 |
||||||
|
|
||||||
|
require ( |
||||||
|
github.com/bwmarrin/discordgo v0.24.0 // indirect |
||||||
|
github.com/gorilla/websocket v1.4.2 // indirect |
||||||
|
github.com/unixvoid/glogger v0.0.0-20160808141529-efa058094480 // indirect |
||||||
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect |
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect |
||||||
|
gopkg.in/gcfg.v1 v1.2.3 // indirect |
||||||
|
gopkg.in/redis.v5 v5.2.9 // indirect |
||||||
|
gopkg.in/warnings.v0 v0.1.2 // indirect |
||||||
|
) |
@ -0,0 +1,20 @@ |
|||||||
|
github.com/bwmarrin/discordgo v0.24.0 h1:Gw4MYxqHdvhO99A3nXnSLy97z5pmIKHZVJ1JY5ZDPqY= |
||||||
|
github.com/bwmarrin/discordgo v0.24.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= |
||||||
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= |
||||||
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= |
||||||
|
github.com/unixvoid/glogger v0.0.0-20160808141529-efa058094480 h1:v5/8W8Oi7f4DcOSsiJoLGT82Bc5nWFk4YJmu60QDNJw= |
||||||
|
github.com/unixvoid/glogger v0.0.0-20160808141529-efa058094480/go.mod h1:K6t28t5XA5wg9q+wm1+Epl41QOvjLnRnavvNUdQ7FmU= |
||||||
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= |
||||||
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= |
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= |
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= |
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= |
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= |
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
||||||
|
gopkg.in/gcfg.v1 v1.2.3 h1:m8OOJ4ccYHnx2f4gQwpno8nAX5OGOh7RLaaz0pj3Ogs= |
||||||
|
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= |
||||||
|
gopkg.in/redis.v5 v5.2.9 h1:MNZYOLPomQzZMfpN3ZtD1uyJ2IDonTTlxYiV/pEApiw= |
||||||
|
gopkg.in/redis.v5 v5.2.9/go.mod h1:6gtv0/+A4iM08kdRfocWYB3bLX2tebpNtfKlFT6H4mY= |
||||||
|
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= |
||||||
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= |
@ -0,0 +1,111 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"strings" |
||||||
|
"time" |
||||||
|
|
||||||
|
"github.com/unixvoid/glogger" |
||||||
|
"gopkg.in/redis.v5" |
||||||
|
) |
||||||
|
|
||||||
|
func loreQuery(searchTerm string, redisClient *redis.Client) ([]string, error) { |
||||||
|
val, err := redisClient.Sort(searchTerm, redis.Sort{Order: "ALPHA"}).Result() |
||||||
|
if err != nil { |
||||||
|
return nil, errors.New("String not found.") |
||||||
|
} else { |
||||||
|
return val, nil |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func loreCheck(searchTerm, searchType string, redisClient *redis.Client) (string, error) { |
||||||
|
val, err := redisClient.HGet(fmt.Sprintf("%s:%s", searchType, searchTerm), "content").Result() |
||||||
|
if err != nil { |
||||||
|
return "", errors.New("String not found.") |
||||||
|
} else { |
||||||
|
return val, nil |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func loreNewString(nick, newString, newType string, redisClient *redis.Client) error { |
||||||
|
s := strings.SplitN(newString, " ", 2) |
||||||
|
command, content := s[0], []byte(s[1]) |
||||||
|
stripContent := strings.Replace(fmt.Sprintf("%s", content), "<", "", -1) |
||||||
|
stripLinks := strings.Replace(stripContent, ">", "", -1) |
||||||
|
|
||||||
|
// dont allow certain chars
|
||||||
|
if strings.ContainsAny(command, ";:,.'\"!$%^*()/\\") { |
||||||
|
// reject user input, it has unwanted chars
|
||||||
|
return errors.New("error: entry contains unwanted characters") |
||||||
|
} |
||||||
|
|
||||||
|
t := time.Now() |
||||||
|
|
||||||
|
// create a timestamp to use
|
||||||
|
cdate := t.Format("2006-01-02 15:04:05") |
||||||
|
|
||||||
|
// create the redis hash
|
||||||
|
_, err := redisClient.HMSet(fmt.Sprintf("%s:%s", newType, command), map[string]string{ |
||||||
|
"content": stripLinks, |
||||||
|
"cdate": cdate, |
||||||
|
"owner": nick, |
||||||
|
}).Result() |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Println("error setting redis hash") |
||||||
|
return errors.New("error setting redis hash") |
||||||
|
} |
||||||
|
|
||||||
|
// add lore to index
|
||||||
|
err = redisClient.SAdd(fmt.Sprintf("index:%s:added", newType), command).Err() |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Println("error updating redis index") |
||||||
|
return errors.New("error updating redis index") |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func loreRmString(nick, rmString, rmType string, redisClient *redis.Client) error { |
||||||
|
t := time.Now() |
||||||
|
|
||||||
|
// remove redis hash containing lore and metadata
|
||||||
|
redisClient.Del(fmt.Sprintf("%s:%s", rmType, rmString)) |
||||||
|
|
||||||
|
// create a timestamp to use
|
||||||
|
rmdate := t.Format("2006-01-02 15:04:05") |
||||||
|
|
||||||
|
// create the redis hash
|
||||||
|
_, err := redisClient.HMSet(fmt.Sprintf("%s:%s", rmType, rmString), map[string]string{ |
||||||
|
"rmdate": rmdate, |
||||||
|
"rmby": nick, |
||||||
|
}).Result() |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Println("error setting redis hash") |
||||||
|
return errors.New("error setting redis hash") |
||||||
|
} |
||||||
|
|
||||||
|
// add lore to index
|
||||||
|
redisClient.SAdd(fmt.Sprintf("index:%s:removed", rmType), rmString).Err() |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Printf("error removing lore from 'index:%s:removed'\n", rmType) |
||||||
|
} |
||||||
|
|
||||||
|
// remove lore form added index
|
||||||
|
redisClient.SRem(fmt.Sprintf("index:%s:added", rmType), rmString).Err() |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Printf("error removing lore from 'index:%s:added'\n", rmType) |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func loreAttrQuery(queryString, queryType, queryAttr string, redisClient *redis.Client) (string, error) { |
||||||
|
val, err := redisClient.HGet(fmt.Sprintf("%s:%s", queryType, queryAttr), queryString).Result() |
||||||
|
|
||||||
|
if err != nil { |
||||||
|
return "", errors.New("String not found.") |
||||||
|
} else { |
||||||
|
return val, nil |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,746 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"bytes" |
||||||
|
"fmt" |
||||||
|
"io" |
||||||
|
"io/ioutil" |
||||||
|
"math/rand" |
||||||
|
"mime/multipart" |
||||||
|
"net/http" |
||||||
|
"net/textproto" |
||||||
|
"os" |
||||||
|
"os/exec" |
||||||
|
"os/signal" |
||||||
|
"strconv" |
||||||
|
"strings" |
||||||
|
"syscall" |
||||||
|
"time" |
||||||
|
|
||||||
|
"github.com/bwmarrin/discordgo" |
||||||
|
"github.com/unixvoid/glogger" |
||||||
|
"gopkg.in/gcfg.v1" |
||||||
|
"gopkg.in/redis.v5" |
||||||
|
) |
||||||
|
|
||||||
|
type Config struct { |
||||||
|
Lorebot struct { |
||||||
|
Loglevel string |
||||||
|
SlackDebug bool |
||||||
|
BootstrapDelay time.Duration |
||||||
|
AuthFile string |
||||||
|
} |
||||||
|
Redis struct { |
||||||
|
Host string |
||||||
|
Password string |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
var ( |
||||||
|
config = Config{} |
||||||
|
) |
||||||
|
|
||||||
|
func main() { |
||||||
|
// read in config file
|
||||||
|
readConf() |
||||||
|
|
||||||
|
// initialize the logger with the configured loglevel
|
||||||
|
initLogger(config.Lorebot.Loglevel) |
||||||
|
|
||||||
|
// read in creds
|
||||||
|
credentials, _ := ioutil.ReadFile(config.Lorebot.AuthFile) |
||||||
|
lines := strings.Split(string(credentials), "\n") |
||||||
|
auth := lines[0] |
||||||
|
|
||||||
|
// Create a new Discord session using the provided bot token.
|
||||||
|
goBot, err := discordgo.New("Bot " + auth) |
||||||
|
if err != nil { |
||||||
|
fmt.Println("error creating Discord session,", err) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// Register the msgParser func as a callback for message events.
|
||||||
|
goBot.AddHandler(msgParser) |
||||||
|
|
||||||
|
// Open a websocket connection to Discord and begin listening.
|
||||||
|
err = goBot.Open() |
||||||
|
if err != nil { |
||||||
|
fmt.Println("error opening connection,", err) |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// Wait here until CTRL-C or other term signal is received.
|
||||||
|
fmt.Println("Bot is now running. Press CTRL-C to exit.") |
||||||
|
sc := make(chan os.Signal, 1) |
||||||
|
signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill) |
||||||
|
<-sc |
||||||
|
|
||||||
|
// Cleanly close down the Discord session.
|
||||||
|
goBot.Close() |
||||||
|
} |
||||||
|
|
||||||
|
func readConf() { |
||||||
|
// init config file
|
||||||
|
err := gcfg.ReadFileInto(&config, "config.gcfg") |
||||||
|
if err != nil { |
||||||
|
panic(fmt.Sprintf("Could not load config.gcfg, error: %s\n", err)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func initLogger(logLevel string) { |
||||||
|
// init logger
|
||||||
|
if logLevel == "debug" { |
||||||
|
glogger.LogInit(os.Stdout, os.Stdout, os.Stdout, os.Stderr) |
||||||
|
} else if logLevel == "cluster" { |
||||||
|
glogger.LogInit(os.Stdout, os.Stdout, ioutil.Discard, os.Stderr) |
||||||
|
} else if logLevel == "info" { |
||||||
|
glogger.LogInit(os.Stdout, ioutil.Discard, ioutil.Discard, os.Stderr) |
||||||
|
} else { |
||||||
|
glogger.LogInit(ioutil.Discard, ioutil.Discard, ioutil.Discard, os.Stderr) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func initRedisConnection() (*redis.Client, error) { |
||||||
|
// init redis connection
|
||||||
|
redisClient := redis.NewClient(&redis.Options{ |
||||||
|
Addr: config.Redis.Host, |
||||||
|
Password: config.Redis.Password, |
||||||
|
DB: 0, |
||||||
|
}) |
||||||
|
|
||||||
|
_, redisErr := redisClient.Ping().Result() |
||||||
|
return redisClient, redisErr |
||||||
|
} |
||||||
|
|
||||||
|
func msgParser(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
// exit out if its a blank message or gif/photo
|
||||||
|
if len(m.Content) == 0 { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
//// // debug message recieved if its not too long
|
||||||
|
//// glogger.Debug.Printf("length of msg is: %d", len(m.Content))
|
||||||
|
//// if len(m.Content) <= 150 {
|
||||||
|
//// glogger.Debug.Printf("Message recieved: %s\n", m.Content)
|
||||||
|
//// } else {
|
||||||
|
//// glogger.Debug.Printf("Message too big to print\n")
|
||||||
|
//// }
|
||||||
|
|
||||||
|
// Ignore all messages created by the bot itself
|
||||||
|
if m.Author.ID == s.State.User.ID { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
comm := fmt.Sprintf("%c", m.Content[0]) |
||||||
|
//glogger.Debug.Printf("comm var: %s", comm)
|
||||||
|
if comm == "." { |
||||||
|
if strings.Count(m.Content, " ") == 0 { |
||||||
|
// no spaces, its a static command
|
||||||
|
glogger.Debug.Printf("processing static command") |
||||||
|
staticCommandHandler(s, m) |
||||||
|
} else { |
||||||
|
// spaces, its a dynamic command
|
||||||
|
glogger.Debug.Printf("processing dynamic command") |
||||||
|
dynamicCommandHandler(s, m) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// If the message is "ping" reply with "Pong!"
|
||||||
|
if m.Content == "ping" { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "fuck off bloam") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//
|
||||||
|
// static functions
|
||||||
|
//
|
||||||
|
func staticCommandHandler(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
// initialize redis connection
|
||||||
|
redisClient, err := initRedisConnection() |
||||||
|
if err != nil { |
||||||
|
glogger.Debug.Printf("redis conneciton cannot be made, trying again in %d seconds", config.Lorebot.BootstrapDelay) |
||||||
|
time.Sleep(config.Lorebot.BootstrapDelay * time.Second) |
||||||
|
redisClient, err = initRedisConnection() |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Println("redis connection cannot be made.") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
tmpStr := strings.SplitN(m.Content, " ", 2) |
||||||
|
command := tmpStr[0] |
||||||
|
trimmedPrefix := strings.TrimPrefix(command, ".") |
||||||
|
|
||||||
|
switch trimmedPrefix { |
||||||
|
case "help": |
||||||
|
helpMsg(s, m) |
||||||
|
case "help2": |
||||||
|
advancedHelpMsg(s, m) |
||||||
|
case "rng": |
||||||
|
rngHandler(s, m, redisClient) |
||||||
|
case "dubs": |
||||||
|
dubsHandler(s, m, redisClient) |
||||||
|
case "lunch": |
||||||
|
lunchHandler(s, m, redisClient) |
||||||
|
case "brb": |
||||||
|
brbHandler(s, m, redisClient) |
||||||
|
case "roll": |
||||||
|
rollHandler(s, m) |
||||||
|
case "rr": |
||||||
|
rrHandler(s, m) |
||||||
|
case "dice": |
||||||
|
diceRollHandler(s, m) |
||||||
|
case "ceelo": |
||||||
|
ceeloRollHandler(s, m) |
||||||
|
case "fortune": |
||||||
|
fortuneHandler(s, m) |
||||||
|
case "kenm": |
||||||
|
kenmHandler(s, m) |
||||||
|
case "showerthoughts": |
||||||
|
showerthoughtsHandler(s, m) |
||||||
|
case "listen": |
||||||
|
s.ChannelMessageSend(m.ChannelID, "*it's what you hearin*") |
||||||
|
case "lorelist": |
||||||
|
listHandler(redisClient, s, m, "lore", "added") |
||||||
|
case "removedlore": |
||||||
|
listHandler(redisClient, s, m, "lore", "removed") |
||||||
|
case "commandlist": |
||||||
|
listHandler(redisClient, s, m, "command", "added") |
||||||
|
case "removedcommands": |
||||||
|
listHandler(redisClient, s, m, "command", "removed") |
||||||
|
case "lorestatus": |
||||||
|
loreStatus(s, m, redisClient) |
||||||
|
} |
||||||
|
|
||||||
|
// get that dice handler
|
||||||
|
if len(m.Content) >= 2 { |
||||||
|
if strings.Contains(m.Content, ".d") { |
||||||
|
trm := strings.Replace(m.Content, ".d", "", -1) |
||||||
|
|
||||||
|
// check if the rest of the string is an int
|
||||||
|
num, err := strconv.Atoi(trm) |
||||||
|
if err == nil { |
||||||
|
//glogger.Debug.Printf("rolling for %d", num)
|
||||||
|
dHandler(s, m, num) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func helpMsg(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
help1 := "I am the lore archival bot, I support the following commands:\n" + |
||||||
|
"```" + |
||||||
|
".lore: view lore\n" + |
||||||
|
".newlore: add new lore\n" + |
||||||
|
".rmlore: remove lore\n" + |
||||||
|
".lorelist: view lore database\n" + |
||||||
|
".lorestatus: view lore DB status\n" + |
||||||
|
".roll: checkum\n" + |
||||||
|
".rr: its high noon\n" + |
||||||
|
".dice: roll a d6\n" + |
||||||
|
".ceelo: roll a ceelo hand\n" + |
||||||
|
".listen: rip the dawg\n" + |
||||||
|
"use '.help2' to see advanced lookup commands." + |
||||||
|
"```" |
||||||
|
|
||||||
|
s.ChannelMessageSend(m.ChannelID, help1) |
||||||
|
} |
||||||
|
|
||||||
|
func advancedHelpMsg(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
help2 := "```" + |
||||||
|
".created view creation timestamp\n" + |
||||||
|
".owner: who created the lore\n" + |
||||||
|
".removed: view removal timestamp\n" + |
||||||
|
".removedby: who removed the lore\n" + |
||||||
|
".rek: rek someone\n" + |
||||||
|
".rip: f's in the chat\n" + |
||||||
|
".summon: summon someone\n" + |
||||||
|
".gnu: dont forget your freedoms\n" + |
||||||
|
".brb: find Tjance's location" + |
||||||
|
"```" |
||||||
|
|
||||||
|
s.ChannelMessageSend(m.ChannelID, help2) |
||||||
|
} |
||||||
|
|
||||||
|
func rngHandler(s *discordgo.Session, m *discordgo.MessageCreate, redisClient *redis.Client) { |
||||||
|
// aka index:command:added
|
||||||
|
newType := fmt.Sprintf("index:lore:added") |
||||||
|
//command, err := botfunc.Query(newType, redisClient)
|
||||||
|
command, err := loreQuery(newType, redisClient) |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Println(err) |
||||||
|
println(err) |
||||||
|
} |
||||||
|
|
||||||
|
// if the array is empty, exit early
|
||||||
|
if len(command) <= 0 { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// pick a random one
|
||||||
|
rand.Seed(time.Now().UnixNano()) |
||||||
|
rngLore := fmt.Sprint(command[rand.Intn(len(command))]) |
||||||
|
glogger.Debug.Printf("rng lore: %s\n", rngLore) |
||||||
|
|
||||||
|
// get lore content
|
||||||
|
rngContent, err := loreCheck(rngLore, "lore", redisClient) |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Printf("%v\n", err) |
||||||
|
s.ChannelMessageSend(m.ChannelID, "beep boop.. broken bot..") |
||||||
|
return |
||||||
|
} |
||||||
|
glogger.Debug.Printf("rng content: %s\n", rngContent) |
||||||
|
rngMsg := fmt.Sprintf("Random lore: `%s`\n%s", rngLore, rngContent) |
||||||
|
s.ChannelMessageSend(m.ChannelID, rngMsg) |
||||||
|
} |
||||||
|
|
||||||
|
func dubsHandler(s *discordgo.Session, m *discordgo.MessageCreate, redisClient *redis.Client) { |
||||||
|
// aka index:command:added
|
||||||
|
newType := fmt.Sprintf("index:dubs") |
||||||
|
|
||||||
|
command, err := loreQuery(newType, redisClient) |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Println(err) |
||||||
|
} |
||||||
|
|
||||||
|
// if the array is empty, exit early
|
||||||
|
if len(command) <= 0 { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// pick a random one
|
||||||
|
rand.Seed(time.Now().UnixNano()) |
||||||
|
rngDubs := fmt.Sprint(command[rand.Intn(len(command))]) |
||||||
|
s.ChannelMessageSend(m.ChannelID, rngDubs) |
||||||
|
|
||||||
|
// roll after we've proccessed dubs
|
||||||
|
// you already know tho..
|
||||||
|
//re := regexp.MustCompile(`taylor|swift|2725225`)
|
||||||
|
//if re.MatchString(rngDubs) {
|
||||||
|
// rndInt := 1 + rand.Intn(10-1)
|
||||||
|
// rndStr := fmt.Sprintf("%06d", rand.Int63n(1e6))
|
||||||
|
// finStr := fmt.Sprintf("%s%d%d", rndStr, rndInt, rndInt)
|
||||||
|
// rtm.SendMessage(rtm.NewOutgoingMessage(finStr, ev.Channel))
|
||||||
|
//} else {
|
||||||
|
// rollhandler(rtm, ev)
|
||||||
|
//}
|
||||||
|
rollHandler(s, m) |
||||||
|
} |
||||||
|
|
||||||
|
func lunchHandler(s *discordgo.Session, m *discordgo.MessageCreate, redisClient *redis.Client) { |
||||||
|
// aka index:command:added
|
||||||
|
newType := fmt.Sprintf("index:lunch") |
||||||
|
|
||||||
|
command, err := loreQuery(newType, redisClient) |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Println(err) |
||||||
|
} |
||||||
|
|
||||||
|
// if the array is empty, exit early
|
||||||
|
if len(command) <= 0 { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// pick a random one
|
||||||
|
rand.Seed(time.Now().UnixNano()) |
||||||
|
rngDubs := fmt.Sprint(command[rand.Intn(len(command))]) |
||||||
|
s.ChannelMessageSend(m.ChannelID, rngDubs) |
||||||
|
} |
||||||
|
|
||||||
|
func brbHandler(s *discordgo.Session, m *discordgo.MessageCreate, redisClient *redis.Client) { |
||||||
|
// aka index:command:added
|
||||||
|
newType := fmt.Sprintf("index:brb") |
||||||
|
|
||||||
|
command, err := loreQuery(newType, redisClient) |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Println(err) |
||||||
|
} |
||||||
|
|
||||||
|
// if the array is empty, exit early
|
||||||
|
if len(command) <= 0 { |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// pick a random one
|
||||||
|
rand.Seed(time.Now().UnixNano()) |
||||||
|
rngDubs := fmt.Sprint(command[rand.Intn(len(command))]) |
||||||
|
s.ChannelMessageSend(m.ChannelID, rngDubs) |
||||||
|
} |
||||||
|
|
||||||
|
func rollHandler(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
//fmt.Print(rand.Intn(100))
|
||||||
|
rngStr := fmt.Sprintf("%08d", rand.Int63n(1e8)) |
||||||
|
s.ChannelMessageSend(m.ChannelID, rngStr) |
||||||
|
} |
||||||
|
|
||||||
|
func rrHandler(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
dice := []string{"*click*", "*BANG*", "*click*", "*click*", "*click*", "*click*"} |
||||||
|
rand.Seed(time.Now().UnixNano()) |
||||||
|
rndStr := dice[rand.Intn(len(dice)-1)] |
||||||
|
|
||||||
|
s.ChannelMessageSend(m.ChannelID, rndStr) |
||||||
|
} |
||||||
|
|
||||||
|
func diceRollHandler(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
//fmt.Print(rand.Intn(100))
|
||||||
|
rand.Seed(time.Now().UnixNano()) |
||||||
|
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("%d", rand.Intn(6)+1)) |
||||||
|
} |
||||||
|
|
||||||
|
func ceeloRollHandler(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
rand.Seed(time.Now().UnixNano()) |
||||||
|
|
||||||
|
// set condition
|
||||||
|
hand := false |
||||||
|
|
||||||
|
for !hand { |
||||||
|
roll0 := rand.Intn(6) + 1 |
||||||
|
roll1 := rand.Intn(6) + 1 |
||||||
|
roll2 := rand.Intn(6) + 1 |
||||||
|
|
||||||
|
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("%d, %d, %d", roll0, roll1, roll2)) |
||||||
|
|
||||||
|
// check for pair
|
||||||
|
if (roll0 == roll1) || (roll0 == roll2) || (roll1 == roll2) { |
||||||
|
hand = true |
||||||
|
} |
||||||
|
a := fmt.Sprintf("%d%d%d", roll0, roll1, roll2) |
||||||
|
// check for instant win
|
||||||
|
if strings.Contains(a, "4") && strings.Contains(a, "5") && strings.Contains(a, "6") { |
||||||
|
hand = true |
||||||
|
} |
||||||
|
// check for instant loss
|
||||||
|
if strings.Contains(a, "1") && strings.Contains(a, "2") && strings.Contains(a, "3") { |
||||||
|
hand = true |
||||||
|
} |
||||||
|
time.Sleep(1000 * time.Millisecond) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func fortuneHandler(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
fortune, err := exec.Command("fortune", "-e", "fortunes").CombinedOutput() |
||||||
|
if err != nil { |
||||||
|
fmt.Printf("%v\n", err) |
||||||
|
s.ChannelMessageSend(m.ChannelID, "Fortune command is broken, contact HFIC") |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("%s", fortune)) |
||||||
|
} |
||||||
|
|
||||||
|
func kenmHandler(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
fortune, err := exec.Command("fortune", "-e", "kenm").CombinedOutput() |
||||||
|
if err != nil { |
||||||
|
fmt.Printf("%v\n", err) |
||||||
|
s.ChannelMessageSend(m.ChannelID, "kenm command is broken, contact HFIC") |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("%s", fortune)) |
||||||
|
} |
||||||
|
|
||||||
|
func showerthoughtsHandler(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
fortune, err := exec.Command("fortune", "-e", "showerthoughts").CombinedOutput() |
||||||
|
if err != nil { |
||||||
|
fmt.Printf("%v\n", err) |
||||||
|
s.ChannelMessageSend(m.ChannelID, "showerthoughts command is broken, contact HFIC") |
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("%s", fortune)) |
||||||
|
} |
||||||
|
|
||||||
|
func listHandler(redisClient *redis.Client, s *discordgo.Session, m *discordgo.MessageCreate, listType, listAttr string) { |
||||||
|
// aka index:command:added
|
||||||
|
newType := fmt.Sprintf("%s:%s:%s", "index", listType, listAttr) |
||||||
|
//command, err := botfunc.Query(newType, redisClient)
|
||||||
|
command, err := loreQuery(newType, redisClient) |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Println(err) |
||||||
|
println(err) |
||||||
|
} |
||||||
|
fCommand := strings.Join(command, "\n") |
||||||
|
|
||||||
|
// initialize buffer
|
||||||
|
bodyBuf := &bytes.Buffer{} |
||||||
|
bodyWriter := multipart.NewWriter(bodyBuf) |
||||||
|
// create header and body. filename must be set
|
||||||
|
mh := make(textproto.MIMEHeader) |
||||||
|
mh.Set("Content-Type", "application/octet-stream") |
||||||
|
mh.Set("Content-Disposition", "form-data; name=\"file\"; filename=\" \"") |
||||||
|
// write body with mime header
|
||||||
|
partWriter, _ := bodyWriter.CreatePart(mh) |
||||||
|
io.Copy(partWriter, bytes.NewBufferString(fCommand)) |
||||||
|
contentType := bodyWriter.FormDataContentType() |
||||||
|
bodyWriter.Close() |
||||||
|
// set content type to multipart/form-data, required for bitnuke.io
|
||||||
|
h := make(textproto.MIMEHeader) |
||||||
|
h.Set("Content-Type", "multipart/form-data") |
||||||
|
bodyWriter.CreatePart(h) |
||||||
|
bodyWriter.Close() |
||||||
|
|
||||||
|
// POST to bitnuke.io
|
||||||
|
resp, err := http.Post("https://bitnuke.io/upload", contentType, bodyBuf) |
||||||
|
if err != nil { |
||||||
|
println(err) |
||||||
|
} |
||||||
|
defer resp.Body.Close() |
||||||
|
resp_body, err := ioutil.ReadAll(resp.Body) |
||||||
|
if err != nil { |
||||||
|
println(err) |
||||||
|
} |
||||||
|
// format response to be link
|
||||||
|
fResponse := fmt.Sprintf("https://bitnuke.io/%s", resp_body[:]) |
||||||
|
// print to channel
|
||||||
|
//rtm.SendMessage(rtm.NewOutgoingMessage(fResponse, ev.Channel))
|
||||||
|
s.ChannelMessageSend(m.ChannelID, fResponse) |
||||||
|
} |
||||||
|
|
||||||
|
func loreStatus(s *discordgo.Session, m *discordgo.MessageCreate, redisClient *redis.Client) { |
||||||
|
command, _ := loreQuery("index:lore:added", redisClient) |
||||||
|
loreammount := len(command) |
||||||
|
status := fmt.Sprintf("the lore db has %d entries", loreammount) |
||||||
|
s.ChannelMessageSend(m.ChannelID, status) |
||||||
|
} |
||||||
|
|
||||||
|
//
|
||||||
|
// dynamic functions
|
||||||
|
//
|
||||||
|
func dynamicCommandHandler(s *discordgo.Session, m *discordgo.MessageCreate) { |
||||||
|
// initialize redis connection
|
||||||
|
redisClient, err := initRedisConnection() |
||||||
|
if err != nil { |
||||||
|
glogger.Debug.Printf("redis conneciton cannot be made, trying again in %d seconds", config.Lorebot.BootstrapDelay) |
||||||
|
time.Sleep(config.Lorebot.BootstrapDelay * time.Second) |
||||||
|
redisClient, err = initRedisConnection() |
||||||
|
if err != nil { |
||||||
|
glogger.Error.Println("redis connection cannot be made.") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
message := m.Content |
||||||
|
if strings.Count(message, " ") < 1 { |
||||||
|
glogger.Debug.Println("not proper syntax") |
||||||
|
} |
||||||
|
|
||||||
|
// verify syntax
|
||||||
|
tmpStr := strings.SplitN(message, " ", 2) |
||||||
|
command, content := tmpStr[0], tmpStr[1] |
||||||
|
trimmedPrefix := strings.TrimPrefix(command, ".") |
||||||
|
|
||||||
|
switch trimmedPrefix { |
||||||
|
case "lore": |
||||||
|
tmp := strings.SplitN(string(m.Content), " ", 2) |
||||||
|
contentHandler(s, m, tmp[1], "lore", redisClient) |
||||||
|
case "newlore": |
||||||
|
if strings.Contains(content, " ") { |
||||||
|
newHandler(s, m, content, "lore", redisClient) |
||||||
|
} else { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "not proper syntax") |
||||||
|
return |
||||||
|
} |
||||||
|
case "newdubs": |
||||||
|
tmp := strings.SplitN(string(m.Content), " ", 2) |
||||||
|
newDubsHandler(s, m, tmp[1], redisClient) |
||||||
|
case "rmdubs": |
||||||
|
tmp := strings.SplitN(string(m.Content), " ", 2) |
||||||
|
rmDubsHandler(s, m, tmp[1], redisClient) |
||||||
|
case "newlunch": |
||||||
|
tmp := strings.SplitN(string(m.Content), " ", 2) |
||||||
|
newLunchHandler(s, m, tmp[1], redisClient) |
||||||
|
case "rmlunch": |
||||||
|
tmp := strings.SplitN(string(m.Content), " ", 2) |
||||||
|
rmLunchHandler(s, m, tmp[1], redisClient) |
||||||
|
case "newbrb": |
||||||
|
tmp := strings.SplitN(string(m.Content), " ", 2) |
||||||
|
newBrbHandler(s, m, tmp[1], redisClient) |
||||||
|
case "rmbrb": |
||||||
|
tmp := strings.SplitN(string(m.Content), " ", 2) |
||||||
|
rmBrbHandler(s, m, tmp[1], redisClient) |
||||||
|
case "rmlore": |
||||||
|
rmHandler(s, m, content, "lore", redisClient) |
||||||
|
case "rek": |
||||||
|
tmp := strings.SplitN(string(m.Content), " ", 2) |
||||||
|
rekHandler(s, m, tmp[1], redisClient) |
||||||
|
case "rip": |
||||||
|
tmp := strings.SplitN(string(m.Content), " ", 2) |
||||||
|
ripHandler(s, m, tmp[1]) |
||||||
|
case "summon": |
||||||
|
tmp := strings.SplitN(string(m.Content), " ", 2) |
||||||
|
summonHandler(s, m, tmp[1]) |
||||||
|
case "gnu": |
||||||
|
tmp := strings.SplitN(string(m.Content), " ", 2) |
||||||
|
gnuHandler(s, m, tmp[1]) |
||||||
|
case "created": |
||||||
|
attrHandler(s, m, "lore", content, "cdate", redisClient) |
||||||
|
case "owner": |
||||||
|
attrHandler(s, m, "lore", content, "owner", redisClient) |
||||||
|
case "removedby": |
||||||
|
attrHandler(s, m, "lore", content, "rmby", redisClient) |
||||||
|
case "removed": |
||||||
|
attrHandler(s, m, "lore", content, "rmdate", redisClient) |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func contentHandler(s *discordgo.Session, m *discordgo.MessageCreate, message, queryType string, redisClient *redis.Client) { |
||||||
|
loreTerm := strings.Replace(message, ".lore", "", -1) |
||||||
|
glogger.Debug.Printf("searching for: %s\n", loreTerm) |
||||||
|
|
||||||
|
content, err := loreCheck(loreTerm, queryType, redisClient) |
||||||
|
if err == nil { |
||||||
|
// lore found, print it
|
||||||
|
s.ChannelMessageSend(m.ChannelID, content) |
||||||
|
} else { |
||||||
|
// lore not found, print error
|
||||||
|
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("lore '%s' not found\n", loreTerm)) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func newHandler(s *discordgo.Session, m *discordgo.MessageCreate, message, newType string, redisClient *redis.Client) { |
||||||
|
// get nick from slack api
|
||||||
|
nick := m.Author.Username |
||||||
|
|
||||||
|
err := loreNewString(nick, message, newType, redisClient) |
||||||
|
if err == nil { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "entry created") |
||||||
|
} else { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "entry could not be created") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func newDubsHandler(s *discordgo.Session, m *discordgo.MessageCreate, newContent string, redisClient *redis.Client) { |
||||||
|
// prep content for dubsification
|
||||||
|
// aka remove the '<' and '>' that slack adds
|
||||||
|
newContent = strings.Replace(newContent, "<", "", -1) |
||||||
|
newContent = strings.Replace(newContent, ">", "", -1) |
||||||
|
|
||||||
|
err := redisClient.SAdd("index:dubs", newContent) |
||||||
|
if err != nil { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "dubs checked") |
||||||
|
} else { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "dubs check failed") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func rmDubsHandler(s *discordgo.Session, m *discordgo.MessageCreate, rmContent string, redisClient *redis.Client) { |
||||||
|
// prep content for dubs removal
|
||||||
|
// aka remove the '<' and '>' that slack adds
|
||||||
|
rmContent = strings.Replace(rmContent, "<", "", -1) |
||||||
|
rmContent = strings.Replace(rmContent, ">", "", -1) |
||||||
|
|
||||||
|
err := redisClient.SRem("index:dubs", rmContent) |
||||||
|
if err != nil { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "dubs unchecked") |
||||||
|
} else { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "dubs check failed") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func newLunchHandler(s *discordgo.Session, m *discordgo.MessageCreate, newContent string, redisClient *redis.Client) { |
||||||
|
// prep content for lunchification
|
||||||
|
// aka remove the '<' and '>' that slack adds
|
||||||
|
newContent = strings.Replace(newContent, "<", "", -1) |
||||||
|
newContent = strings.Replace(newContent, ">", "", -1) |
||||||
|
|
||||||
|
err := redisClient.SAdd("index:lunch", newContent) |
||||||
|
if err != nil { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "lunch location added") |
||||||
|
} else { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "lunch location addition failed") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func rmLunchHandler(s *discordgo.Session, m *discordgo.MessageCreate, rmContent string, redisClient *redis.Client) { |
||||||
|
// prep content for lunch removal
|
||||||
|
// aka remove the '<' and '>' that slack adds
|
||||||
|
rmContent = strings.Replace(rmContent, "<", "", -1) |
||||||
|
rmContent = strings.Replace(rmContent, ">", "", -1) |
||||||
|
|
||||||
|
err := redisClient.SRem("index:lunch", rmContent) |
||||||
|
if err != nil { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "lunch location removed") |
||||||
|
} else { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "lunch location removal failed") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func newBrbHandler(s *discordgo.Session, m *discordgo.MessageCreate, newContent string, redisClient *redis.Client) { |
||||||
|
// prep content for brbification
|
||||||
|
// aka remove the '<' and '>' that slack adds
|
||||||
|
newContent = strings.Replace(newContent, "<", "", -1) |
||||||
|
newContent = strings.Replace(newContent, ">", "", -1) |
||||||
|
|
||||||
|
err := redisClient.SAdd("index:brb", newContent) |
||||||
|
if err != nil { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "tjancism added") |
||||||
|
} else { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "tjancism addition failed") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func rmBrbHandler(s *discordgo.Session, m *discordgo.MessageCreate, rmContent string, redisClient *redis.Client) { |
||||||
|
// prep content for brb removal
|
||||||
|
// aka remove the '<' and '>' that slack adds
|
||||||
|
rmContent = strings.Replace(rmContent, "<", "", -1) |
||||||
|
rmContent = strings.Replace(rmContent, ">", "", -1) |
||||||
|
|
||||||
|
err := redisClient.SRem("index:brb", rmContent) |
||||||
|
if err != nil { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "tjancism removed") |
||||||
|
} else { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "tjancism removal failed") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func rmHandler(s *discordgo.Session, m *discordgo.MessageCreate, message, rmType string, redisClient *redis.Client) { |
||||||
|
nick := m.Author.Username |
||||||
|
|
||||||
|
err := loreRmString(nick, message, rmType, redisClient) |
||||||
|
if err == nil { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "entry removed") |
||||||
|
} else { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "entry could not be removed") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func rekHandler(s *discordgo.Session, m *discordgo.MessageCreate, target string, redisClient *redis.Client) { |
||||||
|
rektBit, _ := redisClient.SRandMember("index:rekt").Result() |
||||||
|
rekFmt := fmt.Sprintf("%s %s", target, rektBit) |
||||||
|
s.ChannelMessageSend(m.ChannelID, rekFmt) |
||||||
|
} |
||||||
|
|
||||||
|
func ripHandler(s *discordgo.Session, m *discordgo.MessageCreate, target string) { |
||||||
|
// create a timestamp to use
|
||||||
|
t := time.Now() |
||||||
|
tstamp := t.Format("01-02-2006") |
||||||
|
ripFmt := fmt.Sprintf("here lies %s, disrespected to death %s..", target, tstamp) |
||||||
|
s.ChannelMessageSend(m.ChannelID, ripFmt) |
||||||
|
} |
||||||
|
|
||||||
|
func summonHandler(s *discordgo.Session, m *discordgo.MessageCreate, target string) { |
||||||
|
sumFmt := fmt.Sprintf("つ◕_◕)つ %s つ◕_◕)つ", target) |
||||||
|
s.ChannelMessageSend(m.ChannelID, sumFmt) |
||||||
|
} |
||||||
|
|
||||||
|
func gnuHandler(s *discordgo.Session, m *discordgo.MessageCreate, target string) { |
||||||
|
gnuFmt := fmt.Sprintf("slaps the nonfree software out of %s's hands", target) |
||||||
|
s.ChannelMessageSend(m.ChannelID, gnuFmt) |
||||||
|
} |
||||||
|
|
||||||
|
func attrHandler(s *discordgo.Session, m *discordgo.MessageCreate, queryType, queryAttr, message string, redisClient *redis.Client) { |
||||||
|
query, err := loreAttrQuery(message, queryType, queryAttr, redisClient) |
||||||
|
if err == nil { |
||||||
|
s.ChannelMessageSend(m.ChannelID, query) |
||||||
|
} else { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "attribute does not exist") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func dHandler(s *discordgo.Session, m *discordgo.MessageCreate, num int) { |
||||||
|
if (num > 0) && (num < 99999999) { |
||||||
|
rand.Seed(time.Now().UnixNano()) |
||||||
|
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("%d", rand.Intn(num)+1)) |
||||||
|
} else { |
||||||
|
s.ChannelMessageSend(m.ChannelID, "na fam, we need a different number. stay lit tho") |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,72 @@ |
|||||||
|
# Lorebot |
||||||
|
This is the bot running over at the sampled slack. |
||||||
|
|
||||||
|
## Commands |
||||||
|
### 2 parameters |
||||||
|
* `lore`: get a specific lore |
||||||
|
* `rip`: rest in piece a target |
||||||
|
* `summon`: summon the specified target |
||||||
|
* `gnu`: educate the target on freedoms |
||||||
|
* `newdubs`: add a new dubs image |
||||||
|
* `rmdubs`: remove an existing dubs image |
||||||
|
* `created`: lookup when lore was created (some old lore wont have this field) |
||||||
|
* `owner`: lookup who created a lore (some old lore wont have this field) |
||||||
|
* `removedby`: lookup who removed a lore |
||||||
|
* `removed`: lookup when lore was removed |
||||||
|
|
||||||
|
### 1 parameter |
||||||
|
* `help`: display help message 1 |
||||||
|
* `help2`: display help message 2 |
||||||
|
* `rng`: display random lore with the new rng algorithm |
||||||
|
* `depricatedrng`: select random lore with the old rng algorithm |
||||||
|
* `roll`: generate a random 8 digit integer |
||||||
|
* `d20`: roll a 20 sided die |
||||||
|
* `rr`: play russian roulette |
||||||
|
* `dice`: roll a 6 sided die |
||||||
|
* `dubs`: pick a random 'dubs checkum' image and roll |
||||||
|
* `listen`: its what you hearin |
||||||
|
* `lorelist`: generate a list of all lore |
||||||
|
* `removedlore`: generate a list of removed lore |
||||||
|
* `lorestatus`: display the number of active lore |
||||||
|
|
||||||
|
|
||||||
|
## Building |
||||||
|
This project makes use of the `make` command. The following commands are supported. |
||||||
|
|
||||||
|
* `all`: dynamically compiles/builds the bot. outputs binary file to `bin/` |
||||||
|
* `run`: runs the bot |
||||||
|
* `stat`: statically compiles/builds the bot. outputs binary file to `bin/` |
||||||
|
* `docker`: builds a docker image |
||||||
|
* `aci`: builds an ACI image |
||||||
|
* `test_docker`: tests the docker image |
||||||
|
* `test_aci`: tests the ACI image |
||||||
|
* `clean`: cleans the project directory of any temp files |
||||||
|
|
||||||
|
## Configuration |
||||||
|
This bot takes advantage of the gcfg configuration which follows the INI |
||||||
|
syntax. |
||||||
|
|
||||||
|
`config.gcfg` |
||||||
|
``` |
||||||
|
[lorebot] |
||||||
|
loglevel = "debug" |
||||||
|
slackdebug = false |
||||||
|
bootstrapdelay = 1 |
||||||
|
AuthFile = ".auth" |
||||||
|
|
||||||
|
[redis] |
||||||
|
host = "127.0.0.1:6379" |
||||||
|
password = "" |
||||||
|
``` |
||||||
|
* `loglevel`: loglevel for the app (debug/info/error) |
||||||
|
* `slackdebug`: wheather or not to show slacks API debugging |
||||||
|
* `bootstrapdeplay`: number in seconds to delay binding the bot to redis (useful in containers) |
||||||
|
* `AuthFile`: name/location of file containing the slack key |
||||||
|
* `host`: location of the redis server |
||||||
|
* `password`: password of the redis server |
||||||
|
|
||||||
|
`.auth` |
||||||
|
``` |
||||||
|
xoxb-86456556-IJDJksfkejsjdfj |
||||||
|
``` |
||||||
|
this is a key generated by slack for the bot |
Loading…
Reference in new issue