feat(telegram): mark business messages as read and add tests for handling

- Implement markBusinessMessageRead function to mark messages as read
- Add tests for successful message read and failure scenarios
This commit is contained in:
Roman Stolyarchuk 2026-05-10 08:53:42 +03:00
parent fd405ef860
commit 4aa6ffb043
2 changed files with 108 additions and 0 deletions

View file

@ -787,9 +787,33 @@ func (c *TelegramChannel) handleBusinessMessage(ctx context.Context, message *te
if businessConnectionID == "" {
return fmt.Errorf("business message missing business_connection_id")
}
c.markBusinessMessageRead(ctx, businessConnectionID, message.Chat.ID, message.MessageID)
return c.handleTelegramMessage(ctx, message, businessConnectionID)
}
func (c *TelegramChannel) markBusinessMessageRead(
ctx context.Context,
businessConnectionID string,
chatID int64,
messageID int,
) {
if c == nil || c.bot == nil || strings.TrimSpace(businessConnectionID) == "" || chatID == 0 || messageID == 0 {
return
}
if err := c.bot.ReadBusinessMessage(ctx, &telego.ReadBusinessMessageParams{
BusinessConnectionID: businessConnectionID,
ChatID: chatID,
MessageID: messageID,
}); err != nil {
logger.DebugCF("telegram", "Failed to mark business message as read", map[string]any{
"business_connection_id": businessConnectionID,
"chat_id": chatID,
"message_id": messageID,
"error": err.Error(),
})
}
}
func (c *TelegramChannel) handleBusinessConnection(_ context.Context, connection telego.BusinessConnection) error {
if !c.businessModeEnabled() {
return nil

View file

@ -150,6 +150,90 @@ func newTestChannelWithConstructor(
}
}
func TestHandleBusinessMessage_MarksMessageRead(t *testing.T) {
messageBus := bus.NewMessageBus()
caller := &stubCaller{
callFn: func(ctx context.Context, url string, data *ta.RequestData) (*ta.Response, error) {
if !strings.Contains(url, "readBusinessMessage") {
t.Fatalf("unexpected API call: %s", url)
}
b, err := json.Marshal(true)
require.NoError(t, err)
return &ta.Response{Ok: true, Result: b}, nil
},
}
ch := newTestChannel(t, caller)
ch.BaseChannel = channels.NewBaseChannel("telegram", nil, messageBus, nil)
ch.BaseChannel.SetOwner(ch)
ch.ctx = context.Background()
ch.tgCfg.BusinessMode = true
msg := &telego.Message{
Text: "hello from business",
MessageID: 17,
BusinessConnectionID: "biz-conn-1",
Chat: telego.Chat{
ID: 777,
Type: "private",
},
From: &telego.User{
ID: 42,
FirstName: "Alice",
},
}
require.NoError(t, ch.handleBusinessMessage(context.Background(), msg))
require.Len(t, caller.calls, 1)
assert.Contains(t, caller.calls[0].URL, "readBusinessMessage")
var params struct {
BusinessConnectionID string `json:"business_connection_id"`
ChatID int64 `json:"chat_id"`
MessageID int `json:"message_id"`
}
require.NoError(t, json.Unmarshal(caller.calls[0].Data.BodyRaw, &params))
assert.Equal(t, "biz-conn-1", params.BusinessConnectionID)
assert.Equal(t, int64(777), params.ChatID)
assert.Equal(t, 17, params.MessageID)
inbound := <-messageBus.InboundChan()
assert.Equal(t, "hello from business", inbound.Content)
}
func TestHandleBusinessMessage_ReadFailureStillForwardsMessage(t *testing.T) {
messageBus := bus.NewMessageBus()
caller := &stubCaller{
callFn: func(ctx context.Context, url string, data *ta.RequestData) (*ta.Response, error) {
return nil, errors.New("missing can_read_messages")
},
}
ch := newTestChannel(t, caller)
ch.BaseChannel = channels.NewBaseChannel("telegram", nil, messageBus, nil)
ch.BaseChannel.SetOwner(ch)
ch.ctx = context.Background()
ch.tgCfg.BusinessMode = true
msg := &telego.Message{
Text: "still forward me",
MessageID: 18,
BusinessConnectionID: "biz-conn-1",
Chat: telego.Chat{
ID: 777,
Type: "private",
},
From: &telego.User{
ID: 42,
FirstName: "Alice",
},
}
require.NoError(t, ch.handleBusinessMessage(context.Background(), msg))
require.Len(t, caller.calls, 1)
inbound := <-messageBus.InboundChan()
assert.Equal(t, "still forward me", inbound.Content)
}
func TestSendMedia_ImageFallbacksToDocumentOnInvalidDimensions(t *testing.T) {
constructor := &multipartRecordingConstructor{}
caller := &stubCaller{