Skip to content

Instantly share code, notes, and snippets.

@SharzyL
Last active June 6, 2021 03:47
Show Gist options
  • Save SharzyL/1e4e17365dd4c7c563ee741e06c1a8fe to your computer and use it in GitHub Desktop.
Save SharzyL/1e4e17365dd4c7c563ee741e06c1a8fe to your computer and use it in GitHub Desktop.
Telegram Relation Graph
# 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())
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