Map influence, information flow, and community structure in Telegram networks.
Telegram channels constantly reference each other — forwarding messages, linking to one another, amplifying certain voices and ignoring others. These cross-references are not random: they reveal alliances, ideological clusters, and influence structures that are otherwise invisible. Which channels set the agenda? Who redistributes their content? Where do otherwise separate ecosystems overlap? Who is the only bridge connecting two communities that never directly interact?
~700 channels, ~10,000 edges. Leiden directed community detection, PageRank node size, vapoRwave palette.Pulpit collects messages from a set of Telegram channels you define, traces every forward and every t.me/ link between them, and turns the result into an interactive network map you can explore in a browser — zooming in on individual channels, filtering by detected community, comparing the reach of different actors, stepping through how the network evolved year by year.
The analytical layer is built on established methods from network science: PageRank, Burt's structural holes, Leiden community detection, k-core decomposition, and more — applied to the specific dynamics of Telegram forwarding networks. See the changelog for recent additions.
- Investigative journalists mapping political influence networks, tracing disinformation ecosystems, or documenting coordinated information campaigns across Telegram
- Academic researchers in political communication, network science, computational social science, and disinformation studies
- Activists and NGOs monitoring specific Telegram ecosystems — far-right networks, health misinformation communities, foreign-influence operations
- Students in digital methods, computational journalism, or media studies courses
Pulpit answers both structural and dynamical questions about a Telegram information ecosystem.
About individual channels:
- Which channels are the hidden agenda-setters — forwarded by all the key players, regardless of subscriber count? (PageRank)
- Which channels are pure distributors — aggregating and reposting from many sources without producing original content? (HITS Hub, Content Originality)
- Which channels bridge ideologically separate communities — the only link between two groups that otherwise share no direct contact? (Burt's Constraint)
- Whose content spreads farthest per post published, despite a modest following? (Amplification Factor)
- Which channels repeatedly forward the same content within minutes of each other — moving in step rather than merely citing one another? (Coordination Analysis)
About communities:
- How does the network cluster when the citation data decides the boundaries — not your own labels? (Leiden, Leiden (directed), Leiden CPM, and more)
- Which channels form the tight, mutually-reinforcing nucleus of the network? (K-core)
- Which community detection algorithms agree on a grouping, and which disagree? (Consensus matrix)
- How cohesive or competitive are the communities? How much do they interact? (E-I Index, Modularity)
About change over time:
- How did the network evolve year by year? Which channels rose, fell, or switched communities? (Timeline export)
- How does the network today compare to a snapshot from six months ago? (Network comparison)
- After a key channel went silent — removed, banned, or simply abandoned — who filled its structural role? (Vacancy Analysis)
- How resilient is this ecosystem if a moderation wave starts pulling channels offline — and which kinds of removals would damage it most? (Robustness Analysis)
- Which messages punched above their channel's own baseline, and which ones escaped their origin community to spread across the network? (Interesting messages)
Prerequisites: Python 3.12 (newer 3.x are not yet supported — the pinned numpy has no wheels for them). No Git required for the download below.
- Download the latest stable release: open the releases page, download Source code (zip) under Assets, and unzip it. You'll get a folder such as
pulpit-0.25. - Open a terminal in that folder and run the setup for your platform:
macOS / Linux
sh setup.sh
# Edit configuration/.env: set TELEGRAM_API_ID, TELEGRAM_API_HASH, TELEGRAM_PHONE_NUMBER
python manage.py runserverWindows
setup.bat
rem Edit configuration/.env: set TELEGRAM_API_ID, TELEGRAM_API_HASH, TELEGRAM_PHONE_NUMBER
python manage.py runserverOpen http://localhost:8000. The entire workflow runs from the browser from here. See Getting started for setup details, Telegram credential registration, and database configuration.
Prefer Git? Run
git clone https://github.com/giovabal/pulpit, thencd pulpit, then setup as above — this gives you the latest development code instead of the stable release. The Getting started guide covers this path.
A Pulpit research project runs in five steps, all accessible from the browser interface:
The four operations: search channels → crawl channels → structural analysis → compare analysis.- Find channels — Operations: Search channels — add keywords; Pulpit searches Telegram and populates a list of matching channels
- Organize — Manage: Labels — define labels (political orientation, country, funding source, or any axis that fits your research), organise them into groups, and mark the ones you care about in target; then tag each channel from its editor. Memberships can be time-bounded, and only channels holding an in-target label enter the analysis
- Collect channels info and messages — Operations: Crawl channels — download messages from every in-target channel; Pulpit records every forward and every
t.me/link, building a directed citation network - Generate the map — Operations: Structural analysis — run community detection and layout algorithms; export an interactive map, sortable tables, and network exchange files
- Compare maps — Operations: Compare analysis — compare two set of data; It could be the same network at two different times, compare the same network context but for two different countries, or just compare two different networks
The core data model is a directed, weighted citation graph: a directed edge from channel A to channel B means A regularly amplifies B's content. Edge weight reflects how much of A's output references B relative to A's overall citing activity.
After export, the output directory contains self-contained files that can be shared without an internet connection. Multiple named exports can coexist — each is written atomically, so an interrupted run never corrupts a previous result.
| Output | What it is |
|---|---|
Structural 2D map (graph.html) |
Search, filter by community, resize nodes by any measure, click for channel detail. Switch between ForceAtlas2, Kamada-Kawai, Spectral, Spring, Circular, Community-shell, t-SNE, UMAP, and Hyperbolic layouts with animated transitions — no re-export required. more |
Structural 3D map (graph3d.html) |
Three.js, rotate/zoom/inspect; multiple themes and coloured-edge toggle more |
Channel table (channel_table.html/.xlsx) |
One row per channel with all computed measures, sortable; per-year sparklines when a timeline was exported more |
Network statistics table (network_table.html/.xlsx) |
Whole-ecosystem metrics, measure comparison scatter plot, modularity-by-strategy table more |
Community table (community_table.html/.xlsx) |
Per-community metrics for each detection strategy; label-group × community cross-tabulations; cross-strategy partition-comparison matrices (ARI/AMI/NMI/VI) and a community-intersection Sankey more |
Structural equivalence matrix (structural_similarity.html) |
Lorrain & White (1971) structural equivalence: cosine similarity of each channel's weighted citation tie profile — high when two channels cite, and are cited by, the same others. Sortable by community or by measure more |
Consensus matrix (consensus_matrix.html) |
Agreement heatmap: how consistently each pair of channels is co-assigned across the partition-based strategies (your label-group partitions and K-core excluded) more |
Vacancy Analysis (vacancy_analysis.html) |
Replacement candidates ranked by up to six scores after a channel goes silent more |
Robustness analysis (robustness_table.html / .xlsx) |
Resistance to node removal: R-index over four damage metrics per attack strategy on the (optionally disparity-filtered) backbone, z-score + FDR-corrected empirical p against a configuration-model null, intra/inter community edge survival, ban-wave scenarios, and ban-replay validation more |
Coordination maps (coordination.html / coordination3d.html) |
Temporal co-forwarding layer: dedicated 2D and 3D maps of channels that repeatedly forwarded the same origin message within a short time window more |
| Timeline animation | Step through annual snapshots with animated node transitions in the structural and coordination maps, 2D and 3D more |
Network comparison (network_compare_table.html) |
Side-by-side comparison of two exports: which channels gained or lost influence more |
CSV node and edge lists (nodes.csv, edges.csv) |
Most portable format for scripting in R, Python, or shell. nodes.csv has the same columns as the channel table. edges.csv has source_label, target_label, weight, weight_forwards, weight_mentions. more |
| GEXF and GraphML | For Gephi, Cytoscape, R/igraph, and any graph-analysis tool more |
Each channel receives a score for up to 12 measures. All can be used to size nodes in the graph viewer, making the most significant channels visually prominent. Measures are grouped below by the type of question they answer.
Influence and reach
| Measure | What it surfaces |
|---|---|
| PageRank | Channels the network's key players treat as authoritative — prestige propagates through forwarding chains |
| HITS Hub | The distributors: channels that amplify many authoritative sources at scale |
| HITS Authority | The primary sources that distributors choose to spread |
| In-degree centrality | The most-cited channels, by raw fraction of the network citing them |
| Out-degree centrality | The most active amplifiers, by raw fraction of the network they cite |
| Amplification factor | Forwards received per message published — who punches above its weight |
Position and brokerage
| Measure | What it surfaces |
|---|---|
| Burt's constraint | Structural hole brokers — the only bridges between otherwise disconnected groups |
| Local clustering | Whether the channel's immediate contacts also cite each other — a tight mutual-amplification neighbourhood vs. an open star of independent sources (Fagiolo 2007) |
| Reciprocity | The share of a channel's citation partners that cite it back — two-way alliances vs. one-way audience (Garlaschelli & Loffredo 2004) |
| Within-module role | Within-community hub vs. cross-community connector — within-module z, the participation coefficient, and the Guimerà-Amaral role label |
Content and dynamics
| Measure | What it surfaces |
|---|---|
| Content originality | Producers vs. redistributors — 1 minus the fraction of forwarded messages |
| Diffusion lag | Median hours between a forwarded message's original publication and this channel forwarding it — early adopter vs. late amplifier |
See Network measures for academic references and worked examples for each measure — and for the reasoning behind the familiar measures Pulpit deliberately leaves out (betweenness and its relatives).
Pulpit runs up to nine community detection algorithms at once, alongside your own partition label groups as baselines (the primary one is conventionally an "Organization" axis). Each reveals a different structural layer of the same data; comparing them shows which groupings are robust and which are algorithm-dependent.
| Algorithm | What it finds | Direction-aware? |
|---|---|---|
| Label groups | Your own domain-knowledge partitions (e.g. an "Organization" or "Region" axis) as a baseline | — |
| Leiden | General community structure from citation density | No |
| Leiden Directed | Same, but the directed null model respects who cites whom | Yes |
| Leiden CPM | Resolution γ tunes granularity — low γ gives few large communities, high γ many small ones | No |
| Leiden Temporal | Communities tracked across timeline years in one shared id space — stable identity and colour year to year (needs --timeline-step year) |
No |
| Louvain | Classic modularity baseline — kept for comparison with older studies; Leiden supersedes it | No |
| K-core | Onion-layer peeling from the tight nucleus to the peripheral amplifiers | No |
| Stochastic block model | Citation-role blocks — channels grouped by structural position (source/amplifier, core/periphery), not just dense clusters | Yes |
| Assortative SBM | Cohesive communities with statistical support — a boundary only where the data back one (Leiden's question, answered inferentially) | No |
| Consensus | The groupings that survive across the other algorithms — the defensible core (needs ≥2 other algorithmic strategies) | Inherited |
The label-group × community cross-tabulation in every strategy section shows how your manual label groups map onto the algorithm's output — confirming agreement or surfacing unexpected internal splits. The consensus matrix aggregates the partition-based detection strategies — every algorithm except your manual label-group partitions and the K-core shell decomposition — into a single heatmap: pairs with large red circles are co-assigned by every algorithm, making their grouping robust independent of method choice.
See Community detection for descriptions, references, and a strategy selection guide.
When a channel goes silent — removed from Telegram, legally forced offline, or simply abandoned — it leaves a structural hole in the network. Channels that used to rely on it as a source now need to find an alternative. Pulpit's Vacancy Analysis answers: who fills that structural role?
An analyst registers a channel as a vacancy with a closure date. Pulpit then identifies the orphaned amplifiers — channels that forwarded from the vacancy before it closed — and ranks replacement candidates by up to six complementary scores (five shown in the interactive card; the temporal score is batch-export only):
| Score | Question | Method |
|---|---|---|
| Amplifier Coverage | What fraction of orphaned amplifiers have started forwarding the candidate? | Coverage / recall ( |
| New-adopter Coverage | Of the orphans that never forwarded the candidate before the closure, how many adopted it after? | Coverage restricted to genuine new adopters — the pre-existing-habit share removed |
| Neighbour-set Equivalence | Does the candidate occupy the same position — same inputs, same amplifiers? | Cosine similarity (Lorrain & White 1971) |
| Brokerage overlap | Does the candidate sit in the same organizational position — drawing on the same source orgs and amplified by the same audience orgs? | Jaccard of the (source-org, amplifier-org) pairs it spans; a one-degree structural-position overlap, not content flow. Brokerage concept per Gould & Fernandez 1989 (not their census) |
| Content Continuity | Does the candidate circulate the vacancy's content — the same origin messages, or the vacancy's own back-catalogue? | Ochiai of shared pre-closure origin messages, with the count of forwards of posts authored by the vacancy (ban-evasion identity lineage: Niverthi et al. 2022) |
| Temporal adoption | How quickly and broadly did the orphaned channels adopt the candidate? | Coverage hyperbolically discounted by mean days-to-adoption (Mazur 1987) |
The two coverage scores measure who re-pointed to the candidate; neighbour-set equivalence and brokerage overlap capture its structural position; content continuity adds identity evidence — a position can be inherited by an unrelated opportunist, but the vacancy's specific content stream cannot; temporal adoption adds timing. A channel scoring high across all of them is a strong structural heir — the same distributors, the same upstream sources, the same brokerage role, the same content, all settled on quickly.
See Vacancy analysis for academic grounding, score interpretation patterns, and the batch export API.
How well does this ecosystem hold up when channels start disappearing? Different removals damage the network in different ways: peripheral amplifiers can leave without a trace, but stripping a hub or a community bridge can fragment the citation web across half the network. Pulpit's Robustness Analysis answers: which kinds of node loss matter most, and does this network have identifiable critical channels at all?
The analysis optionally extracts the disparity-filter backbone (Serrano-Boguñá-Vespignani 2009) — pruning edges statistically indistinguishable from uniform weight noise — then progressively removes nodes under the attack strategies you select and tracks how the residual network shrinks:
| Strategy | Mode | What it models |
|---|---|---|
| Random | Static (averaged over N runs) | Indiscriminate node loss — the baseline against which targeted attacks should look much worse |
| In-strength | Static | Take down everything that's heavily cited — moderation aimed at popular destinations |
| Out-strength | Static | Take down everything that cites heavily — moderation aimed at aggregators |
| PageRank | Static | Take down the highest-prestige nodes — moderation aware of inherited prestige |
| Betweenness | Static | Take down the bridges — the channels whose removal cuts the network apart |
| Collective Influence | Static | Take down the near-optimal dismantling set (Morone & Makse 2015) — the coordinated worst-case attacker |
| Subscribers | Static | Take down the biggest audiences — moderation as it actually happens, targeting visibility rather than structure |
| In-strength / Out-strength / PageRank / Betweenness (dyn) | Dynamic — re-rank after every removal | The same four targeted attacks with cascade awareness |
| Collective Influence (dyn) | Dynamic | The canonical adaptive CI algorithm — the strongest dismantling order Pulpit ships |
| Greedy fragmentation (dyn) | Dynamic | Borgatti (2006) key-player dismantling — repeatedly remove whatever most shatters the residual network |
The default run uses random, in-strength, out-strength, PageRank, and betweenness; pick any subset with --robustness-strategies. (Betweenness and the dismantling strategies use multi-hop topology purely as a removal-order heuristic — they make no per-channel content-flow claim; see the one-degree guardrails in the docs.)
Four damage metrics are tracked simultaneously: largest weakly-connected component, largest strongly-connected component (the mutually-reinforcing core), the fraction of directed source→target pairs still reachable, and the surviving citation weight (Bellingeri & Cassi 2018) — the weighted damage that node-count curves systematically understate. A coarse weighted global-efficiency curve additionally tracks how well the surviving core stays knit as each attack proceeds.
For each (strategy, damage metric) pair Pulpit reports the Schneider et al. (2011) R-index — the average residual size across the entire attack — plus a 5%-collapse threshold, and calibrates it against a configuration-model null: randomised graphs that keep each channel's in/out degree exactly and its in/out strength approximately while reshuffling the wiring, so a significant deviation reflects higher-order structure rather than the degree sequence the attacks already rank on. A reciprocity-preserving variant (Squartini & Garlaschelli 2011) is available when mutual citation is itself the structure under test. Each cell gets a z-score, an empirical p-value, and a BH/FDR-corrected q across the whole strategy × metric grid. R values lower than random failure mean the network has critical channels.
Beyond the attack curves: when community partitions are active the analysis tracks intra- vs inter-community edge survival (does the attack cut bridges first, or hollow out cliques?); ban-wave scenarios remove a whole community or label-group block in one step — making "what if organisation O were banned?" a first-class query — and compare it against removing the same number of channels at random; ban-replay validation replays each year's actually-recorded channel closures against the prior-year graph and checks the prediction against the observed next-year structure; and an α-sensitivity sweep re-runs the headline numbers across a grid of backbone thresholds. When --timeline-step year is also active, the whole battery runs once per calendar year alongside the global one, with the HTML page surfacing a year navigator over the per-year results.
See Robustness analysis for the formal definitions, the null-model limits (what it does not preserve), interpretation guidance, and the academic references.
Crawling. The official Telegram API (via Telethon) downloads messages from the channels you select. For each message, Pulpit records forwards (which channel's content was reposted) and inline t.me/ references (links to other channels). The result is a directed, weighted graph. Edge weight is computed as the number of forwards and references from A to B divided by the number of A's messages that contain any outward reference — not A's total message count — so channels that mostly publish original content and channels that are mostly aggregators are treated symmetrically.
Analysis. The graph is analysed with NetworkX. Node-level measures rank channels by influence, reach, or structural importance; the battery is deliberately matched to what Telegram's forward-attribution data can support, and the measures left out are documented with the same care as the ones included (why). Community detection algorithms identify clusters. Whole-network statistics — density, reciprocity, algebraic connectivity (Fiedler 1973), E-I index (Krackhardt & Stern 1988), global efficiency (Latora & Marchiori 2001), and more — characterise the ecosystem as a system. Cross-strategy partition-comparison matrices (ARI, AMI, NMI, VI) quantify how much any two community partitions agree, independently of community labels.
Layout and visualisation. Nodes are placed using ForceAtlas2 seeded from a Kamada-Kawai initial layout, improving reproducibility across re-exports. Alternative spatial layouts (Spectral, Spring, Circular, Community shells, t-SNE, UMAP, and Hyperbolic) are pre-computed at export time and selectable at viewing time with smooth animated transitions. The structural 2D map is a self-contained HTML file powered by Sigma.js. The optional structural 3D map uses Three.js with Lambert-shaded spheres and full mouse rotation, zoom, and pan.
Storage and access control. Data is stored in SQLite by default — a single file, no database server required. PostgreSQL, MySQL/MariaDB, and Oracle are supported for multi-user deployments. The browser interface supports three access modes: fully open (personal use on your own machine), semi-protected (public channel browser, restricted operations panel), and fully protected (login required for all pages).
CLI access. Every operation is also available as a management command for scripting, scheduling, and automation. See the Workflow documentation for the full command reference.
Accessibility. Even though Pulpit is a data-intensive interface, we care about accessibility, and most of the interface tries to be friendly in this regard: keyboard-reachable controls, visible focus indicators, screen-reader announcements for asynchronous updates, hidden data-table companions for charts, labelled landmarks, and a skip-to-content link on every page.
| File | Contents |
|---|---|
| Getting started | Requirements, installation, Telegram credentials, database setup, access control — written for readers with no prior programming experience |
| Workflow | Step-by-step guide: search → organize → crawl → export; all CLI options |
| Network measures | All 12 per-channel measures with academic references and worked examples |
| Community detection | 9 algorithms plus your label groups, consensus matrix, cross-strategy comparison, choosing a strategy |
| Whole-network statistics | Ecosystem-level metrics: density, reciprocity, clustering, Fiedler value, E-I index, NMI, and more |
| Vacancy analysis | 6 scores for identifying structural replacement channels after a node disappears |
| Robustness analysis | Resistance to node removal: 13 attack strategies, R-index over four damage metrics, configuration-model null with FDR-corrected p-values, ban-wave scenarios and ban-replay validation |
| Coordination analysis | Temporal co-forwarding maps: repeated near-simultaneous forwards of the same origin message, rendered as dedicated 2D/3D maps |
| Interesting messages | Per-channel z-scored engagement composite plus structural-reach metrics (cross-community reach, authority-weighted reach) |
| Web interface | Browser UI: channel browser, channel detail pages, Operations panel, backoffice |
| Export formats | All output files: graphs, tables, GEXF, GraphML, atomic write safety |
| Operations defaults & configuration | How the form, the CLI, and the snapshot files relate; the three buttons (Save / Load / Write CLI); the every-flag-must-be-explicit CLI rule |
| Configuration reference | Every setting in configuration/.env and the two .operations-* TOML files, with built-in defaults |
| Backup and migration | Bundle an installation (database, session, configuration, media) into a drop-in directory to back it up or move it to another machine |
| Changelog | Version history |
Pulpit is intended for academic research, investigative journalism, and analytical work on publicly accessible Telegram channels. It was written with the aim of complying with applicable laws and with Telegram's Terms of Service as they stood at the time of development.
Laws governing data collection, storage, and analysis of public communications vary across jurisdictions and change over time. Telegram's Terms of Service are likewise subject to revision. It is your responsibility to verify that your use of this software complies with the laws of your country and with Telegram's current Terms of Service before running it. The authors accept no liability for uses that fall outside lawful research and analysis.

