Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- #
- # flask_app.py
- #
- #
- import os, os.path
- import re
- import click
- import telepot
- import urllib.parse
- from pprint import pprint
- # see https://pastebin.com/DnRQD648
- from jet.expando import Expando, expando_update, bind_expando_method
- # Set the proper value
- #~ SERVER_TYPE = 'REMOTE'
- SERVER_TYPE = 'LOCAL' # for flask server on your computer
- from flask import Flask, request, g
- app = Flask(__name__)
- app.config.from_object('config')
- def set_telepot_socks_proxy(proxy_url, username=None, password=None):
- from urllib3.contrib.socks import SOCKSProxyManager
- from telepot.api import _default_pool_params, _onetime_pool_params
- telepot.api._onetime_pool_spec = (SOCKSProxyManager, dict(proxy_url=proxy_url, username=username, password=password, **_onetime_pool_params))
- telepot.api._pools['default'] = SOCKSProxyManager(proxy_url, username=username, password=password, **_default_pool_params)
- def set_telepot_http_proxy(proxy_url) :
- import urllib3
- telepot.api._pools = {
- 'default': urllib3.ProxyManager(proxy_url=proxy_url, num_pools=3, maxsize=10, retries=False, timeout=30),
- }
- telepot.api._onetime_pool_spec = (urllib3.ProxyManager, dict(proxy_url=proxy_url, num_pools=1, maxsize=1, retries=False, timeout=30))
- if SERVER_TYPE == 'LOCAL' :
- # running a local flask server
- proxy_url = app.config['PROXY_URL']
- if proxy_url and proxy_url.startswith('socks') :
- set_telepot_socks_proxy(proxy_url)
- elif proxy_url and proxy_url.startswith('http') :
- set_telepot_http_proxy(proxy_url)
- else :
- # running a remote flask server on PythonAnywhere
- proxy_url = "http://proxy.server:3128"
- set_telepot_http_proxy(proxy_url)
- # create one time proenv data-ware :
- host_url = app.config['HOST_URL']
- home = os.path.expanduser('~')
- project = app.config['PROJECT']
- var_path = os.path.join(home, 'var', project)
- session_path = os.path.join(var_path, 'sessions')
- proenv = Expando(
- app_path = app.config['APT_PATH'],
- home = home,
- project = project,
- var_path = var_path,
- session_path = session_path,
- config = app.config
- )
- os.makedirs(var_path, exist_ok=True)
- os.makedirs(session_path, exist_ok=True)
- # create one-time (monobot) bot_info :
- bot_info = Expando(
- id = app.config['BOT_ID'],
- name = app.config['BOT_NAME'],
- username = app.config['BOT_USERNAME'],
- webhook_route = app.config['WEBHOOK_ROUTE'],
- webhook_url = urllib.parse.urljoin(app.config['HOST_URL'], app.config['WEBHOOK_ROUTE']),
- bot = telepot.Bot(app.config['BOT_TOKEN'])
- )
- if SERVER_TYPE == 'REMOTE' :
- bot_info.bot.setWebhook(bot_info.webhook_url, max_connections=1)
- def get_sender_info_summary(msg, ignore_lang=True) :
- parts = []
- if 'from' in msg :
- sender = msg['from']
- parts.append('{}:'.format(sender['id']))
- if 'first_name' in sender and sender['first_name'] is not None :
- parts.append(sender['first_name'])
- if 'last_name' in sender and sender['last_name'] is not None :
- parts.append(sender['last_name'])
- if 'username' in sender and sender['username'] is not None :
- parts.append('(@{})'.format(sender['username']))
- if 'is_bot' in sender and sender['is_bot'] :
- parts.append('[BOT]')
- if not ignore_lang and 'language_code' in sender and sender['language_code'] is not None :
- parts.append('<{}>'.format(sender['language_code']))
- return ' '.join(parts)
- def get_chat_info_summary(msg, ignore_adm=True) :
- parts = []
- if 'chat' in msg :
- chat = msg['chat']
- parts.append('{}:'.format(chat['id']))
- if 'first_name' in chat and chat['first_name'] is not None :
- parts.append(chat['first_name'])
- if 'last_name' in chat and chat['last_name'] is not None :
- parts.append(chat['last_name'])
- if 'username' in chat and chat['username'] is not None :
- parts.append('(@{})'.format(chat['username']))
- if 'title' in chat and chat['title'] is not None :
- parts.append(chat['title'])
- if 'type' in chat and chat['type'] is not None :
- parts.append('[{}]'.format(chat['type']))
- if not ignore_adm and 'all_members_are_administrators' in chat and chat['all_members_are_administrators'] :
- parts.append('[ALL:ADMIN]')
- return ' '.join(parts)
- command_mention_re = re.compile(r'^/([\w]+)@([\w]+)\s*(.*)')
- command_re = re.compile(r'^/([\w]+)\s*(.*)')
- space_split_re = re.compile(r'\s+')
- def split_message_text(text) :
- body_parts = text.split('\n', maxsplit=1)
- cmd_line = body_parts[0]
- tail = None if len(body_parts) == 1 else body_parts[1].strip()
- command = None
- bot_mention = None
- line = None
- omat = command_mention_re.match(text)
- if omat :
- command = omat.group(1).upper()
- bot_mention = omat.group(2).lower()
- line = omat.group(3).strip() or None
- else :
- omat = command_re.match(text)
- if omat :
- command = omat.group(1).upper()
- line = omat.group(2).strip() or None
- else :
- line = text.strip() or None
- args = (line and space_split_re.split(line)) or []
- return Expando(command=command, bot_mention=bot_mention, line=line, args=args, tail=tail)
- def act_start(command, message, extras) :
- bot = extras.bot_info.bot
- chat_id = extras.provars.chat_id
- text = f'Hello! I am {extras.bot_info.name}. Nice to meet you.'
- bot.sendMessage(chat_id, text)
- def act_hello(command, message, extras) :
- bot = extras.bot_info.bot
- chat_id = extras.provars.chat_id
- text = f'Hello! Good to see you again! 🌺'
- bot.sendMessage(chat_id, text)
- def act_bad_command(command, message, extras) :
- bot = extras.bot_info.bot
- chat_id = extras.provars.chat_id
- text = f'🚫 Unknown command: {command}'
- bot.sendMessage(chat_id, text)
- def act_no_command(command, message, extras) :
- bot = extras.bot_info.bot
- chat_id = extras.provars.chat_id
- text = f'🚫 No command in message!'
- bot.sendMessage(chat_id, text)
- commands = {
- 'START' : act_start,
- 'HELLO' : act_hello,
- }
- def handle_chat(message, extras) :
- flavor = telepot.flavor(message)
- assert flavor == 'chat'
- content_type, chat_type, chat_id = telepot.glance(message, flavor=flavor)
- sender_id = message['from']['id']
- expando_update(extras.provars, content_type=content_type, chat_type=chat_type, chat_id=chat_id, sender_id=sender_id)
- extras.provars.sender_info = get_sender_info_summary(message)
- extras.provars.chat_info = get_chat_info_summary(message)
- if content_type == 'text' :
- command_expo = split_message_text(message['text'])
- expando_update(extras.provars, command_expo)
- # useful in local server:
- # pprint(extras.provars.__dict__)
- # Trivial method to process the command : dictionary look up:
- command = extras.provars.command
- if not command :
- act_no_command(command, message, extras)
- elif command in commands :
- commands[command](command, message, extras)
- else :
- act_bad_command(command, message, extras)
- else :
- text = '{} says : You sent me a "{}" message.'.format(extras.bot_info.name, content_type)
- bot = extras.bot_info.bot
- bot.sendMessage(chat_id, text)
- @app.route(bot_info.webhook_route, methods=['POST'])
- def route_bot_hook() :
- g.proenv = proenv
- g.bot_info = bot_info
- g.provars = Expando() # TODO: create provars based on current request context
- g.session = Expando() # TODO: create based on current user-bot pair
- update = request.get_json()
- if 'message' in update:
- # it's a chat message
- message = update['message']
- pprint(message)
- handle_chat(message, g)
- return 'OK'
- # useful command-line commands if webhook URL is not known at the time that flask starts
- @app.cli.command(with_appcontext=True)
- @click.option('-u', '--url', prompt='URL?')
- def set_webhook(url) :
- '''Set WEBHOOK for bot.'''
- base_url = url
- url = urllib.parse.urljoin(base_url, app.config['WEBHOOK_ROUTE'])
- bot = bot_info.bot
- res = bot.setWebhook(url, max_connections=1)
- pprint(res)
- @app.cli.command(with_appcontext=False)
- def del_webhook() :
- '''Delete WEBHOOK for bot.'''
- bot = bot_info.bot
- res = bot.deleteWebhook()
- pprint(res)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement