92 lines
1.7 KiB
Go
92 lines
1.7 KiB
Go
package telegram
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/d1nch8g/jules/chat"
|
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
|
"golang.org/x/net/proxy"
|
|
)
|
|
|
|
const BaseURL = tgbotapi.APIEndpoint
|
|
|
|
type Bot struct {
|
|
api *tgbotapi.BotAPI
|
|
}
|
|
|
|
func New(token, baseURL, proxyURL string) (*Bot, error) {
|
|
client := &http.Client{
|
|
Timeout: 30 * time.Second,
|
|
}
|
|
|
|
if proxyURL != "" {
|
|
proxyURL, _ := url.Parse(proxyURL)
|
|
dialer, err := proxy.FromURL(proxyURL, proxy.Direct)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
client.Transport = &http.Transport{
|
|
Dial: dialer.Dial,
|
|
}
|
|
}
|
|
|
|
api, err := tgbotapi.NewBotAPIWithClient(token, baseURL, client)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to connect to telegram: %w", err)
|
|
}
|
|
|
|
return &Bot{api: api}, nil
|
|
}
|
|
|
|
func (b *Bot) Send(_ context.Context, id string, text string) error {
|
|
chatID, err := strconv.ParseInt(id, 10, 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = b.api.Send(tgbotapi.NewMessage(chatID, text))
|
|
return err
|
|
}
|
|
|
|
func (b *Bot) Receive(ctx context.Context) <-chan chat.Message {
|
|
out := make(chan chat.Message)
|
|
updates := b.api.GetUpdatesChan(tgbotapi.NewUpdate(0))
|
|
|
|
go func() {
|
|
defer close(out)
|
|
defer b.api.StopReceivingUpdates()
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
|
|
case update := <-updates:
|
|
if update.Message != nil && update.Message.Chat != nil {
|
|
msg := chat.Message{
|
|
Chat: chat.Telegram,
|
|
ID: strconv.FormatInt(update.Message.Chat.ID, 10),
|
|
Text: update.Message.Text,
|
|
}
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
slog.Error("telegram chat can't deliver message, context done", "message", msg)
|
|
return
|
|
|
|
case out <- msg:
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
|
|
return out
|
|
}
|