kitty

package module
v0.0.41 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 4, 2022 License: MIT Imports: 16 Imported by: 1

README

KittyBot

GoDoc

Hard fork of github.com/whyrusleeping/hellabot

kittybot

Kitten approved Internet Relay Chat (IRC) bot. KittyBot is an easily hackable event based IRC bot framework with the ability to be updated without losing connection to the server. To respond to an event, simply create a "Trigger" struct containing two functions, one for the condition, and one for the action.

Warning

We are at v0.0.X, the API may change without warning!!!

Example Trigger

var myTrigger = kitty.Trigger{
    Condition: func(bot *kitty.Bot, m *kitty.Message) bool {
        return m.From == "ugjka"
    },
    Action: func(bot *kitty.Bot, m *kitty.Message) {
        bot.Reply(m, "ugjka said something")
    },
}

The trigger makes the bot announce to everyone that something was said in the current channel. Use the code snippet below to make the bot and add the trigger.

bot, err := kitty.NewBot("irc.freenode.net:6667","kittybot")
if err != nil {
    panic(err)
}
bot.AddTrigger(MyTrigger)
bot.Run() // Blocks until exit

The 'To' field on the message object in triggers will refer to the channel that a given message is in, unless it is a server message, or a user to user private message. In such cases, the field will be the target user's name.

For more example triggers, check the examples directory.

The Message struct

The message struct is primarily what you will be dealing with when building triggers or reading off the Incoming channel. This is mainly the ircmsg.Message struct with some additions. See https://github.com/ugjka/ircmsg/blob/master/message.go#L221

 // Message represents a message received from the server
 type Message struct {
     // ircmsg.Message with extended data, like GetTag() for IRCv3 tags
     *ircmsg.Message
     // Content generally refers to the text of a PRIVMSG
     Content string

     //Time at which this message was recieved
     TimeStamp time.Time

     // Entity that this message was addressed to (channel or user)
     To string

     // Nick of the messages sender (equivalent to Prefix.Name)
     // Outdated, please use .Name
     From string
 }

Connection Passing

KittyBot is able to restart without dropping its connection to the server (on Linux machines, and BSD flavours) by passing the TCP connection through a UNIX domain socket. This allows you to update triggers and other addons without actually logging your bot out of the IRC, avoiding the loss of op status and spamming the channel with constant join/part messages. To do this, run the program again with the same nick and without killing the first program (different nicks wont reuse the same bot instance). The first program will shutdown, and the new one will take over.

**This does not work with SSL connections, because we can't hand over a SSL connections state.**

Security

KittyBot supports both SSL and SASL for secure connections to whichever server you like. To enable SSL, pass the following option to the NewBot function.

sslOptions := func(bot *kitty.Bot) {
    bot.SSL = true
}

bot, err := kitty.NewBot("irc.freenode.net:6667","kittybot",sslOptions)
// Handle err as you like

bot.Run() # Blocks until disconnect.

To use SASL to authenticate with the server:

saslOption = func(bot *kitty.Bot) {
    bot.SASL = true
    bot.Password = "somepassword"
}

bot, err := kitty.NewBot("irc.freenode.net:6667", "kittybot", saslOption)
// Handle err as you like

bot.Run() # Blocks until disconnect.

Note: SASL does not require SSL but can be used in combination.

Passwords

For servers that require passwords in the initial registration, simply set the Password field of the Bot struct before calling its Start method.

Debugging

Hellabot uses github.com/inconshreveable/log15 for logging. See http://godoc.org/github.com/inconshreveable/log15

By default it discards all logs. In order to see any logs, give it a better handler. Example: This would only show INFO level and above logs, logging to STDOUT

import log "gopkg.in/inconshreveable/log15.v2"

logHandler := log.LvlFilterHandler(log.LvlInfo, log.StdoutHandler)
bot.Logger.SetHandler(logHandler)

Note: This might be revisited in the future.

Why

What do you need an IRC bot for you ask? Well, I've gone through the trouble of compiling a list of fun things for you! The following are some of the things KittyBot is currently being used for:

  • AutoOp Bot: ops you when you join the channel
  • Stats counting bot: counts how often people talk in a channel
  • Mock users you don't like by repeating what they say
  • Fire a USB dart launcher on a given command
  • Control an MPD radio stream based on chat commands
  • Award praise to people for guessing a random number
  • Scrape news sites for relevant articles and send them to a channel
  • And many other 'fun' things!

References

Client Protocol, RFC 2812 SASL Authentication Documentation IRCv3 Documentation

Contributors before the hard fork

Documentation

Overview

Package kitty is IRCv3 enabled framework for writing IRC bots

Index

Constants

View Source
const CapAccountNotify = "account-notify"

CapAccountNotify is account-notify CAP

View Source
const CapAccountTag = "account-tag"

CapAccountTag is account-tag CAP

View Source
const CapAwayNotify = "away-notify"

CapAwayNotify is away-notify CAP

View Source
const CapCapNotify = "cap-notify"

CapCapNotify is cap-notify CAP

View Source
const CapChghost = "chghost"

CapChghost is chghost CAP

View Source
const CapExtendedJoin = "extended-join"

CapExtendedJoin is extended-join CAP

View Source
const CapIdentifyMsg = "identify-msg"

CapIdentifyMsg is identify-msg CAP

View Source
const CapInviteNotify = "invite-notify"

CapInviteNotify is invite-notify CAP

View Source
const CapMessageTags = "message-tags"

CapMessageTags is message-tags CAP

View Source
const CapMultiPrefix = "multi-prefix"

CapMultiPrefix is multi-prefix CAP

View Source
const CapSASL = "sasl"

CapSASL is SASL CAP

View Source
const CapServerTime = "server-time"

CapServerTime is server-time CAP

View Source
const CapSetName = "setname"

CapSetName is setname CAP

View Source
const CapTLS = "tls"

CapTLS is tls CAP

View Source
const CapUserhostInNames = "userhost-in-names"

CapUserhostInNames is userhost-in-names CAP

Variables

This section is empty.

Functions

func ReconOpt

func ReconOpt() func(*Bot)

ReconOpt enables session hijacking

func SaslAuth

func SaslAuth(pass string) func(*Bot)

SaslAuth enables SASL authentification

Types

type Bot

type Bot struct {

	// Log15 loggger
	log.Logger

	// Exported fields
	Host          string
	Password      string
	Channels      []string
	SSL           bool
	SASL          bool
	HijackSession bool
	// Set it if long messages get truncated
	// on the receiving end
	MsgSafetyBuffer bool
	// HijackAfterFunc executes in its own goroutine after a succesful session hijack
	// If you need to do something after a hijack
	// for example, to run some irc commands or to restore some state
	HijackAfterFunc func()
	// Fires after joining the channels
	Joined chan struct{}
	// An optional function that connects to an IRC server over plaintext:
	Dial func(network, addr string) (net.Conn, error)
	// An optional function that connects to an IRC server over a secured connection:
	DialTLS func(network, addr string, tlsConf *tls.Config) (*tls.Conn, error)
	// This bots nick
	Nick string

	// Duration to wait between sending of messages to avoid being
	// kicked by the server for flooding (default 200ms)
	ThrottleDelay time.Duration
	// Maxmimum time between incoming data
	PingTimeout time.Duration

	TLSConfig tls.Config
	// contains filtered or unexported fields
}

Bot implements an irc bot to be connected to a given server

func NewBot

func NewBot(host, nick string, options ...func(*Bot)) *Bot

NewBot creates a new instance of Bot

func (*Bot) Action

func (bot *Bot) Action(who, text string)

Action sends an action to 'who' (user or channel)

func (*Bot) AddTrigger

func (bot *Bot) AddTrigger(h Handler)

AddTrigger adds a trigger to the bot's handlers

func (*Bot) CapStatus

func (bot *Bot) CapStatus(cap string) (enabled, present bool)

CapStatus returns whether the server capability is enabled and present

func (*Bot) ChMode

func (bot *Bot) ChMode(user, channel, mode string)

ChMode is used to change users modes in a channel operator = "+o" deop = "-o" ban = "+b"

func (*Bot) Close

func (bot *Bot) Close()

Close closes the bot

func (*Bot) Join

func (bot *Bot) Join(ch string)

Join a channel

func (*Bot) Msg

func (bot *Bot) Msg(who, text string)

Msg sends a message to 'who' (user or channel)

func (*Bot) MsgMaxSize

func (bot *Bot) MsgMaxSize(who string) int

MsgMaxSize returns maximum number of bytes that fit into one message. Useful, for example, if you want to generate a wall of emojis that fit into one message, or you want to cap some output to one message

func (*Bot) Notice

func (bot *Bot) Notice(who, text string)

Notice sends a NOTICE message to 'who' (user or channel)

func (*Bot) NoticeMaxSize

func (bot *Bot) NoticeMaxSize(who string) int

NoticeMaxSize returns maximum number of bytes that fit into one message. Useful, for example, if you want to generate a wall of emojis that fit into one message, or you want to cap some output to one message

func (*Bot) Part

func (bot *Bot) Part(ch, msg string)

Part a channel

func (*Bot) Prefix

func (bot *Bot) Prefix() *ircmsg.Prefix

Prefix returns the bot's own prefix. Can be useful if for example you want to make an emoji wall that fits into one message perfectly

func (*Bot) PrefixChange

func (bot *Bot) PrefixChange(name, user, host string)

PrefixChange changes bot's prefix, use empty strings to make no change

func (*Bot) Reply

func (bot *Bot) Reply(m *Message, text string)

Reply sends a message to where the message came from (user or channel)

func (*Bot) ReplyMaxSize

func (bot *Bot) ReplyMaxSize(m *Message) int

ReplyMaxSize is just like MsgMaxSize but calculates message size for the reply target

func (*Bot) Run

func (bot *Bot) Run() (hijacked bool)

Run starts the bot and connects to the server. Blocks until we disconnect from the server. Returns true if we have been hijacked (if you loop over Run it might be wise to break on hijack to avoid looping between 2 instances).

func (*Bot) Send

func (bot *Bot) Send(command string)

Send any command to the server

func (*Bot) SetNick

func (bot *Bot) SetNick(nick string)

SetNick sets the bots nick on the irc server. This does not alter *Bot.Nick, so be vary of that

func (*Bot) String

func (bot *Bot) String() string

func (*Bot) Topic

func (bot *Bot) Topic(c, topic string)

Topic sets the channel 'c' topic (requires bot has proper permissions)

func (*Bot) Uptime

func (bot *Bot) Uptime() string

Uptime returns the uptime of the bot

type Handler

type Handler interface {
	Handle(*Bot, *Message)
}

Handler is used to subscribe and react to events on the bot Server

type Message

type Message struct {
	// ircmsg.Message with extended data, like GetTag() for IRCv3 tags
	*ircmsg.Message
	// Content generally refers to the text of a PRIVMSG
	Content string

	//Time at which this message was recieved
	TimeStamp time.Time

	// Entity that this message was addressed to (channel or user)
	To string

	// Nick of the messages sender (equivalent to Prefix.Name)
	// Outdated, please use .Name
	From string
}

Message represents a message received from the server

type Trigger

type Trigger struct {
	// Returns true if this trigger applies to the passed in message
	Condition func(*Bot, *Message) bool

	// The action to perform if Condition is true
	Action func(*Bot, *Message)
}

Trigger is a Handler which is guarded by a condition. DO NOT alter *Message in your triggers or you'll have strange things happen.

func (Trigger) Handle

func (t Trigger) Handle(bot *Bot, m *Message)

Handle executes the trigger action if the condition is satisfied

Directories

Path Synopsis
examples
main
This is an example program showing the usage of KittyBot
This is an example program showing the usage of KittyBot

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL