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.
295 lines
8.7 KiB
295 lines
8.7 KiB
package message |
|
|
|
import ( |
|
"context" |
|
"encoding/hex" |
|
"time" |
|
|
|
"github.com/go-faster/errors" |
|
|
|
"github.com/gotd/td/tg" |
|
) |
|
|
|
// DocumentBuilder is a Document media option. |
|
type DocumentBuilder struct { |
|
doc tg.InputMediaDocument |
|
caption []StyledTextOption |
|
} |
|
|
|
// TTL sets time to live of self-destructing document. |
|
func (u *DocumentBuilder) TTL(ttl time.Duration) *DocumentBuilder { |
|
return u.TTLSeconds(int(ttl.Seconds())) |
|
} |
|
|
|
// TTLSeconds sets time to live in seconds of self-destructing document. |
|
func (u *DocumentBuilder) TTLSeconds(ttl int) *DocumentBuilder { |
|
u.doc.TTLSeconds = ttl |
|
return u |
|
} |
|
|
|
// Query sets query field of InputMediaDocument. |
|
func (u *DocumentBuilder) Query(query string) *DocumentBuilder { |
|
u.doc.Query = query |
|
return u |
|
} |
|
|
|
// apply implements MediaOption. |
|
func (u *DocumentBuilder) apply(ctx context.Context, b *multiMediaBuilder) error { |
|
return Media(&u.doc, u.caption...).apply(ctx, b) |
|
} |
|
|
|
// applyMulti implements MultiMediaOption. |
|
func (u *DocumentBuilder) applyMulti(ctx context.Context, b *multiMediaBuilder) error { |
|
return u.apply(ctx, b) |
|
} |
|
|
|
// Document adds document attachment. |
|
func Document(doc FileLocation, caption ...StyledTextOption) *DocumentBuilder { |
|
v := new(tg.InputDocument) |
|
v.FillFrom(doc) |
|
|
|
return &DocumentBuilder{ |
|
doc: tg.InputMediaDocument{ |
|
ID: v, |
|
}, |
|
caption: caption, |
|
} |
|
} |
|
|
|
// Document sends document. |
|
func (b *Builder) Document( |
|
ctx context.Context, file FileLocation, caption ...StyledTextOption, |
|
) (tg.UpdatesClass, error) { |
|
return b.Media(ctx, Document(file, caption...)) |
|
} |
|
|
|
// SearchDocumentBuilder is a Document media option which uses messages.getDocumentByHash |
|
// to find document. |
|
// |
|
// See https://core.telegram.org/method/messages.getDocumentByHash. |
|
// |
|
// See https://core.telegram.org/api/files#re-using-pre-uploaded-files. |
|
type SearchDocumentBuilder struct { |
|
hash []byte |
|
size int |
|
mime string |
|
builder *DocumentBuilder |
|
} |
|
|
|
// TTL sets time to live of self-destructing document. |
|
func (u *SearchDocumentBuilder) TTL(ttl time.Duration) *SearchDocumentBuilder { |
|
return u.TTLSeconds(int(ttl.Seconds())) |
|
} |
|
|
|
// TTLSeconds sets time to live in seconds of self-destructing document. |
|
func (u *SearchDocumentBuilder) TTLSeconds(ttl int) *SearchDocumentBuilder { |
|
u.builder.doc.TTLSeconds = ttl |
|
return u |
|
} |
|
|
|
// Query sets query field of InputMediaDocument. |
|
func (u *SearchDocumentBuilder) Query(query string) *SearchDocumentBuilder { |
|
u.builder.doc.Query = query |
|
return u |
|
} |
|
|
|
// apply implements MediaOption. |
|
func (u *SearchDocumentBuilder) apply(ctx context.Context, b *multiMediaBuilder) error { |
|
result, err := b.sender.getDocumentByHash(ctx, &tg.MessagesGetDocumentByHashRequest{ |
|
SHA256: u.hash, |
|
Size: u.size, |
|
MimeType: u.mime, |
|
}) |
|
if err != nil { |
|
return errors.Wrap(err, "find document") |
|
} |
|
|
|
doc, ok := result.AsNotEmpty() |
|
if !ok { |
|
return errors.Errorf("document with hash %q not found", hex.EncodeToString(u.hash)) |
|
} |
|
|
|
v := new(tg.InputDocument) |
|
v.FillFrom(doc) |
|
u.builder.doc.ID = v |
|
return Media(&u.builder.doc, u.builder.caption...).apply(ctx, b) |
|
} |
|
|
|
// applyMulti implements MultiMediaOption. |
|
func (u *SearchDocumentBuilder) applyMulti(ctx context.Context, b *multiMediaBuilder) error { |
|
return u.apply(ctx, b) |
|
} |
|
|
|
// DocumentByHash finds document by hash and adds as attachment. |
|
// |
|
// See https://core.telegram.org/method/messages.getDocumentByHash. |
|
// |
|
// See https://core.telegram.org/api/files#re-using-pre-uploaded-files. |
|
func DocumentByHash( |
|
hash []byte, size int, mime string, |
|
caption ...StyledTextOption, |
|
) *SearchDocumentBuilder { |
|
return &SearchDocumentBuilder{ |
|
hash: hash, |
|
size: size, |
|
mime: mime, |
|
builder: &DocumentBuilder{ |
|
caption: caption, |
|
}, |
|
} |
|
} |
|
|
|
// DocumentByHash finds document by hash and sends as attachment. |
|
func (b *Builder) DocumentByHash( |
|
ctx context.Context, hash []byte, size int, mime string, |
|
caption ...StyledTextOption, |
|
) (tg.UpdatesClass, error) { |
|
return b.Media(ctx, DocumentByHash(hash, size, mime, caption...)) |
|
} |
|
|
|
// DocumentExternalBuilder is a DocumentExternal media option. |
|
type DocumentExternalBuilder struct { |
|
doc tg.InputMediaDocumentExternal |
|
caption []StyledTextOption |
|
} |
|
|
|
// TTL sets time to live of self-destructing document. |
|
func (u *DocumentExternalBuilder) TTL(ttl time.Duration) *DocumentExternalBuilder { |
|
return u.TTLSeconds(int(ttl.Seconds())) |
|
} |
|
|
|
// TTLSeconds sets time to live in seconds of self-destructing document. |
|
func (u *DocumentExternalBuilder) TTLSeconds(ttl int) *DocumentExternalBuilder { |
|
u.doc.TTLSeconds = ttl |
|
return u |
|
} |
|
|
|
// apply implements MediaOption. |
|
func (u *DocumentExternalBuilder) apply(ctx context.Context, b *multiMediaBuilder) error { |
|
return Media(&u.doc, u.caption...).apply(ctx, b) |
|
} |
|
|
|
// DocumentExternal adds document attachment that will be downloaded by the Telegram servers. |
|
func DocumentExternal(url string, caption ...StyledTextOption) *DocumentExternalBuilder { |
|
return &DocumentExternalBuilder{ |
|
doc: tg.InputMediaDocumentExternal{ |
|
URL: url, |
|
}, |
|
caption: caption, |
|
} |
|
} |
|
|
|
// DocumentExternal sends document attachment that will be downloaded by the Telegram servers. |
|
func (b *Builder) DocumentExternal(ctx context.Context, url string, caption ...StyledTextOption) (tg.UpdatesClass, error) { |
|
return b.Media(ctx, DocumentExternal(url, caption...)) |
|
} |
|
|
|
// UploadedDocumentBuilder is a UploadedDocument media option. |
|
type UploadedDocumentBuilder struct { |
|
doc tg.InputMediaUploadedDocument |
|
caption []StyledTextOption |
|
} |
|
|
|
// NosoundVideo sets flag that the specified document is a video file with no audio tracks |
|
// (a GIF animation (even as MPEG4), for example). |
|
func (u *UploadedDocumentBuilder) NosoundVideo(v bool) *UploadedDocumentBuilder { |
|
u.doc.NosoundVideo = v |
|
return u |
|
} |
|
|
|
// ForceFile sets flag to force the media file to be uploaded as document. |
|
func (u *UploadedDocumentBuilder) ForceFile(v bool) *UploadedDocumentBuilder { |
|
u.doc.ForceFile = v |
|
return u |
|
} |
|
|
|
// Thumb sets thumbnail of the document, uploaded as for the file. |
|
func (u *UploadedDocumentBuilder) Thumb(file tg.InputFileClass) *UploadedDocumentBuilder { |
|
u.doc.Thumb = file |
|
return u |
|
} |
|
|
|
// MIME sets MIME type of document. |
|
func (u *UploadedDocumentBuilder) MIME(mime string) *UploadedDocumentBuilder { |
|
u.doc.MimeType = mime |
|
return u |
|
} |
|
|
|
// Attributes adds given attributes to the document. |
|
// Attribute specify the type of the document (video, audio, voice, sticker, etc.). |
|
func (u *UploadedDocumentBuilder) Attributes(attrs ...tg.DocumentAttributeClass) *UploadedDocumentBuilder { |
|
u.doc.Attributes = append(u.doc.Attributes, attrs...) |
|
return u |
|
} |
|
|
|
// Filename sets name of uploaded file. |
|
func (u *UploadedDocumentBuilder) Filename(name string) *UploadedDocumentBuilder { |
|
return u.Attributes(&tg.DocumentAttributeFilename{ |
|
FileName: name, |
|
}) |
|
} |
|
|
|
// HasStickers sets flag that document attachment has stickers. |
|
func (u *UploadedDocumentBuilder) HasStickers() *UploadedDocumentBuilder { |
|
return u.Attributes(&tg.DocumentAttributeHasStickers{}) |
|
} |
|
|
|
// Stickers adds attached mask stickers. |
|
func (u *UploadedDocumentBuilder) Stickers(stickers ...FileLocation) *UploadedDocumentBuilder { |
|
u.doc.Stickers = append(u.doc.Stickers, inputDocuments(stickers...)...) |
|
return u |
|
} |
|
|
|
// TTL sets time to live of self-destructing document. |
|
func (u *UploadedDocumentBuilder) TTL(ttl time.Duration) *UploadedDocumentBuilder { |
|
return u.TTLSeconds(int(ttl.Seconds())) |
|
} |
|
|
|
// TTLSeconds sets time to live in seconds of self-destructing document. |
|
func (u *UploadedDocumentBuilder) TTLSeconds(ttl int) *UploadedDocumentBuilder { |
|
u.doc.TTLSeconds = ttl |
|
return u |
|
} |
|
|
|
// apply implements MediaOption. |
|
func (u *UploadedDocumentBuilder) apply(ctx context.Context, b *multiMediaBuilder) error { |
|
return Media(&u.doc, u.caption...).apply(ctx, b) |
|
} |
|
|
|
// applyMulti implements MultiMediaOption. |
|
func (u *UploadedDocumentBuilder) applyMulti(ctx context.Context, b *multiMediaBuilder) error { |
|
m, err := b.sender.uploadMedia(ctx, &tg.MessagesUploadMediaRequest{ |
|
Peer: b.peer, |
|
Media: &u.doc, |
|
}) |
|
if err != nil { |
|
return errors.Wrap(err, "upload media") |
|
} |
|
|
|
input, err := convertMessageMediaToInput(m) |
|
if err != nil { |
|
return errors.Wrap(err, "convert") |
|
} |
|
|
|
return Media(input, u.caption...).apply(ctx, b) |
|
} |
|
|
|
// UploadedDocument adds document attachment. |
|
func UploadedDocument(file tg.InputFileClass, caption ...StyledTextOption) *UploadedDocumentBuilder { |
|
return &UploadedDocumentBuilder{ |
|
doc: tg.InputMediaUploadedDocument{ |
|
File: file, |
|
}, |
|
caption: caption, |
|
} |
|
} |
|
|
|
// File adds document attachment and forces it to be used as plain file, not media. |
|
func File(file tg.InputFileClass, caption ...StyledTextOption) *UploadedDocumentBuilder { |
|
return UploadedDocument(file, caption...).ForceFile(true) |
|
} |
|
|
|
// File sends uploaded file as document and forces it to be used as plain file, not media. |
|
func (b *Builder) File(ctx context.Context, file tg.InputFileClass, caption ...StyledTextOption) (tg.UpdatesClass, error) { |
|
return b.Media(ctx, File(file, caption...)) |
|
}
|
|
|