Source code for platforms.factory
from typing import Callable, Any
from config import Config, PlatformConfig
from media_cache import MediaCache
from core.proxy_adapter import ProxyPlatformAdapter
# Assume PlatformAdapter is a generic type representing any platform
# Let's import it or just type hint as Any
PlatformAdapter = Any
[docs]
def create_platform(
pcfg: PlatformConfig,
message_handler: Callable[..., Any],
media_cache: MediaCache | None = None,
message_update_handler: Callable[..., Any] | None = None,
message_delete_handler: Callable[..., Any] | None = None,
config: Config | None = None,
reaction_update_handler: Callable[..., Any] | None = None,
) -> PlatformAdapter:
"""Instantiate the correct platform adapter for a single platform config.
Dispatches on ``pcfg.type`` to build the matching connector
(``MatrixPlatform``, ``DiscordPlatform``, ``DiscordSelfPlatform``,
``WebChatPlatform``, or ``RedisPlatformAdapter``), lazily importing the
chosen platform module so unused dependencies are never loaded. Each
adapter is wired with the gateway's inbound callbacks (new message,
update, delete, reaction) plus the shared ``MediaCache`` and global
``Config``, and per-platform secrets such as tokens, homeserver, and
credentials are pulled out of ``pcfg`` with sane defaults. The adapter
itself owns the actual platform connection and event loop; this function
only constructs it. Called by the gateway service (``gateway_main``)
during startup, once per enabled entry in ``cfg.platforms``, with the
returned adapter appended to its adapter list and later bound to an
outbound stream consumer.
Args:
pcfg: Configuration for one platform, including its ``type``
discriminator and any platform-specific keys.
message_handler: Coroutine invoked when a new inbound message
arrives on the platform.
media_cache: Shared cache used to deduplicate and store downloaded
attachments; passed through to platforms that support it.
message_update_handler: Optional callback for edited messages.
message_delete_handler: Optional callback for deleted messages.
config: Global bot configuration handed to each adapter.
reaction_update_handler: Optional callback for reaction add/remove
events.
Returns:
A constructed platform adapter instance for the requested type.
Raises:
ValueError: If ``pcfg.type`` does not match any known platform.
"""
if pcfg.type == "matrix":
from platforms.matrix import MatrixPlatform
return MatrixPlatform(
message_handler=message_handler,
homeserver=pcfg.get("homeserver", "https://matrix.org"),
user_id=pcfg.get("user_id", ""),
password=pcfg.get("password", ""),
store_path=pcfg.get("store_path", "nio_store"),
credentials_file=pcfg.get(
"credentials_file",
"matrix_credentials.json",
),
media_cache=media_cache,
config=config,
)
if pcfg.type == "discord":
from platforms.discord import DiscordPlatform
return DiscordPlatform(
message_handler=message_handler,
token=pcfg.get("token", ""),
config=config,
media_cache=media_cache,
message_update_handler=message_update_handler,
message_delete_handler=message_delete_handler,
reaction_update_handler=reaction_update_handler,
)
if pcfg.type == "discord-self":
from platforms.discord_self import DiscordSelfPlatform
return DiscordSelfPlatform(
message_handler=message_handler,
token=pcfg.get("token", ""),
prefix=pcfg.get("prefix", "!"),
config=config,
media_cache=media_cache,
message_update_handler=message_update_handler,
message_delete_handler=message_delete_handler,
reaction_update_handler=reaction_update_handler,
)
if pcfg.type == "webchat":
from platforms.webchat import WebChatPlatform
return WebChatPlatform(
message_handler=message_handler,
)
if pcfg.type == "redis":
from platforms.redis import RedisPlatformAdapter
return RedisPlatformAdapter(
message_handler=message_handler,
config=config,
)
raise ValueError(f"Unknown platform type: {pcfg.type}")