Refactoring & allow Discord avatar, custom server ID

This commit is contained in:
Aram 🍐 2023-07-22 19:20:55 -04:00
parent 71ed01df58
commit 9fbbd2cd22
4 changed files with 99 additions and 39 deletions

View file

@ -14,7 +14,10 @@ This program is configured using environment variables:
- `TS_QUERY_ADDR`: Address to the TeamSpeak ServerQuery port. Example: `127.0.0.1:10011`
- `TS_QUERY_USER`: The username you selected for ServerQuery in the setup
- `TS_QUERY_PASS`: The password TeamSpeak generated for ServerQuery in the setup
- `TS_QUERY_SERVER_ID`: Virtual server ID to monitor. Defaults to `1`
- `TS_DISCORD_WEBHOOK`: Webhook URL for Discord. You can create this from the channel "Integrations" page
- `TS_DISCORD_AVATAR`: Optional URL for Discord bot avatar
- `TS_DISCORD_USERNAME`: Optional nickname for Discord bot
## Run it
[![docker hub](https://img.shields.io/docker/v/aramperes/ts-activity?color=%232496ed&label=docker%20hub&logo=docker&logoColor=fff&sort=semver)](https://hub.docker.com/r/aramperes/ts-activity)

119
cmd.go
View file

@ -1,6 +1,7 @@
package main
import (
"errors"
"fmt"
"log"
"os"
@ -10,26 +11,83 @@ import (
"github.com/multiplay/go-ts3"
)
// App holds the configuration
type App struct {
discordURL string
discordUsername string
discordAvatarURL *string
tsQueryAddr string
tsQueryUser string
tsQueryPass string
tsQueryServerID int
}
func appFromEnv() (*App, error) {
discordURL := os.Getenv("TS_DISCORD_WEBHOOK")
if discordURL == "" {
return nil, errors.New("must configure: TS_DISCORD_WEBHOOK")
}
discordUsername := os.Getenv("TS_DISCORD_USERNAME")
if discordUsername == "" {
discordUsername = "TeamSpeak"
}
var discordAvatarURL *string = nil
if val, ok := os.LookupEnv("TS_DISCORD_AVATAR"); ok {
discordAvatarURL = &val
}
tsQueryAddr := os.Getenv("TS_QUERY_ADDR")
if tsQueryAddr == "" {
return nil, errors.New("must configure: TS_QUERY_ADDR")
}
tsQueryUser := os.Getenv("TS_QUERY_USER")
if tsQueryUser == "" {
return nil, errors.New("must configure: TS_QUERY_USER")
}
tsQueryPass := os.Getenv("TS_QUERY_PASS")
if tsQueryPass == "" {
return nil, errors.New("must configure: TS_QUERY_PASS")
}
tsQueryServerID := 1
if val, ok := os.LookupEnv("TS_QUERY_SERVER_ID"); ok {
val, err := strconv.Atoi(val)
if err == nil {
tsQueryServerID = val
} else {
return nil, errors.New("invalid TS_QUERY_SERVER_ID, must be int")
}
}
return &App{
discordURL: discordURL,
discordUsername: discordUsername,
discordAvatarURL: discordAvatarURL,
tsQueryAddr: tsQueryAddr,
tsQueryUser: tsQueryUser,
tsQueryPass: tsQueryPass,
tsQueryServerID: tsQueryServerID,
}, nil
}
func main() {
discord := os.Getenv("TS_DISCORD_WEBHOOK")
if discord == "" {
log.Fatal("Must configure: TS_DISCORD_WEBHOOK")
app, err := appFromEnv()
if err != nil {
log.Fatal(err)
}
// Connect and login
c, err := ts3.NewClient(os.Getenv("TS_QUERY_ADDR"))
c, err := ts3.NewClient(app.tsQueryAddr)
if err != nil {
log.Fatal(err)
}
defer c.Close()
user := os.Getenv("TS_QUERY_USER")
pass := os.Getenv("TS_QUERY_PASS")
if err := c.Login(user, pass); err != nil {
if err := c.Login(app.tsQueryUser, app.tsQueryPass); err != nil {
log.Fatal(err)
}
if err := c.Use(1); err != nil {
if err := c.Use(app.tsQueryServerID); err != nil {
log.Fatal(err)
}
@ -66,7 +124,6 @@ func main() {
for {
event := <-notifs
log.Println("=>", event)
if event.Type == "cliententerview" {
if event.Data["client_type"] != "0" {
@ -89,7 +146,7 @@ func main() {
clientMap[clientID] = clientNick
if !previous {
clientConnected(discord, clientNick)
app.clientConnected(clientNick)
}
} else if event.Type == "clientleftview" {
clientID, ok := event.Data["clid"]
@ -105,41 +162,29 @@ func main() {
}
delete(clientMap, clientID)
clientDisconnected(discord, clientNick)
app.clientDisconnected(clientNick)
}
}
}
func clientConnected(discord string, nick string) {
bot := os.Getenv("TS_DISCORD_USERNAME")
if bot == "" {
bot = "Jeff"
func (app *App) sendWebhook(content string) {
message := discordwebhook.Message{
Username: &app.discordUsername,
Content: &content,
AvatarUrl: app.discordAvatarURL,
}
if err := discordwebhook.SendMessage(app.discordURL, message); err != nil {
log.Println("Failed to log Discord message:", err)
}
}
func (app *App) clientConnected(nick string) {
content := fmt.Sprintf("Client connected: %s", nick)
message := discordwebhook.Message{
Username: &bot,
Content: &content,
}
if err := discordwebhook.SendMessage(discord, message); err != nil {
log.Println("Failed to log Discord message:", err)
}
app.sendWebhook(content)
}
func clientDisconnected(discord string, nick string) {
bot := os.Getenv("TS_DISCORD_USERNAME")
if bot == "" {
bot = "Jeff"
}
func (app *App) clientDisconnected(nick string) {
content := fmt.Sprintf("Client disconnected: %s", nick)
message := discordwebhook.Message{
Username: &bot,
Content: &content,
}
if err := discordwebhook.SendMessage(discord, message); err != nil {
log.Println("Failed to log Discord message:", err)
}
app.sendWebhook(content)
}

View file

@ -32,8 +32,16 @@ spec:
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
{{- with .Values.config.discordUsername }}
- name: TS_DISCORD_USERNAME
value: "{{ .Values.config.discordUsername | default "Jeff" }}"
value: {{ . | quote }}
{{- end }}
{{- with .Values.config.discordAvatar }}
- name: TS_DISCORD_AVATAR
value: {{ . | quote }}
{{- end }}
- name: TS_QUERY_SERVER_ID
value: {{ .Values.config.serverQueryId | quote }}
- name: TS_QUERY_ADDR
value: "{{ .Values.config.serverQueryAddr | required "must provide serverQueryAddr" }}"
- name: TS_QUERY_USER

View file

@ -5,19 +5,23 @@
image:
repository: aramperes/ts-activity
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart version.
# Overrides the image tag whose default is the chart appVersion.
tag: ""
config:
# Discord username displayed in webhook messages.
# Defaults to 'Jeff'
discordUsername: ""
# Discord avatar displayed in webhook messages.
discordAvatar: ""
# Address to plain ServerQuery. Usually <ts_host>:10011
serverQueryAddr: ""
# Secret containing 'username' and 'password' for ServerQuery.
serverQuerySecret: ""
# Secret containing 'discord' with the Webhook URL.
webhookSecret: ""
# TeamSpeak virtual server ID.
serverQueryId: 1
imagePullSecrets: []
nameOverride: ""