You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
4.0 KiB

package message
import (
"context"
"github.com/go-faster/errors"
"github.com/gotd/td/telegram/message/entity"
"github.com/gotd/td/telegram/message/styling"
"github.com/gotd/td/tg"
)
func performTextOptions(media *tg.InputSingleMedia, opts []StyledTextOption) error {
if len(opts) > 0 {
tb := entity.Builder{}
if err := styling.Perform(&tb, opts...); err != nil {
return err
}
media.Message, media.Entities = tb.Complete()
}
return nil
}
// Media adds given media attachment to message.
func Media(media tg.InputMediaClass, caption ...StyledTextOption) MediaOption {
return mediaOptionFunc(func(ctx context.Context, b *multiMediaBuilder) error {
singleMedia := tg.InputSingleMedia{
Media: media,
}
if err := performTextOptions(&singleMedia, caption); err != nil {
return err
}
b.media = append(b.media, singleMedia)
return nil
})
}
// Album sends message with multiple media attachments.
func (b *Builder) Album(ctx context.Context, media MultiMediaOption, album ...MultiMediaOption) (tg.UpdatesClass, error) {
p, err := b.peer(ctx)
if err != nil {
return nil, errors.Wrap(err, "peer")
}
if len(album) < 1 {
return b.Media(ctx, media)
}
mb, err := b.applyMedia(ctx, p, media, album...)
if err != nil {
return nil, err
}
upd, err := b.sender.sendMultiMedia(ctx, &tg.MessagesSendMultiMediaRequest{
Silent: b.silent,
Background: b.background,
ClearDraft: b.clearDraft,
Peer: p,
ReplyToMsgID: b.replyToMsgID,
MultiMedia: mb,
ScheduleDate: b.scheduleDate,
})
if err != nil {
return nil, errors.Wrap(err, "send album")
}
return upd, nil
}
func (b *Builder) applyMedia(
ctx context.Context,
p tg.InputPeerClass,
media MultiMediaOption, album ...MultiMediaOption,
) ([]tg.InputSingleMedia, error) {
mb := multiMediaBuilder{
sender: b.sender,
peer: p,
media: make([]tg.InputSingleMedia, 0, len(album)+1),
}
if err := media.applyMulti(ctx, &mb); err != nil {
return nil, errors.Wrap(err, "media first option")
}
if len(album) > 0 {
for i, opt := range album {
if err := opt.applyMulti(ctx, &mb); err != nil {
return nil, errors.Wrapf(err, "media option %d", i+2)
}
}
}
return mb.media, nil
}
// Media sends message with media attachment.
func (b *Builder) Media(ctx context.Context, media MediaOption) (tg.UpdatesClass, error) {
p, err := b.peer(ctx)
if err != nil {
return nil, errors.Wrap(err, "peer")
}
attachment, err := b.applySingleMedia(ctx, p, media)
if err != nil {
return nil, err
}
upd, err := b.sender.sendMedia(ctx, &tg.MessagesSendMediaRequest{
Silent: b.silent,
Background: b.background,
ClearDraft: b.clearDraft,
Peer: p,
ReplyToMsgID: b.replyToMsgID,
Media: attachment.Media,
Message: attachment.Message,
ReplyMarkup: b.replyMarkup,
Entities: attachment.Entities,
ScheduleDate: b.scheduleDate,
})
if err != nil {
return nil, errors.Wrap(err, "send media")
}
return upd, nil
}
func (b *Builder) applySingleMedia(
ctx context.Context,
p tg.InputPeerClass,
media MediaOption,
) (tg.InputSingleMedia, error) {
mb := multiMediaBuilder{
sender: b.sender,
peer: p,
media: make([]tg.InputSingleMedia, 0, 1),
}
if err := media.apply(ctx, &mb); err != nil {
return tg.InputSingleMedia{}, errors.Wrap(err, "media first option")
}
return mb.media[0], nil
}
// UploadMedia uses messages.uploadMedia to upload a file and associate it to
// a chat (without actually sending it to the chat).
//
// See https://core.telegram.org/method/messages.uploadMedia.
func (b *Builder) UploadMedia(ctx context.Context, media MediaOption) (tg.MessageMediaClass, error) {
p, err := b.peer(ctx)
if err != nil {
return nil, errors.Wrap(err, "peer")
}
attachment, err := b.applySingleMedia(ctx, p, media)
if err != nil {
return nil, err
}
r, err := b.sender.uploadMedia(ctx, &tg.MessagesUploadMediaRequest{
Peer: p,
Media: attachment.Media,
})
if err != nil {
return nil, errors.Wrap(err, "upload media")
}
return r, nil
}