Skip to content

Instantly share code, notes, and snippets.

@parabola949
Created January 11, 2018 19:35
Show Gist options
  • Save parabola949/db46d8eb73517a55e8651bbb19c3af86 to your computer and use it in GitHub Desktop.
Save parabola949/db46d8eb73517a55e8651bbb19c3af86 to your computer and use it in GitHub Desktop.
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