| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- """Read-only Tencent daily spend summaries for Feishu commands."""
- from __future__ import annotations
- import logging
- from datetime import datetime
- from typing import Any
- from operator_commands import (
- SCOPE_ACCOUNTS,
- SCOPE_ALL,
- SCOPE_AUTOMATION,
- ParsedCommand,
- )
- from storage import load_all_spend_accounts, load_automation_spend_accounts
- from tencent_client import TencentClient
- logger = logging.getLogger("tencent_realtime_control.today_spend")
- def _select_accounts(parsed: ParsedCommand) -> tuple[str, list[int]]:
- all_accounts = {
- int(row["account_id"]) for row in load_all_spend_accounts()
- }
- if parsed.scope_type == SCOPE_ALL:
- return "全部账户", sorted(all_accounts)
- if parsed.scope_type == SCOPE_AUTOMATION:
- automation_ids = {
- int(row["account_id"]) for row in load_automation_spend_accounts()
- }
- return "自动化账户", sorted(automation_ids & set(all_accounts))
- if parsed.scope_type == SCOPE_ACCOUNTS:
- missing = [value for value in parsed.account_ids if value not in all_accounts]
- if missing:
- raise ValueError(f"账户不在启用白名单: {missing}")
- return "指定账户", list(parsed.account_ids)
- raise ValueError(f"不支持的今日消耗查询范围: {parsed.scope_type}")
- def query_today_spend(
- parsed: ParsedCommand,
- *,
- now: datetime,
- tencent: TencentClient | None = None,
- ) -> dict[str, Any]:
- scope_label, account_ids = _select_accounts(parsed)
- if not account_ids:
- raise ValueError(f"{scope_label}范围内没有可查询账户")
- results: list[dict[str, int]] = []
- failed_account_ids: list[int] = []
- client = tencent or TencentClient()
- for account_id in account_ids:
- try:
- results.append(
- client.get_today_account_metrics(account_id, now.date())
- )
- except Exception:
- failed_account_ids.append(account_id)
- logger.exception("Today spend query failed account=%s", account_id)
- return {
- "scope_label": scope_label,
- "data_date": now.date(),
- "queried_at": now,
- "account_count": len(account_ids),
- "successful_account_count": len(results),
- "failed_account_count": len(failed_account_ids),
- "spending_account_count": sum(
- 1 for row in results if int(row.get("cost_fen") or 0) > 0
- ),
- "cost_fen": sum(int(row.get("cost_fen") or 0) for row in results),
- "impressions": sum(int(row.get("impressions") or 0) for row in results),
- "clicks": sum(int(row.get("clicks") or 0) for row in results),
- "conversions": sum(int(row.get("conversions") or 0) for row in results),
- "complete": not failed_account_ids,
- "failed_account_ids": failed_account_ids,
- }
|