bot

package module
v0.0.0-...-2e5e40a Latest Latest
Warning

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

Go to latest
Published: Apr 21, 2023 License: MIT Imports: 12 Imported by: 0

README

go-bot

Circle CI GoDoc Coverage Status Go report Reviewed by Hound

IRC, Slack & Telegram bot written in Go using go-ircevent for IRC connectivity, nlopes/slack for Slack and Syfaro/telegram-bot-api for Telegram.

2016-01-17 11 21 38 036

Plugins

Please see the plugins repository for a complete list of plugins.

You can also write your own, it's really simple.

Compiling and testing the bot and plugins (Debug)

This project uses the new Go 1.11 modules if you have Go 1.11 installed, just clone the project and follow the instructions bellow, when you build Go will automatically download all dependencies.

To test the bot, use the debug console app.

  • Clone this repository or use go get github.com/go-chat-bot/bot
  • Build everything: go build ./...
  • Build and execute the debug app:
    • cd debug
    • go build
    • ./debug
  • This will open a console where you can type commands
  • Type !help to see the list of available commands
Testing your plugin
  • Add your plugin to debug/main.go import list
  • Build the debug app
  • Execute it and test with the interactive console

Protocols

Slack

To deploy your go-bot to Slack, you need to:

  • Create a new bot user integration on Slack and get your token
  • Import the package github.com/go-chat-bot/bot/slack
  • Import the commands you would like to use
  • Call slack.Run(token)

Here is a full example reading the Slack token from the SLACK_TOKEN env var:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/slack"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
    // Import all the commands you wish to use
)

func main() {
    slack.Run(os.Getenv("SLACK_TOKEN"))
}
IRC

To deploy your own go-bot to IRC, you need to:

  • Import the package github.com/go-chat-bot/bot/irc
  • Import the commands you would like to use
  • Fill the Config struct
  • Call irc.Run(config)

Here is a full example:

package main

import (
	"github.com/go-chat-bot/bot/irc"
	_ "github.com/go-chat-bot/plugins/catfacts"
	_ "github.com/go-chat-bot/plugins/catgif"
	_ "github.com/go-chat-bot/plugins/chucknorris"
	// Import all the commands you wish to use
	"os"
	"strings"
)

func main() {
	irc.Run(&irc.Config{
		Server:   os.Getenv("IRC_SERVER"),
		Channels: strings.Split(os.Getenv("IRC_CHANNELS"), ","),
		User:     os.Getenv("IRC_USER"),
		Nick:     os.Getenv("IRC_NICK"),
		Password: os.Getenv("IRC_PASSWORD"),
		UseTLS:   true,
		Debug:    os.Getenv("DEBUG") != "",})
}

To join channels with passwords just put the password after the channel name separated by a space:

Channels: []string{"#mychannel mypassword", "#go-bot"}
Telegram

To deploy your go-bot to Telegram, you need to:

  • Follow Telegram instructions to create a new bot user and get your token
  • Import the package github.com/go-chat-bot/bot/telegram
  • Import the commands you would like to use
  • Call telegram.Run(token, debug)

Here is a full example reading the telegram token from the TELEGRAM_TOKEN env var:

package main

import (
    "os"

    "github.com/go-chat-bot/bot/telegram"
    _ "github.com/go-chat-bot/plugins/catfacts"
    _ "github.com/go-chat-bot/plugins/catgif"
    _ "github.com/go-chat-bot/plugins/chucknorris"
    // Import all the commands you wish to use
)

func main() {
    telegram.Run(os.Getenv("TELEGRAM_TOKEN"), os.Getenv("DEBUG") != "")
}
Rocket.chat

To deploy your go-bot to Rocket.chat, you need to:

  • Import the package github.com/go-chat-bot/bot/rocket
  • Import the commands you would like to use
  • Call rocket.Run(config)

Here is a full example:

package main

import (
	"os"

	"github.com/go-chat-bot/bot/rocket"
	_ "github.com/go-chat-bot/plugins/godoc"
	_ "github.com/go-chat-bot/plugins/catfacts"
	_ "github.com/go-chat-bot/plugins/catgif"
	_ "github.com/go-chat-bot/plugins/chucknorris"
)

func main() {
	config := &rocket.Config{
		Server:   os.Getenv("ROCKET_SERVER"),
		Port:     os.Getenv("ROCKET_PORT"),
		User:     os.Getenv("ROCKET_USER"),
		Email:    os.Getenv("ROCKET_EMAIL"),
		Password: os.Getenv("ROCKET_PASSWORD"),
		UseTLS:   false,
		Debug:    os.Getenv("DEBUG") != "",
	}
	rocket.Run(config)
}
Google Chat

To deploy your go-bot to Google Chat (also known as Hangouts Chat, not plain Hangouts) you will first need to follow documentation to setup pub/sub project in Google Cloud. This will enable your bot to receive messages even when it is behind a firewall.

Condensed, the steps you will need to take are as follows:

  • Create new project in google cloud console
    • ID of the project will be used in Config.PubSubProject
  • Create service credentials for this project
    • Path to downloaded credentials file should be in env variable GOOGLE_APPLICATION_CREDENTIALS
    • Choose "Pub/Sub Editor" role for the credential
  • Enable Pub/Sub API in cloud console
  • Create new topic in the Pub/Sub (say "google-chat")
    • Use the value of "Topic Name" (not "Topic ID") for Config.TopicName (e.g. /project/<proj_name>/topics/<topic_name>)
  • Modify permissions on created topic so that "chat-api-push@system.gserviceaccount.com" has Pub/Sub Publisher permissions
  • Enable hangouts chat api in Cloud Console
  • Go to hangouts chat API config in the Cloud Console and fill in info
    • Connection settings - use Pub/Sub and fill in topic string you created above

Config.SubscriptionName should be unique for each environment or you'll not process messages correctly. If you encounter issues make sure your credentials are correct and permissions for topics/queues are set up correctly.

Config.WelcomeMessage is sent each time the bot joins a new room or private chat.

Full example is here:

package main

import (
	"os"

	"github.com/go-chat-bot/bot/google-chat"
	_ "github.com/go-chat-bot/plugins/godoc"
	_ "github.com/go-chat-bot/plugins/catfacts"
	_ "github.com/go-chat-bot/plugins/catgif"
	_ "github.com/go-chat-bot/plugins/chucknorris"
)

func main() {
	googlechat.Run(&googlechat.Config{
		PubSubProject:    os.Getenv("HANGOUTS_PROJECT"),
		TopicName:        os.Getenv("HANGOUTS_TOPIC"),
		SubscriptionName: os.Getenv("HANGOUTS_SUB"),
		WelcomeMessage:   os.Getenv("HANGOUTS_WELCOME"),
}

Deploying your own bot

To see an example project on how to deploy your bot, please see my own configuration:

Documentation

Overview

Package bot provides a simple to use IRC, Slack and Telegram bot

Index

Constants

View Source
const (
	// CmdPrefix is the prefix used to identify a command.
	// !hello would be identified as a command
	CmdPrefix = "!"

	// MsgBuffer is the max number of messages which can be buffered
	// while waiting to flush them to the chat service.
	MsgBuffer = 100
)

Variables

View Source
var (
	// ErrProtocolServerMismatch server && proto must match
	ErrProtocolServerMismatch = errors.New("the specified protocol and server do not correspond to this bot instance")
)

Functions

func RegisterCommand

func RegisterCommand(command, description, exampleArgs string, cmdFunc activeCmdFuncV1)

RegisterCommand adds a new command to the bot. The command(s) should be registered in the Init() func of your package command: String which the user will use to execute the command, example: reverse decription: Description of the command to use in !help, example: Reverses a string exampleArgs: Example args to be displayed in !help <command>, example: string to be reversed cmdFunc: Function which will be executed. It will received a parsed command as a Cmd value

func RegisterCommandV2

func RegisterCommandV2(command, description, exampleArgs string, cmdFunc activeCmdFuncV2)

RegisterCommandV2 adds a new command to the bot. It is the same as RegisterCommand but the command can specify the channel to reply to

func RegisterCommandV3

func RegisterCommandV3(command, description, exampleArgs string, cmdFunc activeCmdFuncV3)

RegisterCommandV3 adds a new command to the bot. It is the same as RegisterCommand but the command return a chan

func RegisterFilterCommand

func RegisterFilterCommand(command string, cmdFunc filterCmdFuncV1)

RegisterFilterCommand adds a command that is run every time bot is about to send a message. The comand should be registered in the Init() func of your package. Filter commands receive message and its destination and should return modified version. Returning empty string prevents message being sent completely command: String used to identify the command, for internal use only (ex: silence) cmdFunc: Function which will be executed. It will receive the message, target channel and nick who triggered original message

func RegisterMessageStream

func RegisterMessageStream(streamName string, msgFunc messageStreamFunc)

RegisterMessageStream adds a new message stream to the bot. The command should be registered in the Init() func of your package MessageStreams send messages to a channel streamName: String used to identify the command, for internal use only (ex: webhook) messageStreamFunc: Function which will be executed. It will received a MessageStream with a chan to push

func RegisterPassiveCommand

func RegisterPassiveCommand(command string, cmdFunc passiveCmdFuncV1)

RegisterPassiveCommand adds a new passive command to the bot. The command should be registered in the Init() func of your package Passive commands receives all the text posted to a channel without any parsing command: String used to identify the command, for internal use only (ex: logs) cmdFunc: Function which will be executed. It will received the raw message, channel and nick

func RegisterPassiveCommandV2

func RegisterPassiveCommandV2(command string, cmdFunc passiveCmdFuncV2)

RegisterPassiveCommandV2 adds a new passive command to the bot. The command should be registered in the Init() func of your package Passive commands receives all the text posted to a channel without any parsing command: String used to identify the command, for internal use only (ex: logs) cmdFunc: Function which will be executed. It will received the raw message, channel and nick

func RegisterPeriodicCommand

func RegisterPeriodicCommand(command string, config PeriodicConfig)

RegisterPeriodicCommand adds a command that is run periodically. The command should be registered in the Init() func of your package config: PeriodicConfig which specify CronSpec and a channel list cmdFunc: A function with single string argument (channel) which gets triggered periodically

func RegisterPeriodicCommandV2

func RegisterPeriodicCommandV2(command string, config PeriodicConfig)

RegisterPeriodicCommandV2 adds a command that is run periodically. The command should be registered in the Init() func of your package config: PeriodicConfig which specifies CronSpec cmdFuncV2: A no-arg function which gets triggered periodically It should return slice of CmdResults (channel and message to send to it)

Types

type Bot

type Bot struct {

	// Protocol and Server are used by MesssageStreams to
	// determine if this is the correct bot to send a message on
	// see:
	// https://github.com/go-chat-bot/bot/issues/37#issuecomment-277661159
	// https://github.com/go-chat-bot/bot/issues/97#issuecomment-442827599
	Protocol string
	// Server and Protocol are used by MesssageStreams to
	// determine if this is the correct bot to send a message on
	// see:
	// https://github.com/go-chat-bot/bot/issues/37#issuecomment-277661159
	// https://github.com/go-chat-bot/bot/issues/97#issuecomment-442827599
	Server string
	// contains filtered or unexported fields
}

Bot handles the bot instance

func New

func New(h *Handlers, bc *Config) *Bot

New configures a new bot instance

func (*Bot) Close

func (b *Bot) Close()

Close will shut down the message sending capabilities of this bot. Call this when you are done using the bot.

func (*Bot) Disable

func (b *Bot) Disable(cmds []string)

Disable allows disabling commands that were registered. It is useful when running multiple bot instances to disabled some plugins like url which is already present on some protocols.

func (*Bot) MessageReceived

func (b *Bot) MessageReceived(channel *ChannelData, message *Message, sender *User)

MessageReceived must be called by the protocol upon receiving a message

func (*Bot) SendMessage

func (b *Bot) SendMessage(om OutgoingMessage)

SendMessage queues a message.

type ChannelData

type ChannelData struct {
	Protocol  string // What protocol the message was sent on (irc, slack, telegram)
	Server    string // The server hostname the message was sent on
	Channel   string // The channel name the message appeared in
	HumanName string // The human readable name of the channel.
	IsPrivate bool   // Whether the channel is a group or private chat
}

ChannelData holds the improved channel info, which includes protocol and server

func (*ChannelData) URI

func (c *ChannelData) URI() string

URI gives back an URI-fied string containing protocol, server and channel.

type Cmd

type Cmd struct {
	Raw         string       // Raw is full string passed to the command
	Channel     string       // Channel where the command was called
	ChannelData *ChannelData // More info about the channel, including network
	User        *User        // User who sent the message
	Message     string       // Full string without the prefix
	MessageData *Message     // Message with extra flags
	Command     string       // Command is the first argument passed to the bot
	RawArgs     string       // Raw arguments after the command
	Args        []string     // Arguments as array
}

Cmd holds the parsed user's input for easier handling of commands

type CmdResult

type CmdResult struct {
	Channel     string // The channel where the bot should send the message
	Message     string // The message to be sent
	ProtoParams interface{}
}

CmdResult is the result message of V2 commands

type CmdResultV3

type CmdResultV3 struct {
	Channel     string
	Message     chan string
	Done        chan bool
	ProtoParams interface{}
}

CmdResultV3 is the result message of V3 commands

type Config

type Config struct {
	// Protocol and Server are used by MesssageStreams to
	/// determine if this is the correct bot to send a message on
	Protocol string
	// Server and Protocol are used by MesssageStreams to
	// determine if this is the correct bot to send a message on
	Server string
}

Config configuration for this Bot instance

type ErrorHandler

type ErrorHandler func(msg string, err error)

ErrorHandler will be called when an error happens

type FilterCmd

type FilterCmd struct {
	Target  string // Channel or user the message is being sent to
	Message string // Message text being sent
	User    *User  // User who triggered original message
}

FilterCmd holds information about what is output being filtered - message and channel where it is being sent

type Handlers

type Handlers struct {
	Response   ResponseHandler
	ResponseV2 ResponseHandlerV2
	Errored    ErrorHandler
}

Handlers that must be registered to receive callbacks from the bot

type Message

type Message struct {
	Text     string      // The actual content of this Message
	IsAction bool        // True if this was a '/me does something' message
	ProtoMsg interface{} // The underlying object that we got from the protocol pkg
}

Message holds the message info - for IRC and Slack networks, this can include whether the message was an action.

type MessageStream

type MessageStream struct {
	Data chan MessageStreamMessage
	// Done is almost never called, usually the bot should just leave the chan open
	Done chan bool
}

MessageStream allows event information to be transmitted to an arbitrary channel https://github.com/go-chat-bot/bot/issues/97

type MessageStreamMessage

type MessageStreamMessage struct {
	Message     string
	ChannelData *ChannelData
}

MessageStreamMessage the actual Message passed back to MessageStream in a chan

type OutgoingMessage

type OutgoingMessage struct {
	Target      string
	Message     string
	Sender      *User
	ProtoParams interface{}
}

OutgoingMessage collects all the information for a message to go out.

type PassiveCmd

type PassiveCmd struct {
	Raw         string       // Raw message sent to the channel
	MessageData *Message     // Message with extra
	Channel     string       // Channel which the message was sent to
	ChannelData *ChannelData // Channel and network info
	User        *User        // User who sent this message
}

PassiveCmd holds the information which will be passed to passive commands when receiving a message

type PeriodicConfig

type PeriodicConfig struct {
	Version   int
	CronSpec  string                               // CronSpec that schedules some function
	Channels  []string                             // A list of channels to notify, ignored for V2
	CmdFunc   func(channel string) (string, error) // func to be executed at the period specified on CronSpec
	CmdFuncV2 func() ([]CmdResult, error)          // func v2 to be executed at the period specified on CronSpec
}

PeriodicConfig holds a cron specification for periodically notifying the configured channels

type ResponseHandler

type ResponseHandler func(target, message string, sender *User)

ResponseHandler must be implemented by the protocol to handle the bot responses

type ResponseHandlerV2

type ResponseHandlerV2 func(OutgoingMessage)

ResponseHandlerV2 may be implemented by the protocol to handle the bot responses

type User

type User struct {
	ID       string
	Nick     string
	RealName string
	IsBot    bool
}

User holds user id, nick and real name

Directories

Path Synopsis
Package irc implements IRC handlers for github.com/go-chat-bot/bot
Package irc implements IRC handlers for github.com/go-chat-bot/bot
Package nostr implements Nostr handlers for github.com/go-chat-bot/bot
Package nostr implements Nostr handlers for github.com/go-chat-bot/bot
Package slack implements Slack handlers for github.com/go-chat-bot/bot
Package slack implements Slack handlers for github.com/go-chat-bot/bot
Package telegram implements Telegram handlers for github.com/go-chat-bot/bot
Package telegram implements Telegram handlers for github.com/go-chat-bot/bot

Jump to

Keyboard shortcuts

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