import logging from dataclasses import dataclass from slack_sdk import WebClient from slack_sdk.oauth.installation_store import InstallationStore from slack_sdk.oauth.installation_store.models import Bot from community_qa_bot.models import SlackInstalledBot, get_or_create from community_qa_bot.db import Session as DBSession logger = logging.getLogger(__name__) @dataclass class SlackBotWrapper: bot: Bot client: WebClient class SlackInstallationStore(InstallationStore): _bots: dict[str, Bot] = {} def __init__(self): self._load_bots_from_db() def _load_bots_from_db(self): self._bots = {} with DBSession() as session: for _bot in session.query(SlackInstalledBot).all(): self._bots[_bot.team_id] = Bot( app_id=_bot.app_id, team_id=_bot.team_id, team_name=_bot.team_name, bot_token=_bot.access_token, bot_user_id=_bot.bot_user_id, bot_id=_bot.bot_id, installed_at=_bot.created_at.timestamp(), ) @property def logger(self) -> logging.Logger: return logger def save_bot(self, bot: Bot): with DBSession() as session: db_bot, _ = get_or_create( session, SlackInstalledBot, app_id=bot.app_id, team_id=bot.team_id, bot_id=bot.bot_id ) db_bot.team_name = bot.team_name db_bot.bot_user_id = bot.bot_user_id db_bot.access_token = bot.bot_token session.commit() self._load_bots_from_db() def find_bot( self, *, enterprise_id: str | None, team_id: str | None, is_enterprise_install: bool = False, ) -> Bot | None: if enterprise_id or is_enterprise_install: raise NotImplementedError('Enterprise bots are not supported yet') return self._bots.get(team_id) def find_bot_with_client(self, team_id: str) -> tuple[Bot | None, WebClient | None]: bot = self._bots.get(team_id) if not bot: return None, None return bot, WebClient(token=bot.bot_token) def get_all_bots(self) -> list[Bot]: return list(self._bots.values()) installation_store = SlackInstallationStore()