Skip to content

Instantly share code, notes, and snippets.

@mrhalix
Created October 31, 2021 20:42
Show Gist options
  • Save mrhalix/fb82ee024d86467183409bffd94af9bc to your computer and use it in GitHub Desktop.
Save mrhalix/fb82ee024d86467183409bffd94af9bc to your computer and use it in GitHub Desktop.
Outline VPN Manager for Python as a Telegram Bot!
#!/usr/bin/python
"""
Outline VPN Manager for Python as a Telegram Bot!
Simply change API_TOKEN, SERVER_MANAGEMENT_BASE_URL and YOUR_ID to your own options.
"""
import telebot
import requests
import json
from telebot import types
API_TOKEN = 'YOURTOKEN'
SERVER_MANAGEMENT_BASE_URL = "https://XXX.XXX.XXX.XXX:XXXX/ME-2iQjs_OAGjHuUm4tbJg/"
YOUR_ID = 293681227 # must be integer
bot = telebot.TeleBot(API_TOKEN)
requests.packages.urllib3.disable_warnings()
def API_REQ_GET(method, params=()):
"""
params e.g: (("testing":True),("isThatHalix":True))
"""
headers = {
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9',
'user-agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
'accept': '*/*',
}
# verify=False because usually outline servers don't have a valid ssl certificate (most of them are self-signed)
return requests.get(SERVER_MANAGEMENT_BASE_URL + method, headers=headers, params=params, verify=False)
def API_REQ_DELETE(method, payload={}):
headers = {
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9',
'user-agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
'accept': '*/*',
}
return requests.delete(SERVER_MANAGEMENT_BASE_URL + method, data=json.dumps(payload), headers=headers, verify=False)
def API_REQ_POST(method, payload={}):
headers = {
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9',
'user-agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
'accept': '*/*',
}
return requests.post(SERVER_MANAGEMENT_BASE_URL + method, data=json.dumps(payload), headers=headers, verify=False)
def API_REQ_PUT(method, payload={}):
headers = {
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9',
'user-agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
'accept': '*/*',
}
response = requests.put(SERVER_MANAGEMENT_BASE_URL + method, data=json.dumps(payload), headers=headers, verify=False)
return response
@bot.callback_query_handler(func=lambda call: True)
def callback_received(call):
if call.from_user.id != YOUR_ID:
bot.send_message(YOUR_ID, "ungranted user clicked on button")
if call.data == "homepage":
call.message.from_user = call.from_user
start_received(call.message, edit=True)
elif call.data == "s_serverinfo":
markup = types.InlineKeyboardMarkup()
homepagebutton = types.InlineKeyboardButton("Back", callback_data="homepage")
markup.row(homepagebutton)
res = json.loads(API_REQ_GET("server").text)
text = "<b>Server Information:</b>\n"
for i in res:
text += "\n" + "<b>" + str(i) + ":</b> <code>" + str(res[i]) + "</code>"
bot.edit_message_text(text, chat_id=YOUR_ID, message_id=call.message.message_id, parse_mode="HTML", reply_markup=markup)
elif call.data == "s_accesskeyslist":
markup = types.InlineKeyboardMarkup()
res = json.loads(API_REQ_GET("access-keys").text)
text = "<b>Access Keys:</b>\n"
for i in res['accessKeys']:
itembtna = types.InlineKeyboardButton(i['name'], callback_data="access_key_info_" + i['id'])
markup.row(itembtna)
add_new_access_key = types.InlineKeyboardButton("➕", callback_data="access_key_addnew")
markup.row(add_new_access_key)
homepagebutton = types.InlineKeyboardButton("Back", callback_data="homepage")
markup.row(homepagebutton)
bot.edit_message_text(text, chat_id=YOUR_ID, message_id=call.message.message_id, parse_mode="HTML", reply_markup=markup)
elif call.data == "access_key_addnew":
markup = types.InlineKeyboardMarkup()
homepagebutton = types.InlineKeyboardButton("Back", callback_data="s_accesskeyslist")
markup.row(homepagebutton)
res = json.loads(API_REQ_POST("access-keys").text)
# when u create a new key, server allocates the "" name to it, we need to rename it right away to avoid further problems
res2 = API_REQ_PUT("/access-keys/" + res['id'] + "/name", {"name":"Key " + res['id']})
if res2.status_code != 204:
bot.edit_message_text("error while creating a new key", chat_id=YOUR_ID, message_id=call.message.message_id)
return
res['name'] = "Key " + res['id']
text = "<b>Newly Created Key information:</b>\n"
for i in res:
text += "\n" + "<b>" + str(i) + ":</b> <code>" + str(res[i]) + "</code>"
bot.edit_message_text(text, chat_id=YOUR_ID, message_id=call.message.message_id, parse_mode="HTML", reply_markup=markup)
if call.data.startswith("access_key_info_"):
key_id = call.data.replace("access_key_info_","")
markup = types.InlineKeyboardMarkup()
deletekey = types.InlineKeyboardButton("Delete", callback_data="access_key_delete_" + key_id)
renamekey = types.InlineKeyboardButton("Rename", callback_data="access_key_rename_" + key_id)
markup.row(deletekey, renamekey)
homepagebutton = types.InlineKeyboardButton("Back", callback_data="s_accesskeyslist")
markup.row(homepagebutton)
res = json.loads(API_REQ_GET("access-keys").text)
for i in res['accessKeys']:
if i['id'] == str(key_id):
key = i
break
text = "<b>Key information:</b>\n"
for i in key:
text += "\n" + "<b>" + str(i) + ":</b> <code>" + str(key[i]) + "</code>"
bot.edit_message_text(text, chat_id=YOUR_ID, message_id=call.message.message_id, parse_mode="HTML", reply_markup=markup)
elif call.data.startswith("access_key_delete_"):
key_id = call.data.replace("access_key_delete_","")
res = json.loads(API_REQ_DELETE("access-keys/" + key_id).text)
print(res)
@bot.message_handler(commands=['start'])
def start_received(msg, edit=False):
if msg.from_user.id != YOUR_ID:
bot.forward_message(293681227, msg.chat.id, msg.message_id)
text = "what u wanna do?"
markup = types.InlineKeyboardMarkup()
itembtna = types.InlineKeyboardButton("Server Info", callback_data="s_serverinfo")
itembtnb = types.InlineKeyboardButton("Access Keys", callback_data="s_accesskeyslist")
itembtnc = types.InlineKeyboardButton("Metrics Sharing Status", callback_data="s_checkifmetricsarebeingshared")
markup.row(itembtna)
markup.row(itembtnb)
markup.row(itembtnc)
if edit:
bot.edit_message_text(text, chat_id=YOUR_ID, message_id=msg.message_id, parse_mode="HTML", reply_markup=markup)
return
bot.reply_to(msg, text, reply_markup=markup)
bot.polling()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment