Merge remote-tracking branch 'origin/main' into feat/nix-nix-nix

This commit is contained in:
Storm
2025-03-29 13:25:16 +01:00
7 changed files with 152 additions and 20 deletions
+14
View File
@@ -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
+33
View File
@@ -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
+2
View File
@@ -1,2 +1,4 @@
.env
bin
vendor
.idea
+10
View File
@@ -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"]
+27
View File
@@ -1 +1,28 @@
# 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
View File
@@ -8,6 +8,7 @@ import (
"math/rand"
"os"
"os/signal"
"strconv"
"syscall"
"time"
@@ -31,29 +32,71 @@ var (
conspiracyIndex int
)
const (
// TODO: update value after debugging
SendMessageIntervalMin = 5
// 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
var (
botToken string
channelID string
)
func main() {
// Load environment variables
var (
SendMessageIntervalMin int
SendMessageIntervalMax int
SendMessageUnit time.Duration
DeleteConspiracyDelay time.Duration
ConspiracyProbability float64
)
func loadEnvConfig() error {
if err := godotenv.Load(); err != nil {
log.Println("[!] No .env file found, using system environment variables.")
}
// Retrieve token and channel ID
botToken, channelID := os.Getenv("DISCORD_BOT_TOKEN"), os.Getenv("DISCORD_CHANNEL_ID")
if botToken == "" || channelID == "" {
log.Fatal("[x] Missing DISCORD_BOT_TOKEN or DISCORD_CHANNEL_ID in .env")
botToken = os.Getenv("DISCORD_BOT_TOKEN")
if botToken == "" {
return fmt.Errorf("Missing DISCORD_BOT_TOKEN")
}
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
@@ -127,7 +170,7 @@ func startScheduler(s *discordgo.Session, channelID string) {
praiseIndex++
// Chance to send a conspiracy theory
if rand.Float32() < ConspiracyProbability {
if rand.Float64() < ConspiracyProbability {
discordMessage := sendMessage(conspiracies[conspiracyIndex%len(conspiracies)], s, channelID)
conspiracyIndex++
+5 -2
View File
@@ -3,9 +3,12 @@ module github.com/khinshankhan/swiftspiracy
go 1.23.4
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/joho/godotenv v1.5.1 // indirect
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
)