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) { var dataRequest = ArgumentReader.ReadArguments(args); var username = dataRequest.Login; Splash.MakeSplash(); loginStage: if (username is null) { Console.WriteLine("Enter your phone number: "); username = Console.ReadLine(); } if (username is null) { Console.WriteLine("Login is invalid!"); goto loginStage; } Helpers.Log = (_, _) => { }; //force logger to shut up Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("Waiting to login..."); DoLogin(username).Wait(); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("[DONE]"); //Check logged Console.ForegroundColor = ConsoleColor.White; Console.WriteLine($"Welcome, {Client.User}!"); List infos = []; foreach(var user in Client.Messages_GetAllDialogs().Result.users.Values) { if(dataRequest.Username is not null && user.username != dataRequest.Username) continue; 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); } SaveAndAddStats(infos, dataRequest.Path); } 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; } List messagesList = []; var messageCount = 0; try { var res = Client.Messages_GetHistory((InputPeer)peer).Result; for (int offset = 0; offset < res.Count; offset += 100) { 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 } } messageCount =res.Count; } catch (Exception) { // ignored } 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, messageCount, string.IsNullOrEmpty(peer?.username ?? "") ? peer?.id.ToString() ?? "unknown" : $"@{peer?.username}"); } static void SaveAndAddStats(List infos, string path = "results.txt") { 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}"); File.WriteAllText(path, fileData); Console.WriteLine("Goodbye!"); } static async Task DoLogin(string loginInfo) { while (Client.User == null) switch (await Client.Login(loginInfo)) // returns which config is needed to continue login { case "verification_code": Console.Write("Code: "); loginInfo = Console.ReadLine()!; break; case "password": Console.Write("Password: "); loginInfo = Console.ReadLine()!; break; // if user has enabled 2FA default: loginInfo = null!; break; } } } }