ProtoRune.Bot.Server (proto_rune v0.1.1)

The ProtoRune.Bot.Server module is responsible for managing bot processes in ProtoRune. It handles bot initialization, session management, and event/message dispatching. This module also integrates with the polling system to retrieve real-time notifications from ATProto and Bluesky services.

The bot server can operate in two modes:

  • Polling: Periodically fetches notifications using the ProtoRune.Bot.Poller module.
  • Firehose: (Not yet implemented) Stream real-time events using a websocket-like connection.

Features

  • Bot Lifecycle Management: The server manages the entire bot lifecycle, from login and session refresh to handling messages and events.
  • Polling Strategy: Supports polling for notifications at regular intervals via the ProtoRune.Bot.Poller.
  • Session Management: Automatically handles session creation, refresh, and expiration.
  • Event and Message Handling: Provides a unified interface for handling events and messages via handle_message/1 and handle_event/2.

Options

  • :name (required) - The name of the bot process.
  • :lang - A list of languages the bot supports (default: ["en"]).
  • :service - The service endpoint the bot will connect to (default: "https://bsky.social").
  • :identifier - The bot's login identifier (e.g., email or username).
  • :password - The bot's password for login.
  • :polling - Polling configuration (e.g., interval and process_from).
  • :firehose - Firehose configuration (not implemented yet).
  • :strategy - The bot's strategy for receiving notifications (:polling or :firehose).

Polling Configuration

Polling can be configured with the following options:

  • :interval - How often (in seconds) the bot should poll for notifications (default: 5 seconds).
  • :process_from - Start processing notifications from a specific timestamp (default: current time).

Example:

ProtoRune.Bot.Server.start_link(
  name: :my_bot,
  strategy: :polling,
  service: "https://bsky.social",
  polling: %{interval: 10}
)

Firehose Configuration (Not Implemented)

While not yet available, the firehose strategy will enable real-time notifications using a websocket connection. Firehose configuration includes:

  • :relay_uri - The WebSocket URI for the relay server.
  • :auto_reconnect - Automatically reconnect if the connection drops (default: true).
  • :cursor - The starting cursor for reading the stream.

Functions

  • start_link/1: Starts the bot process with the given configuration options.
  • handle_message/2: Handles incoming messages for the bot.
  • handle_event/3: Handles events dispatched to the bot.
  • format_status/1: Formats the bot's internal state for debugging.

Session Management

The bot manages its session by authenticating with the ATProto server upon startup. It also refreshes the session token periodically. If the session expires or cannot be refreshed, the bot will stop.

Example

ProtoRune.Bot.Server.start_link([
  name: :my_bot,
  strategy: :polling,
  service: "https://bsky.social",
  identifier: "my-bot-id",
  password: "super-secret-password"
])

This will start a bot that uses the polling strategy to retrieve notifications from the Bsky service every 5 seconds.

The bot can handle messages and events like this:

ProtoRune.Bot.Server.handle_message(:my_bot, "hello")
ProtoRune.Bot.Server.handle_event(:my_bot, :user_joined, %{user: "user123"})

Internal State

The server maintains a state that includes:

  • name: The bot's name.
  • service: The endpoint to connect to.
  • session: The session data for making authenticated requests.
  • poller: The PID of the polling process (if using the polling strategy).
  • langs: The languages the bot supports.

Error Handling

  • The bot gracefully handles errors such as rate limits and API failures by retrying or stopping the process when necessary.
  • Errors are dispatched as events to the bot, allowing custom error handling.

Summary

Types

Link to this type

firehose_t()

@type firehose_t() :: %{
  optional(:relay_uri) => String.t(),
  optional(:auto_reconnect) => boolean(),
  optional(:cursor) => String.t()
}
@type kwargs() :: [option(), ...]
@type mapargs() :: %{
  :name => atom(),
  :strategy => :polling | :firehose,
  :service => String.t(),
  optional(:langs) => [String.t()],
  optional(:identifier) => String.t(),
  optional(:password) => String.t(),
  optional(:polling) => polling_t(),
  optional(:firehose) => firehose_t()
}
@type option() ::
  {:name, atom()}
  | {:lang, [String.t()]}
  | {:service, String.t()}
  | {:identifier, String.t() | nil}
  | {:password, String.t() | nil}
  | {:polling, polling_t() | nil}
  | {:firehose, firehose_t() | nil}
  | {:strategy, :polling | :firehose}
@type options_t() :: kwargs() | mapargs()
@type polling_t() :: %{
  optional(:interval) => integer(),
  optional(:process_from) => NaveDateTime.t()
}

Functions

Link to this function

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function

firehose_t(data)

Link to this function

firehose_t!(data)

Link to this function

get_schema(atom)

Link to this function

handle_event(name, event, payload \\ %{})

@spec handle_event(pid() | atom(), atom(), map()) :: :ok
Link to this function

handle_message(name, message)

@spec handle_message(pid() | atom(), String.t()) :: :ok
Link to this function

options_t(data)

Link to this function

options_t!(data)

Link to this function

polling_t(data)

Link to this function

polling_t!(data)

Link to this function

start_link(opts)

@spec start_link(options_t()) :: {:ok, pid()} | {:error, term()}