I've finished my Python Bot for telegram to send HTML5 games through the chat, thanks to the help of this community! Unfortunately it seems that in order for the bot to fetch the score, I need to actually set up a HTTP server within the bot to do so. As it seems through my research, I can't seem to figure out how to create a server in python with ssl, without it being self signed (since it will give a blank page when the user clicks to play the game).
I bought a domain and it's already set up with my VPS IP adress, altough I have a ssl certificate for Apache...
Could someone help me set this up? Since sending and unsecured HTTP connection or a self-signed one will result in a blank page within the app...
Thank you very much!
Edit1: Bot Code:
import configparser, threading, requests, json, re, time, sys
from uuid import uuid4
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram import InlineQueryResultGame, ParseMode, InputTextMessageContent
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, InlineQueryHandler, CommandHandler, CallbackContext
from http.server import HTTPServer, BaseHTTPRequestHandler
def error_callback(update, context):
logger.warning('Update "%s" caused error "%s"', update, context.error)
class Global:
def __init__(self):
return
class GameHTTPRequestHandler(BaseHTTPRequestHandler):
def __init__(self, *args):
BaseHTTPRequestHandler.__init__(self, *args)
def do_GET(self):
if "#" in self.path:
self.path = self.path.split("#")[0]
if "?" in self.path:
(route, params) = self.path.split("?")
else:
route = self.path
params = ""
route = route[1:]
params = params.split("&")
if route in Global.games:
self.send_response(200)
self.end_headers()
self.wfile.write(open(route+'.html', 'rb').read())
elif route == "setScore":
params = {}
for item in self.path.split("?")[1].split("&"):
if "=" in item:
pair = item.split("=")
params[pair[0]] = pair[1]
print(params)
if "imid" in params:
Global.bot.set_game_score(params["uid"], params["score"], inline_message_id=params["imid"])
else:
Global.bot.set_game_score(params["uid"], params["score"], message_id=params["mid"], chat_id=params["cid"])
self.send_response(200)
self.end_headers()
self.wfile.write(b'Set score')
else:
self.send_response(404)
self.end_headers()
self.wfile.write(b'Invalid game!')
def start(update, context):
Global.bot.send_game(update.message.chat_id, Global.featured)
def error(update, context):
print(update, error)
def button(update, context):
print(update)
query = update.callback_query
game = query.game_short_name
uid = str(query.from_user.id)
if query.message:
mid = str(query.message.message_id)
cid = str(query.message.chat.id)
url = "http://" + Global.host + ":"+Global.port + "/" + game + "?uid="+uid+"&mid="+mid+"&cid="+cid
else:
imid = update.callback_query.inline_message_id
url = "http://" + Global.host + ":"+Global.port + "/" + game + "?uid="+uid+"&imid="+imid
print(url)
Global.bot.answer_callback_query(query.id, text=game, url=url)
def inlinequery(update, context):
query = update.inline_query.query
results = []
for game in Global.games:
if query.lower() in game.lower():
results.append(InlineQueryResultGame(id=str(uuid4()),game_short_name=game))
Global.update.inline_query.answer(results)
def main():
config = configparser.ConfigParser()
config.read('config.ini')
token = config['DEFAULT']['API_KEY']
Global.games = config['DEFAULT']['GAMES'].split(',')
Global.host = config['DEFAULT']['HOST']
Global.port = config['DEFAULT']['PORT']
Global.featured = config['DEFAULT']['FEATURED']
updater = Updater(token=token, use_context=True)
dp = updater.dispatcher
dp.add_handler(CommandHandler('start', start))
dp.add_handler(InlineQueryHandler(inlinequery))
dp.add_handler(CallbackQueryHandler(button))
dp.add_error_handler(error)
Global.bot = updater.bot
print("Polling telegram")
updater.start_polling()
print("Starting http server")
http = HTTPServer((Global.host, int(Global.port)), GameHTTPRequestHandler)
http.serve_forever()
if __name__ == '__main__':
main()
Code inside the HTML5 Game, related to the score:
function gameOver() {
isGameOver = true;
clearInterval(gameInterval);
const urlParams = new URLSearchParams(window.location.search);
const uid = urlParams.get('uid');
const mid = urlParams.get('mid');
const cid = urlParams.get('cid');
const imid = urlParams.get('imid');
if (imid) {
const request = new Request(`/setScore?uid=${uid}&imid=${imid}&score=${score}`);
fetch(request).then(response => console.log("set score"));
}
else {
const request = new Request(`/setScore?uid=${uid}&mid=${mid}&cid=${cid}&score=${score}`);
fetch(request).then(response => console.log("set score"));
}
}
Original Bot by Mark Powers
pythonandpython-telegram-botbut didn't tell us anything about how you use those.set_game_scorerequest directly from your HTML game (which is hosted independently from your bot) would be an acceptable solution for you? And in the case where you have the SimpleHTTPServer set up in python: Does it listen to traffic directly (i.e. posting to your-domain.org directly posts to that server) or is there e.g. some reverse-proxy step in between?