mirror of
https://github.com/watn3y/steamsalty.git
synced 2025-10-25 09:51:02 +02:00
Compare commits
12 commits
c6c7480493
...
b55e60bcc7
| Author | SHA1 | Date | |
|---|---|---|---|
| b55e60bcc7 | |||
| 1b93bab69f | |||
| 70d36e32d2 | |||
| 22c01b54b8 | |||
| 9f582e4c75 | |||
| 038d375ae7 | |||
| f17601c470 | |||
| ac2146af1b | |||
| 6e4575f298 | |||
| f445fef85a | |||
| f3dec30b56 | |||
| 1e94b1fc1e |
15 changed files with 319 additions and 40 deletions
10
.env.example
Normal file
10
.env.example
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
STEAMSALTY_LOGLEVEL=
|
||||||
|
STEAMSALTY_CHATID=
|
||||||
|
STEAMSALTY_WATCHERS=
|
||||||
|
STEAMSALTY_SLEEPINTERVAL=
|
||||||
|
STEAMSALTY_TRANSLATE_ENABLED=
|
||||||
|
STEAMSALTY_TRANSLATE_LANGUAGE=
|
||||||
|
STEAMSALTY_TELEGRAM_APITOKEN=
|
||||||
|
STEAMSALTY_STEAMAPIKEY=
|
||||||
|
STEAMSALTY_DEEPL_APIKEY=
|
||||||
|
STEAMSALTY_DEEPL_FREETIER=
|
||||||
11
.github/workflows/on-push.yml
vendored
11
.github/workflows/on-push.yml
vendored
|
|
@ -8,6 +8,7 @@ on:
|
||||||
- 'go.sum'
|
- 'go.sum'
|
||||||
- 'Dockerfile'
|
- 'Dockerfile'
|
||||||
- '.github/workflows/**'
|
- '.github/workflows/**'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
@ -21,14 +22,14 @@ jobs:
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
username: ${{secrets.DOCKERHUB_USERNAME}}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{secrets.DOCKERHUB_TOKEN}}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: docker/build-push-action@v6
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v7,linux/riscv64
|
platforms: linux/amd64,linux/386,linux/arm64,linux/arm/v7,linux/riscv64
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
${{ github.repository }}:${{ github.ref_name }}
|
${{ github.repository }}:commit-${{ github.sha }}
|
||||||
${{ github.repository }}:commit-${{ github.sha }}
|
${{ github.ref_name == 'master' && format('{0}:{1}', github.repository, github.ref_name) || '' }}
|
||||||
|
|
|
||||||
12
.vscode/launch.json
vendored
Normal file
12
.vscode/launch.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch Package",
|
||||||
|
"type": "go",
|
||||||
|
"request": "launch",
|
||||||
|
"mode": "auto",
|
||||||
|
"program": "${workspaceRoot}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
38
README.md
38
README.md
|
|
@ -1,6 +1,6 @@
|
||||||
# SteamSalty
|
# SteamSalty
|
||||||
|
|
||||||
SteamSalty notifies you on telegram about new comments on any steam profile.
|
SteamSalty notifies you on telegram about new comments on any steam profile **with built in auto translation**.
|
||||||
|
|
||||||
## Running with Docker Compose
|
## Running with Docker Compose
|
||||||
|
|
||||||
|
|
@ -18,11 +18,15 @@ services:
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
environment:
|
environment:
|
||||||
#- STEAMSALTY_LOGLEVEL=
|
#- STEAMSALTY_LOGLEVEL=
|
||||||
- STEAMSALTY_TELEGRAMAPITOKEN=
|
|
||||||
- STEAMSALTY_STEAMAPIKEY=
|
|
||||||
- STEAMSALTY_CHATID=
|
- STEAMSALTY_CHATID=
|
||||||
- STEAMSALTY_WATCHERS=
|
- STEAMSALTY_WATCHERS=
|
||||||
#- STEAMSALTY_SLEEPINTERVAL=
|
- STEAMSALTY_SLEEPINTERVAL=
|
||||||
|
#- STEAMSALTY_TRANSLATE_ENABLED=
|
||||||
|
#- STEAMSALTY_TRANSLATE_LANGUAGE=
|
||||||
|
- STEAMSALTY_TELEGRAM_APITOKEN=
|
||||||
|
- STEAMSALTY_STEAMAPIKEY=
|
||||||
|
#- STEAMSALTY_DEEPL_APIKEY=
|
||||||
|
#- STEAMSALTY_DEEPL_FREETIER=
|
||||||
```
|
```
|
||||||
|
|
||||||
## Running on Linux
|
## Running on Linux
|
||||||
|
|
@ -34,11 +38,21 @@ Grab a release from the [releases page](https://github.com/watn3y/steamsalty/rel
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> For development purposes, SteamSalty supports loading environment variables from a .env file placed in the project root directory.
|
> For development purposes, SteamSalty supports loading environment variables from a .env file placed in the project root directory.
|
||||||
|
|
||||||
| Variable | Description | Default | Required |
|
| Variable | Description | Default | Required | Example |
|
||||||
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------| ------------------ | -------------- |
|
|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|----------|-----------------------------------------------|
|
||||||
| `STEAMSALTY_LOGLEVEL` | LogLevel as described [in the zerolog documentation](https://pkg.go.dev/github.com/rs/zerolog@v1.34.0#readme-simple-leveled-logging-example) | 1 (Info) | ❌ |
|
| `STEAMSALTY_LOGLEVEL` | LogLevel as described [in the zerolog documentation](https://pkg.go.dev/github.com/rs/zerolog@v1.34.0#readme-simple-leveled-logging-example) | 1 (Info) | ❌ | 1 |
|
||||||
| `STEAMSALTY_TELEGRAMAPITOKEN` | Telegram BotToken, get it from [@BotFather on Telegram](https://t.me/BotFather) | None | ✅ |
|
| `STEAMSALTY_SLEEPINTERVAL` | Amount of time to wait between requests to Steam in seconds | 60 | ❌ | 60 |
|
||||||
| `STEAMSALTY_STEAMAPIKEY` | Steam API Key, get it from [steamcommunity.com/dev/apikey](https://steamcommunity.com/dev/apikey) | None | ✅ |
|
| `STEAMSALTY_TRANSLATE_ENABLED` | Whether to enable translation of comments | False | ❌ | True, False |
|
||||||
| `STEAMSALTY_CHATID` | Chat to notify about new comments | None | ✅ |
|
| `STEAMSALTY_TRANSLATE_LANGUAGE` | Language to translate as described [in the DeepL API documentation](https://developers.deepl.com/docs/getting-started/supported-languages#translation-target-languages) | EN-US | ❌ | EN-US,DE |
|
||||||
| `STEAMSALTY_WATCHERS` | SteamIDs (in SteamID64 format) to check for new profile comments | None | ✅ |
|
| `STEAMSALTY_CHATID` | Chat to notify about new comments | None | ✅ | -1001234567890 |
|
||||||
| `STEAMSALTY_SLEEPINTERVAL` | Amount of time to wait between requests to Steam in seconds | 60 | ❌ |
|
| `STEAMSALTY_WATCHERS` | SteamIDs (in SteamID64 format) to check for new profile comments | None | ✅ | 76561198012345678,76561198087654321 |
|
||||||
|
| `STEAMSALTY_TELEGRAMAPITOKEN` | Telegram BotToken, get it from [@BotFather on Telegram](https://t.me/BotFather) | None | ✅ | 1234567890:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw |
|
||||||
|
| `STEAMSALTY_STEAMAPIKEY` | Steam API Key, get it from [steamcommunity.com/dev/apikey](https://steamcommunity.com/dev/apikey) | None | ✅ | A7B3C9D2E5F1A4B8C6D9E2F5A8B1C4D7E0F3A6B9 |
|
||||||
|
| `STEAMSALTY_DEEPL_APIKEY` | DeepL API Key, get it from [deepl.com/en/your-account/keys](https://www.deepl.com/en/your-account/keys) | None | ❌ | a1b2c3d4-56e7-89f0-a1b2-c3d4e5f6a7b8:fx |
|
||||||
|
| `STEAMSALTY_DEEPL_FREETIER` | Whether you are using the DeepL Free Tier | True | ❌ | True, False |
|
||||||
|
|
||||||
|
## Nice to know
|
||||||
|
|
||||||
|
### Semantic Versioning
|
||||||
|
|
||||||
|
This project does it's best to follow [Semantic Versioning](https://semver.org/#semantic-versioning-200), however I can't guarantee anything.
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
package botIO
|
package botIO
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"watn3y/steamsalty/config"
|
||||||
|
|
||||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"watn3y/steamsalty/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Authenticate() (tgbotapi.UpdatesChannel, *tgbotapi.BotAPI) {
|
func Authenticate() (tgbotapi.UpdatesChannel, *tgbotapi.BotAPI) {
|
||||||
bot, err := tgbotapi.NewBotAPI(config.BotConfig.TelegramAPIToken)
|
bot, err := tgbotapi.NewBotAPI(config.BotConfig.Telegram.APIToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic().Err(err).Msg("Failed to authenticate to Telegram")
|
log.Fatal().Err(err).Msg("Failed to authenticate to Telegram")
|
||||||
}
|
}
|
||||||
|
|
||||||
bot.Debug = false
|
bot.Debug = false
|
||||||
|
|
|
||||||
|
|
@ -2,28 +2,31 @@ package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/joho/godotenv"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/joho/godotenv"
|
|
||||||
envconfig "github.com/sethvargo/go-envconfig"
|
envconfig "github.com/sethvargo/go-envconfig"
|
||||||
)
|
)
|
||||||
|
|
||||||
var BotConfig config
|
var BotConfig config
|
||||||
|
|
||||||
func LoadConfig() {
|
func LoadConfig() {
|
||||||
|
if err := godotenv.Load(); err != nil {
|
||||||
if err := godotenv.Load(); err != nil {
|
|
||||||
log.Info().Err(err).Msg("Failed to load .env file, using the system environment")
|
log.Info().Err(err).Msg("Failed to load .env file, using the system environment")
|
||||||
} else {
|
} else {
|
||||||
log.Info().Err(err).Msg(".env file loaded successfully")
|
log.Info().Err(err).Msg(".env file loaded successfully")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := envconfig.Process(context.Background(), &BotConfig); err != nil {
|
if err := envconfig.Process(context.Background(), &BotConfig); err != nil {
|
||||||
log.Panic().Err(err).Msg("Failed to parse config from env variables")
|
log.Fatal().Err(err).Msg("Failed to parse config from env variables")
|
||||||
}
|
}
|
||||||
zerolog.SetGlobalLevel(zerolog.Level(BotConfig.LogLevel))
|
zerolog.SetGlobalLevel(zerolog.Level(BotConfig.LogLevel))
|
||||||
|
|
||||||
|
BotConfig.Translate.Language = strings.ToUpper(BotConfig.Translate.Language)
|
||||||
|
|
||||||
|
|
||||||
log.Info().Msg("Config loaded successfully")
|
log.Info().Msg("Config loaded successfully")
|
||||||
log.Debug().Interface("config", BotConfig).Msg("")
|
log.Debug().Interface("config", BotConfig).Msg("")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,27 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
LogLevel int `env:"STEAMSALTY_LOGLEVEL, default=1"`
|
LogLevel int `env:"STEAMSALTY_LOGLEVEL, default=1"`
|
||||||
TelegramAPIToken string `env:"STEAMSALTY_TELEGRAMAPITOKEN, required"`
|
|
||||||
SteamAPIKey string `env:"STEAMSALTY_STEAMAPIKEY, required"`
|
ChatID int64 `env:"STEAMSALTY_CHATID, required"`
|
||||||
ChatID int64 `env:"STEAMSALTY_CHATID, required"`
|
Watchers []uint64 `env:"STEAMSALTY_WATCHERS, required"`
|
||||||
Watchers []uint64 `env:"STEAMSALTY_WATCHERS, required"`
|
SleepInterval int `env:"STEAMSALTY_SLEEPINTERVAL, default=60"`
|
||||||
SleepInterval int `env:"STEAMSALTY_SLEEPINTERVAL, default=60"`
|
|
||||||
|
Translate struct {
|
||||||
|
Enabled bool `env:"STEAMSALTY_TRANSLATE_ENABLED, default=False"`
|
||||||
|
Language string `env:"STEAMSALTY_TRANSLATE_LANGUAGE, default=EN-US"`
|
||||||
|
}
|
||||||
|
|
||||||
|
Telegram struct {
|
||||||
|
APIToken string `env:"STEAMSALTY_TELEGRAM_APITOKEN, required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
Steam struct {
|
||||||
|
APIKey string `env:"STEAMSALTY_STEAMAPIKEY, required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
DeepL struct {
|
||||||
|
APIKey string `env:"STEAMSALTY_DEEPL_APIKEY"`
|
||||||
|
FreeTier bool `env:"STEAMSALTY_DEEPL_FREETIER, default=True"`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
60
deepL/http.go
Normal file
60
deepL/http.go
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
package deepl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func get(endpoint string) (responseBody []byte, err error) {
|
||||||
|
httpReq, _ := http.NewRequest("GET", client.baseURL+endpoint, nil)
|
||||||
|
httpReq.Header.Set("Authorization", "DeepL-Auth-Key "+client.authKey)
|
||||||
|
|
||||||
|
resp, err := client.httpClient.Do(httpReq)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("endpoint", endpoint).Msg("Failed to send GET request to DeepL API")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
log.Error().Str("response", resp.Status).Str("endpoint", endpoint).Msg("Failed to send GET request to DeepL API, non 200 HTTP response")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
respBody, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("endpoint", endpoint).Msg("Failed to read DeepL API response")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return respBody, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func post(endpoint string, data []byte) (responseBody []byte, err error) {
|
||||||
|
httpReq, _ := http.NewRequest("POST", client.baseURL+endpoint, bytes.NewReader(data))
|
||||||
|
httpReq.Header.Set("Authorization", "DeepL-Auth-Key "+client.authKey)
|
||||||
|
httpReq.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := client.httpClient.Do(httpReq)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("endpoint", endpoint).Msg("Failed to send request to POST DeepL API")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
log.Error().Str("response", resp.Status).Str("endpoint", endpoint).Msg("Failed to send POST request to DeepL API, non 200 HTTP response")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
respBody, err := io.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Str("endpoint", endpoint).Msg("Failed to read DeepL API response")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return respBody, nil
|
||||||
|
}
|
||||||
108
deepL/translate.go
Normal file
108
deepL/translate.go
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
package deepl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
"watn3y/steamsalty/config"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var client *apiClient
|
||||||
|
|
||||||
|
var SourceLanguages map[string]string
|
||||||
|
var TargetLanguages map[string]string
|
||||||
|
|
||||||
|
func Init() {
|
||||||
|
log.Info().Msg("Translation is enabled, creating HTTP client for DeepL API")
|
||||||
|
baseURL := baseURLPro
|
||||||
|
if config.BotConfig.DeepL.FreeTier {
|
||||||
|
baseURL = baseURLFree
|
||||||
|
}
|
||||||
|
|
||||||
|
client = &apiClient{
|
||||||
|
authKey: config.BotConfig.DeepL.APIKey,
|
||||||
|
baseURL: baseURL,
|
||||||
|
httpClient: &http.Client{Timeout: 30 * time.Second},
|
||||||
|
}
|
||||||
|
|
||||||
|
err := getAndValidateLanguages()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("Failed to set up languages")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Translate(text string) (translatedText string, sourceLanguage string, err error) {
|
||||||
|
log.Debug().Str("text", text).Msg("Starting translation")
|
||||||
|
req := translateRequest{
|
||||||
|
Text: []string{text},
|
||||||
|
TargetLang: config.BotConfig.Translate.Language,
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(req)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to ")
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
respBody, err := post("/translate", body)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to make DeepL API request")
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result translateResponse
|
||||||
|
err = json.Unmarshal(respBody, &result)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to parse DeepL API response")
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.Translations[0].Text, result.Translations[0].DetectedSourceLanguage, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAndValidateLanguages() (err error) {
|
||||||
|
log.Info().Msg("Setting up supported languages")
|
||||||
|
respBody, err := get("/languages?type=source")
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to make DeepL API request")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var parsedResp languagesResponse
|
||||||
|
err = json.Unmarshal(respBody, &parsedResp)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to parse DeepL API response")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceLanguages = make(map[string]string)
|
||||||
|
for _, l := range parsedResp {
|
||||||
|
SourceLanguages[l.Language] = l.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
respBody, err = get("/languages?type=target")
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to make DeepL API request")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(respBody, &parsedResp)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to parse DeepL API response")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
TargetLanguages = make(map[string]string)
|
||||||
|
for _, l := range parsedResp {
|
||||||
|
TargetLanguages[l.Language] = l.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := TargetLanguages[config.BotConfig.Translate.Language]; !ok {
|
||||||
|
return fmt.Errorf("Selected language not supported by DeepL")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
35
deepL/types.go
Normal file
35
deepL/types.go
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
package deepl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type translateResponse struct {
|
||||||
|
Translations []struct {
|
||||||
|
DetectedSourceLanguage string `json:"detected_source_language"`
|
||||||
|
Text string `json:"text"`
|
||||||
|
} `json:"translations"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type translateRequest struct {
|
||||||
|
Text []string `json:"text"`
|
||||||
|
TargetLang string `json:"target_lang"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type languagesResponse []struct {
|
||||||
|
Language string `json:"language"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
SupportsFormality bool `json:"supports_formality"` //unused
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type apiClient struct {
|
||||||
|
authKey string
|
||||||
|
baseURL string
|
||||||
|
httpClient *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
baseURLPro = "https://api.deepl.com/v2"
|
||||||
|
baseURLFree = "https://api-free.deepl.com/v2"
|
||||||
|
)
|
||||||
2
go.mod
2
go.mod
|
|
@ -6,13 +6,13 @@ require (
|
||||||
github.com/Philipp15b/go-steamapi v0.0.0-20210114153316-ec4fdd23b4c1
|
github.com/Philipp15b/go-steamapi v0.0.0-20210114153316-ec4fdd23b4c1
|
||||||
github.com/PuerkitoBio/goquery v1.10.3
|
github.com/PuerkitoBio/goquery v1.10.3
|
||||||
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
||||||
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/rs/zerolog v1.34.0
|
github.com/rs/zerolog v1.34.0
|
||||||
github.com/sethvargo/go-envconfig v1.3.0
|
github.com/sethvargo/go-envconfig v1.3.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/andybalholm/cascadia v1.3.3 // indirect
|
github.com/andybalholm/cascadia v1.3.3 // indirect
|
||||||
github.com/joho/godotenv v1.5.1 // indirect
|
|
||||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
golang.org/x/net v0.43.0 // indirect
|
golang.org/x/net v0.43.0 // indirect
|
||||||
|
|
|
||||||
8
main.go
8
main.go
|
|
@ -8,16 +8,18 @@ import (
|
||||||
|
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
"watn3y/steamsalty/config"
|
"watn3y/steamsalty/config"
|
||||||
|
deepl "watn3y/steamsalty/deepL"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
println("Starting SteamSalty...")
|
println("Starting SteamSalty...")
|
||||||
|
|
||||||
configureLogger()
|
configureLogger()
|
||||||
|
|
||||||
config.LoadConfig()
|
config.LoadConfig()
|
||||||
|
if config.BotConfig.Translate.Enabled {
|
||||||
|
deepl.Init()
|
||||||
|
}
|
||||||
|
|
||||||
bot()
|
bot()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
func GetPlayerDetails(steamID uint64) (summary steamapi.PlayerSummary) {
|
func GetPlayerDetails(steamID uint64) (summary steamapi.PlayerSummary) {
|
||||||
|
|
||||||
response, err := steamapi.GetPlayerSummaries([]uint64{steamID}, config.BotConfig.SteamAPIKey)
|
response, err := steamapi.GetPlayerSummaries([]uint64{steamID}, config.BotConfig.Steam.APIKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Failed to retrive player summary")
|
log.Error().Err(err).Msg("Failed to retrive player summary")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ func GetComments(steamID uint64, start int, count int) (page CommentsPage) {
|
||||||
body, err := io.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Failed to parse comments")
|
log.Error().Err(err).Msg("Failed to parse comments")
|
||||||
log.Trace().Interface("Body", resp.Body)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(body, &page)
|
err = json.Unmarshal(body, &page)
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,18 @@ package steam
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"watn3y/steamsalty/botIO"
|
"watn3y/steamsalty/botIO"
|
||||||
"watn3y/steamsalty/config"
|
"watn3y/steamsalty/config"
|
||||||
|
deepl "watn3y/steamsalty/deepL"
|
||||||
|
|
||||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var steamContentCheckText string = "This comment is awaiting analysis by our automated content check system. It will be temporarily hidden until we verify that it does not contain harmful content (e.g. links to websites that attempt to steal information)."
|
const steamContentCheckText string = "This comment is awaiting analysis by our automated content check system. It will be temporarily hidden until we verify that it does not contain harmful content (e.g. links to websites that attempt to steal information)."
|
||||||
|
|
||||||
func StartWatchers(bot *tgbotapi.BotAPI) {
|
func StartWatchers(bot *tgbotapi.BotAPI) {
|
||||||
|
|
||||||
|
|
@ -69,9 +68,27 @@ func watcher(bot *tgbotapi.BotAPI, steamID uint64, sleeptime time.Duration) {
|
||||||
Text: fmt.Sprintf(`<b><a href="%s">%s</a> just commented on <a href="%s">%s</a>'s profile:</b>`, comment.AuthorProfileURL, comment.Author, profileOwner.ProfileURL, profileOwner.PersonaName) + "\n" +
|
Text: fmt.Sprintf(`<b><a href="%s">%s</a> just commented on <a href="%s">%s</a>'s profile:</b>`, comment.AuthorProfileURL, comment.Author, profileOwner.ProfileURL, profileOwner.PersonaName) + "\n" +
|
||||||
"<blockquote>" + comment.Text + "</blockquote>",
|
"<blockquote>" + comment.Text + "</blockquote>",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.BotConfig.Translate.Enabled {
|
||||||
|
translatedText, translatedTextLanguage, err := deepl.Translate(comment.Text)
|
||||||
|
if translatedTextLanguage == config.BotConfig.Translate.Language {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("Failed to translate comment, continuing without translation")
|
||||||
|
msg.Text += "\n" + "Translation failed"
|
||||||
|
|
||||||
|
} else {
|
||||||
|
msg.Text += "\n" +
|
||||||
|
fmt.Sprintf(`Translated from %s:`, deepl.SourceLanguages[translatedTextLanguage]) + "\n" +
|
||||||
|
"<blockquote>" + translatedText + "</blockquote>"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
log.Info().Interface("Comment", comment).Msg("Notifying about new comment")
|
log.Info().Interface("Comment", comment).Msg("Notifying about new comment")
|
||||||
botIO.SendMessage(msg, bot)
|
botIO.SendMessage(msg, bot)
|
||||||
time.Sleep(time.Minute / 20)
|
time.Sleep(time.Second * 3) //I have no Idea why this is here
|
||||||
}
|
}
|
||||||
|
|
||||||
newestProcessedComment = currentCommentsPage.TimeLastPost
|
newestProcessedComment = currentCommentsPage.TimeLastPost
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue