Last active
June 6, 2021 03:47
-
-
Save SharzyL/1e4e17365dd4c7c563ee741e06c1a8fe to your computer and use it in GitHub Desktop.
Telegram Relation Graph
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# requirements: telethon, networkx, python-pysocks[asyncio], pygraphviz, tqdm | |
from telethon.client import TelegramClient | |
from telethon.tl.types import User as TgUser, Channel as TgChannel, Chat as TgChat | |
import telethon | |
import asyncio | |
import networkx as nx | |
from tqdm import tqdm | |
import pickle | |
client = TelegramClient( | |
api_id=114514, | |
api_hash='xxxxxxxxxxxxxxxxxxxxxxxxxxxxx', | |
session='relation-bot', | |
proxy=('socks5', 'localhost', 1080) | |
).start() | |
def format_entity_name(entity): | |
if isinstance(entity, TgUser): | |
first_name = entity.first_name or '' | |
last_name = entity.last_name or '' | |
return (first_name + ' ' + last_name).strip() | |
elif isinstance(entity, TgChat) or isinstance(entity, TgChannel): | |
return entity.title | |
else: | |
raise ValueError(f'Unknown entity {entity}') | |
async def start(): | |
g = nx.Graph() | |
for dialog in tqdm(await client.get_dialogs()): | |
g.add_node(dialog.entity.id, _type='Chat', _name=format_entity_name(dialog.entity)) | |
try: | |
async for person in client.iter_participants(dialog): | |
if dialog.entity.id != person.id: | |
g.add_node(person.id, _type='Person', _name=format_entity_name(person)) | |
g.add_edge(dialog.entity.id, person.id) | |
except telethon.errors.rpcerrorlist.ChatAdminRequiredError: | |
pass | |
print(g.degree) | |
with open('relation.pickle', 'wb') as fp: | |
pickle.dump(g, fp) | |
loop = asyncio.get_event_loop() | |
loop.run_until_complete(start()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import networkx | |
import pickle | |
import graphistry | |
import pandas as pd | |
if __name__ == '__main__': | |
with open('relation.pickle', 'rb') as fp: | |
g: networkx.Graph = pickle.load(fp) | |
for n, deg in list(g.degree): | |
if deg >= 2000: | |
g.remove_node(n) | |
for n, deg in list(g.degree): | |
if deg <= 1: | |
g.remove_node(n) | |
labels = [] | |
for n in g.nodes: | |
labels.append(g.nodes[n]['_name']) | |
reverse_edges = [(e[1], e[0]) for e in g.edges] | |
all_edges = list(g.edges) + reverse_edges | |
edges = pd.DataFrame(all_edges, columns=['chat', 'user']) | |
nodes = pd.DataFrame({'id': g.nodes, 'name': labels}) | |
graphistry.register(api=3, protocol="https", server="hub.graphistry.com", username="<your-username>", password="<your-password>") | |
gra = graphistry.nodes(nodes, 'id').edges(edges).bind(source='chat', destination='user', point_title='name') | |
gra.plot() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment