Skip to content

Commit

Permalink
Implement !1 using Gin framework
Browse files Browse the repository at this point in the history
  • Loading branch information
Scott Bragg committed Dec 27, 2024
1 parent 6becc66 commit 56fb376
Show file tree
Hide file tree
Showing 18 changed files with 370 additions and 94 deletions.
52 changes: 52 additions & 0 deletions .air-bot.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
args_bin = []
bin = "./tmp/bot"
cmd = "go build -o ./tmp/bot ./cmd/bot"
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = []
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false

[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"

[log]
main_only = false
silent = false
time = false

[misc]
clean_on_exit = false

[proxy]
app_port = 0
enabled = false
proxy_port = 0

[screen]
clear_on_rebuild = false
keep_scroll = true
52 changes: 52 additions & 0 deletions .air.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
args_bin = []
bin = "./tmp/web"
cmd = "go build -o ./tmp/web ./cmd/web"
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = []
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false

[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"

[log]
main_only = false
silent = false
time = false

[misc]
clean_on_exit = false

[proxy]
app_port = 0
enabled = false
proxy_port = 0

[screen]
clear_on_rebuild = false
keep_scroll = true
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ go.work.sum
# env file
.env

bin/
bin/
tmp/
28 changes: 27 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ FROM golang:1.23-alpine AS builder
# Install dependencies required to run the Makefile
RUN apk add --no-cache make

# Set up Go environment variables
ENV GOPATH=/golang
ENV PATH=$GOPATH/bin:$PATH

# Set the working directory
WORKDIR /app

Expand All @@ -14,7 +18,7 @@ COPY . .
RUN make build

# Use a minimal base image for the final container
FROM alpine:latest
FROM alpine:latest AS deploy

# Set the working directory
WORKDIR /app
Expand All @@ -26,6 +30,9 @@ RUN apk add --no-cache ca-certificates
COPY --from=builder /app/bin/bot /app/bin/bot

# Set environment variables for database connection
ENV GOPATH=/golang
ENV PATH=$GOPATH/bin:$PATH

ENV DB_HOST=postgres
ENV DB_PORT=5432
ENV DB_USER=napandgo
Expand All @@ -36,5 +43,24 @@ ENV DB_SSLMODE=disable
# Expose any required ports (optional)
EXPOSE 8080

# Run the container as a non-root user
USER nobody

# Run the bot binary
CMD ["/app/bin/bot"]

# Development image we actually use go so we can use hot reloading with air
FROM builder AS dev

# Install air for Go for hot reloading
RUN apk add --no-cache git
RUN go install github.com/air-verse/air@latest

# Expose any required ports (optional)
EXPOSE 8080

# Run the container as a non-root user
USER root

# Run the bot binary
CMD ["air", "-c", ".air-bot.toml"]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ bot:

# Build the web interface binary
web:
$(GO_BUILD_CMD) -o bin/web ./cmd/web
CGO_ENABLED=$(CGO_ENABLED) $(GO_BUILD_CMD) -o bin/web ./cmd/web

# Run both bot and web
run: build
Expand Down
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,47 @@ My way to learn Go by creating a Discord bot with a bunch of features
- Replies to a message when it is sent a message in a channel

Features will be added as they get completed

## Usage

The application is designed to be run in a collection of containers with Postgres.

```
docker compose up -d
docker compose logs -f
```

## Create a Discord application and Bot

- Go to the [Discord Developer portal](https://discord.com/developers/applications)
- Click the *New Application* button at the top right
![Discord application page](docs/images/screen-new-app.png)
- Give the application a name
![Discord create app modal](docs/images/screen-create-app.png)
- Click the OAuth menu item and configure the a redirect URI. Don't forget to save the page!
- For development http://localhost:3000/api/oauth
- For production https://YOURSERVER/api/oauth
![Discord OAuth page](docs/images/screen-bot-settings.png)
- Click the *Reset Secret* button and copy the new secret that you are given. This will become DISCORD_CLIENT_SECRET in your environment file
- Copy the Client ID - this will become DISCORD_CLIENT_ID in your environment file.
- Click the Bot menu item, and configure the bot settings (you will need to enable several Intents as noted below)
![Discord Bot page](docs/images/screen-bot-settings2.png)
- Click the *Reset Token* button and copy the new token that you receive. This will become your DISCORD_BOT_TOKEN environment variable.

## Installation

- Create an .env file using the .env-prod-example as a template
- Enter your values for DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET and DISCORD_BOT_TOKEN from the above procedure.

## Development Notes

### Project layout

- cmd/bot -- stuff for the bot
- cmd/web -- stuff for the web UI
- config -- handles configuration (mainly loading by environment variables)
- db -- stuff for the database
- docs -- additional documentation
- models -- database models
- static -- web UI static files
- templates -- web UI templates
19 changes: 19 additions & 0 deletions cmd/web/auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Package web runs Gin based webserver for the application.
// auth.go has endpoints to handle authentication
package main

import (
"net/http"
"github.com/gin-gonic/gin"
)

// homeHandler handles the home page rendering index.html
func homeHandler(c *gin.Context) {
// Render the home page
c.HTML(http.StatusOK, "index.html", nil)
}

func testHandler(c *gin.Context) {
// Render the home page
c.String(http.StatusOK, "Hello World")
}
34 changes: 34 additions & 0 deletions cmd/web/web.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Package web runs Gin based webserver for the application.
package main

import (
"log"

"github.com/gin-gonic/gin"
)

func main() {
// Initialize the web server
router := gin.Default()

// Load the templates
router.LoadHTMLGlob("templates/*")

// Register the routes
registerRoutes(router)

// Run the web server
addr := ":8080"
log.Printf("Starting web server on %s", addr)
err := router.Run(addr)
if err != nil {
log.Fatalf("failed to start web server: %v", err)
}
}

// registerRoutes registers the routes for the web server.
func registerRoutes(router *gin.Engine) {
// Define the routes
router.GET("/", homeHandler)
router.GET("/test", testHandler)
}
31 changes: 23 additions & 8 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,35 @@ services:
build:
context: .
dockerfile: Dockerfile
target: dev
container_name: bot
depends_on:
- postgres
environment:
- DB_HOST=postgres
- DB_PORT=5432
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- DB_NAME=${DB_NAME}
- DB_SSLMODE=disable
# Get environment variables from .env file
env_file:
- path: ./.env
volumes:
- ./bin:/app/bin
command: ["sh", "-c", "while :; do sleep infinity; done"]
# command: ["./bin/bot"]
# For development we just run air
command: ["air", "-c", ".air-bot.toml"]
restart: always

web:
build:
context: .
dockerfile: Dockerfile
target: dev
container_name: web
depends_on:
- bot
env_file:
- path: ./.env
volumes:
- ./bin:/app/bin
# command: ["./bin/web"]
# For development we just run air
command: ["air"]
restart: always

postgres:
Expand Down
Binary file added docs/images/screen-bot-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/screen-bot-settings2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/screen-create-app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/screen-new-app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 27 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,50 @@ module github.com/faulteh/nap-and-go
go 1.23.4

require (
github.com/bwmarrin/discordgo v0.28.1
github.com/gin-gonic/gin v1.10.0
gorm.io/driver/postgres v1.5.11
gorm.io/gorm v1.25.12
)

require (
github.com/bwmarrin/discordgo v0.28.1 // indirect
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.7.2 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.31.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/faulteh/nap-and-go/pkg => ./pkg

replace github.com/faulteh/nap-and-go/config => ./config

replace github.com/faulteh/nap-and-go/db => ./db
Loading

0 comments on commit 56fb376

Please sign in to comment.