连接应该是一个类而不是实例(GramJS)

问题描述 投票:0回答:1

我有一个使用 GramJS 的服务。在此服务中,我尝试使用 GramJS 库初始化与电报的连接。运行代码后,我收到此错误:

[2024-04-19 15:10:02] (node:11888) UnhandledPromiseRejectionWarning: Error: Connection should be a class not an instance
    at new TelegramBaseClient (C:\Users\r.trisnosaputra\Documents\ACM-NEW\telegram-notification-backend-new\node_modules\telegram\client\telegramBaseClient.js:84:19)
    at new TelegramClient (C:\Users\r.trisnosaputra\Documents\ACM-NEW\telegram-notification-backend-new\node_modules\telegram\client\TelegramClient.js:63:9)
    at Command.callback (C:\Users\r.trisnosaputra\Documents\ACM-NEW\telegram-notification-backend-new\dist\lib\appExternalServices\telegramExternalService.js:108:35)
    at normal_reply (C:\Users\r.trisnosaputra\Documents\ACM-NEW\telegram-notification-backend-new\node_modules\redis\index.js:654:21)
    at RedisClient.return_reply (C:\Users\r.trisnosaputra\Documents\ACM-NEW\telegram-notification-backend-new\node_modules\redis\index.js:752:9)
    at JavascriptRedisParser.returnReply (C:\Users\r.trisnosaputra\Documents\ACM-NEW\telegram-notification-backend-new\node_modules\redis\index.js:137:18)
    at JavascriptRedisParser.execute (C:\Users\r.trisnosaputra\Documents\ACM-NEW\telegram-notification-backend-new\node_modules\redis-parser\lib\parser.js:544:14)
    at Socket.<anonymous> (C:\Users\r.trisnosaputra\Documents\ACM-NEW\telegram-notification-backend-new\node_modules\redis\index.js:218:27)
    at Socket.emit (events.js:400:28)
    at addChunk (internal/streams/readable.js:293:12)
[2024-04-19 15:10:02] (node:11888) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
[2024-04-19 15:10:02] (node:11888) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
[2024-04-19 15:10:02] Schedule not found!

这是代码:

import * as telethon from "telegram";
import { StringSession } from "telegram/sessions";
import { Config } from "../config";
import { Api } from "telegram";
import { IDI } from "../../interface";
import { TelegramClientDto } from "../../dto";
import { Hash } from "../helper";
import { ConnectionTCPObfuscated } from "telegram/network";

export default class TelegramExternalService {
    public client: TelegramClientDto;
    private config: Config;
    private static di: IDI = null;
    private static isReady = false;
    private static recommendedDc: {
        id: number;
        ipAddress: string;
        port: number;
    } = null;

    private static sessions: {
        [phoneNumber: string]: TelegramClientDto
    } = {};

    public static get ready(): boolean {
        return TelegramExternalService.isReady;
    }

    public static setDI(di: IDI): void {
        if (this.di !== null) {
            throw new Error("TelegramExternalService.setDI cannot be called twice");
        }
        this.di = di;
    }

    public static getSession(phoneNumber: string): TelegramClientDto {
        if (this.sessions[phoneNumber] && this.sessions[phoneNumber].connected) {
            return this.sessions[phoneNumber];
        }
    }
    
    public static async startSession(phoneNumber: string): Promise<{token?: string; status: string;}> {
        const telegramExternalService =  new TelegramExternalService();
        if (this.sessions[phoneNumber] && this.sessions[phoneNumber].connected) {
            telegramExternalService.client = this.sessions[phoneNumber];
            return({status: "LOGIN_SUCCESS"});
        }

        await telegramExternalService.initializeSession(phoneNumber);

        try {
            const status = await telegramExternalService.initializeConnection(phoneNumber);
            if (status) {
                return({status: "LOGIN_SUCCESS"});
            }

            console.log(status);
    
            const token = Hash.encode(phoneNumber);
            TelegramExternalService.di.redis.setex(`/phone/${phoneNumber}/token`, 999, token);
            return({status: "SEND_PHONE_CODE", token});
        } catch (e) {
            console.log(e);
            return {status: e.message};
        }
    }
    
    private static async getRecommendedDc(config) {
        if (TelegramExternalService.recommendedDc !== null) {
            return TelegramExternalService.recommendedDc;
        }
        
        let recommendedDc;
        const client = new telethon.TelegramClient(new StringSession(""), config.appAPIId, config.appAPIHash, {
            useIPV6: false,
            connectionRetries: 1
        });

        if (config.telegramEnvironment === "test") {
            recommendedDc = {
                id: 2,
                ipAddress: "149.154.167.40",
                port: 443
            };
        } else {
            console.log("Connecting...");
            await client.connect();
            console.log("Done connecting...");
            const nearestDc = await client.invoke(new Api.help.GetNearestDc());
            const connectionConfig = await client.invoke(new Api.help.GetConfig());
            await client.destroy();

            recommendedDc = connectionConfig.dcOptions.find(dc => dc.id === nearestDc.nearestDc && !dc.ipv6);
        }

        TelegramExternalService.recommendedDc = recommendedDc;
        return recommendedDc;
    }
    
    private constructor() {
        this.config = new Config();
    }

    private initializeSession(phoneNumber: string): Promise<void> {
        return new Promise((resolve) => {
            if (TelegramExternalService.sessions[phoneNumber]) {
                this.client = TelegramExternalService.sessions[phoneNumber];
                console.log(`[${phoneNumber}] uses exising connection`);
                resolve();
            } else {
                console.log(`[${phoneNumber}] attemps to create new connection`);
                TelegramExternalService.di.redis.get(`sessions/${phoneNumber}`, async (err, sessionString) => {
                    let session: StringSession;
                    if (sessionString) {
                        console.log(`[${phoneNumber}] has saved session`);
                        session = new StringSession(sessionString);
                    } else {
                        console.log(`[${phoneNumber}] has no saved session`);
                        session = new StringSession("");
                    }

                    this.client = new telethon.TelegramClient(session, this.config.appAPIId, this.config.appAPIHash, {
                        useIPV6: false,
                        connectionRetries: 1,
                        connection: this.config.telegramEnvironment === "test" ? undefined : ConnectionTCPObfuscated
                    });
                    resolve();
                });
            }
        });
    }

    private initializeConnection(phoneNumber: string): Promise<boolean> {
        return new Promise((async (initialized, failedToInitialize) => {
            const eventName = `/phone/${phoneNumber}/applyCode`;
            const recommendedDc = await TelegramExternalService.getRecommendedDc(this.config);
            console.log("recommendedDc", recommendedDc);
            this.client.session.setDC(recommendedDc.id, recommendedDc.ipAddress, recommendedDc.port);

            try {
                // @ts-ignore
                await this.client.start({
                    phoneNumber: phoneNumber,
                    onError: (e) => {
                        TelegramExternalService.di.redis.emit(`/phone/${phoneNumber}/applyCode/callback`, "false");
                        console.log(e);
                    },
                    phoneCode: () => new Promise((sendPhoneCode) => {
                        console.log(`Try to listening on event [${eventName}]`);
                        console.log(`Connected to ${this.client.session.dcId}`);
                        console.log("HEY! WHeRE IS YOUR CODE?");
                        TelegramExternalService.di.redis.once(eventName, (phoneCode) => {
                            console.log(`Phone code of ${phoneNumber} is ${phoneCode}`);
                            sendPhoneCode(phoneCode);
                        });
                        
                        console.log(`Listening on event [${eventName}]`);
                        initialized(false);
                    }),
                });

                console.log(`Phone number [${phoneNumber}] is ready`);
                TelegramExternalService.di.redis.emit(`/phone/${phoneNumber}/applyCode/callback`, "true");

                const currentUser = await this.client.getMe();
                TelegramExternalService.sessions[phoneNumber] = this.client;
                TelegramExternalService.sessions[phoneNumber].currentUser = currentUser as any;
                this.client.currentUser = currentUser as any;

                console.log(currentUser);
                console.log("Connected to ",  this.client.session.serverAddress);
                this.client.session.save();
                const session = this.client.session.serverAddress;
                if (session) {
                    const key = `sessions/${phoneNumber}`;
                    TelegramExternalService.di.redis.setex(key, 999, session);
                    TelegramExternalService.di.redis.persist(key);
                }
                TelegramExternalService.isReady = true;
                console.log(session);

                initialized(true);
            } catch (e) {
                console.log(e);
                failedToInitialize(e);
            }
        }));
    }
}

有人知道如何修复这个错误吗?

我希望修复代码中的错误。

javascript node.js typescript telegram
1个回答
0
投票

问题是您的

undefined
连接值会覆盖默认值并导致误报。

来自telegramBaseClient源代码...

const clientParamsDefault = {
  connection: isNode ? ConnectionTCPFull : ConnectionTCPObfuscated,

// ...

clientParams = { ...clientParamsDefault, ...clientParams };

// ...

if (!(clientParams.connection instanceof Function)) {
  throw new Error("Connection should be a class not an instance");
}

快速演示显示问题

class Connection {};
const defaults = { connection: Connection };
let params = { connection: undefined };

params = { ...defaults, ...params };
console.log('params', params);
console.log('Connection is a function?', defaults.connection instanceof Function);
console.log('params.connection is function?', params.connection instanceof Function);

Gram.js 代码可以更好,可以检查未定义的值,但事实并非如此。这里的解决方案是设置一个值

const params = {
  useIPV6: false,
  connectionRetries: 1,
};
if (this.config.telegramEnvironment !== "test") {
  params.connection = ConnectionTCPObfuscated;
}
this.client = new telethon.TelegramClient(
  session,
  this.config.appAPIId,
  this.config.appAPIHash,
  params,
);
© www.soinside.com 2019 - 2024. All rights reserved.