Создание приложения для прослушивания телеграмм канала

Прежде всего, обратите внимание, что речь идет не о создании бота.

Моя цель - создать приложение, которое будет просто прослушивать любое количество телеграммных каналов, на которые подписана учетная запись, на которую я буду предоставлять его, и извлекать все сообщения, отправленные на эти каналы (как если бы я был обычным пользователем). Я думаю, что мне нужно будет

  • Аутентифицировать себя, используя номер телефона моей учетной записи
  • Уметь настроить прослушиватель обратного вызова для каждого канала или общего прослушивателя для всех входящих сообщений

Я искал вокруг 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);
  });
});

Он использует эти 2 библиотеки: telegram-mt-node telegram-tl-node

4 ответа

Поздний ответ, но может помочь другим.

Вы можете использовать mtproto-core для аутентификации с помощью обычной учетной записи Telegram и слушать обновления (или делать все, что вы можете с клиентами Telegram, на самом деле)

Вот пример сценария, который я написал, который прослушивает новые сообщения из каналов / супергрупп, на которые подписан пользователь:

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_id а также api_hashс https://my.telegram.org/.

При первом запуске сценарий запрашивает у пользователя phone_number, код и пароль.

[+] 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

вот мой рабочий код с использованием gramjs и только на nodejs. Получение всех сообщений со всех каналов без задержек.

Примечание. Игнорируйте «Выполнить фрагмент кода», так как это лучший способ добавить весь код вместо форматирования.

Я использовал библиотеку gram.js и, по сути, сделал это :

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

Бот НЕ обязательно должен быть участником канала, который вы хотите слушать.

Мой код работает как приложение Node.js.

Сначала вам нужно создать токен, поговорив с @BotFather через Telegram.

Вы можете использовать библиотеку gram.js следующим образом:

  1. Установите это:

            npm install properties-reader
    npm install telegram
    npm install input
    
  2. Тогда получите свойapiIdиapiHashиз Telegram Auth в разделе «Конфигурация приложения».

  3. Создать файлconfig.propertiesс содержанием, подобным этому:

            [telegram]
    apiId=12345678
    apiHash=12345678901234567890123456789012
    
  4. Внутри вашегоnodejsкод, вы можете слушать определенный чат, подобный этому (см.chatIdвнутри кода ниже):

            const PropertiesReader = require('properties-reader');
    const configs = PropertiesReader('config.properties');
    getProp = (bundle, key) => {return configs.get(`${bundle}.${key}`);}
    
    const { TelegramClient } = require("telegram");
    const { StoreSession } = require("telegram/sessions");
    const { NewMessage } = require("telegram/events");
    const { EditedMessage } = require("telegram/events/EditedMessage");
    const input = require("input");
    
    const apiId = getProp("telegram", "apiId")
    const apiHash = getProp("telegram", "apiHash")
    const storeSession = new StoreSession("telegram_session"); // see: https://painor.gitbook.io/gramjs/getting-started/authorization#store-session
    
    (async () => {
        console.log("Loading interactive example...");
        const client = new TelegramClient(storeSession, 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.");
        client.session.save(); // Save the session to avoid logging in again
    
        async function eventPrint(event) {
            // see 'node_modules/telegram/tl/custom/message.d.ts'
            const message = event.message
            const isNew = message.editDate === undefined
            const text = message.text
            const date = new Date(message.date*1000)
    
            console.log(`The message is ${isNew ? 'new' : 'an update'}`)
            console.log(`The text is: ${text}`)
            console.log(`The date is: ${date}`)
        }
    
        // to get the chatId:
        // option 1: open telegram on a web browser, go to the chat, and look the url in the address bar
        // option 2: open telegram app, copy link to any message, it should be something like: https://t.me/c/1234567890/12345, the first number after "/c/" is the chatId
        const chatId = 1234567890
        client.addEventHandler(eventPrint, new NewMessage({ chats: [chatId] }));
        client.addEventHandler(eventPrint, new EditedMessage({ chats: [chatId] }));
    })();
    
Другие вопросы по тегам