Bläddra i källkod

Add sending albums friendly method.

painor 3 år sedan
förälder
incheckning
b51591b717

+ 1 - 1
gramjs/Version.ts

@@ -1 +1 @@
-export const version = "2.2.0";
+export const version = "2.2.1";

+ 16 - 4
gramjs/client/messageParse.ts

@@ -115,7 +115,7 @@ export function _getResponseMessage(
     const schedToMessage = new Map<number, Api.Message>();
     for (const update of updates) {
         if (update instanceof Api.UpdateMessageID) {
-            randomToId.set(update.randomId.toString(), update.id);
+            randomToId.set(update.randomId!.toString(), update.id);
         } else if (
             update instanceof Api.UpdateNewChannelMessage ||
             update instanceof Api.UpdateNewMessage
@@ -228,11 +228,23 @@ export function _getResponseMessage(
         }
         return msg;
     } else {
+        let arrayRandomId: bigInt.BigInteger[] =
+            randomId as bigInt.BigInteger[];
         const mappingToReturn = [];
         let warned = false;
-        for (let i = 0; i < randomId.length; i++) {
-            const rnd = randomId[i] + "";
-            const msg = mapping.get(randomToId.get(rnd)!);
+        for (let i = 0; i < arrayRandomId.length; i++) {
+            const tempRandom = arrayRandomId[i];
+            if (tempRandom == undefined) {
+                warned = true;
+                break;
+            }
+            const rnd = tempRandom.toString();
+            const msgId = randomToId.get(rnd);
+            if (msgId == undefined) {
+                warned = true;
+                break;
+            }
+            const msg = mapping.get(msgId);
             if (!msg) {
                 warned = true;
                 break;

+ 1 - 1
gramjs/client/messages.ts

@@ -494,7 +494,7 @@ export interface SendMessageParams {
     /** Should the link preview be shown? */
     linkPreview?: boolean;
     /** Sends a message with a file attached (e.g. a photo, video, audio or document). The message may be empty. */
-    file?: FileLike;
+    file?: FileLike | FileLike[];
     /** Optional JPEG thumbnail (for documents). Telegram will ignore this parameter unless you pass a .jpg file!<br/>
      * The file must also be small in dimensions and in disk size. Successful thumbnails were files below 20kB and 320x320px.<br/>
      *  Width/height and dimensions/size ratios may be important.

+ 133 - 6
gramjs/client/uploads.ts

@@ -2,7 +2,7 @@ import { Api } from "../tl";
 
 import { TelegramClient } from "./TelegramClient";
 import { generateRandomBytes, readBigIntFromBuffer, sleep } from "../Helpers";
-import { getAppropriatedPartSize } from "../Utils";
+import { getAppropriatedPartSize, getInputMedia } from "../Utils";
 import { EntityLike, FileLike, MarkupLike, MessageIDLike } from "../define";
 import path from "path";
 import { promises as fs } from "fs";
@@ -165,6 +165,7 @@ export async function uploadFile(
               md5Checksum: "", // This is not a "flag", so not sure if we can make it optional.
           });
 }
+
 /**
  * Interface for sending files to a chat.
  */
@@ -175,11 +176,12 @@ export interface SendFileInterface {
      *   - can be an external direct URL. Telegram will download the file and send it.
      *   - can be an existing media from another message.
      *   - can be a handle to a file that was received by using {@link uploadFile}
+     *   - can be a list when using an album
      *   - can be {@link Api.TypeInputMedia} instance. For example if you want to send a dice you would use {@link Api.InputMediaDice}
      */
-    file: FileLike;
-    /** Optional caption for the sent media message.*/
-    caption?: string;
+    file: FileLike | FileLike[];
+    /** Optional caption for the sent media message. can be a list for albums*/
+    caption?: string | string[];
     /** If left to false and the file is a path that ends with the extension of an image file or a video file, it will be sent as such. Otherwise always as a document. */
     forceDocument?: boolean;
     /** The size of the file to be uploaded if it needs to be uploaded, which will be determined automatically if not specified. */
@@ -322,7 +324,10 @@ export async function _fileToMedia(
                 (await fs.stat(file)).size,
                 file
             );
-        } else if ((typeof File !== "undefined" && file instanceof File) || file instanceof CustomFile) {
+        } else if (
+            (typeof File !== "undefined" && file instanceof File) ||
+            file instanceof CustomFile
+        ) {
             createdFile = file;
         } else {
             let name;
@@ -424,6 +429,114 @@ export async function _fileToMedia(
     };
 }
 
+/** @hidden */
+export async function _sendAlbum(
+    client: TelegramClient,
+    entity: EntityLike,
+    {
+        file,
+        caption,
+        forceDocument = false,
+        fileSize,
+        clearDraft = false,
+        progressCallback,
+        replyTo,
+        attributes,
+        thumb,
+        parseMode,
+        voiceNote = false,
+        videoNote = false,
+        silent,
+        supportsStreaming = false,
+        scheduleDate,
+        workers = 1,
+        noforwards,
+    }: SendFileInterface
+) {
+    entity = await client.getInputEntity(entity);
+    let files = [];
+    if (!Array.isArray(file)) {
+        files = [file];
+    } else {
+        files = file;
+    }
+    if (!Array.isArray(caption)) {
+        if (!caption) {
+            caption = "";
+        }
+        caption = [caption];
+    }
+    const captions: [string, Api.TypeMessageEntity[]][] = [];
+    for (const c of caption) {
+        captions.push(await _parseMessageText(client, c, parseMode));
+    }
+    replyTo = utils.getMessageId(replyTo);
+    const albumFiles = [];
+    for (const file of files) {
+        let { fileHandle, media, image } = await _fileToMedia(client, {
+            file: file,
+            forceDocument: forceDocument,
+            fileSize: fileSize,
+            progressCallback: progressCallback,
+            attributes: attributes,
+            thumb: thumb,
+            voiceNote: voiceNote,
+            videoNote: videoNote,
+            supportsStreaming: supportsStreaming,
+            workers: workers,
+        });
+        if (
+            media instanceof Api.InputMediaUploadedPhoto ||
+            media instanceof Api.InputMediaPhotoExternal
+        ) {
+            const r = await client.invoke(
+                new Api.messages.UploadMedia({
+                    peer: entity,
+                    media,
+                })
+            );
+            if (r instanceof Api.MessageMediaPhoto) {
+                media = getInputMedia(r.photo);
+            }
+        } else if (media instanceof Api.InputMediaUploadedDocument) {
+            const r = await client.invoke(
+                new Api.messages.UploadMedia({
+                    peer: entity,
+                    media,
+                })
+            );
+            if (r instanceof Api.MessageMediaDocument) {
+                media = getInputMedia(r.document);
+            }
+        }
+        let text = "";
+        let msgEntities: Api.TypeMessageEntity[] = [];
+        if (captions.length) {
+            [text, msgEntities] = captions.shift()!;
+        }
+        albumFiles.push(
+            new Api.InputSingleMedia({
+                media: media!,
+                message: text,
+                entities: msgEntities,
+            })
+        );
+    }
+    const result = await client.invoke(
+        new Api.messages.SendMultiMedia({
+            peer: entity,
+            replyToMsgId: replyTo,
+            multiMedia: albumFiles,
+            silent: silent,
+            scheduleDate: scheduleDate,
+            clearDraft: clearDraft,
+            noforwards: noforwards,
+        })
+    );
+    const randomIds = albumFiles.map((m) => m.randomId);
+    return client._getResponseMessage(randomIds, result, entity) as Api.Message;
+}
+
 /** @hidden */
 export async function sendFile(
     client: TelegramClient,
@@ -458,7 +571,21 @@ export async function sendFile(
     }
     entity = await client.getInputEntity(entity);
     replyTo = utils.getMessageId(replyTo);
-    // TODO support albums in the future
+    if (Array.isArray(file)) {
+        return await _sendAlbum(client, entity, {
+            file: file,
+            caption: caption,
+            parseMode: parseMode,
+            silent: silent,
+            scheduleDate: scheduleDate,
+            supportsStreaming: supportsStreaming,
+            clearDraft: clearDraft,
+            forceDocument: forceDocument,
+        });
+    }
+    if (Array.isArray(caption)) {
+        caption = caption[0] || "";
+    }
     let msgEntities;
     if (formattingEntities != undefined) {
         msgEntities = formattingEntities;

+ 25 - 25
gramjs/tl/api.d.ts

@@ -16,7 +16,7 @@ export namespace Api {
     type float = number;
     type int128 = BigInteger;
     type int256 = BigInteger;
-    type long = BigInteger | string;
+    type long = BigInteger;
     type bytes = Buffer;
     class VirtualClass<Args extends AnyLiteral> {
         static CONSTRUCTOR_ID: number;
@@ -2381,7 +2381,7 @@ export namespace Api {
     }
     export class UpdateMessageID extends VirtualClass<{
         id: int;
-        randomId: long;
+        randomId?: long;
     }> {
         CONSTRUCTOR_ID: 1318109142;
         SUBCLASS_OF_ID: 2676568142;
@@ -2389,7 +2389,7 @@ export namespace Api {
         className: "UpdateMessageID";
         static fromReader(reader: Reader): UpdateMessageID;
         id: int;
-        randomId: long;
+        randomId?: long;
     }
     export class UpdateDeleteMessages extends VirtualClass<{
         messages: int[];
@@ -4183,7 +4183,7 @@ export namespace Api {
         keyFingerprint: int;
     }
     export class EncryptedMessage extends VirtualClass<{
-        randomId: long;
+        randomId?: long;
         chatId: int;
         date: int;
         bytes: bytes;
@@ -4194,14 +4194,14 @@ export namespace Api {
         classType: "constructor";
         className: "EncryptedMessage";
         static fromReader(reader: Reader): EncryptedMessage;
-        randomId: long;
+        randomId?: long;
         chatId: int;
         date: int;
         bytes: bytes;
         file: Api.TypeEncryptedFile;
     }
     export class EncryptedMessageService extends VirtualClass<{
-        randomId: long;
+        randomId?: long;
         chatId: int;
         date: int;
         bytes: bytes;
@@ -4211,7 +4211,7 @@ export namespace Api {
         classType: "constructor";
         className: "EncryptedMessageService";
         static fromReader(reader: Reader): EncryptedMessageService;
-        randomId: long;
+        randomId?: long;
         chatId: int;
         date: int;
         bytes: bytes;
@@ -8372,7 +8372,7 @@ export namespace Api {
     export class InputSingleMedia extends VirtualClass<{
         // flags: null;
         media: Api.TypeInputMedia;
-        randomId: long;
+        randomId?: long;
         message: string;
         entities?: Api.TypeMessageEntity[];
     }> {
@@ -8383,7 +8383,7 @@ export namespace Api {
         static fromReader(reader: Reader): InputSingleMedia;
         // flags: null;
         media: Api.TypeInputMedia;
-        randomId: long;
+        randomId?: long;
         message: string;
         entities?: Api.TypeMessageEntity[];
     }
@@ -16042,7 +16042,7 @@ export namespace Api {
                 peer: Api.TypeEntityLike;
                 replyToMsgId?: MessageIDLike;
                 message: string;
-                randomId: long;
+                randomId?: long;
                 replyMarkup?: Api.TypeReplyMarkup;
                 entities?: Api.TypeMessageEntity[];
                 scheduleDate?: int;
@@ -16064,7 +16064,7 @@ export namespace Api {
             peer: Api.TypeEntityLike;
             replyToMsgId?: MessageIDLike;
             message: string;
-            randomId: long;
+            randomId?: long;
             replyMarkup?: Api.TypeReplyMarkup;
             entities?: Api.TypeMessageEntity[];
             scheduleDate?: int;
@@ -16081,7 +16081,7 @@ export namespace Api {
                 replyToMsgId?: MessageIDLike;
                 media: Api.TypeInputMedia;
                 message: string;
-                randomId: long;
+                randomId?: long;
                 replyMarkup?: Api.TypeReplyMarkup;
                 entities?: Api.TypeMessageEntity[];
                 scheduleDate?: int;
@@ -16103,7 +16103,7 @@ export namespace Api {
             replyToMsgId?: MessageIDLike;
             media: Api.TypeInputMedia;
             message: string;
-            randomId: long;
+            randomId?: long;
             replyMarkup?: Api.TypeReplyMarkup;
             entities?: Api.TypeMessageEntity[];
             scheduleDate?: int;
@@ -16399,7 +16399,7 @@ export namespace Api {
                 // flags: null;
                 silent?: boolean;
                 peer: Api.TypeInputEncryptedChat;
-                randomId: long;
+                randomId?: long;
                 data: bytes;
             }>,
             messages.TypeSentEncryptedMessage
@@ -16412,7 +16412,7 @@ export namespace Api {
             // flags: null;
             silent?: boolean;
             peer: Api.TypeInputEncryptedChat;
-            randomId: long;
+            randomId?: long;
             data: bytes;
         }
         export class SendEncryptedFile extends Request<
@@ -16420,7 +16420,7 @@ export namespace Api {
                 // flags: null;
                 silent?: boolean;
                 peer: Api.TypeInputEncryptedChat;
-                randomId: long;
+                randomId?: long;
                 data: bytes;
                 file: Api.TypeInputEncryptedFile;
             }>,
@@ -16434,14 +16434,14 @@ export namespace Api {
             // flags: null;
             silent?: boolean;
             peer: Api.TypeInputEncryptedChat;
-            randomId: long;
+            randomId?: long;
             data: bytes;
             file: Api.TypeInputEncryptedFile;
         }
         export class SendEncryptedService extends Request<
             Partial<{
                 peer: Api.TypeInputEncryptedChat;
-                randomId: long;
+                randomId?: long;
                 data: bytes;
             }>,
             messages.TypeSentEncryptedMessage
@@ -16452,7 +16452,7 @@ export namespace Api {
             className: "messages.SendEncryptedService";
             static fromReader(reader: Reader): SendEncryptedService;
             peer: Api.TypeInputEncryptedChat;
-            randomId: long;
+            randomId?: long;
             data: bytes;
         }
         export class ReceivedQueue extends Request<
@@ -16637,7 +16637,7 @@ export namespace Api {
             Partial<{
                 bot: Api.TypeEntityLike;
                 peer: Api.TypeEntityLike;
-                randomId: long;
+                randomId?: long;
                 startParam: string;
             }>,
             Api.TypeUpdates
@@ -16649,7 +16649,7 @@ export namespace Api {
             static fromReader(reader: Reader): StartBot;
             bot: Api.TypeEntityLike;
             peer: Api.TypeEntityLike;
-            randomId: long;
+            randomId?: long;
             startParam: string;
         }
         export class GetMessagesViews extends Request<
@@ -16851,7 +16851,7 @@ export namespace Api {
                 hideVia?: boolean;
                 peer: Api.TypeEntityLike;
                 replyToMsgId?: MessageIDLike;
-                randomId: long;
+                randomId?: long;
                 queryId: long;
                 id: string;
                 scheduleDate?: int;
@@ -16871,7 +16871,7 @@ export namespace Api {
             hideVia?: boolean;
             peer: Api.TypeEntityLike;
             replyToMsgId?: MessageIDLike;
-            randomId: long;
+            randomId?: long;
             queryId: long;
             id: string;
             scheduleDate?: int;
@@ -17388,7 +17388,7 @@ export namespace Api {
             Partial<{
                 peer: Api.TypeEntityLike;
                 replyToMsgId: MessageIDLike;
-                randomId: long;
+                randomId?: long;
             }>,
             Api.TypeUpdates
         > {
@@ -17399,7 +17399,7 @@ export namespace Api {
             static fromReader(reader: Reader): SendScreenshotNotification;
             peer: Api.TypeEntityLike;
             replyToMsgId: MessageIDLike;
-            randomId: long;
+            randomId?: long;
         }
         export class GetFavedStickers extends Request<
             Partial<{

+ 2 - 2
gramjs/tl/custom/dialog.ts

@@ -60,8 +60,8 @@ export class Dialog {
 
         this.isUser = this.entity instanceof Api.User;
         this.isGroup = !!(
-            (this.entity instanceof Api.Chat ||
-                this.entity instanceof Api.ChatForbidden) ||
+            this.entity instanceof Api.Chat ||
+            this.entity instanceof Api.ChatForbidden ||
             (this.entity instanceof Api.Channel && this.entity.megagroup)
         );
         this.isChannel = this.entity instanceof Api.Channel;

+ 3 - 2
gramjs/tl/types-generator/template.js

@@ -180,9 +180,10 @@ ${indent}}`.trim();
         const { isVector, isFlag, skipConstructorId, type } = argConfig;
 
         const valueType = renderValueType(type, isVector, !skipConstructorId);
-
         return `${argName === "flags" ? "// " : ""}${argName}${
-            isFlag ? "?" : ""
+            isFlag || (argName === "randomId" && type === "long" && !isVector)
+                ? "?"
+                : ""
         }: ${valueType}`;
     }
 

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 8300 - 2
package-lock.json


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "telegram",
-  "version": "2.2.0",
+  "version": "2.2.1",
   "description": "NodeJS/Browser MTProto API Telegram client library,",
   "main": "index.js",
   "types": "index.d.ts",

Vissa filer visades inte eftersom för många filer har ändrats