Browse Source

Add album event updates

painor 4 years ago
parent
commit
0bc4c46856

+ 1 - 1
gramjs/Version.ts

@@ -1 +1 @@
-export const version = "1.7.24";
+export const version = "1.7.26";

+ 12 - 0
gramjs/client/TelegramClient.ts

@@ -25,6 +25,7 @@ import { NewMessage, NewMessageEvent } from "../events";
 import { _dispatchUpdate, _handleUpdate, _updateLoop } from "./updates";
 import { Session } from "../sessions";
 import { inspect } from "util";
+import { Album, AlbumEvent } from "../events/Album";
 
 /**
  * The TelegramClient uses several methods in different files to provide all the common functionality in a nice interface.</br>
@@ -805,6 +806,11 @@ export class TelegramClient extends TelegramBaseClient {
         event: NewMessage
     ): void;
     /** @hidden */
+    addEventHandler(
+        callback: { (event: AlbumEvent): void },
+        event: Album
+    ): void;
+    /** @hidden */
     addEventHandler(
         callback: { (event: any): void },
         event?: EventBuilder
@@ -1297,5 +1303,11 @@ export class TelegramClient extends TelegramBaseClient {
         return betterConsoleLog(this);
     }
 
+    /**
+     * Small hack for using it in browsers
+     */
+    static get events() {
+        return require("../events");
+    }
     // endregion
 }

+ 8 - 8
gramjs/client/downloads.ts

@@ -329,7 +329,9 @@ export async function _downloadDocument(
         {
             fileSize:
                 size && !(size instanceof Api.PhotoSizeEmpty)
-                    ? (size instanceof Api.PhotoSizeProgressive ? Math.max(...size.sizes) : size.size)
+                    ? size instanceof Api.PhotoSizeProgressive
+                        ? Math.max(...size.sizes)
+                        : size.size
                     : doc.size,
             progressCallback: args.progressCallback,
             start: args.start,
@@ -364,12 +366,7 @@ function pickFileSize(sizes: Api.TypePhotoSize[], sizeType: string) {
     let size;
     for (let i = indexOfSize; i < sizeTypes.length; i++) {
         size = sizes.find((s) => s.type === sizeTypes[i]);
-        if (
-            size &&
-            !(
-                size instanceof Api.PhotoPathSize
-            )
-        ) {
+        if (size && !(size instanceof Api.PhotoPathSize)) {
             return size;
         }
     }
@@ -423,7 +420,10 @@ export async function _downloadPhoto(
         }),
         {
             dcId: photo.dcId,
-            fileSize: size instanceof Api.PhotoSizeProgressive ? Math.max(...size.sizes) : size.size,
+            fileSize:
+                size instanceof Api.PhotoSizeProgressive
+                    ? Math.max(...size.sizes)
+                    : size.size,
             progressCallback: args.progressCallback,
         }
     );

+ 5 - 0
gramjs/client/telegramBaseClient.ts

@@ -170,6 +170,11 @@ export class TelegramBaseClient {
     public _lastRequest?: number;
     /** @hidden */
     public _parseMode?: ParseInterface;
+    /** @hidden */
+    public _ALBUMS = new Map<
+        string,
+        [ReturnType<typeof setTimeout>, Api.TypeUpdate[]]
+    >();
 
     constructor(
         session: string | Session,

+ 3 - 1
gramjs/client/updates.ts

@@ -25,6 +25,7 @@ export function addEventHandler(
         const raw = require("../events/Raw").Raw;
         event = new raw({}) as Raw;
     }
+    event.client = client;
     client._eventBuilders.push([event, callback]);
 }
 
@@ -113,7 +114,8 @@ export async function _dispatchUpdate(
             if (!(event instanceof UpdateConnectionState)) {
                 // TODO fix me
             }
-            event = builder.build(event);
+            // TODO fix others not being passed
+            event = builder.build(event, undefined, callback);
             if (event) {
                 if ("_eventName" in event) {
                     event._setClient(client);

+ 115 - 0
gramjs/events/Album.ts

@@ -0,0 +1,115 @@
+import { DefaultEventInterface, EventBuilder, EventCommon } from "./common";
+import { Entity, EntityLike } from "../define";
+import { Message as CustomMessage } from "../tl/custom/message";
+import { Api } from "../tl";
+import { TelegramClient } from "..";
+
+const _ALBUM_DELAY = 500; // 0.5 sec
+
+/**
+ * Occurs whenever an album (multiple grouped messages with media) arrive.
+ * @example
+ * ```ts
+ * // Albums are basically a list of messages. so event is a list
+ *   async function listenForAlbums(event: AlbumEvent) {
+ *       const messages = event.messages;
+ *       for (const message of messages){
+ *           console.log("Caption is",message.text);
+ *           console.log("Message id is",message.id);
+ *           console.log("Chat id is",message.chatId);
+ *       }
+ *   }
+ * // adds an event handler for new messages
+ * client.addEventHandler(listenForAlbums, new Album({}));
+ * ```
+ */
+export class Album extends EventBuilder {
+    chats?: EntityLike[];
+    func?: { (event: Album): boolean };
+
+    constructor(albumParams: DefaultEventInterface) {
+        let { chats, func, blacklistChats = false } = albumParams;
+        super({ chats, blacklistChats, func });
+    }
+
+    build(
+        update: Api.TypeUpdate,
+        others: any = null,
+        dispatch?: CallableFunction
+    ): any {
+        if (
+            !("message" in update) ||
+            typeof update.message == "string" ||
+            !("groupedId" in update.message)
+        ) {
+            return;
+        }
+        const groupedId = update.message.groupedId;
+        if (!groupedId) {
+            return;
+        }
+        const albums = this.client!._ALBUMS;
+        const oldTimeout = albums.get(groupedId.toString());
+        let oldValues = [];
+        if (oldTimeout) {
+            clearTimeout(oldTimeout[0]);
+            oldValues.push(...oldTimeout[1]);
+        }
+        albums.set(groupedId.toString(), [
+            setTimeout(() => {
+                const values = albums.get(groupedId.toString());
+                albums.delete(groupedId.toString());
+                if (!values) {
+                    return;
+                }
+                const messages = values[1] as unknown as CustomMessage[];
+
+                if (!messages) {
+                    return;
+                }
+                const event = new AlbumEvent(messages, values[1]);
+                event._setClient(this.client!);
+                event._entities = messages[0]._entities!;
+                dispatch!(event);
+            }, _ALBUM_DELAY),
+            [...oldValues, update.message],
+        ]);
+    }
+}
+
+export class AlbumEvent extends EventCommon {
+    messages: CustomMessage[];
+    originalUpdates: (Api.TypeUpdate & { _entities?: Map<number, Entity> })[];
+
+    constructor(messages: CustomMessage[], originalUpdates: Api.TypeUpdate[]) {
+        super({
+            msgId: messages[0].id,
+            chatPeer: messages[0].peerId,
+            broadcast: messages[0].post,
+        });
+        this.originalUpdates = originalUpdates;
+        this.messages = messages;
+    }
+
+    _setClient(client: TelegramClient) {
+        super._setClient(client);
+        for (let i = 0; i < this.messages.length; i++) {
+            try {
+                // todo make sure this never fails
+                this.messages[i]._finishInit(
+                    client,
+                    this.originalUpdates[i]._entities || new Map(),
+                    undefined
+                );
+            } catch (e) {
+                client._log.error(
+                    "Got error while trying to finish init message with id " +
+                        this.messages[i].id
+                );
+                if (client._log.canSend("error")) {
+                    console.error(e);
+                }
+            }
+        }
+    }
+}

+ 6 - 1
gramjs/events/common.ts

@@ -91,6 +91,7 @@ export class EventBuilder {
     blacklistChats: boolean;
     resolved: boolean;
     func?: CallableFunction;
+    client?: TelegramClient;
 
     constructor(eventParams: DefaultEventInterface) {
         this.chats = eventParams.chats;
@@ -99,7 +100,11 @@ export class EventBuilder {
         this.func = eventParams.func;
     }
 
-    build(update: Api.TypeUpdate, others = null): any {
+    build(
+        update: Api.TypeUpdate,
+        others?: any,
+        callback?: CallableFunction
+    ): any {
         if (update) return update;
     }
 

+ 2 - 2
package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "telegram",
-  "version": "1.7.24",
+  "version": "1.7.26",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "telegram",
-      "version": "1.7.24",
+      "version": "1.7.26",
       "license": "MIT",
       "dependencies": {
         "@cryptography/aes": "^0.1.1",

+ 1 - 1
package.json

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

+ 12 - 12
webpack.config.js

@@ -8,20 +8,20 @@ module.exports = {
       {
         test: /\.ts$/,
         use: "ts-loader",
-        exclude: /node_modules/
+        exclude: /node_modules/,
       },
 
       {
         test: /\.js$/,
         use: "babel-loader",
-        exclude: /node_modules/
+        exclude: /node_modules/,
       },
 
       {
         test: /\.tl$/i,
-        loader: "raw-loader"
-      }
-    ]
+        loader: "raw-loader",
+      },
+    ],
   },
 
   resolve: {
@@ -35,17 +35,17 @@ module.exports = {
       util: require.resolve("util/"),
       assert: false,
       stream: false,
-      constants: false
-    }
+      constants: false,
+    },
   },
   mode: "development",
   plugins: [
     new webpack.ProvidePlugin({
-      Buffer: ["buffer", "Buffer"]
+      Buffer: ["buffer", "Buffer"],
     }),
     new webpack.ProvidePlugin({
-      process: "process/browser"
-    })
+      process: "process/browser",
+    }),
   ],
 
   output: {
@@ -53,6 +53,6 @@ module.exports = {
     libraryTarget: "umd",
     auxiliaryComment: "Test Comment",
     filename: "gramjs.js",
-    path: path.resolve(__dirname, "browser")
-  }
+    path: path.resolve(__dirname, "browser"),
+  },
 };