feat: per-chat command toggle, listener name + toggle in bot tab

- Add commands_enabled field to TelegramChat (default off) with
  migration, gating command dispatch in both poller and webhook
- Show toggle switch per chat in bot tab for enabling/disabling commands
- Fix listener response to include bot name instead of just type
- Replace listener "Enabled" label + "Edit" link with toggle switch
  and crosslink to command-trackers page
This commit is contained in:
2026-03-23 19:23:37 +03:00
parent 37388c430c
commit b3b6c31c4d
10 changed files with 90 additions and 24 deletions
@@ -256,7 +256,7 @@ async def list_listeners(
CommandTrackerListener.command_tracker_id == tracker_id
)
)
return [_listener_response(l) for l in result.all()]
return [await _listener_response(session, l) for l in result.all()]
@router.post("/{tracker_id}/listeners", status_code=status.HTTP_201_CREATED)
@@ -312,7 +312,7 @@ async def add_listener(
from ..services.command_sync import mark_bot_dirty
mark_bot_dirty(body.listener_id)
return _listener_response(listener)
return await _listener_response(session, listener)
@router.delete("/{tracker_id}/listeners/{listener_id}", status_code=status.HTTP_204_NO_CONTENT)
@@ -377,17 +377,23 @@ async def _tracker_response(
CommandTrackerListener.command_tracker_id == t.id
)
)
resp["listeners"] = [_listener_response(l) for l in lr.all()]
resp["listeners"] = [await _listener_response(session, l) for l in lr.all()]
return resp
def _listener_response(l: CommandTrackerListener) -> dict:
async def _listener_response(session: AsyncSession, l: CommandTrackerListener) -> dict:
name = ""
if l.listener_type == "telegram_bot":
bot = await session.get(TelegramBot, l.listener_id)
if bot:
name = bot.name
return {
"id": l.id,
"command_tracker_id": l.command_tracker_id,
"listener_type": l.listener_type,
"listener_id": l.listener_id,
"name": name,
"created_at": l.created_at.isoformat(),
}