Search code examples
pythonhyperlinkbotsirc

Python IRC Bot link resolver?


So I haven't been able to find a bunch of information on the subject, but I'm looking for an example to resolve a given link when it is posted to the IRC channel. Any tips/examples?


Solution

  • I wrote a quick example that does exactly what you're after.

    Feel free to use this as a basis for your needs!

    #!/usr/bin/env python
    
    from re import findall
    
    from circuits import Component
    from circuits.ne t.events import connect
    from circuits.net.sockets import TCPClient
    from circuits.protocols.irc import ERR_NICKNAMEINUSE
    from circuits.protocols.irc import RPL_ENDOFMOTD, ERR_NOMOTD
    from circuits.protocols.irc import IRC, PRIVMSG, USER, NICK, JOIN
    
    from requests import get
    from lxml.html import fromstring
    
    
    class Bot(Component):
    
        def init(self, host, port=6667):
            self.host = host
            self.port = port
    
            TCPClient().register(self)
            IRC().register(self)
    
        def ready(self, component):
            self.fire(connect(self.host, self.port))
    
        def connected(self, host, port):
            self.fire(USER("circuits", host, host, "Test circuits IRC Bot"))
            self.fire(NICK("circuits"))
    
        def numeric(self, source, target, numeric, args, message):
            if numeric == ERR_NICKNAMEINUSE:
                self.fire(NICK("%s_" % args))
            if numeric in (RPL_ENDOFMOTD, ERR_NOMOTD):
                self.fire(JOIN("#circuits"))
    
        def message(self, source, target, message):
            if target[0] == "#":
                urls = findall("http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+", message)  # noqa
                if urls:
                    url = urls[0]
                    response = get(url)
                    if response.status_code == 200:
                        doc = fromstring(response.text)
                        title = doc.cssselect("title")
                        if title:
                            title = title[0].text.strip()
                            self.fire(
                                PRIVMSG(
                                    target,
                                    "URL: {0:s} Title: {1:s}".format(
                                        url,
                                        title
                                    )
                                )
                            )
            else:
                self.fire(PRIVMSG(source[0], message))
    
    
    bot = Bot("irc.freenode.net")
    
    bot.run()
    

    You will need:

    You can install these via:

    pip install circuits cssselect lxml requests
    

    Disclaimer: I'm the developer of circuits

    Updated: Tested to be working as expected.