ForcePilot/backend/package/yuxi/channels/adapters/slack/auto_presence.py
Kris a2aa782b86 feat(slack adapter): 实现完整的Slack频道适配器基础功能
新增Slack适配器全套核心模块,包括消息处理流水线、会话管理、配置适配、权限控制等完整功能:
1. 新增语音、视觉相关的TTS和图像分析导出接口
2. 实现消息预处理、路由、线程上下文处理的完整流水线
3. 新增账号管理、缓存机制、房间上下文提取功能
4. 支持Webhook和Socket Mode两种事件接收方式
5. 实现权限白名单、审批配对、自动状态管理功能
6. 新增配置迁移、作用域校验、重连策略等辅助模块
2026-05-12 00:48:57 +08:00

75 lines
2.4 KiB
Python

from __future__ import annotations
import asyncio
from datetime import datetime, UTC
from typing import Any
from yuxi.channels.models import DeliveryResult
from yuxi.utils.logging_config import logger
class AutoPresence:
def __init__(
self,
client,
*,
interval_minutes: int = 5,
status_text: str = "",
status_emoji: str = "",
):
self._client = client
self._interval_seconds = interval_minutes * 60
self._status_text = status_text
self._status_emoji = status_emoji
self._task: asyncio.Task | None = None
self._running = False
self._last_update: datetime | None = None
async def start(self) -> None:
self._running = True
self._task = asyncio.create_task(self._loop())
logger.info(f"Auto-presence started, interval: {self._interval_seconds}s")
async def stop(self) -> None:
self._running = False
if self._task and not self._task.done():
self._task.cancel()
try:
await self._task
except (asyncio.CancelledError, Exception):
pass
logger.info("Auto-presence stopped")
async def update_now(self) -> DeliveryResult:
try:
profile: dict[str, Any] = {}
if self._status_text:
profile["status_text"] = self._status_text
if self._status_emoji:
profile["status_emoji"] = self._status_emoji
if profile:
result = await self._client.users_profile_set(profile=profile)
self._last_update = datetime.now(UTC)
ok = result.get("ok", False)
return DeliveryResult(success=ok, error=result.get("error") if not ok else None)
return DeliveryResult(success=True)
except Exception as e:
logger.error(f"Auto-presence update failed: {e}")
return DeliveryResult(success=False, error=str(e))
async def _loop(self) -> None:
while self._running:
try:
await self.update_now()
except Exception as e:
logger.debug(f"Auto-presence loop error: {e}")
await asyncio.sleep(self._interval_seconds)
@property
def last_update_at(self) -> datetime | None:
return self._last_update
@property
def is_running(self) -> bool:
return self._running