Merge branch 'dev' of pocketjawa/discord-pocketbot-go into master

Version 1.0
master v1.0
pocketjawa 2020-05-21 02:44:30 +00:00 committed by Gogs
commit 47e23e8a0a
6 changed files with 380 additions and 0 deletions

20
.drone.yml Normal file
View File

@ -0,0 +1,20 @@
kind: pipeline
name: default
workspace:
base: /go
path: src/discord-pocketbot-go
steps:
- name: test
image: golang
commands:
- go get
- go build
- name: docker
image: plugins/docker
settings:
repo: pocketjawa/discord-pocketbot
auto_tag: true
username:
from_secret: docker_username
password:
from_secret: docker_password

26
.gitignore vendored Normal file
View File

@ -0,0 +1,26 @@
# ---> Go
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof

11
Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM golang:latest AS build
WORKDIR /go/src/discord-pocketbot
COPY . .
RUN go get -d -v ./...
RUN CGO_ENABLED=0 GOOS=linux go install -v ./...
FROM alpine:latest
run apk add --no-cache ca-certificates
WORKDIR /app
COPY --from=build /go/bin/discord-pocketbot discord-pocketbot
CMD ./discord-pocketbot

225
commands.go Normal file
View File

@ -0,0 +1,225 @@
package main
import (
"context"
"encoding/json"
"github.com/bwmarrin/discordgo"
"github.com/bwmarrin/disgord/x/mux"
"github.com/nishanths/go-xkcd"
"io/ioutil"
"log"
"math/rand"
"net/http"
"os"
"regexp"
"strconv"
"strings"
)
//Check member roles
func checkRole(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context, roleid string) bool {
if ctx.IsPrivate {
return false
}
channel, _ := s.Channel(m.ChannelID)
guild := channel.GuildID
member, _ := s.GuildMember(guild, m.Author.ID)
for _, role := range member.Roles {
if role == roleid {
return true
}
}
return false
}
//Generate a heckin swear word
func getSwear(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context) {
resp := ""
swear, err := http.Get("https://swear.jawa.moe/")
if err != nil {
resp = "Error fetching swear: " + err.Error()
}
defer swear.Body.Close()
if swear.StatusCode == http.StatusOK {
body, err := ioutil.ReadAll(swear.Body)
if err != nil {
resp = "Error fetching swear: " + err.Error()
}
resp = string(body)
}
s.ChannelMessageSend(m.ChannelID, resp)
}
//Post the Maki Monday pic!
func makiMonday(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context) {
resp := "https://maki.jawa.moe/monday.png"
s.ChannelMessageSend(m.ChannelID, resp)
}
//Post link to mixes B)
func postMixes(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context) {
resp := "https://maki.jawa.moe/mixes/"
s.ChannelMessageSend(m.ChannelID, resp)
}
//Post a link to a random mix
func getRandomMix(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context) {
//Define mix details
type Mix struct {
Name string `json:"name"`
Type string `json:"type"`
Mtime string `json:"mtime"`
Size int `json:"size"`
}
mixresp, err := http.Get("https://maki.jawa.moe/mixesjson/")
if err != nil {
resp := "Error fetching mixes: " + err.Error()
s.ChannelMessageSend(m.ChannelID, resp)
return
}
defer mixresp.Body.Close()
if mixresp.StatusCode == http.StatusOK {
var mixes []*Mix
err = json.NewDecoder(mixresp.Body).Decode(&mixes)
rmix := mixes[rand.Intn(len(mixes))]
resp := "https://maki.jawa.moe/mixes/" + rmix.Name
s.ChannelMessageSend(m.ChannelID, resp)
}
}
//Post XKCD comic!
func getXKCD(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context) {
resp := ""
xkclient := xkcd.NewClient()
var err error
var comic xkcd.Comic
var arg string
if len(ctx.Fields) > 1 {
arg = ctx.Fields[1]
} else {
arg = "random"
}
matchedNum, _ := regexp.MatchString(`^[0-9]+$`, arg)
if arg == "latest" {
comic, err = xkclient.Latest(context.Background())
} else if matchedNum {
comicNum, _ := strconv.Atoi(arg)
comic, err = xkclient.Get(context.Background(), comicNum)
} else {
latestcomic, _ := xkclient.Latest(context.Background())
randcomic := rand.Intn(latestcomic.Number)
comic, err = xkclient.Get(context.Background(), randcomic)
}
if err != nil {
resp = err.Error()
}
resp = comic.ImageURL
s.ChannelMessageSend(m.ChannelID, resp)
}
//Restart the bot
func restartBot(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context) {
if !checkRole(s, m, ctx, bot_admin_role) {
resp := "OwO you aren't my daddy..."
s.ChannelMessageSend(m.ChannelID, resp)
return
}
resp := "Goodnight ;-;"
s.ChannelMessageSend(m.ChannelID, resp)
Session.Close()
log.Println("brb dying at the request of ", m.Author.String())
os.Exit(0)
}
//Morgana yells at you to sleep...
func goToSleep(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context) {
embed := &discordgo.MessageEmbed{
Description: "Aren't you tired?\nLet's call it a day\nand get some sleep.",
Thumbnail: &discordgo.MessageEmbedThumbnail{
URL: "https://cdn.discordapp.com/emojis/396429379686629378.png",
},
Title: "Morgana",
}
s.ChannelMessageSendEmbed(m.ChannelID, embed)
}
func setNowPlaying(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context) {
if !checkRole(s, m, ctx, bot_admin_role) {
resp := "OwO you aren't my daddy..."
s.ChannelMessageSend(m.ChannelID, resp)
return
}
var resp string
if len(ctx.Fields) > 1 {
arg := strings.Join(ctx.Fields[1:], " ")
s.UpdateStatus(0, arg)
resp = "Now playing: " + arg
} else {
resp = "Please tell me what to play!"
}
s.ChannelMessageSend(m.ChannelID, resp)
}
//Roll any number of dice of the same kind
func diceRoller(dienum, diesides int) (total int, diceroles []string) {
for 0 < dienum {
dienum--
rollresult := rand.Intn(diesides) + 1
total += rollresult
diceroles = append(diceroles, "D"+strconv.Itoa(diesides)+": **"+strconv.Itoa(rollresult)+"**")
}
return
}
//Dice rolling command
func rollDice(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context) {
var resp string
var diceroles []string
var dicetotal int
var matchDicePattern = regexp.MustCompile(`^[0-9]*[Dd][1-9][0-9]*$`)
var args = ctx.Fields[1:]
for i := range args {
if matchDicePattern.MatchString(args[i]) {
dLocation := strings.Index(strings.ToLower(args[i]), "d")
dienum, _ := strconv.Atoi(args[i][:dLocation])
diesides, _ := strconv.Atoi(args[i][dLocation+1:])
if dienum == 0 {
dienum = 1
}
resultsTotal, resultsRolls := diceRoller(dienum, diesides)
if dienum > 25 {
diceroles = append(diceroles, strconv.Itoa(dienum)+"*D"+strconv.Itoa(diesides)+": **"+strconv.Itoa(resultsTotal)+"**")
} else {
diceroles = append(diceroles, resultsRolls...)
}
dicetotal += resultsTotal
}
}
results := strings.Join(diceroles, ", ")
resp = m.Author.Username + " rolled " + results + ", for a total of **" + strconv.Itoa(dicetotal) + "**!"
if dicetotal == 0 {
resp = "Oops, looks like no dice were rolled! Try something like `!roll d20`, `!roll 2d6`, or `!roll 3d6 d20` instead."
}
s.ChannelMessageSend(m.ChannelID, resp)
}
//Ask the Magic Conch shell to predict the future!
func askConch(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context) {
var resp string
if len(ctx.Fields) > 1 {
conchResponses := []string{"It is certain", "It is decidedly so", "Without a doubt", "Yes definitely", "You may rely on it", "As I see it, yes", "Most likely", "Outlook good", "Yes", "Signs point to yes", "Reply hazy try again", "Ask again later", "Better not tell you now", "Cannot predict now", "Concentrate and ask again", "Don't count on it", "My reply is no", "My sources say no", "Outlook not so good", "Very doubtful"}
resp = conchResponses[rand.Intn(len(conchResponses))]
} else {
resp = "The Magic Conch™ may be able to see into the future, but it can't read your mind! Please include a question."
}
s.ChannelMessageSend(m.ChannelID, resp)
}
//Test command that says UwU
func sayUwU(s *discordgo.Session, m *discordgo.Message, ctx *mux.Context) {
s.ChannelMessageSend(m.ChannelID, "UwU *nuzzles*")
}

96
pocketbot.go Normal file
View File

@ -0,0 +1,96 @@
package main
import (
"flag"
"fmt"
"github.com/bwmarrin/discordgo"
"github.com/bwmarrin/disgord/x/mux"
"log"
"math/rand"
"os"
"os/signal"
"syscall"
"time"
)
var Session, _ = discordgo.New()
var bot_token string
var bot_channel string
var bot_admin_role string
var Router = mux.New()
func init() {
rand.Seed(time.Now().UnixNano())
flag.StringVar(&bot_token, "t", "", "Discord Authentication Token")
flag.StringVar(&bot_channel, "bc", "", "Bot status channel")
flag.Parse()
if os.Getenv("DISCORD_TOKEN") != "" {
Session.Token = "Bot " + os.Getenv("DISCORD_TOKEN")
} else {
Session.Token = "Bot " + bot_token
}
if os.Getenv("DISCORD_BOT_CHANNEL") != "" {
bot_channel = os.Getenv("DISCORD_BOT_CHANNEL")
}
if os.Getenv("POCKETBOT_ADMIN_ROLE") != "" {
bot_admin_role = os.Getenv("POCKETBOT_ADMIN_ROLE")
}
}
func main() {
var err error
fmt.Println("pocketbot")
//flag.Parse()
if Session.Token == "" {
log.Println("You must provide a Discord auth token!")
return
}
//Handlers
Session.AddHandler(ready)
Session.AddHandler(Router.OnMessageCreate)
//Set the command prefix
if os.Getenv("POCKETBOT_PREFIX") != "" {
Router.Prefix = os.Getenv("POCKETBOT_PREFIX")
} else {
Router.Prefix = "!"
}
// Register the build-in help command.
Router.Route("help", "Display this message.", Router.Help)
Router.Route("swear", "Make me swear!", getSwear)
Router.Route("maki", "It's Maki Monday my dudes!", makiMonday)
Router.Route("monday", "It's Maki Monday my dudes!", makiMonday)
Router.Route("mixes", "Post the link to my fire mixtapes!", postMixes)
Router.Route("rmix", "Post a random mix!", getRandomMix)
Router.Route("xkcd", "Post a specific, random, or the latest XKCD comic", getXKCD)
Router.Route("restart", "Restart the bot.", restartBot)
Router.Route("kill", "Restart the bot.", restartBot)
Router.Route("sleep", "Something about sleeping...", goToSleep)
Router.Route("setplaying", "Set the nowplaying message for the bot.", setNowPlaying)
Router.Route("roll", "Roll some dice!", rollDice)
Router.Route("conch", "Ask the Magic Conch™ shell to predict the future!", askConch)
Router.Route("uwu", "Say UwU", sayUwU)
//Open a connection to Discord
err = Session.Open()
if err != nil {
log.Printf("Error opening connection to Discord, %s\n", err)
os.Exit(1)
}
//Wait for a CTRL-C
log.Printf("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
Session.Close()
}
func ready(s *discordgo.Session, event *discordgo.Ready) {
s.UpdateStatus(0, "with droids!")
if os.Getenv("POCKETBOT_STARTUP_MESSAGE") == "TRUE" {
s.ChannelMessageSend(bot_channel, "This isn't Tatooine...")
}
}

2
userdata/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore