mirror of
https://github.com/the-programmers-hangout/swiftspiracy-bot.git
synced 2026-09-10 07:56:26 +02:00
Merge remote-tracking branch 'origin/main' into feat/nix-nix-nix
This commit is contained in:
+14
@@ -0,0 +1,14 @@
|
|||||||
|
# Discord bot credentials
|
||||||
|
DISCORD_BOT_TOKEN=your-bot-token-here
|
||||||
|
DISCORD_CHANNEL_ID=your-channel-id-here
|
||||||
|
|
||||||
|
# Timing configuration
|
||||||
|
SEND_MESSAGE_INTERVAL_MIN=5
|
||||||
|
SEND_MESSAGE_INTERVAL_MAX=10
|
||||||
|
SEND_MESSAGE_UNIT=second # "second" | "seconds" | "minute" | "minutes" | "millisecond" | "milliseconds"
|
||||||
|
|
||||||
|
# Delay before deleting a conspiracy message (eg "3s", "500ms", "1m")
|
||||||
|
DELETE_CONSPIRACY_DELAY=3s
|
||||||
|
|
||||||
|
# Probability of sending a conspiracy message (0.0 to 1.0)
|
||||||
|
CONSPIRACY_PROBABILITY=0.4
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
name: publish-latest
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.event.workflow_run.head_repository.full_name }}::${{ github.event.workflow_run.head_branch }}::${{ github.workflow }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
jobs:
|
||||||
|
publish-latest:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
timeout-minutes: 60
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: docker/setup-qemu-action@v3
|
||||||
|
- uses: docker/setup-buildx-action@v3
|
||||||
|
- name: Get image repository
|
||||||
|
run: echo IMAGE_REPOSITORY=$(echo ghcr.io/the-programmers-hangout/${{ github.event.repository.name }} | tr '[:upper:]' '[:lower:]') >> $GITHUB_ENV
|
||||||
|
- name: Login to registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: the-programmers-hangout
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64
|
||||||
|
pull: true
|
||||||
|
push: true
|
||||||
|
tags: ${{ env.IMAGE_REPOSITORY }}:latest
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
.env
|
.env
|
||||||
bin
|
bin
|
||||||
|
vendor
|
||||||
|
.idea
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
FROM golang:alpine AS builder
|
||||||
|
RUN apk --update add ca-certificates
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . ./
|
||||||
|
RUN go mod tidy
|
||||||
|
ENV DISCORD_BOT_TOKEN=""
|
||||||
|
ENV GIT_COMMIT=""
|
||||||
|
ENV BUILD_DATE=""
|
||||||
|
RUN go build -ldflags="-s -w -X main.CommitHash=$GIT_COMMIT -X main.BuildDate=$BUILD_DATE" -o bin/swiftspiracybot cmd/bot/main.go
|
||||||
|
ENTRYPOINT ["bin/swiftspiracybot"]
|
||||||
@@ -1 +1,28 @@
|
|||||||
# swiftspiracy
|
# swiftspiracy
|
||||||
|
|
||||||
|
A playful Discord bot that sends random praises and (occasionally) a conspiracy theory — and cleans up after itself.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
Create a `.env` file in the root of your project with the following keys:
|
||||||
|
|
||||||
|
- `DISCORD_BOT_TOKEN`: Your bot token from the Discord developer portal.
|
||||||
|
- `DISCORD_CHANNEL_ID`: The ID of the channel where the bot should send messages.
|
||||||
|
|
||||||
|
- `SEND_MESSAGE_INTERVAL_MIN`: Minimum interval between messages (as an integer).
|
||||||
|
- `SEND_MESSAGE_INTERVAL_MAX`: Maximum interval between messages (as an integer).
|
||||||
|
- `SEND_MESSAGE_UNIT`: Time unit for the interval. Acceptable values: "second", "seconds", "minute", "minutes",
|
||||||
|
"millisecond", "milliseconds".
|
||||||
|
|
||||||
|
- `DELETE_CONSPIRACY_DELAY`: Time to wait before deleting a conspiracy message. Use Go duration format (eg "3s",
|
||||||
|
"500ms", "1m").
|
||||||
|
- `CONSPIRACY_PROBABILITY`: Probability (from 0.0 to 1.0) that a conspiracy message is sent after a praise. Eg, 0.4 =
|
||||||
|
40% chance.
|
||||||
|
|
||||||
|
You can view the [.env-sample](./.env-sample) as an example.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The bot gracefully shuts down on CTRL+C.
|
||||||
|
|||||||
+61
-18
@@ -8,6 +8,7 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -31,29 +32,71 @@ var (
|
|||||||
conspiracyIndex int
|
conspiracyIndex int
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
var (
|
||||||
// TODO: update value after debugging
|
botToken string
|
||||||
SendMessageIntervalMin = 5
|
channelID string
|
||||||
// TODO: update value after debugging
|
|
||||||
SendMessageIntervalMax = 10
|
|
||||||
// TODO: update value after debugging
|
|
||||||
SendMessageUnit = time.Second
|
|
||||||
// TODO: update value after debugging
|
|
||||||
DeleteConspiracyDelay = 3 * time.Second
|
|
||||||
// TODO: update value after debugging
|
|
||||||
ConspiracyProbability = 0.4
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
var (
|
||||||
// Load environment variables
|
SendMessageIntervalMin int
|
||||||
|
SendMessageIntervalMax int
|
||||||
|
SendMessageUnit time.Duration
|
||||||
|
DeleteConspiracyDelay time.Duration
|
||||||
|
ConspiracyProbability float64
|
||||||
|
)
|
||||||
|
|
||||||
|
func loadEnvConfig() error {
|
||||||
if err := godotenv.Load(); err != nil {
|
if err := godotenv.Load(); err != nil {
|
||||||
log.Println("[!] No .env file found, using system environment variables.")
|
log.Println("[!] No .env file found, using system environment variables.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve token and channel ID
|
botToken = os.Getenv("DISCORD_BOT_TOKEN")
|
||||||
botToken, channelID := os.Getenv("DISCORD_BOT_TOKEN"), os.Getenv("DISCORD_CHANNEL_ID")
|
if botToken == "" {
|
||||||
if botToken == "" || channelID == "" {
|
return fmt.Errorf("Missing DISCORD_BOT_TOKEN")
|
||||||
log.Fatal("[x] Missing DISCORD_BOT_TOKEN or DISCORD_CHANNEL_ID in .env")
|
}
|
||||||
|
channelID = os.Getenv("DISCORD_CHANNEL_ID")
|
||||||
|
if botToken == "" {
|
||||||
|
return fmt.Errorf("Missing DISCORD_CHANNEL_ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
SendMessageIntervalMin, err = strconv.Atoi(os.Getenv("SEND_MESSAGE_INTERVAL_MIN"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("SEND_MESSAGE_INTERVAL_MIN: %w", err)
|
||||||
|
}
|
||||||
|
SendMessageIntervalMax, err = strconv.Atoi(os.Getenv("SEND_MESSAGE_INTERVAL_MAX"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("SEND_MESSAGE_INTERVAL_MAX: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch os.Getenv("SEND_MESSAGE_UNIT") {
|
||||||
|
case "second", "seconds":
|
||||||
|
SendMessageUnit = time.Second
|
||||||
|
case "minute", "minutes":
|
||||||
|
SendMessageUnit = time.Minute
|
||||||
|
case "millisecond", "milliseconds":
|
||||||
|
SendMessageUnit = time.Millisecond
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported SEND_MESSAGE_UNIT: %s", os.Getenv("SEND_MESSAGE_UNIT"))
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteConspiracyDelay, err = time.ParseDuration(os.Getenv("DELETE_CONSPIRACY_DELAY"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("DELETE_CONSPIRACY_DELAY: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ConspiracyProbability, err = strconv.ParseFloat(os.Getenv("CONSPIRACY_PROBABILITY"), 64)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("CONSPIRACY_PROBABILITY: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := loadEnvConfig(); err != nil {
|
||||||
|
log.Fatalf("[x] Failed to load configuration: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load messages at build time
|
// Load messages at build time
|
||||||
@@ -127,7 +170,7 @@ func startScheduler(s *discordgo.Session, channelID string) {
|
|||||||
praiseIndex++
|
praiseIndex++
|
||||||
|
|
||||||
// Chance to send a conspiracy theory
|
// Chance to send a conspiracy theory
|
||||||
if rand.Float32() < ConspiracyProbability {
|
if rand.Float64() < ConspiracyProbability {
|
||||||
discordMessage := sendMessage(conspiracies[conspiracyIndex%len(conspiracies)], s, channelID)
|
discordMessage := sendMessage(conspiracies[conspiracyIndex%len(conspiracies)], s, channelID)
|
||||||
conspiracyIndex++
|
conspiracyIndex++
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,12 @@ module github.com/khinshankhan/swiftspiracy
|
|||||||
go 1.23.4
|
go 1.23.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bwmarrin/discordgo v0.28.1 // indirect
|
github.com/bwmarrin/discordgo v0.28.1
|
||||||
|
github.com/joho/godotenv v1.5.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
github.com/gorilla/websocket v1.4.2 // indirect
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
github.com/joho/godotenv v1.5.1 // indirect
|
|
||||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
|
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user