IRC Backends#
sopel.irc.abstract_backends#
sopel.irc.abstract_backends
defines the IRC backend interface.
Warning
This is all internal code, not intended for direct use by plugins. It is subject to change between versions, even patch releases, without any advance warning.
Please use the public APIs on bot
.
- class sopel.irc.abstract_backends.AbstractIRCBackend(bot: AbstractBot)#
Abstract class defining the interface and basic logic of an IRC backend.
- Parameters:
bot (
sopel.bot.Sopel
) – a Sopel instance
Some methods of this class MUST be overridden by a subclass, or the backend implementation will not function correctly.
- abstract irc_send(data: bytes) None #
Send an IRC line as raw
data
.- Parameters:
data (bytes) – raw line to send
This method must be thread-safe.
- log_exception() None #
Log an exception to
sopel.exceptions
.The IRC backend must use this method to log any exception that isn’t caught by the bot itself (i.e. while handling messages), such as connection errors, SSL errors, etc.
- abstract on_irc_error(pretrigger: PreTrigger) None #
Action to perform when the server sends an error event.
- Parameters:
pretrigger – PreTrigger object with the error event
On IRC error, if
bot.hasquit
is set, the backend should close the connection so the bot can quit or reconnect as required.
- prepare_command(*args: str, text: str | None = None) str #
Prepare an IRC command from
args
and optionaltext
.- Parameters:
args – arguments of the IRC command to send
text – text to send with the IRC command (optional keyword argument)
- Returns:
the raw message to send through the connection
From the IRC Client Protocol specification, RFC 2812 § 2.3:
IRC messages are always lines of characters terminated with a CR-LF (Carriage Return - Line Feed) pair, and these messages SHALL NOT exceed 512 characters in length, counting all characters including the trailing CR-LF. Thus, there are 510 characters maximum allowed for the command and its parameters. There is no provision for continuation of message lines.
The length in the RFC refers to the length in bytes, which can be bigger than the length of the Unicode string. This method cuts the message until its length fits within this limit of 510 bytes.
The returned message contains the CR-LF pair required at the end, and can be sent as-is.
- abstract run_forever() None #
Run the backend forever (blocking call).
This method is responsible for initiating the connection to the server, and it must call
bot.on_connect
once connected, orbot.on_close
if it fails to connect.Upon successful connection, it must run forever, listening to the server and allowing the bot to use
send_command()
in a thread-safe way.
- send_command(*args: str, text: str | None = None) None #
Send a command through the IRC connection.
- Parameters:
args – IRC command to send with its argument(s)
text – the text to send (optional keyword argument)
Example:
# send the INFO command backend.send_command('INFO') # send the NICK command with the argument 'Sopel' backend.send_command('NICK', 'Sopel') # send the PRIVMSG command to channel #sopel with some text backend.send_command('PRIVMSG', '#sopel', text='Hello world!')
Note
This will call the
sopel.bot.Sopel.on_message_sent()
callback on the bot instance with the raw message sent.
- send_join(channel: str, password: str | None = None) None #
Send a
JOIN
command tochannel
with optionalpassword
.- Parameters:
channel – channel to join
password – optional password for protected channels
- send_kick( ) None #
Send a
KICK
command fornick
inchannel
.- Parameters:
channel – the channel from which to kick
nick
nick – nickname to kick from the
channel
reason – optional reason for the kick
- send_part(channel: str, reason: str | None = None) None #
Send a
PART
command tochannel
.- Parameters:
channel – the channel to part
text – optional text for leaving the channel
- send_pass(password: str) None #
Send a
PASS
command with apassword
.- Parameters:
password – password for authentication
- send_ping(host: str) None #
Send a
PING
command to the server.- Parameters:
host – IRC server host
A
PING
command should be sent at a regular interval to make sure the server knows the IRC connection is still active.
- send_pong(host: str) None #
Send a
PONG
command to the server.- Parameters:
host – IRC server host
A
PONG
command must be sent each time the server sends aPING
command to the client.
- send_privmsg(dest: str, text: str) None #
Send a
PRIVMSG
command todest
withtext
.- Parameters:
dest – nickname or channel name
text – the text to send
sopel.irc.backends#
sopel.irc.backends
defines Sopel’s IRC connection handlers.
Warning
This is all internal code, not intended for direct use by plugins. It is subject to change between versions, even patch releases, without any advance warning.
Please use the public APIs on bot
.
- class sopel.irc.backends.AsyncioBackend(
- bot: AbstractBot,
- host: str,
- port: int,
- source_address: tuple[str, int] | None,
- server_timeout: int | None = None,
- ping_interval: int | None = None,
- use_ssl: bool = False,
- certfile: str | None = None,
- keyfile: str | None = None,
- verify_ssl: bool = True,
- ca_certs: str | None = None,
- ssl_ciphers: list[str] | None = None,
- ssl_minimum_version: ssl.TLSVersion = ssl.TLSVersion.TLSv1_2,
- **kwargs,
Bases:
AbstractIRCBackend
IRC Backend implementation using
asyncio
.- Parameters:
bot – an instance of a bot that uses the backend
host – hostname/IP to connect to
port – port to connect to
source_address – optional source address as a tuple of
(host, port)
server_timeout – optional time (in seconds) before the backend reach a timeout (defaults to 120s)
ping_interval – optional ping interval (in seconds) between last message received and sending a PING to the server (defaults to
server_timeout * 0.45
)use_ssl – if the connection must use SSL/TLS or not
certfile – optional location of the certificates; used when
use_ssl
isTrue
keyfile – optional location to the key file for certificates; used when
use_ssl
isTrue
andcertfile
is notNone
verify_ssl – if the certificates must be verified; ignored if
use_ssl
is notTrue
ca_certs – optional location to the CA certificates; ignored if
verify_ssl
isFalse
ssl_ciphers – the OpenSSL cipher suites to use
ssl_minimum_version – the lowest SSL/TLS version to accept
- irc_send(data: bytes) None #
Send an IRC line as raw
data
.- Parameters:
data (bytes) – raw line to send
This method must be thread-safe.
- on_irc_error(pretrigger: PreTrigger) None #
Action to perform when the server sends an error event.
- Parameters:
pretrigger – PreTrigger object with the error event
On IRC error, if
bot.hasquit
is set, the backend should close the connection so the bot can quit or reconnect as required.
- async read_forever() None #
Main reading loop of the backend.
This listens to the reader for an incoming IRC line, decodes the data, and passes it to
bot.on_message(data)
, until the reader reaches the EOF (i.e. connection closed).It manages connection timeouts by scheduling two tasks:
a PING task, that will send a PING to the server as defined by the ping interval (from the configuration)
a Timeout task, that will stop the bot if it reaches the timeout
Whenever a message is received, both tasks are cancelled and rescheduled.
When the connection is closed, the reader will reach EOF, and return an empty string, which in turn will end the coroutine.
See also
The
decode_line()
method is used to decode the IRC line frombytes
tostr
.
- class sopel.irc.backends.UninitializedBackend(bot: AbstractBot)#
Bases:
AbstractIRCBackend
IRC Backend shim to use before the bot has started connecting.
- Parameters:
bot – an instance of a bot that uses the backend
This exists to intercept attempts to do “illegal” things before connection, like sending messages to IRC before we even have a socket.
- irc_send(data: bytes) None #
Dummy method to send IRC data.
Since it is impossible to send data to IRC without an IRC connection, this implementation raises an error if it is ever called.
Note
Plugins will likely never need to call this method directly, but many public API methods of
bot
call it.Plugin code that can be triggered by anything that isn’t an IRC event/message should check the
bot.connection_registered
flag before calling any bot method that modifies IRC state.
- is_connected() bool #
Check if the backend is connected to an IRC server.
Always returns False: This backend type is never connected.
Jobs (
interval()
) or other time-based triggers can be invoked before the bot is finished initizalizing, even before it has begun the IRC connection process. We need to provide a reliable way for those triggers to abort early if they need a connection.Note
Your plugin code doesn’t need to call this directly; unless your plugin does something during connection setup, it should check the
bot.connection_registered
flag, which also takes into account whether the IRC connection is ready to accept normal commands like PRIVMSG.
- on_irc_error(pretrigger: PreTrigger) None #
Dummy IRC error handler.
Since it should be impossible to receive an error from IRC when there is no server connection, this implementation raises an error if it is ever called.