12

首先请注意,这不是关于创建机器人

我的目标是创建一个应用程序,该应用程序将简单地收听我将为其提供的帐户订阅的任意数量的电报频道,并检索发送到这些频道的所有消息(就像我是普通用户一样)。我的猜测是我需要

  • 使用我帐户的电话号码进行身份验证
  • 能够为每个通道设置回调侦听器或为所有传入消息设置通用侦听器

我已经环顾四周了telegram api几天,我对它的工作原理感到非常困惑。在放弃它之后,我开始寻找现成的实现,主要是为了NodeJS但仍然无法找到具体的解决方案。我正在使用telegram-js api测试一些东西,但直接使用它运行它node不起作用。它需要在浏览器中运行吗?有没有更简化的方法呢?最好是有良好文档的东西。

PS:我主要精通 Java 和 Javascript,所以我优先考虑基于这些语言的库。

编辑:

这是我编写的代码(基本上复制了一个示例)

var { Telegram } = require("../libs/telegram");
var TypeLanguage = require("telegram-tl-node") ;
var MTProto = require("telegram-mt-node");

var schema = require("../libs/api-schema.json");

const APP_ID = "111111";
const APP_HASH = "fb6da8f6abdf876abd6a9d7bf6";
const SERVER = { host: "111.111.111.11", port: "443" };
const config = {
  id: APP_ID,
  hash: APP_HASH,
  version: '0.0.1',
  lang_code: 'en',
  authKey: null
};

let telegram = new Telegram(MTProto, TypeLanguage);
telegram.useSchema(schema);
addPublicKeys(telegram);

let connection = new MTProto.net.HttpConnection(SERVER);

let client = telegram.createClient();
client.setConnection(connection);

connection.connect(function() {
  let ready = client.setup(config);
  ready.then(function(client) {
    // it never resolves this promise
    function callback(response) {
      console.log(response);
    }
    client.callApi("help.getConfig").then(callback, callback);
  });
});

它使用这两个库: telegram-mt-node telegram-tl-node

4

2 回答 2

10

迟到的答案,但可能会帮助其他人。

您可以利用mtproto-core使用常规电报帐户进行身份验证并收听更新(或者真的可以对电报客户端做任何事情)

这是我编写的一个示例脚本,用于监听来自用户订阅的频道/超级组的新消息:

const { MTProto, getSRPParams } = require('@mtproto/core');
const prompts = require('prompts');

const api_id = ...; // insert api_id here
const api_hash = ' ... '; // insert api_hash here

async function getPhone() {
    return (await prompts({
        type: 'text',
        name: 'phone',
        message: 'Enter your phone number:'
    })).phone
}

async function getCode() {
    // you can implement your code fetching strategy here
    return (await prompts({
        type: 'text',
        name: 'code',
        message: 'Enter the code sent:',
    })).code
}

async function getPassword() {
    return (await prompts({
        type: 'text',
        name: 'password',
        message: 'Enter Password:',
    })).password
}


const mtproto = new MTProto({
    api_id,
    api_hash,
});

function startListener() {
    console.log('[+] starting listener')
    mtproto.updates.on('updates', ({ updates }) => {
        const newChannelMessages = updates.filter((update) => update._ === 'updateNewChannelMessage').map(({ message }) => message) // filter `updateNewChannelMessage` types only and extract the 'message' object

        for (const message of newChannelMessages) {
            // printing new channel messages
            console.log(`[${message.to_id.channel_id}] ${message.message}`)
        }
    });
}


// checking authentication status
mtproto
    .call('users.getFullUser', {
        id: {
            _: 'inputUserSelf',
        },
    })
    .then(startListener) // means the user is logged in -> so start the listener
    .catch(async error => {

        // The user is not logged in
        console.log('[+] You must log in')
        const phone_number = await getPhone()

        mtproto.call('auth.sendCode', {
            phone_number: phone_number,
            settings: {
                _: 'codeSettings',
            },
        })
            .catch(error => {
                if (error.error_message.includes('_MIGRATE_')) {
                    const [type, nextDcId] = error.error_message.split('_MIGRATE_');

                    mtproto.setDefaultDc(+nextDcId);

                    return sendCode(phone_number);
                }
            })
            .then(async result => {
                return mtproto.call('auth.signIn', {
                    phone_code: await getCode(),
                    phone_number: phone_number,
                    phone_code_hash: result.phone_code_hash,
                });
            })
            .catch(error => {
                if (error.error_message === 'SESSION_PASSWORD_NEEDED') {
                    return mtproto.call('account.getPassword').then(async result => {
                        const { srp_id, current_algo, srp_B } = result;
                        const { salt1, salt2, g, p } = current_algo;

                        const { A, M1 } = await getSRPParams({
                            g,
                            p,
                            salt1,
                            salt2,
                            gB: srp_B,
                            password: await getPassword(),
                        });

                        return mtproto.call('auth.checkPassword', {
                            password: {
                                _: 'inputCheckPasswordSRP',
                                srp_id,
                                A,
                                M1,
                            },
                        });
                    });
                }
            })
            .then(result => {
                console.log('[+] successfully authenticated');
                // start listener since the user has logged in now
                startListener()
            });
    })

您可以从api_idhttps://my.telegram.org找到值。api_hash

在第一次运行时,脚本会提示用户输入电话号码、代码和密码。

[+] You must log in
√ Enter your phone number: ... <phone_number>
√ Enter the code sent: ... <code>
√ Enter Password: ... <2FA password>

验证结束后,示例运行输出:

[+] starting listener
[13820XXXXX] Ja
[13820XXXXX] Bis bald guys��
[13820XXXXX] Ja. �
[13820XXXXX] Bis später
[13820XXXXX] Jaaa�

我检查身份验证状态的方式取自此处

值得一试的替代库在编写时处于活动状态(并且可用于创建相同的行为):Airgram (tdlib) 和GramJs

于 2020-06-13T17:36:23.330 回答
1

我使用了 gram.js库,基本上是这样做

import { TelegramClient } from 'telegram'
TelegramClient().addEventHandler(handler, { chats: [1234567890] })

该机器人不需要成为您要收听的频道的成员。

我的代码作为Node.js应用程序运行。

您需要先通过Telegram 与@BotFather交谈来创建令牌。

于 2022-02-01T00:26:26.860 回答