2025-02-05 14:05:04 +03:00
using TL ;
using WTelegram ;
namespace TelegramMessageCounter
{
internal static class Program
{
private static readonly Client Client = new ( 23711185 , "9e23f24bbb2f3dc3e561c0a5c9d3e622" ) ; //Please, create your client, but don't shy use it if you are lazy :)
static void Main ( string [ ] args )
{
2025-02-05 14:48:24 +03:00
if ( args . Length > 0 & & args [ 0 ] = = "--help" )
{
Console . WriteLine ( "Usage: TelegramMessageCounter <login (phone number)> <path>" +
"\n login - Phone number of telegram. If argument is empty, waiting for Keyboard interrupt" +
"\n path - Path to save results file. If argument is empty, path will be \"results.txt\"\n" ) ;
}
string? login = args . Length > 0 ? args [ 0 ] : null ;
string? path = args . Length > 1 ? args [ 1 ] : null ;
2025-02-05 14:05:04 +03:00
Splash . MakeSplash ( ) ;
loginStage :
if ( login is null )
{
Console . WriteLine ( "Enter your phone number: " ) ;
login = Console . ReadLine ( ) ;
}
if ( login is null )
{
Console . WriteLine ( "Login is invalid!" ) ;
goto loginStage ;
}
Helpers . Log = ( _ , _ ) = > { } ; //force logger to shut up
Console . ForegroundColor = ConsoleColor . Yellow ;
2025-02-05 14:48:24 +03:00
Console . WriteLine ( "Waiting to login..." ) ;
2025-02-05 14:05:04 +03:00
DoLogin ( login ) . Wait ( ) ;
Console . ForegroundColor = ConsoleColor . Green ;
Console . WriteLine ( "[DONE]" ) ; //Check logged
Console . ForegroundColor = ConsoleColor . White ;
Console . WriteLine ( $"Welcome, {Client.User}!" ) ;
List < CounterInfo > infos = [ ] ;
foreach ( var user in Client . Messages_GetAllDialogs ( ) . Result . users . Values )
{
var res = GetInfo ( user . id ) ;
if ( res = = null )
{
Console . WriteLine ( $"User {user.id} not found! Skipping..." ) ;
continue ;
}
Console . WriteLine ( $"Multiplier {Client.User}/{res.TargetUsername} is: {res.Multiplier} of {res.MyMsg}/{res.TargetMsg} and total {res.FullMsg} messages" ) ;
infos . Add ( res ) ;
}
2025-02-05 14:48:24 +03:00
if ( path is not null )
SaveAndAddStats ( infos , path ) ;
else
SaveAndAddStats ( infos ) ;
2025-02-05 14:05:04 +03:00
}
static CounterInfo ? GetInfo ( long targetId )
{
var dialogs = Client . Messages_GetAllDialogs ( ) . Result ;
int myCounter = 0 ;
int targetCounter = 0 ;
User ? peer ;
try
{
Console . ForegroundColor = ConsoleColor . Yellow ;
Console . Write ( $"Attempt to found chat for id: {targetId}..." ) ;
peer = dialogs . users . Values . FirstOrDefault ( x = > x . ID = = targetId ) ;
Console . ForegroundColor = ConsoleColor . Green ;
Console . WriteLine ( "[DONE]" ) ;
Console . WriteLine ( $"Username is: {(peer)?.username}" ) ;
}
catch ( Exception ex )
{
Console . ForegroundColor = ConsoleColor . Red ;
Console . WriteLine ( $"[FAILED]\nError was happened({ex.Message})! Returning..." ) ;
Console . ForegroundColor = ConsoleColor . White ;
return null ;
}
2025-02-06 17:59:39 +03:00
List < Messages_MessagesBase > messagesList = [ ] ;
var messageCount = 0 ;
try
2025-02-05 14:05:04 +03:00
{
2025-02-06 17:59:39 +03:00
var res = Client . Messages_GetHistory ( ( InputPeer ) peer ) . Result ;
2025-02-05 14:05:04 +03:00
2025-02-06 17:59:39 +03:00
for ( int offset = 0 ; offset < res . Count ; offset + = 100 )
2025-02-05 14:05:04 +03:00
{
2025-02-06 17:59:39 +03:00
if ( offset > res . Count ) offset = res . Count ;
Console . ForegroundColor = ConsoleColor . Yellow ;
Console . Write ( $"\rReading messages, please wait, it may take a while... {offset} => {res.Count}" ) ;
try
{
messagesList . Add ( Client . Messages_GetHistory ( ( InputPeer ) peer , 0 , default , offset ) . Result ) ;
}
catch ( Exception )
{
// ignored
}
2025-02-05 14:05:04 +03:00
}
2025-02-06 17:59:39 +03:00
messageCount = res . Count ;
2025-02-05 14:05:04 +03:00
}
2025-02-06 17:59:39 +03:00
catch ( Exception )
{
// ignored
}
2025-02-05 14:05:04 +03:00
Console . ForegroundColor = ConsoleColor . Yellow ;
Console . Write ( "\nEvaluating results..." ) ;
foreach ( var messageBase in messagesList )
{
foreach ( var message in messageBase . Messages )
{
if ( message is Message msg )
{
if ( msg . from_id ! = null )
{
myCounter + + ;
}
else targetCounter + + ;
}
}
}
Console . ForegroundColor = ConsoleColor . Green ;
Console . WriteLine ( "[DONE]" ) ;
Console . ForegroundColor = ConsoleColor . White ;
return new (
( float ) myCounter / targetCounter ,
targetCounter ,
myCounter ,
2025-02-06 17:59:39 +03:00
messageCount ,
2025-02-05 14:48:24 +03:00
string . IsNullOrEmpty ( peer ? . username ? ? "" ) ? peer ? . id . ToString ( ) ? ? "unknown" : $"@{peer?.username}" ) ;
2025-02-05 14:05:04 +03:00
}
2025-02-05 14:48:24 +03:00
static void SaveAndAddStats ( List < CounterInfo > infos , string path = "results.txt" )
2025-02-05 14:05:04 +03:00
{
Console . ForegroundColor = ConsoleColor . Yellow ;
Console . Write ( "Saving results..." ) ;
File . Create ( "results.txt" ) ;
string fileData = "" ;
float multiplier = 0 ;
foreach ( CounterInfo info in infos )
{
fileData + = "username: " + info . TargetUsername + "\n" +
"multiplier: " + info . Multiplier + "\n" +
"total messages: " + info . FullMsg + "\n" +
"your messages: " + info . MyMsg + "\n" +
"target messages: " + info . TargetMsg + "\n-----\n" ;
multiplier + = info . Multiplier ;
}
multiplier / = infos . Count ;
Console . ForegroundColor = ConsoleColor . Green ;
Console . WriteLine ( "[DONE]" ) ;
Console . ForegroundColor = ConsoleColor . White ;
Console . WriteLine ( $"Middle result is: {multiplier}" ) ;
2025-02-05 14:48:24 +03:00
File . WriteAllText ( path , fileData ) ;
Console . WriteLine ( "Goodbye!" ) ;
2025-02-05 14:05:04 +03:00
}
static async Task DoLogin ( string loginInfo )
{
while ( Client . User = = null )
switch ( await Client . Login ( loginInfo ) ) // returns which config is needed to continue login
{
2025-02-05 14:48:24 +03:00
case "verification_code" : Console . Write ( "Code: " ) ; loginInfo = Console . ReadLine ( ) ! ; break ;
case "password" : Console . Write ( "Password: " ) ; loginInfo = Console . ReadLine ( ) ! ; break ; // if user has enabled 2FA
2025-02-05 14:05:04 +03:00
default : loginInfo = null ! ; break ;
}
}
}
}