Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// ==UserScript==
// @name Telegram - Get Users
// @author thefabledowl@gmail.com
// @desription Greasemonkey script to extract users from Telegram groups
// @namespace https://fabledowlblog.wordpress.com/
// @include https://web.telegram.org/*
// @downloadUrl https://gist.github.com/fabledowl/8c8db5858e096866c42dfa114034f0f2/raw/getUsers.user.js
// @updateUrl https://gist.github.com/fabledowl/8c8db5858e096866c42dfa114034f0f2/raw/getUsers.user.js
// @version 0.4
// @grant none
// @run-at document-start
// ==/UserScript==
(function () {
'use strict';
var runAngular = function () {
try {
if (angular.element(document.body).injector().get('$rootScope')) {
initialize();
return;
}
} catch (e) {
window.setTimeout(runAngular, 1);
}
};
runAngular();
function initialize() {
var rootScope = angular.element(document.body).injector().get('$rootScope');
var mtpApiManager = angular.element(document).injector().get('MtpApiManager');
var appChatsManager = angular.element(document).injector().get('AppChatsManager');
var users = [
];
var jsonData = [
];
var id;
var channelName;
var userCount;
var offset = 0;
function getUsers() {
id = Math.abs(rootScope.selectedPeerID);
if (appChatsManager.isChannel(id)) {
getChannelFull(id).then(function(data) {
if (data.full_chat.pFlags.can_view_participants) {
getParticipants();
} else {
reset();
}
});
} else {
getChatFull(id).then(function(data) {
parseResults(data);
displayData();
});
}
}
function reset() {
$('#spinner').hide();
$('#getUsers').prop('disabled', false);
}
function getParticipants() {
if (offset > userCount) {
return;
}
mtpApiManager.invokeApi('channels.getParticipants', {
channel: appChatsManager.getChannelInput(id),
filter: {
_: 'channelParticipantsRecent'
},
limit: 200,
offset: offset
}).then(function (data) {
parseResults(data);
offset += 200;
if (offset > userCount) {
displayData();
return;
}
}).then(delayPromise(randomIntBetween(2000, 5000))).then(function () {
getParticipants();
}).catch (function (e) {
reset();
});
} // Delay promise function
function getChannelFull(id) {
return mtpApiManager.invokeApi("channels.getFullChannel", {
channel: appChatsManager.getChannelInput(id)
});
}
function getChatFull(id) {
return mtpApiManager.invokeApi("messages.getFullChat", {
chat_id: appChatsManager.getChatInput(id)
});
}
function delayPromise(delay) {
return function (data) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(data);
}, delay);
});
};
}
function randomIntBetween(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function addStyle(css) {
$('head').append($('<style>').text(css));
}
function addUserRow(user) {
$('#users').append($('<tr><td><a class="view-user" href="https://web.telegram.org/#/im?p=u' + user.id + '_' + user.access_hash + '">' + user.id + '</a></td><td>' + user.full_name + '</td><td>' + user.username + '</td><td>' + user.lastOnline + '</td><td>' + user.type + '</td>'));
}
function downloadFile(users, channelName, channelID) {
var d = new Date();
var day = d.getUTCDate();
var month = d.getUTCMonth() + 1;
var year = d.getUTCFullYear();
var filename = channelID + '_' + day + '-' + month + '-' + year;
var fileContent = 'Channel Name:\t' + channelName + '\r\n';
fileContent += 'ID\tFirst Name\tLast Name\tUsername\tAccount Type\tLast Online\tDate Joined\tInvited By\tAccess Hash\r\n';
for (var l = 0; l < users.length; l++) {
var user = users[l];
var id = user.id;
var firstName = (user.first_name ? user.first_name : '').replace(/\n/g, '').replace(/\r/g, '');
var lastName = (user.last_name ? user.last_name : '').replace(/\n/g, '').replace(/\r/g, '');
var username = (user.username ? user.username : '').replace(/\n/g, '').replace(/\r/g, '');
var dataString = id + '\t' + firstName + '\t' + lastName + '\t' + username + '\t' + user.type + '\t' + user.lastOnline + '\t' + user.dateJoined + '\t' + user.inviter_id + '\t' + user.access_hash;
fileContent += (l < users.length ? dataString + '\r\n' : dataString);
}
var link = document.createElement('a');
link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(fileContent));
link.setAttribute('download', filename + '.txt');
$('body').append(link);
link.click();
link.remove();
}
function parseResults(data) {
var participants;
if (data.participants) {
participants = data.participants.map(function (participant) {
var user = data.users[getUserById(participant.user_id, data.users)];
Object.assign(user, participant);
return user;
});
} else {
participants = data.users;
}
for (var j = 0; j < participants.length; j++) {
participants[j].dateJoined = 'N/A';
if (participants[j].date) {
participants[j].dateJoined = new Date(participants[j].date * 1000).toUTCString();
}
participants[j].full_name = '';
if (participants[j].first_name) {
participants[j].full_name += participants[j].first_name;
}
if (participants[j].last_name) {
participants[j].full_name += ' ' + participants[j].last_name;
}
participants[j].username = (participants[j].username ? participants[j].username : '');
if (participants[j]._.includes('Creator')) {
participants[j].type = 'Creator';
} else if (participants[j]._.includes('Editor')) {
participants[j].type = 'Admin';
} else {
participants[j].type = 'User';
}
if (participants[j].status) {
if (participants[j].status._ == 'userStatusOffline') {
participants[j].lastOnline = new Date(participants[j].status.was_online * 1000).toUTCString();
} else if (participants[j].status._ == 'userStatusOnline') {
participants[j].lastOnline = new Date().toUTCString();
} else if (participants[j].status._ == 'userStatusRecently') {
participants[j].lastOnline = 'Recently';
} else if (participants[j].status._ == 'userStatusLastWeek') {
participants[j].lastOnline = 'Last Week';
} else if (participants[j].status._ == 'userStatusLastMonth') {
participants[j].lastOnline = 'Last Month';
}
} else {
participants[j].lastOnline = 'Unknown';
}
participants[j].inviter_id = (participants[j].inviter_id ? participants[j].inviter_id : '');
addUserRow(participants[j]);
}
Array.prototype.push.apply(users, participants);
function getUserById(id, elements) {
var index = elements.filter(function (element) {
return element.id === id;
}) [0];
return elements.indexOf(index);
}
}
function displayData() {
$('#usercount').text(users.length + ' members');
$('#exportUsers').unbind('click').click(function () {
downloadFile(users, channelName, id);
});
$('#spinner').hide();
$('.custom-panel').show();
}
function createUI() {
// Create UI - Modal/Button/Spinner
addStyle('.spinner {position: absolute; display:none; overflow: auto; top: 50%; left: 50%; width: 150px; height: 150px; margin: -75px 0 0 -75px; z-index:250; background-color: #FFFFFF; border: 1px solid #000000;}' +
'.spinner img {width: 60px; height: 60px; margin-top: 45px; margin-left: 45px;}' +
'.custom-panel {position: absolute; display: none; top: 50%; left: 50%; width: 700px; height: 400px; margin: -200px 0 0 -350px; z-index:240;}' +
'.custom-panel-heading {background-color:rgb(86, 130, 163); color: #FFFFFF; height:48px; padding: 15px; font-size: 13px;}' +
'.custom-panel-body {background-color: #FFFFFF; height:352px; border-left: 1px solid rgb(233, 235, 237); border-right: 1px solid rgb(233, 235, 237); border-bottom: 1px solid rgb(233, 235, 237); overflow: auto;}' +
'.close-btn {background-color:rgb(86, 130, 163); border: 1px solid rgb(233, 235, 237); float: right; margin-left: 5px;}' +
'.profile_photo {border-radius: 50%; height:18px; width: 18px;}' +
'.get-users-btn {position: absolute; bottom: 5px; left: 5px; background-color:rgb(86, 130, 163); border: 1px solid rgb(233, 235, 237); padding: 10px; color: #FFFFFF; font-weight: bold;}'
);
$('body').append('<div id="spinner" class="spinner"><img src="data:image/gif;base64,R0lGODlhLQAtAPMPANTU1O3t7fJoRfv7++9OJdvb2+Lf3/SBZPixn/7v6/m+r/b29ubm5u0wAM3Nzf///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQFCgAPACwAAAAALQAtAAAE//DJSesIBjg3WxMHklRkaUpBsa2c5L0fcs5VoLFrB7+ETJsDFY6l270Eox8lMBwWjS+fktnEPaEehVJiqBJd2NdhOul6ARNCuDFGnZiG8tAQGFQSioOx/egGSgsrcVwrDHYzCXoefGYOCyRCG4N9AI9bBgSMLAU1c1s0jSt/Ezc4k58VoStoKFWsqBWlOKOROJawFIFNnANVDLglDFUXw8AkvU0YTafGcnOyos0kVDjQK4fSE8heLK/ZpE3f4uPk5RVN3uLWXuXb1cnk1N2qkuT0DnTF3+4sdb7iwprYqcUCmzF+Kzg9kNct2zoHox6sY4brnjeG+MTRiyih1qQMBltpDADwcRMJXRkJbTAkMmDKPituLXmpiiTHCcpMybm5xJkrcF4m8Sxxz4oEbvW2YAx3FCnET0uNPnA6dMYCglK5FZCJykaVCa6qdsUKFkcBscAuZNhQ1mbIGREAACH5BAUKAA8ALBgAAAAVABUAAARg0Lliwng46y37DFuIeR4AihlJFheqqmf4wuLsGShgOzimhIOAQdV7HBoI1IDRKR4bjQTqsQA4oVDBdPPEIreYrpcAfhC83t/WgMZqwWLvotyGJuH1Q1lRf28TdQ1lZnURACH5BAUKAA8ALCIABwALAB8AAARe8EkZppXG1fuyc8PlfYU1fhqGroAErGu1wGj5MPQXPnna5QZKzjboTV40jnLJ5BAa0GhDkpBKJQorVCA5aBuHR/WLeHi/Cca3wX1+FeYvYXKWlulS7qWeUHrvSnAWEQAh+QQFCgAPACwYABgAFQAVAAAEZ/DJSSdwOLvK39BaVwUgVoiUUToGKn1r4D7M6gzuYp/uFc+qEmAmCWpkHQPhMDE6eJXEoUFlFjO4SUIxpXqtDxVSQvCav5Ox5MxugCtttqITNyNE9YYggYoT7i5sAnNEVAIHCHxEEhEAIfkEBQoADwAsBwAiAB8ACwAABFrwSXmImTjPBa6mTXh82cA4qJcdYdscSlIGBmo7KujuxATcQNyEtStOgsGLosg8IoGBB4K5cz5RUUlCQA1ZkYWBBkGgfm+ALEnBrUqCBTVpkkAc2s6CISD+RAAAIfkEBQoADwAsAAAYABUAFQAABF+wydnIuzhjSpP+j8BJCqgdY3OYGZI2Hvsk7yqHr3Err3UTKZvMxRHeRBOhAbBg0SRKh5TBckWlWENg8CldDNgwFmACi8+gwHltUq/DrEHhLb0FAO/bJWCG6y8DfHMOEQAh+QQFCgAPACwAAAcACwAfAAAEYPBJqaaVqJ0rU/vbJXyglZGlRKDkprAk8YxwY3j1dsLSkUs0VuVRayQkNRlnyWxeHNCoAzCRSgeSghUakBi2DoMkAHZgB2VGtrx4kMHUBwAsdm/r6yhegobuJ2R/Fl0WEQAh+QQFCgAPACwAAAAAFQAVAAAEYvDJSWtCR7RWu1TaJnoUQogoRyZhOnqI63qKPHuHjVbBlOsESsBh8LkOigRl4GgWJb/GgVRoOn2EZ2dovZIogK5VS+KKHYCvpHp2LNTMNkP9MIvpD0ObTG336G0OA3htaXgRADs="></div>');
$('body').append('<button class="get-users-btn" id="getUsers">Get Users</button>');
$('body').append('<div class="custom-panel"><div class="custom-panel-heading">' +
'<span style="font-weight: bold;">Channel Participants</span> <span id="usercount" style="color: rgb(185, 207, 227);"></span><button class="close-btn" id="closeUsers">Close</button><button class="close-btn" id="exportUsers">Export</button></div>' +
'<div class="custom-panel-body"><table id="users" class="table table-striped"><tr><th>ID</th><th>Name</th><th>Username</th><th>Last Online</th><th>Type</th></tr></table></div></div>');
$('#closeUsers').click(function () {
$('#users').find('tr:gt(0)').remove();
$('.custom-panel').hide();
$('#getUsers').prop('disabled', false);
});
$('#getUsers').click(function () {
if (!rootScope.selectedPeerID || rootScope.selectedPeerID > 0) {
return;
}
users = [
];
offset = 0;
userCount = parseInt($('span.tg_head_peer_status span').text().split(' ') [0]);
channelName = $('span.tg_head_peer_title').text();
if (userCount === '' || channelName === '') {
return;
}
$('#spinner').show();
$('#getUsers').prop('disabled', true);
getUsers();
});
}
createUI();
}
}) ();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.