RaxolGateway
Unified messaging gateway for Raxol: one supervised daemon connects many chat platforms through a single adapter contract, with process-per-chat sessions, unified session keying, and DM pairing authorization.
Installation
def deps do
[{:raxol_gateway, "~> 0.2"}]
end
Start the daemon under your supervisor with the handler each chat session runs:
children = [
{Raxol.Gateway.Supervisor,
handler: {MyApp.ChatHandler, []}, adapter: {MyApp.Adapter, conn}}
]
MyApp.ChatHandler implements Raxol.Gateway.Handler; MyApp.Adapter
implements Raxol.Gateway.Adapter, and conn is what its connect/1 returned.
Pieces
Raxol.Gateway.Route: the routing tuple and the session keyagent:main:{platform}:{chat_type}:{chat_id}.Raxol.Gateway.Adapter: the behaviour every platform implements (connect/disconnect/platform/normalize_event/send_message).Raxol.Gateway.Adapter.InMemoryis a reference adapter for tests.Raxol.Gateway.Handler: the per-chat behaviour a session runs (init/2,handle_event/2, optionalterminate/2on clean stops).Raxol.Gateway.Handler.Lifecycle: a full TEA app per chat underenvironment: :gateway(needs the optionalraxoldependency; no driver, no plugin manager, unnamed processes, so one app module serves many chats).Raxol.Gateway.Session: one process per chat, with an idle timeout.Raxol.Gateway.SessionRouter: starts and routes to sessions, keyed byRoute.key/1, with the idle-timeout, cooldown, and max-session limits.Raxol.Gateway.Pairing: DM pairing codes plus allowlists and the authorization check order.Raxol.Gateway.Delivery: the four outbound destinations (direct, home, cross-platform, explicit target string).Raxol.Gateway.Pipeline.Transcribe: feed-loop stage that turns a%{media: %{kind: :voice, ...}}event into%{text: transcript}before routing (injectable fetch/convert/recognize; ffmpeg + the optionalraxol_speechRecognizer by default; failures drop the one event, loudly).Raxol.Gateway.Supervisor: the daemon that ties them together.
A session optionally records each inbound event and each successfully delivered
outbound reply to a :log (any append(server, conversation_id, items), e.g.
Conversation.Log) keyed by a stable conversation_id. Adapter errors,
exceptions, and exits emit [:raxol_gateway, :session, :delivery_failed] and do
not create phantom outbound history. SessionRouter.handoff/3 rebinds a
conversation to another platform's route, reusing that conversation_id so the
log resumes the same history.
Platform adapters
- Telegram:
Raxol.Telegram.GatewayAdapter+Raxol.Telegram.UpdatePoller(in the raxol_telegram package). The adapter compiles only whenraxol_gatewayis already compiled; after addingraxol_gatewayto a project that hasraxol_telegram, runmix deps.compile raxol_telegram --force. - Discord:
Raxol.Gateway.Adapter.Discord(REST sends, optionalreq) +Raxol.Gateway.Adapter.Discord.GatewaySocket(Gateway v10 WebSocket feed, optionalmint_web_socket). - Email:
Raxol.Gateway.Adapter.Email(bidirectional via optionalgen_smtp: outbound SMTP submission, inbound RFC822 parsing throughnormalize_event/1, withAdapter.Email.Inboxas the sink-agnostic poll feed andAdapter.Email.ThreadStorefor reply threading; the mailbox transport itself, IMAP/POP/Gmail, is deployment-supplied).