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
172 lines
4.0 KiB
3 years ago
|
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
|
||
|
}
|