Compare commits

..

13 Commits

Author SHA1 Message Date
DutchEllie
780fe972cd fix apparent mistake 2021-06-04 16:21:36 +02:00
b64a4096e9 implement? 2021-06-04 16:08:44 +02:00
661ce08764 log 2021-06-04 16:07:19 +02:00
062e9276f2 packaged up server, added mutex 2021-06-04 09:54:28 +02:00
a8128b120a changed 2021-06-03 17:07:33 +02:00
eff943a715 fixed error message 2021-06-03 14:07:11 +02:00
8555a686a6 this might break it all 2021-06-03 13:52:53 +02:00
ebbbc3680d added middleware 2021-06-03 13:45:07 +02:00
DutchEllie
9f1d13d3aa added build 2021-06-03 13:28:47 +02:00
e56686ee3c added newsendpepe 2021-06-03 12:54:03 +02:00
0829c2a39d ready for testing?? 2021-06-03 12:50:42 +02:00
6e65f9165b renamed general 2021-06-03 11:29:43 +02:00
91c9230e05 basic idea 2021-06-03 11:29:34 +02:00
20 changed files with 317 additions and 582 deletions

View File

@ -1,4 +0,0 @@
.drone.yml
docker-ignore.yml
LICENCE
README.md

View File

@ -1,231 +0,0 @@
kind: pipeline
type: kubernetes
name: pepebot_build_amd64
platform:
os: linux
arch: amd64
steps:
- name: build-pepebot
image: golang:1.16.4
volumes:
- name: build
path: /drone/src/build
environment:
CGO_ENABLED: 0
GOOS: linux
commands:
- go build -a -installsuffix cgo -o ./build/app ./discord
- name: build-publish-image
image: plugins/docker
privileged: true
volumes:
- name: build
path: /drone/src/build
settings:
cache_from:
- "dutchellie/pepebot:latest"
username:
from_secret: docker_username
password:
from_secret: docker_password
dockerfile: Dockerfile
repo: dutchellie/pepebot
tags:
- latest-amd64
volumes:
- name: build
temp: {}
---
kind: pipeline
type: kubernetes
name: pepebot_service_build_amd64
platform:
os: linux
arch: amd64
steps:
- name: build-pepebot_service
image: golang:1.17
volumes:
- name: build
path: /drone/src/build
environment:
CGO_ENABLED: 0
GOOS: linux
commands:
- cd ./pepeservice
- go build -a -installsuffix cgo -o ../build/app .
- name: build-service
image: plugins/docker
privileged: true
volumes:
- name: build
path: /drone/src/build
settings:
cache_from:
- "dutchellie/pepebot_service:latest"
username:
from_secret: docker_username
password:
from_secret: docker_password
dockerfile: pepeservice/Dockerfile
repo: dutchellie/pepebot_service
tags:
- latest-amd64
volumes:
- name: build
temp: {}
---
kind: pipeline
type: docker
name: pepebot_build_arm64
platform:
os: linux
arch: arm64
steps:
- name: build-pepebot
image: golang:1.16.4
volumes:
- name: build
path: /drone/src/build
environment:
CGO_ENABLED: 0
GOOS: linux
commands:
- go build -a -installsuffix cgo -o ./build/app ./discord
- name: build-publish-image
image: plugins/docker
privileged: true
volumes:
- name: build
path: /drone/src/build
settings:
cache_from:
- "dutchellie/pepebot:latest"
username:
from_secret: docker_username
password:
from_secret: docker_password
dockerfile: Dockerfile
repo: dutchellie/pepebot
tags:
- latest-arm64
volumes:
- name: build
temp: {}
---
kind: pipeline
type: docker
name: pepebot_service_build_arm64
platform:
os: linux
arch: arm64
steps:
- name: build-pepebot_service
image: golang:1.17
volumes:
- name: build
path: /drone/src/build
environment:
CGO_ENABLED: 0
GOOS: linux
commands:
- cd ./pepeservice
- go build -a -installsuffix cgo -o ../build/app .
- name: build-service
image: plugins/docker
privileged: true
volumes:
- name: build
path: /drone/src/build
settings:
cache_from:
- "dutchellie/pepebot_service:latest"
username:
from_secret: docker_username
password:
from_secret: docker_password
dockerfile: pepeservice/Dockerfile
repo: dutchellie/pepebot_service
tags:
- latest-arm64
volumes:
- name: build
temp: {}
---
kind: pipeline
type: kubernetes
name: manifest
steps:
- name: manifest-main
image: plugins/manifest
settings:
platforms:
- linux/amd64
- linux/arm64
target: dutchellie/pepebot:latest
template: dutchellie/pepebot:latest-ARCH
username:
from_secret: docker_username
password:
from_secret: docker_password
- name: manifest-pepebotservice
image: plugins/manifest
settings:
platforms:
- linux/amd64
- linux/arm64
target: dutchellie/pepebot_service:latest
template: dutchellie/pepebot_service:latest-ARCH
username:
from_secret: docker_username
password:
from_secret: docker_password
depends_on:
- pepebot_build_arm64
- pepebot_build_amd64
- pepebot_service_build_arm64
- pepebot_service_build_amd64
---
kind: pipeline
type: kubernetes
name: deploy_on_pi
trigger:
branch:
- main
steps:
- name: deploy
image: appleboy/drone-ssh
settings:
host: home.dutchellie.nl
port: 223
username: ellie
key:
from_secret: ssh_key
script:
- cd /home/ellie/pepebot
- docker-compose pull app
- docker-compose pull pepe_service
- docker-compose up -d
depends_on:
- manifest

2
.gitignore vendored
View File

@ -1,3 +1 @@
discordtoken.txt
deploy_ed25519
deploy_ed25519.pub

View File

@ -1,13 +1,13 @@
# syntax=docker/dockerfile:1
#FROM golang:1.16.4-alpine AS builder
#WORKDIR /go/src/quenten.nl/pepebot/
#
#COPY . ./
#RUN go mod download
#RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app ./discord
FROM golang:1.16.4 AS builder
WORKDIR /go/src/quenten.nl/pepebot/
COPY . ./
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app ./discord
FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY ./build/app /root
WORKDIR /root
WORKDIR /root/
COPY --from=builder /go/src/quenten.nl/pepebot/app .
CMD ["./app"]

View File

@ -1,10 +1,6 @@
package main
import (
"net/http"
"github.com/bwmarrin/discordgo"
)
import "github.com/bwmarrin/discordgo"
func (app *application) addWord(s *discordgo.Session, m *discordgo.MessageCreate, splitCommand []string) {
/* Check if admin */
@ -30,6 +26,8 @@ func (app *application) addWord(s *discordgo.Session, m *discordgo.MessageCreate
return
}
err = app.updateAllBadWords()
if err != nil {
app.unknownError(err, s, true, m.ChannelID)
@ -167,26 +165,3 @@ func (app *application) removeAdmin(s *discordgo.Session, m *discordgo.MessageCr
app.successMessage(s, m)
}
func (app *application) reloadPepeList(s *discordgo.Session, m *discordgo.MessageCreate) {
/* Check if admin */
r, err := app.checkIfAdmin(s, m)
if err != nil {
app.errorLog.Print(err)
return
}
if !r {
return
}
s.ChannelMessageSend(m.ChannelID, "Reloading list of pepes")
url := "http://" + app.pepeServer + "/reload"
_, err = http.Get(url)
if err != nil {
app.errorLog.Print(err)
s.ChannelMessageSend(m.ChannelID, "An error occured!")
return
}
app.successMessage(s, m)
}

View File

@ -1,9 +1,6 @@
package main
import (
"strings"
"time"
"github.com/bwmarrin/discordgo"
)
@ -11,12 +8,20 @@ func (app *application) messageCreate(s *discordgo.Session, m *discordgo.Message
if m.Author.Bot {
return
}
app.limiter.LogInteraction(m.Author.ID, "messagecreate")
app.LogInteraction(app.LogToConsole(app.commandMux)).Execute(s, m)
/* if strings.HasPrefix(m.Content, "!newpepe") {
app.LogToConsole(app.commandMux).Execute(s, m)
return
} */
//app.limiter.LogInteraction(m.Author.ID, "messagecreate")
/* Check if the user is even allowed by the rate limiter */
err := app.limiter.CheckAllowed(m.Author.ID)
/* err := app.limiter.CheckAllowed(m.Author.ID)
if err != nil {
/* normally don't send, but now do for debug purposes. This is the admin bot channel */
/* normally don't send, but now do for debug purposes. This is the admin bot channel *
//app.unknownError(err, s, true, "815952128106430514")
app.infoLog.Printf("Rate limit exceeded by used %s", m.Author.Username)
channel, err := s.UserChannelCreate(m.Author.ID)
@ -26,55 +31,40 @@ func (app *application) messageCreate(s *discordgo.Session, m *discordgo.Message
}
s.ChannelMessageSend(channel.ID, "You exceeded the rate limit for the server, please stop spamming")
return
}
/*
Temporary checking for Ben's birthday
*/
if time.Now().Month() == time.May && time.Now().Day() == 19 && m.Author.ID == "287892688919986176" {
s.ChannelMessageSend(m.ChannelID, "Happy birthday ben!! https://www.youtube.com/watch?v=z21HOwUk5oM")
}
} */
/* Checking if the message starts with the trigger specified in application struct
if it does then we start the switch statement to trigger the appropriate function
if it does not then we check if it contains a triggerword from the database */
if strings.HasPrefix(m.Content, app.trigger) {
/* if strings.HasPrefix(m.Content, app.trigger) {
splitCommand := strings.Split(strings.TrimSpace(m.Content), " ")
/* If the whole message on it's own is just "!pepe" aka the triggerword, then send a pepe and stop */
/* If the whole message on it's own is just "!pepe" aka the triggerword, then send a pepe and stop *
if strings.TrimSpace(m.Content) == app.trigger {
app.sendPepe(s, m)
return
}
/* This switches on the first word in the message
it could be anything starting with !pepe */
it could be anything starting with !pepe *
if len(splitCommand) > 1 {
switch splitCommand[1] {
/* --- Funny commands --- */
/* --- Funny commands --- *
case "cringe":
app.sendCringe(s, m)
case "gif":
app.sendNigelGif(s, m)
case "monday":
app.sendMonday(s, m)
case "tuesday":
app.sendTuesday(s, m)
case "wednesday":
app.sendWednesday(s, m)
case "friday":
app.sendFriday(s, m)
case "github", "source":
app.sendGithub(s, m)
case "peski", "rotterdam":
app.sendPeski(s, m)
case "proper", "based":
app.sendProper(s, m)
/* --- Bot commands for words --- */
/* --- Bot commands for words --- *
case "spam":
app.sendManyPepes(s, m, splitCommand)
case "stop":
app.stopRequest(s, m)
/* --- Bot commands, but only admins --- */
/* --- Bot commands, but only admins --- *
case "addword":
app.addWord(s, m, splitCommand)
case "removeword":
@ -83,14 +73,12 @@ func (app *application) messageCreate(s *discordgo.Session, m *discordgo.Message
app.addAdmin(s, m, splitCommand)
case "removeadmin":
app.removeAdmin(s, m, splitCommand)
case "reload":
app.reloadPepeList(s, m)
}
}
} else {
/* If the trigger wasn't the prefix of the message, we need to check all the words for a trigger */
/* If the trigger wasn't the prefix of the message, we need to check all the words for a trigger
app.findTrigger(s, m)
}
} */
}

View File

@ -1 +0,0 @@
package main

7
discord/handlers.go Normal file
View File

@ -0,0 +1,7 @@
package main
import "github.com/bwmarrin/discordgo"
func newCringe(s *discordgo.Session, m *discordgo.MessageCreate) {
s.ChannelMessageSend(m.ChannelID, "this is a test message right from the new command system!")
}

View File

@ -25,7 +25,7 @@ func openDB(dsn string) (*sql.DB, error){
return db, nil
}
func (app *application) updateAllBadWords() (error) {
func (app *application) updateAllBadWords() error {
var err error
app.allBadWords, err = app.badwords.AllWords()
if err != nil {

View File

@ -10,6 +10,7 @@ import (
"time"
"github.com/bwmarrin/discordgo"
"quenten.nl/pepebot/discord/mux"
"quenten.nl/pepebot/limiter"
"quenten.nl/pepebot/models/mysql"
)
@ -24,8 +25,8 @@ type application struct {
adminroles *mysql.AdminRolesModel
trigger string
allBadWords map[string][]string
pepeServer string
limiter *limiter.Limiter
commandMux *mux.CommandMux
active bool
stop bool
@ -37,7 +38,6 @@ func main() {
discordToken := os.Getenv("DISCORD_TOKEN")
rateLimit := os.Getenv("RATE_LIMIT")
timeLimit := os.Getenv("TIME_LIMIT")
pepeServer := os.Getenv("PEPE_SERVER")
dsn := fmt.Sprintf("%s:%s@tcp(db:3306)/badwords?parseTime=true", dbUser, dbPass)
infoLog := log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime)
errorLog := log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile)
@ -63,6 +63,9 @@ func main() {
Logs: make(map[string][]*limiter.Action),
}
server := mux.NewCommandMux()
server.Prefix = "!pepe"
app := &application{
infoLog: infoLog,
errorLog: errorLog,
@ -70,7 +73,7 @@ func main() {
adminroles: &mysql.AdminRolesModel{DB: db},
trigger: "!pepe",
limiter: limiter,
pepeServer: pepeServer,
commandMux: server,
}
app.allBadWords, err = app.badwords.AllWords()
@ -78,6 +81,23 @@ func main() {
app.errorLog.Fatal(err)
}
server.HandleFunc("cringe", app.sendCringe)
server.HandleFunc("gif", app.sendNigelGif)
server.HandleFunc("tuesday", app.sendTuesday)
server.HandleFunc("wednesday", app.sendWednesday)
server.HandleFunc("github", app.sendGithub)
server.HandleFunc("source", app.sendGithub)
/* The admin commands are left out for now.
They have specialised functions and don't work yet.
Their code is left unworking and nonfunctional to be fixed
sometime in the future... sometime
Another thing left out is the bad words feature.
It goes underused and has had it's joke.
Oh and no one must be sad to see the death of the spam command...*/
server.HandleFunc(server.Prefix, app.sendPepe)
/* token, err := app.readAuthToken()
if err != nil {
app.errorLog.Fatal(err)

39
discord/middleware.go Normal file
View File

@ -0,0 +1,39 @@
package main
import (
"github.com/bwmarrin/discordgo"
"quenten.nl/pepebot/discord/mux"
"quenten.nl/pepebot/limiter"
)
/*
Middleware chain
Logtoconsole -> loginteraction -> mux -> command
*/
func (app *application) LogToConsole(next mux.Command) mux.Command {
fn := func(s *discordgo.Session, m *discordgo.MessageCreate) {
app.infoLog.Printf("%s \tsaid: %s\n", m.Author.Username, m.Content)
next.Execute(s, m)
}
return mux.HandlerFunc(fn)
}
func (app *application) LogInteraction(next mux.Command) mux.Command {
fn := func(s *discordgo.Session, m *discordgo.MessageCreate) {
// Logging interaction
a := limiter.NewAction("Any message")
app.limiter.Logs[m.Author.ID] = append(app.limiter.Logs[m.Author.ID], a)
// Checking if rate limit exceeded
err := app.limiter.CheckAllowed(m.Author.ID)
if err != nil {
mux.NotFound(s, m)
} else {
next.Execute(s, m)
}
}
return mux.HandlerFunc(fn)
}

114
discord/mux/server.go Normal file
View File

@ -0,0 +1,114 @@
package mux
import (
"strings"
"sync"
"github.com/bwmarrin/discordgo"
)
type Command interface {
Execute(s *discordgo.Session, m *discordgo.MessageCreate)
}
func NotFound(s *discordgo.Session, m *discordgo.MessageCreate) {
return
}
func NotFoundHandler() Command { return HandlerFunc(NotFound) }
type HandlerFunc func(s *discordgo.Session, m *discordgo.MessageCreate)
func (f HandlerFunc) Execute(s *discordgo.Session, m *discordgo.MessageCreate) {
f(s, m)
}
/* The CommandMux struct is a type of mux for Discord commands. It's modelled after the net/http ServeMux */
type CommandMux struct {
mu sync.RWMutex
m map[string]muxEntry
Prefix string
}
func NewCommandMux() *CommandMux { return new(CommandMux) }
func (c *CommandMux) removeFirst(command string) string {
split := strings.SplitN(strings.TrimSpace(command), " ", 2)
if len(split) > 1 {
return split[1]
}
return ""
}
func (c *CommandMux) firstCommand(command string) string {
split := strings.SplitN(strings.TrimSpace(command), " ", 2)
if len(split) > 0 {
return split[0]
}
return ""
}
func (c *CommandMux) Handler(m *discordgo.MessageCreate) (cmd Command, pattern string) {
c.mu.RLock()
defer c.mu.RUnlock()
if strings.HasPrefix(m.Content, c.Prefix) {
/* Special case for this bot alone. It has a command that is only it's prefix
So we check if the whole message is only the prefix before proceding.
So please don't forget to add the command, since it's totally hardcoded here. */
if strings.TrimSpace(m.Content) == c.Prefix {
return c.m[c.Prefix].h, c.m[c.Prefix].pattern
}
m := c.removeFirst(m.Content) /* Here the prefix is removed, so we're left with only the first keyword */
cmd, ok := c.m[c.firstCommand(m)]
if ok {
return cmd.h, cmd.pattern
}
}
/* Here is where I might add the whole checking for bad words part */
return nil, ""
}
func (c *CommandMux) Execute(s *discordgo.Session, m *discordgo.MessageCreate) {
h, _ := c.Handler(m)
if h == nil {
//log.Printf("There exists no handler for %s\n", m.Content)
return
}
h.Execute(s, m)
}
func (c *CommandMux) Handle(pattern string, handler Command) {
c.mu.Lock()
defer c.mu.Unlock()
if pattern == "" {
panic("commandmux: invalid pattern")
}
if handler == nil {
panic("commandmux: nil handler")
}
if _, exist := c.m[pattern]; exist {
panic("commandmux: multiple registrations for " + pattern)
}
if c.m == nil {
c.m = make(map[string]muxEntry)
}
e := muxEntry{h: handler, pattern: pattern}
c.m[pattern] = e
}
func (c *CommandMux) HandleFunc(pattern string, handler func(s *discordgo.Session, m *discordgo.MessageCreate)) {
if handler == nil {
panic("commandmux: nil handler")
}
c.Handle(pattern, HandlerFunc(handler))
}
/* The muxEntry struct contains the actual Command implementation as well as the pattern (discord command)
it will be matched against */
type muxEntry struct {
h Command
pattern string
}

View File

@ -3,9 +3,10 @@ package main
import (
"errors"
"fmt"
"io"
"io/ioutil"
"math/rand"
"net/http"
"regexp"
"strconv"
"strings"
"time"
@ -14,31 +15,30 @@ import (
)
func (app *application) getPepeLink() (string, error) {
url := "http://" + app.pepeServer + "/pepe"
resp, err := http.Get(url)
resp, err := http.Get("http://bbwroller.com/random")
if err != nil {
return "", err
}
body, err := io.ReadAll(resp.Body)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
rep, err := regexp.Compile("/static.*\\.jpg")
if err != nil {
return "", err
}
pepes := rep.FindAllString(string(body), 200)
if pepes == nil {
return "", err
}
randomIndex := rand.Intn(35)
url := "https://bbwroller.com"
url += pepes[randomIndex]
return string(body), nil
return url, nil
}
func (app *application) sendPepe(s *discordgo.Session, m *discordgo.MessageCreate) {
ch, err := s.Channel(m.ChannelID)
if err != nil {
app.errorLog.Print(err)
return
}
if !strings.Contains(ch.Topic, "pepebot allowed") {
app.errorLog.Print("Can't send pepe within this channel")
return
}
url, err := app.getPepeLink()
if err != nil {
app.errorLog.Print(err)
@ -69,22 +69,6 @@ func (app *application) sendNigelGif(s *discordgo.Session, m *discordgo.MessageC
}
}
func (app *application) sendMonday(s *discordgo.Session, m *discordgo.MessageCreate) {
if time.Now().Weekday().String() != "Monday" {
_, err := s.ChannelMessageSend(m.ChannelID, "This command only works on mondays")
if err != nil {
app.errorLog.Print(err)
return
}
return
}
_, err := s.ChannelMessageSend(m.ChannelID, "https://www.youtube.com/watch?v=EkALyaMjoXw")
if err != nil {
app.errorLog.Print(err)
return
}
}
func (app *application) sendTuesday(s *discordgo.Session, m *discordgo.MessageCreate) {
if time.Now().Weekday().String() != "Tuesday" {
_, err := s.ChannelMessageSend(m.ChannelID, "This command only works on tuesdays")
@ -126,46 +110,8 @@ func (app *application) sendWednesday(s *discordgo.Session, m *discordgo.Message
}
}
func (app *application) sendFriday(s *discordgo.Session, m *discordgo.MessageCreate) {
if time.Now().Weekday().String() != "Friday" {
_, err := s.ChannelMessageSend(m.ChannelID, "This command only works on fridays")
if err != nil {
app.errorLog.Print(err)
return
}
return
}
_, err := s.ChannelMessageSend(m.ChannelID, "https://www.youtube.com/watch?v=kfVsfOSbJY0")
if err != nil {
app.errorLog.Print(err)
return
}
}
func (app *application) sendGithub(s *discordgo.Session, m *discordgo.MessageCreate) {
_, err := s.ChannelMessageSend(m.ChannelID, "My code is hosted publicly over at https://dutchellie.nl/DutchEllie/pepebot")
if err != nil {
app.errorLog.Print(err)
return
}
}
func (app *application) sendPeski(s *discordgo.Session, m *discordgo.MessageCreate) {
_, err := s.ChannelMessageSend(m.ChannelID, "https://www.youtube.com/watch?v=P0jHTCJYm44")
if err != nil {
app.errorLog.Print(err)
return
}
}
func (app *application) sendProper(s *discordgo.Session, m *discordgo.MessageCreate) {
responseList := []string{"That's proper", "I use Gentoo", "So based", "That's best practice", "Emacs is the best", "LISP is so fucking based", "My website is here https://forestofunix.xyz\nIt's written in Lisp. It's so based!", "Python is LISP based"}
source := rand.NewSource(time.Now().UnixNano())
rng := rand.New(source)
index := rng.Intn(len(responseList))
_, err := s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("\"%s\"\n-Sebastiaan", responseList[index]))
_, err := s.ChannelMessageSend(m.ChannelID, "My code is hosted publicly over at https://github.com/DutchEllie/pepebot")
if err != nil {
app.errorLog.Print(err)
return
@ -173,16 +119,6 @@ func (app *application) sendProper(s *discordgo.Session, m *discordgo.MessageCre
}
func (app *application) sendManyPepes(s *discordgo.Session, m *discordgo.MessageCreate, splitCommand []string) {
ch, err := s.Channel(m.ChannelID)
if err != nil {
app.errorLog.Print(err)
return
}
if !strings.Contains(ch.Topic, "pepebot allowed") {
app.errorLog.Print("Can't send pepe within this channel")
return
}
override := false
/* [0] is !pepe, [1] is spam, [2] is amount, [3] is override*/
@ -238,7 +174,7 @@ func (app *application) sendManyPepes(s *discordgo.Session, m *discordgo.Message
return
}
if len(msg+link) > 512 {
if len(msg + link) > 1950 {
s.ChannelMessageSend(m.ChannelID, msg)
msg = ""
time.Sleep(time.Millisecond * 500)
@ -409,7 +345,7 @@ func (app *application) checkIfAdmin(s *discordgo.Session, m *discordgo.MessageC
return false, nil
}
func (app *application) contextLength(splitCommand []string) error {
func (app *application) contextLength(splitCommand []string) (error) {
if !(len(splitCommand) > 2) {
app.errorLog.Printf("The command's context was not enough.\n")
return errors.New("not enough context")

View File

@ -1,4 +1,5 @@
version: "3.7"
services:
app:
container_name: pepebot_server
@ -8,31 +9,22 @@ services:
depends_on:
- db
environment:
- DB_USER=changemeusername
- DB_PASS=changemepassword
- DISCORD_TOKEN=<discord token>
- RATE_LIMIT=2 # 2 Actions per TIME_LIMIT
- TIME_LIMIT=5 # Per second
- PEPE_SERVER=pepe_service:4000
- DB_USER=
- DB_PASS=
- DISCORD_TOKEN=
- RATE_LIMIT=
- TIME_LIMIT=
db:
container_name: pepebot_database
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: changeme
MYSQL_DATABASE: pepebot
MYSQL_USER: changemeusername
MYSQL_PASSWORD: changemepassword
MYSQL_ROOT_PASSWORD:
MYSQL_DATABASE:
MYSQL_USER:
MYSQL_PASSWORD:
volumes:
- pepe_db_data:/var/lib/mysql
pepe_service:
container_name: pepebot_service
image: dutchellie/pepebot_service:latest
build: pepeservice
restart: always
environment:
- PEPE_DIR=/pepe/1.00
volumes:
- /your/pepe/folder:/pepe #edit this
volumes:
pepe_db_data: {}

View File

@ -6,3 +6,10 @@ type Action struct {
Type string
Timestamp time.Time
}
func NewAction(t string) *Action {
a := new(Action)
a.Timestamp = time.Now()
a.Type = t
return a
}

View File

@ -43,7 +43,7 @@ func (l *Limiter) CheckAllowed(userid string) error {
l.removeAction(userid, expiredEntries[i])
}
if counter > l.RateLimit {
if counter >= l.RateLimit {
return errors.New("rate limit exceeded")
} else {
return nil

View File

@ -1,4 +0,0 @@
.drone.yml
docker-ignore.yml
LICENCE
README.md

View File

@ -1,14 +0,0 @@
# syntax=docker/dockerfile:1
#FROM golang:1.17-alpine AS builder
#WORKDIR /go/src/quenten.nl/pepeservice
#
#COPY . ./
#WORKDIR /go/src/quenten.nl/pepeservice/pepeservice
#RUN go mod download
#RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app ./
FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY ./build/app /root
WORKDIR /root
CMD ["./app"]

View File

@ -1,3 +0,0 @@
module quenten.nl/pepeservice
go 1.17

View File

@ -1,84 +0,0 @@
package main
import (
"log"
"math/rand"
"net/http"
"os"
"time"
)
type application struct {
errorLog *log.Logger
infoLog *log.Logger
pepe_list []string
pepe_dir string
}
func main() {
pepe_dir := os.Getenv("PEPE_DIR")
infoLog := log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime)
errorLog := log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile)
file, err := os.Open(pepe_dir)
if err != nil {
errorLog.Printf("Error opening pepe directory\n")
return
}
pepe_list, err := file.Readdirnames(0)
if err != nil {
errorLog.Printf("Error reading pepe directory file names\n")
return
}
file.Close()
app := &application{
infoLog: infoLog,
errorLog: errorLog,
pepe_dir: pepe_dir,
pepe_list: pepe_list,
}
mux := http.NewServeMux()
mux.HandleFunc("/pepe", app.sendPepe)
mux.HandleFunc("/reload", app.reloadList)
app.infoLog.Printf("Starting server at :4000\n")
err = http.ListenAndServe(":4000", mux)
log.Fatal(err)
}
func (app *application) sendPepe(w http.ResponseWriter, r *http.Request) {
// Random number generator
s := rand.NewSource(time.Now().UnixMicro())
rd := rand.New(s) // Init pseudorandom generator
number := rd.Intn(len(app.pepe_list))
baseURL := "https://cdn.nicecock.eu/pepe/1.00/"
URL := baseURL + app.pepe_list[number]
w.Write([]byte(URL))
}
func (app *application) reloadList(w http.ResponseWriter, r *http.Request) {
file, err := os.Open(app.pepe_dir)
if err != nil {
app.errorLog.Printf("Error opening pepe directory\n")
return
}
defer file.Close()
pepe_list, err := file.Readdirnames(0)
if err != nil {
app.errorLog.Printf("Error reading pepe directory file names\n")
return
}
app.pepe_list = pepe_list
w.WriteHeader(http.StatusOK)
w.Write([]byte("200 - Reloaded the list of pepes"))
}