Home

Awesome

Telegram Proxy Bot

A simple BITM, for Telegram acting as some kind of "proxy". Can use it as "virtual" second account for your purposes without revealing your "actual" identity. Credits to Groosha for the actual version, I've simply added certain features which I thought were needed <br>

ChangeLog!

Version 1.4.1 (current):

Version 1.4.0:

Version 1.3:

Version 1.2:

Version1.1:

Version1.0

Prerequisites

How to install

What's new ???

How it works

Basic Functionality

The idea of this bot is pretty simple: you just place the bot between you and the one you want to chat with. The upside is that no one will find out your unique chat id or some other info (nickname, first name or avatar, for example). They won't also know your last seen time. However, the downside is that you can't initiate chat with someone (Because you're writing from bot and bots can't start chats to prevent spam), so you'll have to ask people to write to your bot first.

<p align="center"> ![A simple scheme of interaction](https://habrastorage.org/files/4a2/d19/753/4a2d19753eb34073bfda0b872bf228b3.png) <p align="center">![Screenshot](http://i.imgur.com/wVMZRgT.png)

Blocking and Unblocking Feature

Alright, so after spending some time with the bot I thought /block~number~ and /unblock~number~ after every text was kinda annoying, so I updated the blocking feature in the bot. <br> <br> I thought that it would be probably easier and less messy if the admin can block a user based on the username.<br> So, now you can block any user you want based on their @username or nickname provided by you, here's how it works: <br> <br> Well, the bot simply stores the data of every user it interacts with in the form of a dictionary with the key as the Username and the val or value as the message.chat.id of the user. And therefore whenever the admin blocks a user by entering the username the bot simply takes in the username and gets the corresponding chat.id out of it and stores it in the block list.

Now some of you might be wondering like what if the user doesn't have a username or what if the user changed his/her username ? Aye! we have a solution for that to but before answering that let's make a list of all the possible cases we can have.<br> There can be many possibilities and chances of error, I've made sure to cover all of them but who knows o_0 <br> <br> Okay! So here are the cases: <br>

case 1: user has a username and is a new user for the bot<br> case 2: user doesnt have a username and is a new user for the bot<br> case 3: user changed his username but is an old user for the bot<br> case 4: user removed his username and is an old user for the bot<br> case 5: idk that's it ? <br> <br>

 if message.chat.id not in user_dir.values():    
  if message.chat.username == None:
     msg = bot.send_message(config.my_id, "*Uh! the user does not have a username o_0*\nCan you please suggest a name that can be used to store the data of the following user ?\n *PS: The nickname should be unique and shouldn't contain* '`@`'",parse_mode="Markdown" )
     bot.register_next_step_handler(msg, lambda m: dictionary.process_name_step(m, dict_name=user_dir, file=config.storage_userdir, val=message.chat.id, firstname=message.chat.first_name))
        
  else:
     userName = "@"+ message.chat.username
     userName = userName.lower()
     #checks whether the message.chat.id of the user is there in the block list (user_list)
     #if message.chat.id present ---> sends a message to the user that he/she is blocked
     #else forwards the message to the admin
     if userName not in user_dir:   
         dictionary.add_key_dict(config.storage_userdir, user_dir, userName, message.chat.id)     
else:
  if message.chat.username == None:
    for userName, chatid in user_dir.items():
       if chatid == message.chat.id:
           z = userName
           if '@' in z:
               msg = bot.send_message(config.my_id, "*Uh! the user does not have a username o_0*\nCan you please suggest a name that can be used to store the data of the following user ?\n *PS: The nickname should be unique and shouldn't contain* '`@`'",parse_mode="Markdown" )
               bot.register_next_step_handler(msg, lambda m: dictionary.process_name_step(m, dict_name=user_dir, file=config.storage_userdir, val=message.chat.id, firstname=message.chat.first_name))
  else:
     userName = "@"+ message.chat.username
     userName = userName.lower()
     if userName not in user_dir:   
         dictionary.add_key_dict(config.storage_userdir, user_dir, userName, message.chat.id) 

Alright so let's understand the code:

'''
 if message.chat.id not in user_dir.values() <-- here the bot checks whether the message.chat.id of the user exists in the dict or not
   if not: <--meaning it's a new user
     then it checks for the username
       if user doesnt have a username then ---> it asks the admin to give a nickname for the user to save that as key
       else it saves the username of the new user as the key and chat.id as the val
       We've successfully covere the cases 1 & 2 ^
   Now if message.chat.id is present in user_dir.values() 
   if yes: <---meaning its an old user 
      it then checks whether the username is present or not 
           if the user doesnt has a username (meaning the old user removed his/her username)
           then it cross checks in the dict whether the key of the user has '@' or not
               Now here's the tricky part: Why did I check for '@' ? Because in the case 2 we have given a nick name 
               to the user so now assume a case :
                     the new user opens the bot writes a text to the bot, the bot checks the chat.id of the user since it's not 
                     there and the user doesnt has a username it will ask the admin to give a nickname. 
                     NOW! if the user will write a text message again then since the chat.id of the user is now present in the 
                     dict() the user will be treated as an old user with the key as the nickname. So, the else part of the code 
                     will execute. Now! here we are only considering the old users and not the users who already have a nickname
                     and hence to differentiate among the two we have checked for '@' symbol in the key.
               Hence, if the user is old and doesnt have a username then it will ask the admin for the new nickname
               We have successfully covered the case 4 ^
            if the old user has a nickname then it checks whether the username is already present or not
                if not: then it saves the data of the user with the key as the new username and message.chat.id as the val
                if yes: then do nothing 
   Hence, we have covered all the possible cases
  '''

I hope this answered the questions and explained all the cases mentioned above, I know it's a bit complicated and a difficult way to code but idk i just didn't get any other idea. :P <br><br> Since we know that no one is perfect in terms of recalling the previous data, I've included the /viewnicknames feature as well. This well help you to view all the nick-names along with the respective first-name of the user to whom it was allotted.<br><br>

So here are the following commands: <br>

Admins can even view the block list by typing /viewblocklist <br>

Screenshots:

#####Basic Blocking Functionality: screenshot<br><br> #####Setting the blocking text: screenshot<br><br> #####Viewing the Block List:

<p align="cente">![screenshot](http://i.imgur.com/CjC3S4M.png)<br><br> ####Setting and Viewing Nicknames: <p align="center">![screenshot](http://i.imgur.com/E6gEQQY.png)<br><br>

Available and Unavailable Feature

There can be at times when you as an admin are unavailable or don't temporarily have access to the bot, but you at the same time want to notify all the users about your unavailability just like the way we have on answering machines ? <br> <br> "Joshua is Unavailable! Kindly leave your message after the beep.........." <br> <br> Keeping this in mind here's the /unavailable and /available feature! <br> You can now set your status as available or unavailable <br> <br> So now the admins set the status by typing:

If your status is set to unavailable then the bot will simply forward the message to the admin and notify the user about the unavailability of the admin ( by sending an unavailable message)<br><br> To set the unavailable message simply send:

To view the unavailable message simply send:

####Screenshots :

Setting Unavailable Message :

screenshot<br><br>

Basic Feature :

screenshot<br><br>

Checking Status:
<p align="center">![screenshot](http://i.imgur.com/KAtq778.png)<br><br>

##In Reply To: Well as stated before/in the previous version. The admins were not able to see the text the user has force replied to, since the bot only forwards every new text and not the old ones.. So admin wouldn't know if the user has replied to a previously sent text or not. Now admins can see the previously send message to which the user replied.

###Screenshot:

<p align="center">![screenshot](http://i.imgur.com/EFJs7T3.png)<br><br>

Notes and restrictions

  1. Message formatting (both Markdown and HTML) is disabled. You can easily add parse_mode argument to send_message function to enable it.<br> example:
bot.send_message(message.chat.id, "Please click on [this](www.google.com)to search on Google",parse_mode="Markdown")
  1. You(Admins) should always use "reply" function, because bot will check message_id of selected "message to reply".
  2. Storage is needed to save "message_id":"user_id" key-value pairs. First, I intended to delete message_id which I've already answered, but then I decided to remove this, so you can answer any message from certain user and multiple times.
  3. Supported message types in reply: text, sticker, photo, video, audio, voice, document, location.
  4. To block a user simply type/block @username/nickname and to unblock a user simply type /unblock @username/nickname
  5. If you dont need these features then you can simply use the original version of the bot which was made by Groosha. Open the terminal and enter bash launch2.sh
  6. All the text files are mentioned in config.py except blank.txt which is used somewhere in between the code.<br> ** I will not recommend you to change the name or the location of the text files. But it's up to you! **
  7. This bot only works in the private chats, I've tried making it work in the groups but it didn't really worked, if you can improve this bot then do let me know! I would be glad to make this work better
  8. You can use the /help command to view all the commands which you can use an admin screenshot

Upcoming Features

Remember!

I understand, that "proxy" bots can be used to prevent spammers from being reported, so if you encounter such bots that are used to do "bad" things, feel free to report them: abuse@telegram.org

F.A.Q

1. Will this bot work in groups/supergroups/channels ?

For the time being this bot just works in private chats.

2. Can I use Emojis in my unavailable message ?

Yes! You can use ONLY emojis or text in your unavailable message, you cannot save stickers/gifs in the unavailable message

3. Will I be able to skip my school/college/job ?

Unfortunately nope :(

Contact

You can contact me via my Proxy Bot.<br> PS: Let me know if you need a new feature/tweak in this bot, please don't hesitate to text me :)