Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 47 additions & 41 deletions bwh_bot/api/telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
import frappe

COMMAND_HANDLERS = {}
COMMAND_DESCRIPTIONS = {}
CALLBACK_HANDLERS = {}


def register_command(command, description=None):
def decorator(fn):
COMMAND_HANDLERS[command] = fn
# Keyed by command rather than stashed on the function: every conversation
# registers the same bound BotConversation.handle_command, so an attribute
# on the function is shared and the last registration wins for all of them.
if description:
try:
fn._description = description
except AttributeError:
fn.__func__._description = description
COMMAND_DESCRIPTIONS[command] = description
return fn

return decorator
Expand All @@ -28,15 +29,12 @@ def decorator(fn):
return decorator


# import handlers to register them
from bwh_bot.handlers import ping # noqa: F401, E402

# import conversation handlers — auto-registers via __init_subclass__
from bwh_bot.handlers import leave, petty_cash, wfh # noqa: F401, E402

# register conversation handlers into COMMAND_HANDLERS and CALLBACK_HANDLERS
# Importing the handler modules is what registers them: ping registers a plain
# command, and the conversation subclasses self-register via __init_subclass__.
from bwh_bot.conversation import CONVERSATION_HANDLERS
from bwh_bot.handlers import hive, leave, petty_cash, ping, wfh

# Register conversation handlers into COMMAND_HANDLERS and CALLBACK_HANDLERS.
for _handler in CONVERSATION_HANDLERS.values():
if _handler.command:
register_command(_handler.command, _handler.command_description)(_handler.handle_command)
Expand Down Expand Up @@ -80,21 +78,25 @@ def hook(**kwargs):
if message.get("date"):
message_date = datetime.fromtimestamp(message["date"])

doc = frappe.get_doc({
"doctype": "Telegram Webhook Log",
"update_type": update_type,
"chat_id": str(chat.get("id", "")),
"chat_title": chat.get("title", ""),
"telegram_user_id": str(telegram_user.get("id", "")),
"telegram_username": telegram_user.get("username", ""),
"telegram_user_name": f"{telegram_user.get('first_name', '')} {telegram_user.get('last_name', '')}".strip(),
"command": command,
"message_text": text,
"message_id": str(message.get("message_id", "")),
"message_thread_id": str(message["message_thread_id"]) if message.get("message_thread_id") else None,
"message_date": message_date,
"payload": json.dumps(data, indent=2),
})
doc = frappe.get_doc(
{
"doctype": "Telegram Webhook Log",
"update_type": update_type,
"chat_id": str(chat.get("id", "")),
"chat_title": chat.get("title", ""),
"telegram_user_id": str(telegram_user.get("id", "")),
"telegram_username": telegram_user.get("username", ""),
"telegram_user_name": f"{telegram_user.get('first_name', '')} {telegram_user.get('last_name', '')}".strip(),
"command": command,
"message_text": text,
"message_id": str(message.get("message_id", "")),
"message_thread_id": str(message["message_thread_id"])
if message.get("message_thread_id")
else None,
"message_date": message_date,
"payload": json.dumps(data, indent=2),
}
)
doc.insert(ignore_permissions=True)
frappe.db.commit()
except Exception:
Expand All @@ -112,20 +114,24 @@ def _handle_callback_query(data, callback_query):
if message.get("date"):
message_date = datetime.fromtimestamp(message["date"])

doc = frappe.get_doc({
"doctype": "Telegram Webhook Log",
"update_type": "callback_query",
"chat_id": str(chat.get("id", "")),
"chat_title": chat.get("title", ""),
"telegram_user_id": str(telegram_user.get("id", "")),
"telegram_username": telegram_user.get("username", ""),
"telegram_user_name": f"{telegram_user.get('first_name', '')} {telegram_user.get('last_name', '')}".strip(),
"callback_query_id": callback_query.get("id", ""),
"callback_data": callback_query.get("data", ""),
"message_id": str(message.get("message_id", "")),
"message_thread_id": str(message["message_thread_id"]) if message.get("message_thread_id") else None,
"message_date": message_date,
"payload": json.dumps(data, indent=2),
})
doc = frappe.get_doc(
{
"doctype": "Telegram Webhook Log",
"update_type": "callback_query",
"chat_id": str(chat.get("id", "")),
"chat_title": chat.get("title", ""),
"telegram_user_id": str(telegram_user.get("id", "")),
"telegram_username": telegram_user.get("username", ""),
"telegram_user_name": f"{telegram_user.get('first_name', '')} {telegram_user.get('last_name', '')}".strip(),
"callback_query_id": callback_query.get("id", ""),
"callback_data": callback_query.get("data", ""),
"message_id": str(message.get("message_id", "")),
"message_thread_id": str(message["message_thread_id"])
if message.get("message_thread_id")
else None,
"message_date": message_date,
"payload": json.dumps(data, indent=2),
}
)
doc.insert(ignore_permissions=True)
frappe.db.commit()
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"actions": [],
"allow_bulk_edit": 1,
"allow_rename": 1,
"creation": "2026-07-30 01:57:20.881718",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"label",
"site_url",
"api_key",
"api_secret",
"is_active"
],
"fields": [
{
"columns": 2,
"fieldname": "label",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Label"
},
{
"columns": 3,
"description": "Base URL of the Frappe site running Hive, e.g. https://hive.example.com",
"fieldname": "site_url",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Site URL",
"reqd": 1
},
{
"columns": 2,
"fieldname": "api_key",
"fieldtype": "Data",
"in_list_view": 1,
"label": "API Key",
"reqd": 1
},
{
"fieldname": "api_secret",
"fieldtype": "Password",
"label": "API Secret",
"reqd": 1
},
{
"columns": 1,
"default": "1",
"fieldname": "is_active",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Is Active"
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2026-07-30 01:57:20.881718",
"modified_by": "Administrator",
"module": "BWH Bot Backend",
"name": "BWH Bot Hive Site",
"owner": "Administrator",
"permissions": [],
"row_format": "Dynamic",
"rows_threshold_for_grid_search": 20,
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright (c) 2026, BWH and contributors
# For license information, please see license.txt

# import frappe
from frappe.model.document import Document


class BWHBotHiveSite(Document):
# begin: auto-generated types
# This code is auto-generated. Do not modify anything in this block.

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from frappe.types import DF

api_key: DF.Data
api_secret: DF.Password
is_active: DF.Check
label: DF.Data | None
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data
site_url: DF.Data
# end: auto-generated types

_DOCTYPE_NAME = "BWH Bot Hive Site"
Loading