Przeglądaj źródła

Fix gzipped updates
Add new Message events
Fix auto peer casting

painor 5 lat temu
rodzic
commit
82f144cf69

+ 10 - 8
gramjs/Utils.js

@@ -32,7 +32,6 @@ function _raiseCastFail(entity, target) {
  */
  */
 function getInputPeer(entity, allowSelf = true, checkHash = true) {
 function getInputPeer(entity, allowSelf = true, checkHash = true) {
     if (entity.SUBCLASS_OF_ID === undefined) {
     if (entity.SUBCLASS_OF_ID === undefined) {
-        console.log('undefined')
         // e.g. custom.Dialog (can't cyclic import).
         // e.g. custom.Dialog (can't cyclic import).
 
 
         if (allowSelf && 'inputEntity' in entity) {
         if (allowSelf && 'inputEntity' in entity) {
@@ -44,8 +43,6 @@ function getInputPeer(entity, allowSelf = true, checkHash = true) {
         }
         }
     }
     }
     if (entity.SUBCLASS_OF_ID === 0xc91c90b6) { // crc32(b'InputPeer')
     if (entity.SUBCLASS_OF_ID === 0xc91c90b6) { // crc32(b'InputPeer')
-        console.log('returningt entity')
-        console.log(entity)
         return entity
         return entity
     }
     }
 
 
@@ -66,7 +63,6 @@ function getInputPeer(entity, allowSelf = true, checkHash = true) {
         return new types.InputPeerChat({ chatId: entity.id })
         return new types.InputPeerChat({ chatId: entity.id })
     }
     }
     if (entity instanceof types.Channel) {
     if (entity instanceof types.Channel) {
-        console.log('it\'s a channel')
         if ((entity.accessHash !== undefined && !entity.min) || checkHash) {
         if ((entity.accessHash !== undefined && !entity.min) || checkHash) {
             return new types.InputPeerChannel({ channelId: entity.id, accessHash: entity.accessHash })
             return new types.InputPeerChannel({ channelId: entity.id, accessHash: entity.accessHash })
         } else {
         } else {
@@ -163,8 +159,9 @@ function getInputUser(entity) {
             })
             })
         }
         }
     }
     }
-
+    console.log(entity)
     if (entity instanceof types.InputPeerSelf) {
     if (entity instanceof types.InputPeerSelf) {
+
         return new types.InputPeerSelf()
         return new types.InputPeerSelf()
     }
     }
     if (entity instanceof types.UserEmpty || entity instanceof types.InputPeerEmpty) {
     if (entity instanceof types.UserEmpty || entity instanceof types.InputPeerEmpty) {
@@ -230,10 +227,13 @@ function getPeer(peer) {
     try {
     try {
         if (typeof peer === 'number') {
         if (typeof peer === 'number') {
             const res = resolveId(peer)
             const res = resolveId(peer)
+
             if (res[1] === types.PeerChannel) {
             if (res[1] === types.PeerChannel) {
                 return new res[1]({ channelId: res[0] })
                 return new res[1]({ channelId: res[0] })
-            } else {
+            } else if (res[1] === types.PeerChat) {
                 return new res[1]({ chatId: res[0] })
                 return new res[1]({ chatId: res[0] })
+            } else {
+                return new res[1]({ userId: res[0] })
             }
             }
         }
         }
         if (peer.SUBCLASS_OF_ID === undefined) {
         if (peer.SUBCLASS_OF_ID === undefined) {
@@ -241,7 +241,7 @@ function getPeer(peer) {
         }
         }
         if (peer.SUBCLASS_OF_ID === 0x2d45687) {
         if (peer.SUBCLASS_OF_ID === 0x2d45687) {
             return peer
             return peer
-        } else if (peer instanceof types.contacts || peer instanceof types.ResolvedPeer ||
+        } else if (peer instanceof types.contacts.ResolvedPeer ||
             peer instanceof types.InputNotifyPeer || peer instanceof types.TopPeer ||
             peer instanceof types.InputNotifyPeer || peer instanceof types.TopPeer ||
             peer instanceof types.Dialog || peer instanceof types.DialogPeer) {
             peer instanceof types.Dialog || peer instanceof types.DialogPeer) {
             return peer.peer
             return peer.peer
@@ -252,8 +252,8 @@ function getPeer(peer) {
             // ChatParticipant, ChannelParticipant
             // ChatParticipant, ChannelParticipant
             return new types.PeerUser({ userId: peer.userId })
             return new types.PeerUser({ userId: peer.userId })
         }
         }
-
         peer = getInputPeer(peer, false, false)
         peer = getInputPeer(peer, false, false)
+
         if (peer instanceof types.InputPeerUser) {
         if (peer instanceof types.InputPeerUser) {
             return new types.PeerUser({ userId: peer.userId })
             return new types.PeerUser({ userId: peer.userId })
         } else if (peer instanceof types.InputPeerChat) {
         } else if (peer instanceof types.InputPeerChat) {
@@ -263,6 +263,7 @@ function getPeer(peer) {
         }
         }
         // eslint-disable-next-line no-empty
         // eslint-disable-next-line no-empty
     } catch (e) {
     } catch (e) {
+        console.log(e)
     }
     }
     _raiseCastFail(peer, 'peer')
     _raiseCastFail(peer, 'peer')
 }
 }
@@ -298,6 +299,7 @@ function getPeerId(peer, addMark = true) {
     try {
     try {
         peer = getPeer(peer)
         peer = getPeer(peer)
     } catch (e) {
     } catch (e) {
+        console.log(e)
         _raiseCastFail(peer, 'int')
         _raiseCastFail(peer, 'int')
     }
     }
     if (peer instanceof types.PeerUser) {
     if (peer instanceof types.PeerUser) {

+ 14 - 11
gramjs/client/TelegramClient.js

@@ -52,7 +52,6 @@ class TelegramClient {
             this._log = args.baseLogger
             this._log = args.baseLogger
         }
         }
         const session = Session.tryLoadOrCreateNew(sessionName)
         const session = Session.tryLoadOrCreateNew(sessionName)
-        console.log(session.serverAddress)
         if (!session.serverAddress || (session.serverAddress.includes(':') !== this._useIPV6)) {
         if (!session.serverAddress || (session.serverAddress.includes(':') !== this._useIPV6)) {
             session.setDC(DEFAULT_DC_ID, this._useIPV6 ? DEFAULT_IPV6_IP : DEFAULT_IPV4_IP, DEFAULT_PORT)
             session.setDC(DEFAULT_DC_ID, this._useIPV6 ? DEFAULT_IPV6_IP : DEFAULT_IPV4_IP, DEFAULT_PORT)
         }
         }
@@ -124,11 +123,9 @@ class TelegramClient {
         const connection = new this._connection(this.session.serverAddress
         const connection = new this._connection(this.session.serverAddress
             , this.session.port, this.session.dcId, this._log)
             , this.session.port, this.session.dcId, this._log)
         if (!await this._sender.connect(connection)) {
         if (!await this._sender.connect(connection)) {
-            console.log('already connected returning')
             return
             return
         }
         }
         this.session.authKey = this._sender.authKey
         this.session.authKey = this._sender.authKey
-        console.log('auth key is ', this.session.authKey)
         await this.session.save()
         await this.session.save()
         await this._sender.send(this._initWith(
         await this._sender.send(this._initWith(
             new GetConfigRequest(),
             new GetConfigRequest(),
@@ -179,7 +176,6 @@ class TelegramClient {
                 addKey(pk.publicKey)
                 addKey(pk.publicKey)
             }
             }
         }
         }
-        console.log('ok')
         for (const DC of this._config.dcOptions) {
         for (const DC of this._config.dcOptions) {
             if (DC.id === dcId && Boolean(DC.ipv6) === this._useIPV6 && Boolean(DC.cdn) === cdn) {
             if (DC.id === dcId && Boolean(DC.ipv6) === this._useIPV6 && Boolean(DC.cdn) === cdn) {
                 return DC
                 return DC
@@ -220,10 +216,8 @@ class TelegramClient {
         }
         }
         this._last_request = new Date().getTime()
         this._last_request = new Date().getTime()
         let attempt = 0
         let attempt = 0
-        console.log('request retries is ,', this._requestRetries)
         for (attempt = 0; attempt < this._requestRetries; attempt++) {
         for (attempt = 0; attempt < this._requestRetries; attempt++) {
             try {
             try {
-                console.log('curernt attepmt is ', attempt)
                 const promise = this._sender.send(request)
                 const promise = this._sender.send(request)
                 const result = await promise
                 const result = await promise
                 this.session.processEntities(result)
                 this.session.processEntities(result)
@@ -370,14 +364,18 @@ class TelegramClient {
     }
     }
 
 
     _handleUpdate(update) {
     _handleUpdate(update) {
-        console.log('got the update')
+
         this.session.processEntities(update)
         this.session.processEntities(update)
         this._entityCache.add(update)
         this._entityCache.add(update)
 
 
         if (update instanceof types.Updates || update instanceof types.UpdatesCombined) {
         if (update instanceof types.Updates || update instanceof types.UpdatesCombined) {
             // TODO deal with entities
             // TODO deal with entities
+            const entities = {}
+            for (const x of [...update.users, ...update.chats]) {
+                entities[utils.getPeerId(x)] = x
+            }
             for (const u of update.updates) {
             for (const u of update.updates) {
-                this._processUpdate(u, update.updates)
+                this._processUpdate(u, update.updates, entities)
             }
             }
         } else if (update instanceof types.UpdateShort) {
         } else if (update instanceof types.UpdateShort) {
             this._processUpdate(update.update, null)
             this._processUpdate(update.update, null)
@@ -581,12 +579,14 @@ class TelegramClient {
         // will work with access_hash = 0. Similar for channels.getChannels.
         // will work with access_hash = 0. Similar for channels.getChannels.
         // If we're not a bot but the user is in our contacts, it seems to work
         // If we're not a bot but the user is in our contacts, it seems to work
         // regardless. These are the only two special-cased requests.
         // regardless. These are the only two special-cased requests.
+        console.log('the peer i will get is ', peer)
         peer = utils.getPeer(peer)
         peer = utils.getPeer(peer)
+        console.log('the peer i got was ', peer)
         if (peer instanceof types.PeerUser) {
         if (peer instanceof types.PeerUser) {
             const users = await this.invoke(new functions.users.GetUsersRequest({
             const users = await this.invoke(new functions.users.GetUsersRequest({
-                id: new types.InputUser({
+                id: [new types.InputUser({
                     userId: peer.userId, accessHash: 0,
                     userId: peer.userId, accessHash: 0,
-                }),
+                })],
             }))
             }))
             if (users && !(users[0] instanceof types.UserEmpty)) {
             if (users && !(users[0] instanceof types.UserEmpty)) {
                 // If the user passed a valid ID they expect to work for
                 // If the user passed a valid ID they expect to work for
@@ -634,9 +634,12 @@ class TelegramClient {
         channelId: null,
         channelId: null,
         ptsDate: null,
         ptsDate: null,
     }) {
     }) {
+        console.log('event args are ', args)
         for (const [builder, callback] of this._eventBuilders) {
         for (const [builder, callback] of this._eventBuilders) {
             const event = builder.build(args.update)
             const event = builder.build(args.update)
-            await callback(event)
+            if (event) {
+                await callback(event)
+            }
         }
         }
     }
     }
 }
 }

+ 96 - 0
gramjs/events/NewMessage.js

@@ -0,0 +1,96 @@
+const { EventBuilder, EventCommon } = require('./common')
+const { types } = require('../tl')
+
+class NewMessage extends EventBuilder {
+
+
+    constructor(args = {
+        chats: null,
+        func: null,
+    }) {
+        super(args)
+
+        this.chats = args.chats
+        this.func = args.func
+        this._noCheck = true
+    }
+
+    async _resolve(client) {
+        await super._resolve(client)
+        this.fromUsers = await _intoIdSet(client, this.fromUsers)
+    }
+
+    build(update, others = null, thisId = null) {
+        let event
+        if (update instanceof types.UpdateNewMessage || update instanceof types.UpdateNewChannelMessage) {
+            if (!(update.message instanceof types.Message)) {
+                return
+            }
+            event = new Event(update.message)
+
+        } else if (update instanceof types.UpdateShortMessage) {
+            event = new Event(new types.Message({
+                out: update.out,
+                mentioned: update.mentioned,
+                mediaUnread: update.mediaUnread,
+                silent: update.silent,
+                id: update.id,
+                // Note that to_id/from_id complement each other in private
+                // messages, depending on whether the message was outgoing.
+                toId: new types.PeerUser(update.out ? update.userId : thisId),
+                fromId: update.out ? thisId : update.userId,
+                message: update.message,
+                date: update.date,
+                fwdFrom: update.fwdFrom,
+                viaBotId: update.viaBotId,
+                replyToMsgId: update.replyToMsgId,
+                entities: update.entities,
+            }))
+        } else if (update instanceof types.UpdateShortChatMessage) {
+            event = new this.Event(new types.Message({
+                out: update.out,
+                mentioned: update.mentioned,
+                mediaUnread: update.mediaUnread,
+                silent: update.silent,
+                id: update.id,
+                toId: new types.PeerChat(update.chatId),
+                fromId: update.fromId,
+                message: update.message,
+                date: update.date,
+                fwdFrom: update.fwdFrom,
+                viaBotId: update.viaBotId,
+                replyToMsgId: update.replyToMsgId,
+                entities: update.entities,
+            }))
+        } else {
+            return
+        }
+
+        // Make messages sent to ourselves outgoing unless they're forwarded.
+        // This makes it consistent with official client's appearance.
+        const ori = event.message
+        if (ori.toId instanceof types.PeerUser) {
+            if (ori.fromId === ori.toId.userId && !ori.fwdFrom) {
+                event.message.out = true
+            }
+        }
+        return event
+
+    }
+
+    filter(event) {
+        if (this._noCheck) {
+            return event
+        }
+        return event
+    }
+
+}
+
+class Event extends EventCommon {
+    constructor(message) {
+        super()
+        this.message = message
+    }
+}
+module.exports = NewMessage

+ 7 - 3
gramjs/events/common.js

@@ -1,7 +1,7 @@
 class EventBuilder {
 class EventBuilder {
     constructor(args = {
     constructor(args = {
-        chats: null, blacklistChats: null, func: null,
-    },
+            chats: null, blacklistChats: null, func: null,
+        },
     ) {
     ) {
         this.chats = args.chats
         this.chats = args.chats
         this.blacklistChats = Boolean(args.blacklistChats)
         this.blacklistChats = Boolean(args.blacklistChats)
@@ -14,5 +14,9 @@ class EventBuilder {
     }
     }
 }
 }
 
 
+class EventCommon {
 
 
-module.exports = { EventBuilder }
+}
+
+
+module.exports = { EventBuilder, EventCommon }

+ 4 - 2
gramjs/network/MTProtoSender.js

@@ -8,9 +8,8 @@ const MessageContainer = require('../tl/core/MessageContainer')
 const GZIPPacked = require('../tl/core/GZIPPacked')
 const GZIPPacked = require('../tl/core/GZIPPacked')
 const RequestState = require('./RequestState')
 const RequestState = require('./RequestState')
 const format = require('string-format')
 const format = require('string-format')
-const { MsgsAck, File, MsgsStateInfo } = require('../tl/types')
+const { MsgsAck, File, MsgsStateInfo,Pong } = require('../tl/types')
 const MessagePacker = require('../extensions/MessagePacker')
 const MessagePacker = require('../extensions/MessagePacker')
-const Pong = require('../tl/core/GZIPPacked')
 const BinaryReader = require('../extensions/BinaryReader')
 const BinaryReader = require('../extensions/BinaryReader')
 const {
 const {
     BadServerSalt,
     BadServerSalt,
@@ -375,9 +374,11 @@ class MTProtoSender {
      * @private
      * @private
      */
      */
     async _processMessage(message) {
     async _processMessage(message) {
+        console.log('got message : ', message)
         this._pending_ack.add(message.msgId)
         this._pending_ack.add(message.msgId)
         // eslint-disable-next-line require-atomic-updates
         // eslint-disable-next-line require-atomic-updates
         message.obj = await message.obj
         message.obj = await message.obj
+        console.log('obj is ', message.obj)
         let handler = this._handlers[message.obj.CONSTRUCTOR_ID]
         let handler = this._handlers[message.obj.CONSTRUCTOR_ID]
         if (!handler) {
         if (!handler) {
             handler = this._handleUpdate.bind(this)
             handler = this._handleUpdate.bind(this)
@@ -523,6 +524,7 @@ class MTProtoSender {
      * @private
      * @private
      */
      */
     async _handlePong(message) {
     async _handlePong(message) {
+        console.log(message)
         const pong = message.obj
         const pong = message.obj
         this._log.debug(`Handling pong for message ${pong.msgId}`)
         this._log.debug(`Handling pong for message ${pong.msgId}`)
         const state = this._pending_state[pong.msgId]
         const state = this._pending_state[pong.msgId]

+ 0 - 1
gramjs/sessions/Session.js

@@ -45,7 +45,6 @@ class Session {
                     return value
                     return value
                 }
                 }
             })
             })
-            console.log('current auth key will be ', this.authKey)
             await fs.writeFile(`${this.sessionUserId}.session`, str)
             await fs.writeFile(`${this.sessionUserId}.session`, str)
         }
         }
     }
     }

+ 12 - 4
gramjs_generator/generators/tlobject.js

@@ -258,17 +258,25 @@ const writeClassConstructor = (tlobject, kind, typeConstructors, builder) => {
     builder.writeln()
     builder.writeln()
     builder.writeln()
     builder.writeln()
     builder.writeln(`class ${tlobject.className} extends ${kind} {`)
     builder.writeln(`class ${tlobject.className} extends ${kind} {`)
-
+    builder.writeln(`static CONSTRUCTOR_ID = 0x${tlobject.id.toString(16).padStart(8, '0')};`)
+    builder.writeln(`static SUBCLASS_OF_ID = 0x${crc32(tlobject.result).toString(16)};`)
+    builder.writeln()
     // Write the __init__ function if it has any argument
     // Write the __init__ function if it has any argument
     if (!tlobject.realArgs.length) {
     if (!tlobject.realArgs.length) {
+        builder.writeln(`constructor() {`)
+        builder.writeln(`super();`)
+        builder.writeln(`this.CONSTRUCTOR_ID = 0x${tlobject.id.toString(16).padStart(8, '0')};`)
+        builder.writeln(`this.SUBCLASS_OF_ID = 0x${crc32(tlobject.result).toString(16)};`)
+
+        builder.writeln()
+        builder.currentIndent--
+        builder.writeln('}')
         return
         return
     }
     }
 
 
     // Note : this is needed to be able to access them
     // Note : this is needed to be able to access them
     // with or without an instance
     // with or without an instance
-    builder.writeln(`static CONSTRUCTOR_ID = 0x${tlobject.id.toString(16).padStart(8, '0')};`)
-    builder.writeln(`static SUBCLASS_OF_ID = 0x${crc32(tlobject.result).toString(16)};`)
-    builder.writeln()
+
 
 
     builder.writeln('/**')
     builder.writeln('/**')