gophirc

package module
v0.0.0-...-63edbfe Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2017 License: AGPL-3.0 Imports: 10 Imported by: 2

README

GoDoc Go Report Card Build Status gophirc version Twitter URL

gophirc

A simple IRC bot framework written from scratch, in Go.

Description

Event based IRC framework.

Warning

The API might break anytime.

Framework managed events

  • Manages server PING requests (not CTCP PING)
  • Registers on first NOTICE *
  • Identifies on RPL_WELCOME (event 001)
  • Joins the received invites & sends a greeting to the channel
  • Logs if the bot gets kicked from a channel

Features

  • Capability to connect to multiple servers
  • Multiple per event callbacks
  • State & general logging
  • Graceful exit handled either by a SIGINT (Ctrl-C)
  • Parses a user from an IRC formatted nick!user@host to a User{}
  • Config implements a basic checking on values
  • Already implemented basic commands - JOIN, PART, PRIVMSG, NOTICE, KICK, INVITE, MODE, CTCP commands
  • Many (?) more

Events & callbacks

An event follows the next schema:

type Event struct {
    Raw       string   // the whole raw line
    Code      string   // the reply code
    Source    string   // the source of the event (server, user)
    Arguments []string // the arguments after the event code

    User    *User  // if we can parse a user from the source, add the parsed user here
    Message string // if it's a PRIVMSG, add the message here
    ReplyTo string // if it's a PRIVMSG, add the recipient here (user or channel)
}

You can set callbacks for, technically, all events - numeric reply codes (e.g. "001", "900", etc.) or alpha codes (e.g. "NOTICE", "INVITE", etc.).

Note: CTCP events will have the code set to the corresponding CTCP action, not PRIVMSG.

The framework already binds callbacks for:

  • 001 - to identify with NickServ
  • 900 - to join the channels specified in config
  • NOTICE - only the first event, in order to register with the network
  • INVITE - joins the channel & greets

Examples

Setting up a simple config:

{
  "servers": {
    "first": {
      "address": "irc.server.tld",
      "port": 6667,
      "nickname": "gophirc",
      "nickserv_password": "my_nick_pass",
      "channels": [
        "#my_chan"
      ],
      "admins": [
        "my_nickname"
      ]
    }
  }
}

Note: a full config example can be found in the config/config.json.example file.

Setting a simple bot:

package main

import (
    "sync"
    "github.com/vlad-s/gophirc"
    "github.com/vlad-s/gophirc/config"
)

func main() {
    var wg sync.WaitGroup
    conf, _ := config.Parse("config.json")
    irc := gophirc.New(conf.Servers["name"], &wg)
    irc.Connect()
    irc.Loop()
}

Note: error handling remains an exercise for the reader

Setting up a callback to respond to a CTCP VERSION:

irc.AddEventCallback("VERSION", func(e *gophirc.Event) {
    irc.Notice(e.User.Nick, "\001My own Go bot!\001")
})

Setting up a callback to check for custom messages:

irc.AddEventCallback("PRIVMSG", func(e *gophirc.Event) {
    replyTo := e.Arguments[0]
    message := strings.Join(e.Arguments[1:], " ")[1:]

    switch message {
    case "shrug":
        irc.PrivMsg(replyTo, `¯\_(ツ)_/¯`)
    }
})

For more examples on usage, please see gophircbot.

To do

  • Add tests
    • Config
    • User
    • Logger
    • Helpers
    • IRC
    • commands
  • Add defaults
    • Nickname, Username, Realname
  • Parse CTCP messages into events
  • Add more commands: MODE, KICK, etc.
  • Add regex matching for nicknames, channels
  • Connect Multiple servers
  • Add ignored users

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsCTCP

func IsCTCP(s string) bool

IsCTCP returns whether a string is a CTCP action based on the 0x01 flag.

func IsChannel

func IsChannel(s string) bool

IsChannel returns whether a string is a channel or not.

Types

type Event

type Event struct {
	Raw       string   // Raw line received from the server
	Code      string   // Event code received or parsed from a CTCP message
	Source    string   // Source of the event, user or server
	Arguments []string // Arguments of the event

	User    *User  // If the source is a user, parse it & store it
	Message string // If the event is a PRIVMSG, store the message here
	ReplyTo string // Store the user or the channel to reply to
}

Event contains the raw event received from the server along with the parsed data. The framework parses CTCP messages as event, changing the Code to the CTCP action received. In case we receive an event from a user (and not the server), we parse it and store it into the `User` variable.

type IRC

type IRC struct {
	Server *config.Server

	State  State
	Events map[string][]func(*Event)

	Waiter *sync.WaitGroup
	// contains filtered or unexported fields
}

IRC is the main structure containing the connection, server, state, event callbacks, etc.

func New

func New(server *config.Server, wg *sync.WaitGroup) *IRC

New returns a pointer to a new IRC struct using the server & wait group specified.

func (*IRC) Action

func (irc *IRC) Action(replyTo, message string)

Action sends a PRIVMSG command to the server, mimicking the "/me" in IRC clients.

func (*IRC) AddEventCallback

func (irc *IRC) AddEventCallback(code string, cb func(*Event)) *IRC

AddEventCallback adds a callback function to the Events map on the specified reply code.

func (*IRC) Ban

func (irc *IRC) Ban(channel, nick string)

Ban sends a MODE +b command to the server, requesting to ban <nick> on <channel>.

func (*IRC) CTCP

func (irc *IRC) CTCP(replyTo, ctcp, message string)

CTCP sends a notice to the server, with CTCP flag 0x01 appended & prepended.

func (*IRC) Connect

func (irc *IRC) Connect() error

Connect tries to connect to the server with the address & port specified in the config. It has a 5 second timeout on the dialing.

func (*IRC) Disconnect

func (irc *IRC) Disconnect(s string)

Disconnect sends a QUIT command to the server, and closes the connection.

func (*IRC) Identify

func (irc *IRC) Identify()

Identify sends the NickServ identify command to the server.

func (*IRC) Invite

func (irc *IRC) Invite(nick, channel string)

Invite sends an INVITE command to the server, requesting to invite <nick> to <channel>.

func (*IRC) IsAdmin

func (irc *IRC) IsAdmin(u *User) bool

IsAdmin returns whether or not the specified user is an admin.

func (*IRC) IsIgnored

func (irc *IRC) IsIgnored(u *User) bool

IsIgnored returns whether or not the specified user is ignored.

func (*IRC) Join

func (irc *IRC) Join(channel string)

Join sends a JOIN command to the server, requesting to join <channel>.

func (*IRC) Kick

func (irc *IRC) Kick(channel, nick, message string)

Kick sends a KICK command to the server, requesting to kick <nick> from <channel> using <message>.

func (*IRC) KickBan

func (irc *IRC) KickBan(channel, nick string)

KickBan bans the user and then kicks him from the channel.

func (*IRC) Loop

func (irc *IRC) Loop()

Loop keeps the connection active, getting the raw text from the server. It also handles the quitting & debug logging.

func (*IRC) Mode

func (irc *IRC) Mode(channel, mode, nick string)

Mode sends a MODE command to the server, requesting to set/unset mode <mode> on <nick> on <channel>.

func (*IRC) Nick

func (irc *IRC) Nick(nick string)

Nick sends a NICK command to the server, requesting to change the current nick into <nick>.

func (*IRC) Notice

func (irc *IRC) Notice(replyTo, message string)

Notice sends a NOTICE command to the server.

func (*IRC) ParseToEvent

func (irc *IRC) ParseToEvent(raw string) (event *Event, ok bool)

ParseToEvent reads and parses a raw string to an Event struct.

func (*IRC) Part

func (irc *IRC) Part(channel string)

Part sents a PART command to the server, requesting to part <channel>.

func (*IRC) PrivMsg

func (irc *IRC) PrivMsg(replyTo, message string)

PrivMsg sends a PRIVMSG command to the server.

func (*IRC) PrivMsgf

func (irc *IRC) PrivMsgf(replyTo, format string, args ...interface{})

PrivMsgf is simply a wrapper for Privmsg & fmt.Sprintf.

func (*IRC) Quit

func (irc *IRC) Quit()

Quit provides a wrapper to sending a value into the `quit` channel.

func (*IRC) ReadEvent

func (irc *IRC) ReadEvent(raw string)

ReadEvent reads a parsed Event, calls the callbacks defined, and adds some basic logging.

func (*IRC) Register

func (irc *IRC) Register()

Register sends the USER and NICK commands to the server, and sets the registered state.

func (*IRC) SendRaw

func (irc *IRC) SendRaw(s string)

SendRaw sends a raw string back to the server, appending a CR LF. It automatically strips carriage returns and line feeds from the string.

func (*IRC) SendRawf

func (irc *IRC) SendRawf(format string, args ...interface{})

SendRawf is simply a wrapper for SendRaw & fmt.Sprintf.

func (*IRC) Unban

func (irc *IRC) Unban(channel, nick string)

Unban sends a MODE -b command to the server, requesting to unban <nick> on <channel>.

type State

type State struct {
	Registered   bool
	Disconnected struct {
		Value     bool
		Requested bool
	}
}

State keeps track of the framework's states, as the name implies.

type User

type User struct {
	Nick string
	User string
	Host string
}

User stores the nick, user, and host of a user parsed from an event.

func ParseUser

func ParseUser(user string) (*User, bool)

ParseUser splits a "nick!user@host" raw user into a User struct, containing the nickname, username, and hostname.

func (*User) String

func (u *User) String() string

String returns "nick!user@host".

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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