Skip to main content

irc based on asyncio

Project description

Introduction to asyncirc
========================

Asyncirc is an IRC library based on Python's asyncio. It is designed to be easy
to use, to provide a nice way of processing IRC events, and to provide a Good
Enough(TM) abstraction of the IRC protocol. It is *not* designed to be a ready-
made bot framework, or to be used without some knowledge of how IRC works.

Installation
------------
You can install asyncirc from PyPI, using whatever method you prefer. The
package name is ``asyncio-irc``.

Signals
-------
Instead of using callback-style event handler registration, asyncirc uses
*signals*. Signals are provided by the excellent
`Blinker<https://pythonhosted.org/blinker/>`_ library. It would be advisable
to read that page for more information on signals, but the tl;dr is::

# register a signal handler
signal("signal-name").connect(signal_handler_function)

# send a signal
signal("signal-name").send(sender, some="keyword", argu="ments")

Asyncirc defines a lot of signals, which are covered in detail below.

Usage
=====

Actually using asyncirc is pretty simple. First you need to import it::

from asyncirc import irc

Then you need to create a connection::

conn = irc.connect("chat.freenode.net", 6697, use_ssl=True)

You'll need to register with the server::

conn.register("nickname", "ident", "realname (can contain spaces)")

Once you're registered and connected, you'll want to join some channels::

@conn.on("irc-001")
def autojoin_channels():
conn.join(["#channel1", "#channel2"])

Maybe you want to connect some event handlers::

@conn.on("join")
def on_join(message, user, channel):
conn.say(channel, "Hi {}! You're connecting from {}.".format(user.nick, user.host))

Once you're done with that, you need to run the event loop::

import asyncio
asyncio.get_event_loop().run_forever()

Your shiny new IRC client should now connect and do what you told it to!
Congratulations!

Using plugins
-------------
Plugins let you do new stuff with your connection. To use them, you import them
before you initially make the connection::

from asyncirc import irc
import asyncirc.plugins.addressed

conn = irc.connect(...)
...

Plugins usually send new signals, so you want to handle those::

@conn.on("addressed")
def on_addressed(message, user, target, text):
# triggers on "bot_nickname: " or similar
bot.say(target, "{}: You said {} to me!".format(user.nick, text))

Fundamental types
=================

There are a few arguments to your handlers that are instances of specific
classes. Here are those:

``user`` is usually an instance of the ``User`` class, which has some important
attributes:

``User.nick`` contains the nickname of the user

``User.user`` contains the ident of the user

``User.host`` contains the host of the user

``User.hostmask`` contains the full hostmask of the user

Events you can handle
=====================

There are a lot of things that can happen on IRC. As such, there are a lot of
signals that asyncirc generates. Here's a list of some useful ones, with event
handler signatures::

@conn.on("private-message")
def on_private_message(message, user, target, text):
...

@conn.on("public-message")
def on_public_message(message, user, target, text):
...

@conn.on("message")
def on_any_message(message, user, target, text):
...

@conn.on("private-notice")
def on_private_notice(message, user, target, text):
...

@conn.on("public-notice")
def on_public_notice(message, user, target, text):
...

@conn.on("notice")
def on_any_notice(message, user, target, text):
...

@conn.on("join")
def on_join(message, user, channel):
...

@conn.on("part")
def on_join(message, user, channel, reason):
# reason defaults to None if there is no reason
...

@conn.on("quit")
def on_quit(message, user, reason):
...

@conn.on("kick")
def on_kick(message, kicker, kickee, channel, reason):
# kicker is a User object
# kickee is just a nickname
...

@conn.on("nick")
def on_nick_change(message, user, new_nick):
...

These signals are actually sent by the ``core`` plugin, so that's pretty neat.

Just what is that ``message`` handler argument, anyway?
-------------------------------------------------------

``message`` is a special argument. It contains the parsed commands from the IRC
server. It has a few useful attributes:

``message.params`` has the arguments of the command

``message.verb`` has the actual IRC verb

``message.sender`` has the hostmask of the sender

``message`` is especially useful when you want to take care of events that don't
already have a signal attached to them. You can hook into the ``irc`` event, or
the ``irc-verb`` event to handle specific verbs. Handlers for that will take a
single argument ``message``.

Plugins
=======

There are a few plugins packaged with asyncirc. These are documented here.

``asyncirc.plugins.nickserv``
-----------------------------
Sends events when authentication to NickServ succeeds or fails. Automatically
tries to regain your nickname when it is not available (usually doesn't work
unless you've authenticated with SASL).

Events::

@conn.on("nickserv-auth-success")
def auth_success(message_text):
# yay! you're authed to nickserv now.
...

@conn.on("nickserv-auth-fail")
def auth_fail(message_text):
# oh no, you had the wrong password!
# try again or exit!
...

``asyncirc.plugins.sasl``
-------------------------
Handles IRCv3 SASL authentication. After importing, there's a single method call
you need to worry about::

asyncirc.plugins.sasl.auth(account_name, password)

And a single event::

@conn.on("sasl-auth-complete")
def sasl_auth_complete(message):
# yay, you've authenticated with SASL.
...

You probably don't even have to worry about the event. This plugin talks to the
core plugin so that registration is delayed until SASL authentication is done.

``asyncirc.plugins.cap``
------------------------
Handles IRCv3 capability negotiation. There's only one method you need to call
to request a capability once you've imported this plugin::

asyncirc.plugins.cap.request_capability("extended-join") # or whatever

The ``caps-acknowledged`` event will be fired when the server has acknowledged
our request for capabilities. As soon as we know what set of capabilities the
server supports, the ``caps-known`` event is fired.

``asyncirc.plugins.tracking``
-----------------------------
Full state tracking. Some methods::

user = asyncirc.plugins.tracking.get_user(hostmask_or_nick)
chan = asyncirc.plugins.tracking.get_channel(channel_name)

Based on that, here's some stuff you can do::

chan.users # a list of nicknames in the channel
user.channels # a list of channels that the user is in
user.account # the user's services account name. works best if you've
# requested the extended-join and account-notify capabilities
chan.mode # return the channel's mode string
user.previous_nicks # return the user's previous nicknames that we know of

How it actually works is really complicated. Don't even ask.

``asyncirc.plugins.addressed``
------------------------------
It has an event that fires when someone mentions your bot by name in IRC::

@conn.on("addressed")
def on_me_addressed(message, user, target, text):
# text contains the text without the "your_bot: " part
...

You can also register command characters that can be used instead of your bot's
nickname::

asyncirc.plugins.addressed.register_command_character(";;")

Questions? Issues? Just want to chat?
=====================================

I'm fwilson on freenode, if you have any questions. I hang out in
``#watchtower`` along with the rest of the Watchtower dev team. Feel free to
join us!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

asyncio-irc-0.2.0.tar.gz (5.3 kB view hashes)

Uploaded Source

Built Distribution

asyncio-irc-0.2.0.linux-x86_64.tar.gz (13.2 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page