创建一个将收听电报频道的应用程序

Kon*_*ine 6 node.js telegram

首先请注意,这与创建机器人无关

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

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

我已经观察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);
  });
});
Run Code Online (Sandbox Code Playgroud)

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

Tib*_*. M 8

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

您可以使用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()
            });
    })

Run Code Online (Sandbox Code Playgroud)

你可以找到的值api_id,并api_hashhttps://my.telegram.org

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

[+] You must log in
? Enter your phone number: ... <phone_number>
? Enter the code sent: ... <code>
? Enter Password: ... <2FA password>
Run Code Online (Sandbox Code Playgroud)

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

[+] starting listener
[13820XXXXX] Ja
[13820XXXXX] Bis bald guys??
[13820XXXXX] Ja. ?
[13820XXXXX] Bis später
[13820XXXXX] Jaaa?
Run Code Online (Sandbox Code Playgroud)

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

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


Adi*_*oke 5

这是我使用 gramjs 及其纯粹在 Nodejs 上的工作代码。从所有渠道获取所有消息,没有任何延迟。

import {
  TelegramClient
} from "telegram";
import {
  NewMessage,
  NewMessageEvent
} from "telegram/events";
import {
  StringSession
} from "telegram/sessions";
const input = require("input");

const apiId = 1233456677;
const apiHash = "xxxxxxxxxxxxxxxxx";
let stringSession = new StringSession("xxxxxxxxxxxxxxxxx");

(async() => {
  console.log("Loading interactive example...");
  const client = new TelegramClient(stringSession, apiId, apiHash, {
    connectionRetries: 5,
  });
  await client.start({
    phoneNumber: async() => await input.text("Please enter your number: "),
    password: async() => await input.text("Please enter your password: "),
    phoneCode: async() =>
      await input.text("Please enter the code you received: "),
    onError: (err) => console.log(err),
  });
  console.log("You should now be connected.");
  const session: any = client.session.save();
  stringSession = new StringSession(session); // Save this string to avoid logging in again - specially in nodemon
  console.log(client.session.save()); // --> you can also copy this session from your console once you get it and paste it in line number 8 - new StringSession("XXXXXXXXXXXXXX")
  // once you saved add the JWT Token on line no. 8 as mention above next time you will getting directly connected.
  await client.sendMessage("me", {
    message: "Hello!"
  });
  async function handler(event: NewMessageEvent) {
    console.log("[newmessage]", event);
  }
  client.addEventHandler(handler, new NewMessage({}));
})();
Run Code Online (Sandbox Code Playgroud)

注意 -忽略“运行代码片段”,因为它是添加整个代码而不是格式化的最佳方法。