Removed async code
This commit is contained in:
parent
62fb0ec8d4
commit
6d3ad14298
12 changed files with 296 additions and 487 deletions
|
@ -1,7 +1,6 @@
|
||||||
import asyncio
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from quart import Quart, request
|
from flask import Flask, request
|
||||||
import structlog
|
import structlog
|
||||||
|
|
||||||
import butterrobot.logging # noqa
|
import butterrobot.logging # noqa
|
||||||
|
@ -13,7 +12,7 @@ from butterrobot.platforms.base import Platform
|
||||||
|
|
||||||
|
|
||||||
logger = structlog.get_logger(__name__)
|
logger = structlog.get_logger(__name__)
|
||||||
app = Quart(__name__)
|
app = Flask(__name__)
|
||||||
available_platforms = {}
|
available_platforms = {}
|
||||||
plugins = get_available_plugins()
|
plugins = get_available_plugins()
|
||||||
enabled_plugins = [
|
enabled_plugins = [
|
||||||
|
@ -21,18 +20,18 @@ enabled_plugins = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
async def handle_message(platform: str, message: Message):
|
def handle_message(platform: str, message: Message):
|
||||||
for plugin in enabled_plugins:
|
for plugin in enabled_plugins:
|
||||||
async for response_message in plugin.on_message(message):
|
for response_message in plugin.on_message(message):
|
||||||
asyncio.ensure_future(available_platforms[platform].methods.send_message(response_message))
|
available_platforms[platform].methods.send_message(response_message)
|
||||||
|
|
||||||
|
|
||||||
@app.before_serving
|
@app.before_first_request
|
||||||
async def init_platforms():
|
def init_platforms():
|
||||||
for platform in PLATFORMS.values():
|
for platform in PLATFORMS.values():
|
||||||
logger.debug("Setting up", platform=platform.ID)
|
logger.debug("Setting up", platform=platform.ID)
|
||||||
try:
|
try:
|
||||||
await platform.init(app=app)
|
platform.init(app=app)
|
||||||
available_platforms[platform.ID] = platform
|
available_platforms[platform.ID] = platform
|
||||||
logger.info("platform setup completed", platform=platform.ID)
|
logger.info("platform setup completed", platform=platform.ID)
|
||||||
except platform.PlatformInitError as error:
|
except platform.PlatformInitError as error:
|
||||||
|
@ -41,12 +40,12 @@ async def init_platforms():
|
||||||
|
|
||||||
@app.route("/<platform>/incoming", methods=["POST"])
|
@app.route("/<platform>/incoming", methods=["POST"])
|
||||||
@app.route("/<platform>/incoming/<path:path>", methods=["POST"])
|
@app.route("/<platform>/incoming/<path:path>", methods=["POST"])
|
||||||
async def incoming_platform_message_view(platform, path=None):
|
def incoming_platform_message_view(platform, path=None):
|
||||||
if platform not in available_platforms:
|
if platform not in available_platforms:
|
||||||
return {"error": "Unknown platform"}, 400
|
return {"error": "Unknown platform"}, 400
|
||||||
|
|
||||||
try:
|
try:
|
||||||
message = await available_platforms[platform].parse_incoming_message(
|
message = available_platforms[platform].parse_incoming_message(
|
||||||
request=request
|
request=request
|
||||||
)
|
)
|
||||||
except Platform.PlatformAuthResponse as response:
|
except Platform.PlatformAuthResponse as response:
|
||||||
|
@ -63,7 +62,8 @@ async def incoming_platform_message_view(platform, path=None):
|
||||||
if not message or message.from_bot:
|
if not message or message.from_bot:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
asyncio.ensure_future(handle_message(platform, message))
|
# TODO: make with rq/dramatiq
|
||||||
|
handle_message(platform, message)
|
||||||
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from typing import Optional, Text
|
from typing import Optional, Text
|
||||||
|
|
||||||
import aiohttp
|
import requests
|
||||||
import structlog
|
import structlog
|
||||||
|
|
||||||
from butterrobot.config import SLACK_BOT_OAUTH_ACCESS_TOKEN
|
from butterrobot.config import SLACK_BOT_OAUTH_ACCESS_TOKEN
|
||||||
|
@ -19,7 +19,7 @@ class SlackAPI:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def send_message(cls, channel, message, thread: Optional[Text] = None):
|
def send_message(cls, channel, message, thread: Optional[Text] = None):
|
||||||
payload = {
|
payload = {
|
||||||
"text": message,
|
"text": message,
|
||||||
"channel": channel,
|
"channel": channel,
|
||||||
|
@ -28,12 +28,11 @@ class SlackAPI:
|
||||||
if thread:
|
if thread:
|
||||||
payload["thread_ts"] = thread
|
payload["thread_ts"] = thread
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
response = requestts.post(
|
||||||
async with session.post(
|
|
||||||
f"{cls.BASE_URL}/chat.postMessage",
|
f"{cls.BASE_URL}/chat.postMessage",
|
||||||
data=payload,
|
data=payload,
|
||||||
headers={"Authorization": f"Bearer {SLACK_BOT_OAUTH_ACCESS_TOKEN}"},
|
headers={"Authorization": f"Bearer {SLACK_BOT_OAUTH_ACCESS_TOKEN}"},
|
||||||
) as response:
|
)
|
||||||
response = await response.json()
|
response_json = response.json()
|
||||||
if not response["ok"]:
|
if not response_json["ok"]:
|
||||||
raise cls.SlackClientError(response)
|
raise cls.SlackClientError(response_json)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import aiohttp
|
import requests
|
||||||
import structlog
|
import structlog
|
||||||
|
|
||||||
from butterrobot.config import TELEGRAM_TOKEN
|
from butterrobot.config import TELEGRAM_TOKEN
|
||||||
|
@ -19,7 +19,7 @@ class TelegramAPI:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def set_webhook(cls, webhook_url, max_connections=40, allowed_updates=None):
|
def set_webhook(cls, webhook_url, max_connections=40, allowed_updates=None):
|
||||||
allowed_updates = allowed_updates or cls.DEFAULT_ALLOWED_UPDATES
|
allowed_updates = allowed_updates or cls.DEFAULT_ALLOWED_UPDATES
|
||||||
url = f"{cls.BASE_URL}/setWebhook"
|
url = f"{cls.BASE_URL}/setWebhook"
|
||||||
payload = {
|
payload = {
|
||||||
|
@ -27,14 +27,13 @@ class TelegramAPI:
|
||||||
"max_connections": max_connections,
|
"max_connections": max_connections,
|
||||||
"allowed_updates": allowed_updates,
|
"allowed_updates": allowed_updates,
|
||||||
}
|
}
|
||||||
async with aiohttp.ClientSession() as session:
|
response = requests.post(url, json=payload)
|
||||||
async with session.post(url, json=payload) as response:
|
response_json = response.json()
|
||||||
response = await response.json()
|
if not response_json["ok"]:
|
||||||
if not response["ok"]:
|
raise cls.TelegramClientError(response_json)
|
||||||
raise cls.TelegramClientError(response)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def send_message(
|
def send_message(
|
||||||
cls,
|
cls,
|
||||||
chat_id,
|
chat_id,
|
||||||
text,
|
text,
|
||||||
|
@ -52,8 +51,8 @@ class TelegramAPI:
|
||||||
"disable_notification": disable_notification,
|
"disable_notification": disable_notification,
|
||||||
"reply_to_message_id": reply_to_message_id,
|
"reply_to_message_id": reply_to_message_id,
|
||||||
}
|
}
|
||||||
async with aiohttp.ClientSession() as session:
|
|
||||||
async with session.post(url, json=payload) as response:
|
response = requests.post(url, json=payload)
|
||||||
response = await response.json()
|
response_json = response.json()
|
||||||
if not response["ok"]:
|
if not response_json["ok"]:
|
||||||
raise cls.TelegramClientError(response)
|
raise cls.TelegramClientError(response_json)
|
|
@ -21,7 +21,7 @@ class Platform:
|
||||||
status_code: int = 200
|
status_code: int = 200
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def init(cls, app):
|
def init(cls, app):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ logger = structlog.get_logger(__name__)
|
||||||
|
|
||||||
class DebugMethods(PlatformMethods):
|
class DebugMethods(PlatformMethods):
|
||||||
@classmethod
|
@classmethod
|
||||||
async def send_message(self, message: Message):
|
def send_message(self, message: Message):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Outgoing message", message=message.__dict__, platform=DebugPlatform.ID
|
"Outgoing message", message=message.__dict__, platform=DebugPlatform.ID
|
||||||
)
|
)
|
||||||
|
@ -24,8 +24,8 @@ class DebugPlatform(Platform):
|
||||||
methods = DebugMethods
|
methods = DebugMethods
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def parse_incoming_message(cls, request):
|
def parse_incoming_message(cls, request):
|
||||||
request_data = await request.get_json()
|
request_data = request.get_json()
|
||||||
logger.debug("Parsing message", data=request_data, platform=cls.ID)
|
logger.debug("Parsing message", data=request_data, platform=cls.ID)
|
||||||
|
|
||||||
return Message(
|
return Message(
|
||||||
|
|
|
@ -13,12 +13,12 @@ logger = structlog.get_logger(__name__)
|
||||||
|
|
||||||
class SlackMethods(PlatformMethods):
|
class SlackMethods(PlatformMethods):
|
||||||
@classmethod
|
@classmethod
|
||||||
async def send_message(self, message: Message):
|
def send_message(self, message: Message):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Outgoing message", message=message.__dict__, platform=SlackPlatform.ID
|
"Outgoing message", message=message.__dict__, platform=SlackPlatform.ID
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
await SlackAPI.send_message(
|
SlackAPI.send_message(
|
||||||
channel=message.chat, message=message.text, thread=message.reply_to
|
channel=message.chat, message=message.text, thread=message.reply_to
|
||||||
)
|
)
|
||||||
except SlackAPI.SlackClientError as error:
|
except SlackAPI.SlackClientError as error:
|
||||||
|
@ -36,14 +36,14 @@ class SlackPlatform(Platform):
|
||||||
methods = SlackMethods
|
methods = SlackMethods
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def init(cls, app):
|
def init(cls, app):
|
||||||
if not (SLACK_TOKEN and SLACK_BOT_OAUTH_ACCESS_TOKEN):
|
if not (SLACK_TOKEN and SLACK_BOT_OAUTH_ACCESS_TOKEN):
|
||||||
logger.error("Missing token. platform not enabled.", platform=cls.ID)
|
logger.error("Missing token. platform not enabled.", platform=cls.ID)
|
||||||
return
|
return
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def parse_incoming_message(cls, request):
|
def parse_incoming_message(cls, request):
|
||||||
data = await request.get_json()
|
data = request.get_json()
|
||||||
|
|
||||||
# Auth
|
# Auth
|
||||||
if data.get("token") != SLACK_TOKEN:
|
if data.get("token") != SLACK_TOKEN:
|
||||||
|
|
|
@ -13,11 +13,11 @@ logger = structlog.get_logger(__name__)
|
||||||
|
|
||||||
class TelegramMethods(PlatformMethods):
|
class TelegramMethods(PlatformMethods):
|
||||||
@classmethod
|
@classmethod
|
||||||
async def send_message(self, message: Message):
|
def send_message(self, message: Message):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Outgoing message", message=message.__dict__, platform=TelegramPlatform.ID
|
"Outgoing message", message=message.__dict__, platform=TelegramPlatform.ID
|
||||||
)
|
)
|
||||||
await TelegramAPI.send_message(
|
TelegramAPI.send_message(
|
||||||
chat_id=message.chat,
|
chat_id=message.chat,
|
||||||
text=message.text,
|
text=message.text,
|
||||||
reply_to_message_id=message.reply_to,
|
reply_to_message_id=message.reply_to,
|
||||||
|
@ -30,7 +30,7 @@ class TelegramPlatform(Platform):
|
||||||
methods = TelegramMethods
|
methods = TelegramMethods
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def init(cls, app):
|
def init(cls, app):
|
||||||
"""
|
"""
|
||||||
Initializes the Telegram webhook endpoint to receive updates
|
Initializes the Telegram webhook endpoint to receive updates
|
||||||
"""
|
"""
|
||||||
|
@ -41,18 +41,18 @@ class TelegramPlatform(Platform):
|
||||||
|
|
||||||
webhook_url = f"https://{HOSTNAME}/telegram/incoming/{TELEGRAM_TOKEN}"
|
webhook_url = f"https://{HOSTNAME}/telegram/incoming/{TELEGRAM_TOKEN}"
|
||||||
try:
|
try:
|
||||||
await TelegramAPI.set_webhook(webhook_url)
|
TelegramAPI.set_webhook(webhook_url)
|
||||||
except TelegramAPI.TelegramError as error:
|
except TelegramAPI.TelegramError as error:
|
||||||
logger.error(f"Error setting Telegram webhook: {error}", platform=cls.ID)
|
logger.error(f"Error setting Telegram webhook: {error}", platform=cls.ID)
|
||||||
raise Platform.PlatformInitError()
|
raise Platform.PlatformInitError()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def parse_incoming_message(cls, request):
|
def parse_incoming_message(cls, request):
|
||||||
token = request.path.split("/")[-1]
|
token = request.path.split("/")[-1]
|
||||||
if token != TELEGRAM_TOKEN:
|
if token != TELEGRAM_TOKEN:
|
||||||
raise cls.PlatformAuthError("Authentication error")
|
raise cls.PlatformAuthError("Authentication error")
|
||||||
|
|
||||||
request_data = await request.get_json()
|
request_data = request.get_json()
|
||||||
logger.debug("Parsing message", data=request_data, platform=cls.ID)
|
logger.debug("Parsing message", data=request_data, platform=cls.ID)
|
||||||
|
|
||||||
if "text" in request_data["message"]:
|
if "text" in request_data["message"]:
|
||||||
|
|
|
@ -11,7 +11,7 @@ logger = structlog.get_logger(__name__)
|
||||||
|
|
||||||
class Plugin:
|
class Plugin:
|
||||||
@abstractclassmethod
|
@abstractclassmethod
|
||||||
async def on_message(cls, message: Message):
|
def on_message(cls, message: Message):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ class PingPlugin(Plugin):
|
||||||
id = "contrib/dev/ping"
|
id = "contrib/dev/ping"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def on_message(cls, message):
|
def on_message(cls, message):
|
||||||
if message.text == "!ping":
|
if message.text == "!ping":
|
||||||
delta = datetime.now() - message.date
|
delta = datetime.now() - message.date
|
||||||
delta_ms = delta.seconds * 1000 + delta.microseconds / 1000
|
delta_ms = delta.seconds * 1000 + delta.microseconds / 1000
|
||||||
|
|
|
@ -8,7 +8,7 @@ class LoquitoPlugin(Plugin):
|
||||||
id = "contrib/fun/loquito"
|
id = "contrib/fun/loquito"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def on_message(cls, message):
|
def on_message(cls, message):
|
||||||
if "lo quito" in message.text.lower():
|
if "lo quito" in message.text.lower():
|
||||||
yield Message(chat=message.chat, reply_to=message.id, text="Loquito tu.",)
|
yield Message(chat=message.chat, reply_to=message.id, text="Loquito tu.",)
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ class DicePlugin(Plugin):
|
||||||
id = "contrib/fun/dice"
|
id = "contrib/fun/dice"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def on_message(cls, message: Message):
|
def on_message(cls, message: Message):
|
||||||
if message.text.startswith("!dice"):
|
if message.text.startswith("!dice"):
|
||||||
roll = int(dice.roll(message.text.replace("!dice ", "")))
|
roll = int(dice.roll(message.text.replace("!dice ", "")))
|
||||||
yield Message(chat=message.chat, reply_to=message.id, text=roll)
|
yield Message(chat=message.chat, reply_to=message.id, text=roll)
|
677
poetry.lock
generated
677
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -13,11 +13,11 @@ readme = "README.md"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.7"
|
python = "^3.7"
|
||||||
quart = "^0.11.3"
|
|
||||||
aiohttp = "^3.6.2"
|
|
||||||
structlog = "^20.1.0"
|
structlog = "^20.1.0"
|
||||||
colorama = "^0.4.3"
|
colorama = "^0.4.3"
|
||||||
dice = "^3.1.0"
|
dice = "^3.1.0"
|
||||||
|
flask = "^1.1.2"
|
||||||
|
requests = "^2.24.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
black = "^19.10b0"
|
black = "^19.10b0"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue