/telegram-stories-viewer-bot

🕵🏼‍♂️ View any Telegram stories anonymously (even protected ones). Just send a @username, phone number or direct link to the story!

Primary LanguageTypeScriptMIT LicenseMIT

The bot allows to view Telegram stories anonymously by leveraging a bot and userbot

📸 Screenshots

downloading happy path downloading progress info
downloading via direct link wrong command use cases

⚙️ How it works?

Initiate the userbot:
import { TelegramClient } from 'telegram';
import { StoreSession } from 'telegram/sessions';

async function main() {
  const client = await initClient();
}

async function initClient() {
  const storeSession = new StoreSession('userbot-session');

  const client = new TelegramClient(
    storeSession,
    USERBOT_API_ID,
    USERBOT_API_HASH,
    {
      connectionRetries: 5,
    }
  );

  await client.start({
    phoneNumber: USERBOT_PHONE_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('error: ', err),
  });
  console.log('You should now be connected.');
  console.log(client.session.save()); // Save the session to avoid logging in again
  await client.sendMessage('me', { message: 'Hi!' });

  return client;
}

• Get user's entities by username:

const username = '@chupapee';
const entity = await client.getEntity(username);

• Get stories data by entity:

import { Api } from 'telegram';

const activeStories = await client.invoke(
  new Api.stories.GetPeerStories({ peer: entity })
);

const pinnedStories = await client.invoke(
  new Api.stories.GetPinnedStories({ peer: entity })
);

• Download stories using media prop of story object:

const stories = await downloadStories(activeStories, pinnedStories);

async function downloadStories(activeStories, pinnedStories) {
  const result = [];

  for (const story of [...activeStories, ...pinnedStories]) {
    const buffer = await client.downloadMedia(story.media);
    if (buffer) {
      result.push({
        buffer,
        mediaType: 'photo' in story.media ? 'photo' : 'video',
      });
    }
  }

  return result;
}

• Send downloaded stories to user using Telegraf api (not Gramjs's userbot):

import { Telegraf } from 'telegraf';

const bot = new Telegraf(BOT_TOKEN);
bot.telegram.sendMediaGroup(
  chatId,
  stories.map((story) => ({
    media: { source: story.buffer },
    type: story.mediaType,
  }))
)

🧰 Tools Used

🤖 GramJS 🤖 - Provides access to the Telegram client API based on MTProto

👾 Telegraf 👾 - Provides access to the Telegram bot API

☄️ Effector ☄️ - used for writing the business logic of the app, ensuring efficient state management and handling of complex workflows

📦 Supabase 📦 - integrated for analytics data collection

🛠 Setup

To run this project locally, follow these steps:

  • Install all dependencies
yarn
  • Configure Credentials:

Set up your Telegram and userbot credentials in the configuration file

  • Start the bot:

Launch the bot in development mode using:

yarn dev
  • Enter Userbot Login Code:

Upon starting the bot, you'll receive a login code from Telegram. Enter this code when prompted by the userbot

  • Ready to Go:

Once the bot and userbot are up and running, the Telegram Story Viewer is ready to use!

🚀 Usage

Just send a message to the bot with the desired Telegram username, phone number, or the direct link to story. Wait for the bot to retrieve and deliver the stories back to you