Files

95 lines
2.6 KiB
Go

package telegram
import (
"context"
"fmt"
"git.yeij.top/AskaEth/Cyrene_v2/internal/channel/adapter"
)
// markdownParseMode is the parse_mode sent with outgoing text/captions so the
// Markdown capability is actually exercised.
const markdownParseMode = "Markdown"
// SendMessage delivers the reply messages contained in resp to their target
// chats. Each message goes to its own ChannelID (or GroupID) conversation.
func (a *Adapter) SendMessage(ctx context.Context, resp adapter.UnifiedResponse) error {
if err := a.requireConnected(); err != nil {
return err
}
for _, m := range resp.Messages {
if err := a.sendOne(ctx, m, resp.ReplyTo); err != nil {
return fmt.Errorf("telegram: send message: %w", err)
}
}
return nil
}
// SendProactive pushes a message not triggered by a recent inbound message.
// Telegram permits arbitrary proactive push, so this is only gated by the
// connection state.
func (a *Adapter) SendProactive(ctx context.Context, msg adapter.UnifiedMessage) error {
if err := a.requireConnected(); err != nil {
return err
}
return a.sendOne(ctx, msg, "")
}
// sendOne delivers a single message to its conversation, choosing the Bot API
// method that matches the content type and the presence of a file_id payload.
func (a *Adapter) sendOne(ctx context.Context, m adapter.UnifiedMessage, replyTo string) error {
chatID := m.ChannelID
if chatID == "" {
chatID = m.GroupID
}
if chatID == "" {
return fmt.Errorf("telegram: %w", ErrNoChatTarget)
}
replyToID := parseReplyToID(replyTo)
fileID := mediaFileID(m.Media)
switch m.ContentType {
case adapter.ContentImage:
if fileID != "" {
_, err := a.sendPhoto(ctx, chatID, fileID, replyToID, m.Content)
return err
}
case adapter.ContentVoice:
if fileID != "" {
_, err := a.sendVoice(ctx, chatID, fileID, replyToID, m.Content)
return err
}
case adapter.ContentFile:
if fileID != "" {
_, err := a.sendDocument(ctx, chatID, fileID, mediaFileName(m.Media), replyToID, m.Content)
return err
}
}
if m.Content == "" {
return fmt.Errorf("telegram: %w: empty message content", ErrBadResponse)
}
_, err := a.sendMessage(ctx, chatID, m.Content, replyToID, markdownParseMode)
return err
}
// mediaFileID returns the first non-empty file_id carried by the media list.
func mediaFileID(media []adapter.Media) string {
for _, md := range media {
if md.URL != "" {
return md.URL
}
}
return ""
}
// mediaFileName returns the first non-empty file name carried by the media list.
func mediaFileName(media []adapter.Media) string {
for _, md := range media {
if md.Name != "" {
return md.Name
}
}
return ""
}