Created
January 11, 2018 19:35
-
-
Save parabola949/db46d8eb73517a55e8651bbb19c3af86 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using TeleSharp.TL; | |
using TeleSharp.TL.Channels; | |
using TeleSharp.TL.Messages; | |
using TeleSharp.TL.Updates; | |
using TeleSharp.TL.Users; | |
using TLSharp.Core; | |
namespace CLI_Responder | |
{ | |
class Program | |
{ | |
private static TLVector<TLAbsMessage> new_messages = new TLVector<TLAbsMessage>(); | |
private static TLVector<TLAbsMessage> messages = new TLVector<TLAbsMessage>(); | |
private static TLVector<TLAbsUpdate> other_updates = new TLVector<TLAbsUpdate>(); | |
private static TLVector<TLAbsChat> chats = new TLVector<TLAbsChat>(); | |
private static TLVector<TLAbsUser> users = new TLVector<TLAbsUser>(); | |
private static List<int> AlreadyNotified = new List<int>(); | |
private static TLDifference updates; | |
private static ISessionStore store; | |
//private static List<long> AdminChats = new List<long>(); | |
private static TelegramClient client; | |
#region Parameters | |
/// <summary> | |
/// Your Telegram UserId | |
/// </summary> | |
private const int _myId = 123456789; | |
/// <summary> | |
/// App Id, obtained from https://my.telegram.org/apps | |
/// </summary> | |
private const int _appId = 12345; | |
/// <summary> | |
/// Api Hash, also from https://my.telegram.org/apps | |
/// </summary> | |
private const string _apiHash = "hash"; | |
/// <summary> | |
/// Your phone number, starting with +countrycode | |
/// </summary> | |
private const string _phoneNumber = "+15551234567"; | |
/// <summary> | |
/// What hour you usually want to not be disturbed | |
/// </summary> | |
private const int _nightStart = 23; | |
/// <summary> | |
/// What hour you are usually back | |
/// </summary> | |
private const int _nightEnd = 7; | |
/// <summary> | |
/// Should the bot notify people of those hours? | |
/// </summary> | |
private const bool _useNightResponse = false; | |
/// <summary> | |
/// Ignores people you already have a history with (checks for report spam button) and contacts | |
/// </summary> | |
private const bool ReplyToNewOnly = true; | |
#endregion | |
static void Main(string[] args) | |
{ | |
new Task(new Action(RunClient)).Start(); | |
Thread.Sleep(-1); | |
} | |
public static async void RunClient() | |
{ | |
client = new TelegramClient(_appId, _apiHash, null, "session"); | |
await client.ConnectAsync(false); | |
if (!client.IsUserAuthorized()) | |
{ | |
var hash = await client.SendCodeRequestAsync(_phoneNumber); | |
Console.Write("Please enter the auth code you just received: "); | |
string code = Console.ReadLine(); | |
await client.MakeAuthAsync(_phoneNumber, hash, code); | |
} | |
int pts = DateTime.UtcNow.AddMinutes(-1.0).GetUnixEpoch(); | |
int date = pts; | |
int seq = 0; | |
//SendSillyMessage("I did a thing", "test"); | |
//Console.Read(); | |
while (true) | |
{ | |
TLAbsDifference update; | |
do | |
{ | |
Thread.Sleep(500); | |
var requestGetDifference = new TLRequestGetDifference | |
{ | |
Pts = pts, | |
Date = date | |
}; | |
update = await client.SendRequestAsync<TLAbsDifference>(requestGetDifference); | |
} | |
while (update is TLDifferenceEmpty); | |
updates = update as TLDifference; | |
pts = updates.State.Pts; | |
date = updates.State.Date; | |
seq = updates.State.Seq; | |
new_messages = updates.NewMessages; | |
foreach (var m in new_messages) | |
messages.Add(m); | |
var enumerator = updates.NewMessages.ToList().GetEnumerator(); | |
try | |
{ | |
while (enumerator.MoveNext()) | |
{ | |
if (enumerator.Current is TLMessage msg) | |
{ | |
if (msg.ToId is TLPeerUser usr) | |
{ | |
//Console.WriteLine($"{GetName(usr)}: {msg.Message}"); | |
if (usr.UserId == _myId & !AlreadyNotified.Contains(msg.FromId ?? 0)) | |
{ | |
var from = ((IEnumerable)((IEnumerable<TLAbsUser>)updates.Users.ToList()).Where(x => x is TLUser)).Cast<TLUser>().FirstOrDefault(x => x.Id == msg.FromId); | |
if (from == null) continue; | |
var requestGetPeerSettings = new TLRequestGetPeerSettings | |
{ | |
Peer = new TLInputPeerUser | |
{ | |
AccessHash = from.AccessHash.Value, | |
UserId = from.Id | |
} | |
}; | |
var settings = await client.SendRequestAsync<TLPeerSettings>(requestGetPeerSettings); | |
DateTime time = DateTime.Now; | |
//respond if they are messaging at a bad hour | |
if (_useNightResponse && (_nightStart <= time.Hour || time.Hour < _nightEnd)) | |
{ | |
if (ReplyToNewOnly && (!settings.ReportSpam || from.Contact)) continue; | |
var u = new TLInputPeerUser | |
{ | |
AccessHash = from.AccessHash.Value, | |
UserId = from.Id | |
}; | |
string str = $"Pardon me, but it is currently {time.ToShortTimeString()} where I am. I am most likely in bed.. please do not PM me right now"; | |
TLAbsUpdates tlAbsUpdates = await client.SendMessageAsync(u, str); | |
AlreadyNotified.Add(from.Id); | |
} | |
if (ReplyToNewOnly && (!settings.ReportSpam || from.Contact)) continue; | |
AlreadyNotified.Add(from.Id); | |
//TODO: send a response of some sort | |
//throw new NotImplementedException("Hey! You forgot to code something here!"); | |
} | |
} | |
else if (msg.ToId is TLPeerChannel ch) | |
{ | |
} | |
} | |
} | |
} | |
finally | |
{ | |
enumerator.Dispose(); | |
} | |
enumerator = new List<TLAbsMessage>.Enumerator(); | |
var otherEnum = updates.OtherUpdates.ToList().GetEnumerator(); | |
try | |
{ | |
while (otherEnum.MoveNext()) | |
{ | |
if (otherEnum.Current is TLUpdateNewChannelMessage cm) | |
{ | |
if (cm.Message is TLMessage msg) | |
{ | |
//Console.WriteLine($"({GetName(msg.ToId)}) {GetName(msg.FromId)}: {msg.Message}"); | |
} | |
else if (cm.Message is TLMessageService s) | |
{ | |
if (s.Action is TLMessageActionChatAddUser add) | |
{ | |
if (GetName(s.ToId) == "Telegram Bot Talk") continue; | |
var users = add.Users; | |
if (users.Count > 4) | |
{ | |
var kick = false; | |
var names = new List<string>(); | |
foreach (var u in users) | |
{ | |
var n = GetName(u); | |
if (names.Contains(n)) | |
{ | |
kick = true; | |
break; | |
} | |
names.Add(n); | |
} | |
if (kick) | |
{ | |
var chpeer = s.ToId as TLPeerChannel; | |
var peer = GetPeer(chpeer.ChannelId).Result as TLInputPeerChannel; | |
var initiate = GetPeer(s.FromId.Value).Result as TLInputPeerUser; | |
var kReq = new TLRequestKickFromChannel | |
{ | |
Channel = new TLInputChannel | |
{ | |
AccessHash = peer.AccessHash, | |
ChannelId = peer.ChannelId | |
}, | |
UserId = new TLInputUser | |
{ | |
AccessHash = initiate.AccessHash, | |
UserId = initiate.UserId | |
}, | |
Kicked = true | |
}; | |
await client.SendRequestAsync<TLUpdates>(kReq); | |
foreach (var u in users) | |
{ | |
Console.ForegroundColor = ConsoleColor.Red; | |
Console.WriteLine($"Kicking {u} ({GetName(u)})"); | |
Console.ForegroundColor = ConsoleColor.Gray; | |
var user = GetPeer(u).Result as TLInputPeerUser; | |
kReq = new TLRequestKickFromChannel | |
{ | |
Channel = new TLInputChannel | |
{ | |
AccessHash = peer.AccessHash, | |
ChannelId = peer.ChannelId | |
}, | |
UserId = new TLInputUser | |
{ | |
AccessHash = user.AccessHash, | |
UserId = user.UserId | |
}, | |
Kicked = true | |
}; | |
await client.SendRequestAsync<object>(kReq); | |
} | |
var ids = new TLVector<int>(); | |
foreach (var m in messages.Where(x => x is TLMessage).Cast<TLMessage>().Where(x => users.Contains(x.FromId.Value))) | |
{ | |
//report users | |
var sReq = new TeleSharp.TL.Messages.TLRequestReportSpam | |
{ | |
MessageId = m.Id, | |
Peer = GetPeer(m.FromId.Value).Result | |
}; | |
await client.SendRequestAsync<object>(sReq); | |
ids.Add(m.Id); | |
} | |
//delete messages | |
var dReq = new TeleSharp.TL.Channels.TLRequestDeleteMessages() | |
{ | |
Channel = new TLInputChannel | |
{ | |
AccessHash = peer.AccessHash, | |
ChannelId = peer.ChannelId | |
}, | |
Id = ids | |
}; | |
await client.SendRequestAsync<object>(dReq); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
catch (Exception e) | |
{ | |
} | |
finally | |
{ | |
otherEnum.Dispose(); | |
} | |
otherEnum = new List<TLAbsUpdate>.Enumerator(); | |
Console.ForegroundColor = ConsoleColor.Gray; | |
update = null; | |
updates = null; | |
} | |
} | |
#region Some Helpful methods that aren't used in this | |
public static string GetName(TLAbsPeer to) | |
{ | |
if (to is TLPeerChannel) | |
return ((IEnumerable)((IEnumerable<TLAbsChat>)updates.Chats.ToList()).Where(x => x is TLChannel)).Cast<TLChannel>().FirstOrDefault(x => x.Id == ((TLPeerChannel)to).ChannelId).Title; | |
if (to is TLPeerChat) | |
return ((IEnumerable)((IEnumerable<TLAbsChat>)updates.Chats.ToList()).Where(x => x is TLChat)).Cast<TLChat>().FirstOrDefault(x => x.Id == ((TLPeerChat)to).ChatId).Title; | |
if (to is TLPeerUser) | |
return ((IEnumerable)((IEnumerable<TLAbsUser>)updates.Users.ToList()).Where(x => x is TLUser)).Cast<TLUser>().FirstOrDefault(x => x.Id == ((TLPeerUser)to).UserId).FirstName; | |
return ""; | |
} | |
public static string GetName(int? to) | |
{ | |
var name = ((IEnumerable)((IEnumerable<TLAbsUser>)updates.Users.ToList()).Where(x => x is TLUser)).Cast<TLUser>().FirstOrDefault(x => x.Id == to)?.FirstName ?? ""; | |
if (String.IsNullOrEmpty(name)) | |
name = ((IEnumerable)((IEnumerable<TLAbsUser>)users.ToList()).Where(x => x is TLUser)).Cast<TLUser>().FirstOrDefault(x => x.Id == to)?.FirstName ?? ""; | |
return name; | |
} | |
public static async Task<T> GetChatFull<T>(TLAbsChat chat, TelegramClient client) | |
{ | |
if (chat is TLChannel c) | |
{ | |
long? accessHash = c.AccessHash; | |
if (!accessHash.HasValue) | |
throw new NullReferenceException("Access Hash for channel is null"); | |
var requestGetFullChannel = new TLRequestGetFullChannel | |
{ | |
Channel = new TLInputChannel | |
{ | |
AccessHash = accessHash.Value, | |
ChannelId = c.Id | |
} | |
}; | |
; | |
return await client.SendRequestAsync<T>(requestGetFullChannel); | |
} | |
if (!(chat is TLChat)) | |
throw new ArgumentException("Argument must be TLChat or TLChannel", "chat"); | |
TLRequestGetFullChat requestGetFullChat = new TLRequestGetFullChat | |
{ | |
ChatId = ((TLChat)chat).Id | |
}; | |
return await client.SendRequestAsync<T>(requestGetFullChat); | |
} | |
public static async Task<TLAbsInputPeer> GetPeer(string groupName) | |
{ | |
var dialogs = (TLDialogsSlice)await client.GetUserDialogsAsync(); | |
var main = dialogs.Chats.Where(c => c.GetType() == typeof(TLChat)) | |
.Cast<TLChat>() | |
.FirstOrDefault(c => c.Title == groupName); | |
if (main != null) | |
{ | |
var ch = main.MigratedTo as TLInputChannel; | |
return new TLInputPeerChannel { AccessHash = ch.AccessHash, ChannelId = ch.ChannelId }; | |
} | |
var mainCh = dialogs.Chats.Where(c => c.GetType() == typeof(TLChannel)) | |
.Cast<TLChannel>() | |
.FirstOrDefault(c => c.Title == groupName); | |
if (mainCh != null) | |
return new TLInputPeerChannel { AccessHash = mainCh.AccessHash.Value, ChannelId = mainCh.Id }; | |
var user = dialogs.Users.Cast<TLUser>().FirstOrDefault(c => (c.FirstName + " " + c.LastName).Trim() == groupName); | |
if (user != null) | |
return new TLInputPeerUser { AccessHash = user.AccessHash.Value, UserId = user.Id }; | |
return null; | |
} | |
public static async Task<TLAbsInputPeer> GetPeer(long id) | |
{ | |
//var dialogs = (TLDialogsSlice)await client.GetUserDialogsAsync(); | |
var main = updates.Chats.Where(c => c.GetType() == typeof(TLChat)) | |
.Cast<TLChat>() | |
.FirstOrDefault(c => c.Id == id); | |
if (main != null) | |
{ | |
var ch = main.MigratedTo as TLInputChannel; | |
return new TLInputPeerChannel { AccessHash = ch.AccessHash, ChannelId = ch.ChannelId }; | |
} | |
var mainCh = updates.Chats.Where(c => c.GetType() == typeof(TLChannel)) | |
.Cast<TLChannel>() | |
.FirstOrDefault(c => c.Id == id); | |
if (mainCh != null) | |
return new TLInputPeerChannel { AccessHash = mainCh.AccessHash.Value, ChannelId = mainCh.Id }; | |
var user = updates.Users.Cast<TLUser>().FirstOrDefault(c => c.Id == id); | |
if (user != null) | |
return new TLInputPeerUser { AccessHash = user.AccessHash.Value, UserId = user.Id }; | |
////try to figure this out..... | |
//user = updates.Users.Cast<TLUser>().FirstOrDefault(x => x.Id == id); | |
//if (user != null) | |
// return new TLInputPeerUser { AccessHash = user.AccessHash.Value, UserId = user.Id }; | |
return null; | |
} | |
public static async void SendSillyMessage(string text, string chatName) | |
{ | |
var finalText = text; | |
var peer = await GetPeer(chatName); | |
var randId = new Random().Next(1000000000); | |
var req = new TLRequestSendMessage() | |
{ | |
Message = finalText[0].ToString(), | |
Peer = peer, | |
RandomId = randId | |
}; | |
var r = client.SendRequestAsync<TLAbsUpdates>(req).Result; | |
int msgUpdate; | |
if (peer is TLInputPeerUser) | |
msgUpdate = (((TLUpdateShortSentMessage)r).Id); | |
else | |
msgUpdate = (((TLUpdates)r).Updates[0] as TLUpdateMessageID).Id; | |
for (var i = 1; i < finalText.Length; i++) | |
{ | |
Thread.Sleep(100); | |
string newText; | |
if (finalText.Length - 1 == i) | |
newText = finalText; | |
else if (finalText[i] == ' ') | |
i++; | |
newText = finalText.Substring(0, i + 1); | |
var edit = new TLRequestEditMessage | |
{ | |
Message = newText, | |
Id = msgUpdate, | |
Peer = peer | |
}; | |
edit.MessageId = msgUpdate; | |
r = client.SendRequestAsync<TLAbsUpdates>(edit).Result; | |
} | |
} | |
#endregion | |
} | |
public static class Extensions | |
{ | |
public static int GetUnixEpoch(this DateTime dateTime) | |
{ | |
return (int)(dateTime.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; | |
} | |
//public static T FirstOrDefault<T>(this IEnumerable<T> source, T alt = default(T)) | |
//{ | |
// var result = source.FirstOrDefault(); | |
// if (result.Equals(default(T))) | |
// return alt; | |
// return result; | |
//} | |
//public static T FirstOrDefault<T>(this IEnumerable<T> source, Func<T, bool> predicate, T alt = default(T)) | |
//{ | |
// return source.Where(predicate).FirstOrDefault(alt); | |
//} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment