Files

82 lines
1.8 KiB
Go

package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"time"
)
// TelegramSender sends alerts to a Telegram chat via Bot API.
type TelegramSender struct {
botToken string
chatID string
client *http.Client
enabled bool
}
// NewTelegramSender creates a sender. Returns a no-op sender if token or chatID is empty.
func NewTelegramSender(botToken, chatID string) *TelegramSender {
return &TelegramSender{
botToken: botToken,
chatID: chatID,
client: &http.Client{
Timeout: 10 * time.Second,
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
},
},
enabled: botToken != "" && chatID != "",
}
}
// IsEnabled returns true if both token and chatID are configured.
func (t *TelegramSender) IsEnabled() bool {
return t.enabled
}
// SendAlert sends a formatted momentum alert to Telegram.
func (t *TelegramSender) SendAlert(alert BinanceAlert) error {
if !t.enabled {
return nil
}
// Build message
icon := "🔴"
directionWord := "暴跌"
if alert.Direction == "up" {
icon = "🟢"
directionWord = "暴涨"
}
sign := "+"
if alert.ChangePct < 0 {
sign = ""
}
text := fmt.Sprintf("%s *%s* %s %s%.2f%% | $%.4f",
icon, alert.Coin, directionWord, sign, alert.ChangePct, alert.Price)
payload := map[string]interface{}{
"chat_id": t.chatID,
"text": text,
"parse_mode": "Markdown",
}
body, _ := json.Marshal(payload)
url := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", t.botToken)
resp, err := t.client.Post(url, "application/json", bytes.NewReader(body))
if err != nil {
return fmt.Errorf("telegram API call failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("telegram API returned %d", resp.StatusCode)
}
log.Printf("[Telegram] Alert sent: %s %s %.2f%%", alert.Coin, alert.Direction, alert.ChangePct)
return nil
}