{{ costEstimate.detail }}
Generates visual charts and tabular data directly in the browser.
Only save posts matching this pattern.
Format: Category Name | Regex
Select a database and click Generate Dashboard.
Total Posts
{{ statsData.total_posts.toLocaleString() }}
Total Views
{{ statsData.total_views.toLocaleString() }}
Channels
{{ statsData.channels.length }}
Posting Timeline
AI Sentiment
Regex Categories
AI Categories
Channel Performance & Sentiment
| Channel Name | Posts | Views | Pos | Neg | Neu |
|---|---|---|---|---|---|
| {{ c.label }} | {{ c.posts.toLocaleString() }} | {{ c.views.toLocaleString() }} | {{ c.Positive || 0 }} | {{ c.Negative || 0 }} | {{ c.Neutral || 0 }} |
Comparison: {{ compareResult.db_a }} vs {{ compareResult.db_b }}
DB A Rows
{{ compareResult.rows_a.toLocaleString() }}
DB B Rows
{{ compareResult.rows_b.toLocaleString() }}
New in B
+{{ compareResult.new_in_b.toLocaleString() }}
Sentiment Shift
{{ s.label }}
{{ s.delta > 0 ? '+' : '' }}{{ s.delta }}%
New Channels in B
{{ compareResult.new_channels.join(', ') }}
| # | {{ col }} |
|---|---|
| {{ dbViewerPage * dbViewerPageSize + rIdx + 1 }} |
{{ row[cIdx] }}
|
Select a database and click Load to view data.
Double-click any cell to edit it.
General
Full URL with https://. Used for topic links in Telegram digests.
Google Gemini
Get a key from Google AI Studio
OpenRouter
FREE MODELSStep 3.5 Flash has mandatory reasoning. This hides it from the response to save tokens.
Get a key from openrouter.ai/keys. Free models available!
OpenAI
Get a key from platform.openai.com
Telegram Sessions for Monitoring
Add multiple Telegram sessions to distribute channel scraping and avoid rate limits. Channels are split evenly across active sessions.
Monitoring Schedule
Global AI Models
Default models for all topics (can be overridden per-topic)Enrichment model is used for sentiment analysis and categorization. Summary model is used for AI summaries and deep analysis.
Data Retention
Older posts will be automatically deleted during scheduled cleanup.
HOW TO GET TELEGRAM CREDENTIALS
- Go to my.telegram.org and log in with your phone number.
- Click on 'API development tools'.
- Create a new application (you can enter any random App Title and Short Name).
- Copy the App api_id and App api_hash into the Setup tab.
- First time you run the scraper, a popup will ask for the Telegram code sent to your app.
SERVER BLOCKED? (STRING SESSION BYPASS)
If you never receive a code, your VPS IP is blocked by Telegram's anti-bot system. Bypass it using a local QR code login:
- Install Python on your local Windows/Mac computer.
- Run
pip install telethon qrcodein your terminal. - Run the Python script below on your PC. It will print a QR code in your terminal.
- Open Telegram on your phone → Settings → Devices → Link Desktop Device, and scan the QR.
- Click the code box below (it will auto-select all), copy the generated
1BJWap...string, and paste it into the Setup tab.
import asyncio
import qrcode
from telethon import TelegramClient
from telethon.sessions import StringSession
from telethon.errors import SessionPasswordNeededError
api_id = YOUR_API_ID # CHANGE THIS
api_hash = 'YOUR_API_HASH' # CHANGE THIS
async def main():
client = TelegramClient(StringSession(), api_id, api_hash)
await client.connect()
if not await client.is_user_authorized():
qr_login = await client.qr_login()
qr = qrcode.QRCode(border=1)
qr.add_data(qr_login.url)
qr.make(fit=True)
qr.print_ascii(invert=True)
try:
await qr_login.wait()
except SessionPasswordNeededError:
password = input("Please type your Telegram 2FA Password: ")
await client.sign_in(password=password)
print("\n--- YOUR SESSION STRING (COPY THIS) ---")
print(client.session.save())
if __name__ == "__main__":
asyncio.run(main())
REGEX (REGULAR EXPRESSIONS) TUTORIAL
Regex is a powerful way to search for specific words or patterns.
- Exact word match:
\bapple\b(Matches 'apple' but not 'apples') - Ignore Capitalization:
(?i)apple(Matches 'Apple', 'aPpLe', 'apple') - OR operator:
apple|banana|orange(Matches any of those words) - Find a hashtag:
#ukraine - Contains numbers:
\d+
Examples for the Categorizer box:
Politics | (?i)biden|trump|putin|zelensky Military | (?i)\b(tank|missile|drone)\b Economy | (?i)inflation|taxes|\$
AI ANALYSIS (GEMINI)
- Get a free API key from Google AI Studio: https://aistudio.google.com/app/apikey
- Because AI reads the text conceptually, you don't need exact words. Just describe what 'Positive' means to you, or describe your desired categories in plain English!
- Note: Free tier strictly limits processing to ~15 messages per minute. The scraper automatically throttles itself to respect this limit.
{{ t.name }}
{{ t.active_alerts }} alertsNo topics configured yet
Go to the Topics tab to create your first monitoring topic.
Posts by Topic ({{ dashPeriodLabel }})
Sentiment Overview ({{ dashPeriodLabel }})
Recent Scrapes
Channel Analytics
Size = views. Green = positive, Red = negative, Gray = neutral. Top 40 channels.
| Channel | Category | Posts | Views | + | ~ | - |
|---|---|---|---|---|---|---|
| @{{ ch.username }}{{ ch.title?.slice(0,25) }} | {{ ch.category || '' }} | {{ ch.post_count }} | {{ (ch.total_views||0).toLocaleString() }} | {{ ch.positive || 0 }} | {{ ch.neutral || 0 }} | {{ ch.negative || 0 }} |
Leave all unchecked = process all channels
{{ selectedTopicDash.topic.name }} All Posts Keyword
{{ selectedTopicDash.topic.description }}
{{ selectedTopicDash.topic.regex_display || selectedTopicDash.topic.regex_pattern }}
AI Summary
Post Volume Over Time
Sentiment Over Time
AI Categories
Regex Categories
Topic Seismograph
SVGPosts ({{ filteredSortedPosts.length }} / {{ selectedTopicDash.recent_posts.length }})
| Date | Channel | Sent. | AI Cat. | Regex Cat. | Text | Views | AI | |
|---|---|---|---|---|---|---|---|---|
| Clear filters | ||||||||
| {{ p.posted_at?.slice(5,16) }} | {{ p.channel_username }} |
{{ p.text?.slice(0, 150) }}
|
{{ (p.views||0).toLocaleString() }} | |||||
Channel Analytics
| Channel | Posts | Views | + | - |
|---|---|---|---|---|
| @{{ ch.username }} | {{ ch.post_count }} | {{ (ch.total_views||0).toLocaleString() }} | {{ ch.positive || 0 }} | {{ ch.negative || 0 }} |
Coordinated Post Groups
Active Alerts
Saved Reports
Select a topic from the left panel
Manage Categories & Types
| Channel | Category | Type | Subs | Posts | Sent. | Active | Actions | |
|---|---|---|---|---|---|---|---|---|
|
@{{ ch.username }}
{{ ch.title }}
|
{{ (ch.subscriber_count||0).toLocaleString() }} | {{ ch.total_posts || 0 }} | {{ ch.positive||0 }}/{{ ch.negative||0 }} — |
No channels added yet
Click Load Defaults to import 279 Ukrainian media channels, or add manually.
Coordinated Post Detection
Posts with ≥ {{ detectionRules.coord_similarity }}% text similarity across ≥ {{ detectionRules.coord_min_channels }} channels within {{ detectionRules.coord_time_window }}h are flagged as coordinated.
Attack Detection
Flags when volume is ≥ {{ detectionRules.attack_volume_mult }}× average AND negativity exceeds baseline + {{ detectionRules.attack_std_devs }}σ with ≥ {{ detectionRules.attack_min_posts }} posts from ≥ {{ detectionRules.attack_min_channels }} channels.
Information Attacks
Coordinated Post Groups
No alerts
Run detection to scan for coordinated posts and information attacks.
Comma-separated. Post matches if it contains at least one of these words.
Comma-separated. Post must contain every single word listed here.
Comma-separated. Posts with any of these words will be excluded.
Examples & Recipes
This bot receives notifications for all topics.
No bots configured
Click "Add Bot" to set up notifications.
Setup Guide
- Open Telegram, search for @BotFather
- Send /newbot and follow the prompts
- Copy the bot token and paste it into a bot card above
- For DMs: start a chat with the bot, send /start. Get your Chat ID from @userinfobot
- For groups: add the bot to the group as admin. Chat ID is the group ID (negative number)
- For forum topics: also enter the Thread ID (from the ?thread= URL param)
- You can use the same bot token for multiple destinations — just create multiple cards with different Chat IDs
{{ viewingPost.text }}
Edit Topic
Leave empty to use default. Template variable {{topic_name}} will be replaced with the topic name.
{{ prompt.title }}
{{ prompt.desc }}