Add configuration options for link generation in .env.example, docker-compose.yml, and main.go; update README.md with new environment variable descriptions.
Publish telemt-bot Docker image / build-and-push (push) Successful in 52s

This commit is contained in:
Denozordec
2026-03-09 17:57:34 +07:00
parent 5b5d99f7b1
commit d8ddc53640
4 changed files with 96 additions and 8 deletions
+78 -8
View File
@@ -3,6 +3,7 @@ package main
import (
"bytes"
"context"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
@@ -32,6 +33,10 @@ type config struct {
TelemtTimeout time.Duration
TelegramTimeout time.Duration
TelemtLinkHost string
TelemtLinkPort int
TelemtLinkTLSDomain string
}
type bot struct {
@@ -168,6 +173,9 @@ func loadConfig() (config, error) {
cfg.TelemtAPIAuth = strings.TrimSpace(os.Getenv("TELEMT_API_AUTH_HEADER"))
cfg.TelemtTimeout = parseSecondsEnv("TELEMT_HTTP_TIMEOUT_SECONDS", defaultTelemtTimeoutSeconds)
cfg.TelegramTimeout = parseSecondsEnv("TELEGRAM_HTTP_TIMEOUT_SECONDS", defaultTelegramTimeoutSeconds)
cfg.TelemtLinkHost = strings.TrimSpace(os.Getenv("TELEMT_LINK_HOST"))
cfg.TelemtLinkPort = parseIntEnv("TELEMT_LINK_PORT", 9443)
cfg.TelemtLinkTLSDomain = strings.TrimSpace(os.Getenv("TELEMT_TLS_DOMAIN"))
return cfg, nil
}
@@ -184,6 +192,18 @@ func parseSecondsEnv(key string, fallback int) time.Duration {
return time.Duration(v) * time.Second
}
func parseIntEnv(key string, fallback int) int {
raw := strings.TrimSpace(os.Getenv(key))
if raw == "" {
return fallback
}
v, err := strconv.Atoi(raw)
if err != nil || v <= 0 {
return fallback
}
return v
}
func (b *bot) run(ctx context.Context) error {
for {
select {
@@ -350,14 +370,7 @@ func (b *bot) handleCreateUser(ctx context.Context, chatID int64, text string) e
return b.sendMessage(ctx, chatID, "Ошибка создания пользователя: "+err.Error())
}
links := created.User.Links
if len(links.Classic) == 0 && len(links.Secure) == 0 && len(links.TLS) == 0 {
var fetched userInfo
path := "/v1/users/" + url.PathEscape(created.User.Username)
if err := b.callTelemt(ctx, path, &fetched); err == nil {
links = fetched.Links
}
}
links := b.resolveUserLinks(ctx, created.User.Username, created.Secret, created.User.Links)
msg := fmt.Sprintf("Пользователь создан: %s\nsecret: %s", created.User.Username, created.Secret)
if linksText := formatUserLinks(links); linksText != "" {
@@ -368,6 +381,63 @@ func (b *bot) handleCreateUser(ctx context.Context, chatID int64, text string) e
return b.sendMessage(ctx, chatID, msg)
}
func hasAnyLinks(links userLinks) bool {
return len(links.Classic) > 0 || len(links.Secure) > 0 || len(links.TLS) > 0
}
func (b *bot) resolveUserLinks(ctx context.Context, username, secret string, initial userLinks) userLinks {
if hasAnyLinks(initial) {
return initial
}
var fetched userInfo
path := "/v1/users/" + url.PathEscape(username)
if err := b.callTelemt(ctx, path, &fetched); err == nil && hasAnyLinks(fetched.Links) {
return fetched.Links
}
var users []userInfo
if err := b.callTelemt(ctx, "/v1/users", &users); err == nil {
for i := range users {
if users[i].Username == username && hasAnyLinks(users[i].Links) {
return users[i].Links
}
}
}
users = nil
if err := b.callTelemt(ctx, "/v1/stats/users", &users); err == nil {
for i := range users {
if users[i].Username == username && hasAnyLinks(users[i].Links) {
return users[i].Links
}
}
}
return b.generateLinksFromSecret(secret)
}
func (b *bot) generateLinksFromSecret(secret string) userLinks {
host := strings.TrimSpace(b.cfg.TelemtLinkHost)
if host == "" || secret == "" {
return userLinks{}
}
port := b.cfg.TelemtLinkPort
classic := fmt.Sprintf("tg://proxy?server=%s&port=%d&secret=%s", host, port, secret)
dd := fmt.Sprintf("tg://proxy?server=%s&port=%d&secret=dd%s", host, port, secret)
out := userLinks{
Classic: []string{classic},
Secure: []string{dd},
}
if b.cfg.TelemtLinkTLSDomain != "" {
hexDomain := hex.EncodeToString([]byte(b.cfg.TelemtLinkTLSDomain))
tls := fmt.Sprintf("tg://proxy?server=%s&port=%d&secret=ee%s%s", host, port, secret, hexDomain)
out.TLS = []string{tls}
}
return out
}
func formatUserLinks(links userLinks) string {
var sb strings.Builder
appendLinks := func(title string, items []string) {