\input texinfo  @c -*- texinfo -*-
@c %**start of header
@setfilename bobot++.info
@settitle Bobot++: A Schemeable IRC Bot
@setchapternewpage on
@c %**end of header

@ifinfo
This file documents Bobot++ by Clinton Ebadi and Etienne Bernard
(The original author who no longer works on the program).

Copyright 2002,2004,2005 Clinton Ebadi

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.

@end ifinfo

@titlepage
@title Bobot++: A Schemeable IRC Bot
@author Clinton Ebadi

@page
@vskip 0pt plus 1filll
Copyright @copyright{} 2002,2004,2005 Clinton Ebadi

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.

@end titlepage

@node Top, Introduction, (dir), (dir)
@comment node-name, next, previous, up

@ifinfo
This document describes Bobot++ by Clinton Ebadi and Etienne Bernard
(The original author who no longer works on the program).

This document applies to version 2.2 of the program named
Bobot++.

Copyright 2002,2004,2005 Clinton Ebadi

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.
@end ifinfo

@menu
* Introduction::                
* Configuration::               
* Using the Bot::               
* Scripting::                   
* Concept Index::               
* Function Index::              
* Variable Index::              

@detailmenu
 --- The Detailed Node Listing ---

Configuration

* Configuration File Placement::  
* Configuration Files::         

Configuration Files

* bot.conf::                    
* bot.users::                   
* bot.init::                    
* bot.autoexec::                
* bot.shit::                    

bot.conf

* server syntax::               
* channel syntax::              

Using Bobot++

* Starting the Bot::            
* Concepts::                    
* Built-In Commands::           

Concepts

* User List::                   
* Shit List::                   
* Spy List::                    
* Levels::                      

Levels

* User Levels::                 
* Protection::                  
* Automatic Op::                
* Shit Levels::                 

Built-In Commands

* Bot Control Commands::        
* Message Commands::            
* Channel Control::             
* Spylist Commands::            
* User List Commands::          
* Server List Commands::        
* Shit List Commands::          
* Channel Info::                
* Scripting Commands::          
* Authentication Commands::     
* Miscellaneous Commands::      

Scripting

* Adding New Commands::         
* Hooks::                       
* Sending Messages::            
* Misc Scripting Stuff::        
* Scheme Commands::             
* Query Functions::             

Hooks

* Creating a Hook::             
* Hook Types::                  

Hook Types

* Received Message Hooks::      
* Sent Message Hooks::          
* DCC CHAT Hooks::              
* Miscellaneous Hooks::         

Sending Messages

* High Level Message Functions::  
* Low Level Message Functions::  

Misc. Scripting Stuff

* Scheme Commands::             
* Query Functions::             

@end detailmenu
@end menu

@node Introduction, Configuration, Top, Top
@chapter Introduction

Bobot++ is a powerful IRC bot written in C++. It can be used
standalone as a channel maintenence bot, or extended to do almost
anything using Scheme scripts.

FIXME: Fill the intro in more?

@node Configuration, Using the Bot, Introduction, Top
@chapter Configuration

Bobot++ is easy to configure. See the @file{examples} directory for an
example configuration. 

The main configuration file is @file{bot.conf}. There are several
auxiliary configuration files (a user list, aliases file, ban list,
and a script autoexec).

@menu
* Configuration File Placement::  
* Configuration Files::         
@end menu

@node Configuration File Placement, Configuration Files, Configuration, Configuration
@section Configuration File Placement

Bobot++ will look in @file{/etc/bobotpp/default/} for its default
config if none is specified on the command line. Put the configuration
files you want to be loaded by default in this directory. If you are
not root, or you want to have your own personal configuration, put it
in @file{~/.bobotpp/config/default/}.

@node Configuration Files,  , Configuration File Placement, Configuration
@section Configuration Files

@menu
* bot.conf::                    
* bot.users::                   
* bot.init::                    
* bot.autoexec::                
* bot.shit::                    
@end menu

@node bot.conf, bot.users, Configuration Files, Configuration Files
@subsection bot.conf

@file{bot.conf} contains key value pairs separated by @code{=}. 

@code{<key> = <value>}

Comments are started with a @code{#} and cause the entire line to be
ignored. @emph{Note that this only works when the @code{#} is the first
character of the line}.

bot.conf is the main configuration file for a Bobot++. The available
configuration variables are listed below in the format ``@var{variable}
<default-value>: description''

A few of the options have more complex syntax, they are documented in
their own subsections.

@menu
* server syntax::               
* channel syntax::              
@end menu

@itemize @bullet

@item @var{maxnicklength} <9>: The maximum length a valid nickname may
be. This should be set before setting the bot's nickname if it will be
more than nine characters long. Most IRC servers support nicknames
longer than nine characters, but Bobot++ still follows the old spec
and defaults to nine.
@item @var{nickname} <Bobot>: The nickname of the bot (@var{nick} is an
alias for @var{nickname})
@item @var{username} <bobot>: The IRC username of the bot
@item @var{cmdchar} <!>: The character that prefixes commands given to
the bot (@var{command} is an alias for @var{cmdchar})
@item @var{ircname} <I'm a bobot++!>: The IRC name (or 'real name') of
the bot (@var{realname} is an alias for @var{ircname})
@item @var{userlist} <bot.users>: Name of the file where the userlist is
stored
@item @var{autoexecfile} <bot.autoexec>: Name of the file containing
Scheme code to be executed when the bot starts (only used if the bot
is compiled with scripting support)
@item @var{initfile} <bot.init>: Name of the file containing the
default command aliases
@item @var{shitlist} <bot.shit>: Name of the file where the shitlist
(ban list) is stored
@item @var{logfile} <$LOGDIR/bot.log>: Location of the bot logfile
(set this to @file{/dev/null} to disable logging).
@item @var{server} <None>: This specifies the server to which the bot
will connect. Note that this has a special syntax @pxref{server
syntax}.
@item @var{channel} <None>: This specifies the channels the bot will join
when it starts up. This has a special syntax @pxref{channel
syntax}.

@end itemize

@node server syntax, channel syntax, bot.conf, bot.conf
@subsubsection server syntax

The server syntax in @file{bot.conf} allows you to specify an
alternate port to connect on, and a password to send the server.

You may use more than one server line; Bobot++ will attempt to connect
to the first one, and will connect to the next one in the list if it
fails. The bot will continue cycling through the server list until it
is able to connect to one. There is a command (@code{!cycle}) to make
the bot to cycle servers.

@var{server} = @var{server_name} [@var{port} [@var{password}]]

This will make Bobot++ attempt to connect to @var{server_name} on port
@var{port} with the password @var{password}. @var{server_name} should
be the address of the server. @var{port} and @var{password} are
optional. 

@node  channel syntax,  , server syntax, bot.conf
@subsubsection channel syntax

The channel syntax in @file{bot.conf} allows you to specify the
initial modes the bot should set on a channel, the modes the bot
should maintain, and a key if the channel needs it.

You may have any number of channel lines. When Bobot++ starts it will
attempt to join and gain operator status in every channel listed.

@var{channel} =
@var{name}:@var{initial_modes}:@var{modes_to_keep}:@var{channel_key}

The bot will join @var{name} and set the channel modes to
@var{initial_modes} (e.g. ``nt'') if it is able to gain operator
status. It will then maintain @var{modes_to_keep}. If the channel
requires a key to enter simply set @var{channel_key}. Every argument
except for @var{name} is optional.

A few example lines:

@example
@var{channel} = #foo:nt:nt:bar
@end example

The bot will join @code{#foo} with the channel key @code{bar} and will
then maintain the modes @code{nt}.

@example
@var{channel} = #bar:::
@end example

The bot will join @code{#bar} and will not set any modes nor will it
attempt to maintain any modes.

@node bot.users, bot.init, bot.conf, Configuration Files
@subsection bot.users (User List)

@file{bot.users} is the default file name of the userlist. It may be
changed in @file{bot.conf} via the @var{userlist} option. @strong{You
must add an entry for yourself manually.} You will probably want to
add other entries using the IRC command interface as it is more
intuitive than editing the file by hand.

The file contains lines with the format:

@samp{@var{host_mask}:@var{channel_mask}:@var{level}:@var{protection}:@var{auto-op}:@var{expiration}:@var{password}}

@itemize

@item @var{host_mask} is the host mask
(e.g. @samp{*!*username@*.domain.com}) of the user

@item @var{channel_mask} is a channel mask of the channels that the user
has priviliges to use the bot in (e.g. @samp{*} for all channels,
@samp{#*} for all non-local channel, @samp{#foo*} for all channels
starting with ``foo,'' @samp{#bar} for channel ``#bar'' only, etc.)

@item @var{level} is the user level of the user (@ref{User Levels}).

@item @var{protection} is the protection level of the user
(@ref{Protection}).

@item @var{auto-op} is set to control whether a user is automatically
given operator priviliges on channel entry (@ref{Automatic Op}).

@item @var{expiration} is the UNIX timestamp of when the user entry
becomes invalid. Setting this to -1 will make the entry permanent.

@item @var{password} is the password the user must supply to the bot
to authenticate. This can be set to @code{*NONE*} to not have a password.

@end itemize

@node bot.init, bot.autoexec, bot.users, Configuration Files
@subsection bot.init (Command Aliases)

This file stores a list of IRC command aliases. The filename may be
changed in @file{bot.conf} via the @var{initfile} option. You use this
file to set up aliases for IRC commands, e.g. to make @code{!a} call
@code{!adduser}. This way you can save typing for commonly used commands.

The format of a line in the file is:
@var{alias} @var{command}

This will make @var{alias} call @var{command}. e.g. @samp{t topic}
will make @code{!t New Topic} set the current channel's topic to ``New
Topic,'' just as if you had used @code{!topic New Topic}.

@node bot.autoexec, bot.shit, bot.init, Configuration Files
@subsection bot.autoexec (Scheme Init File)

This file is only used when Bobot++ is compiled with scripting
support. The name of the autoexec file can be changed in
@file{bot.conf} via the @var{autoexecfile} option.

The contents of this file are evaluated by Guile when the bot
starts. You can use this to do things like loading a few default
modules when the bot starts.

@node bot.shit,  , bot.autoexec, Configuration Files
@subsection bot.shit (Ban/Shit List)

This file stores the ban list. The name may be changed in
@file{bot.conf} via the @var{shitlist} option. You will most likely
want to use the IRC command interface to edit this file instead of
editing it directly.

The file contains lines in the form:

@samp{@var{host_mask}:@var{channel_mask}:@var{level}:@var{expiration}:@var{reason}}

@itemize

@item @var{host_mask} is the host mask
(e.g. @samp{*!*username@*.domain.com}) of the user

@item @var{channel_mask} is a channel mask of the channels that the user
is banned on (e.g. @samp{*} for all channels,
@samp{#*} for all non-local channel, @samp{#foo*} for all channels
starting with ``foo,'' @samp{#bar} for channel ``#bar'' only, etc.

@item @var{level} is a number specifying if the bot should not allow
the user to gain ops, to kick the user upon joining, or to prevent the
user from being debanned by other users. @ref{Shit Levels} for
information on the available levels.

@item @var{expiration} is the UNIX timestamp of when the shit entry
becomes invalid. This may be set to -1 to make it valid forever.

@item @var{reason} is text that is sent to the user when they are
kicked or banned from the channel.

@end itemize

@node Using the Bot, Scripting, Configuration, Top
@chapter Using Bobot++

Using Bobot++ is easy. This chapter covers starting the bot, a few
Bobot++ specific concepts, and using the built-in commands of the bot.

@menu
* Starting the Bot::            
* Concepts::                    
* Built-In Commands::           
@end menu

@node Starting the Bot, Concepts, Using the Bot, Using the Bot
@section Starting the Bot

The bot is usually installed with the binary name @file{bobotpp}. It
accepts the following command line arguments.

@itemize
@item @code{[--help][-h]} - Shows detailed help and exits
@item @code{[--version][-v]} - Shows version information and exits
@item @code{[--no-background][-b]} - Run bobot++ in the foreground
@item @code{[--config-file file][-f]} - Use file instead of @file{bot.conf}
@item @code{[--config-dir dir][-d]} - Use dir as dir to load config file from
@item @code{[--config dir][-c]} - Search your config path (defaults to
@file{@var{$HOME}/.bobotpp/config/} and then @file{/etc/bobotpp/}) for
dir and then loads your config data using dir
@item @code{[--sys-config dir][-s]} - Looks for config in
@file{/etc/bobotpp/dir}. Note that the user dir is still searched
first
@item @code{[--user-config dir][-u]} - Looks for config in
@file{@var{$HOME}/.bobotpp/config/dir/}. Note that the system dir is
still searched after this if dir is not found.
@item @code{[--debug][-D]} Makes Bobot++ print debugging info and run
in the foreground
@item @code{[--debug-scripts][-S]} Enables the Guile debugging
evaluator for verbose script errors and backtraces while still running
the bot in the background.
@end itemize

The default configuration is read from
@file{@var{$HOME}/.bobotpp/config/default/} and then
@file{/etc/bobotpp/default/} if the user config is not found.

The bot defaults to running in the background as a daemon.

@node Concepts, Built-In Commands, Starting the Bot, Using the Bot
@section Concepts

There are a few general concepts that a user of Bobot++ should know
about.

@menu
* User List::                   
* Shit List::                   
* Spy List::                    
* Levels::                      
@end menu

@node User List, Shit List, Concepts, Concepts
@subsection User List

@node Shit List, Spy List, User List, Concepts
@subsection Shit List

@node Spy List, Levels, Shit List, Concepts
@subsection Spy List

@node Levels,  , Spy List, Concepts
@subsection Levels

@menu
* User Levels::                 
* Protection::                  
* Automatic Op::                
* Shit Levels::                 
@end menu

@node User Levels, Protection, Levels, Levels
@subsubsection User Levels

There are several user levels available in Bobot++ to provide gradated
access to commands. @command{!adduser} and @file{bot.users} use the
numeric code; Scheme uses the textual name for the level. By default
(if the user is not found in the userlist) a user has access to
commands with the level @code{bot:user-none}.

@enumerate 0

@item @code{bot:user-none} - No @strong{built-in} commands may be
executed @emph{by default} (commands may be added from Scheme that can
be executed by users of level none and the level required to execute a
command may be changed from Scheme).

@item @code{bot:user-user} - Will be able to execute most commands but
not all and cannot use masks on kicks and bans.

@item @code{bot:user-trusted} - For built-ins with a default
configuration this user has access to the same set of commands as an
@code{user} but may use masks on kicks and bans. Scheme commands may
be added which require a user to be of this level.

@item @code{bot:user-friend} - In the default configuration a user who
is a friend will be able to do everything short of stopping the
bot. Again, there may be user added commands that require a higher
user level.

@item @code{bot:user-master} - This is the highest user level and has
access to every feature of the bot.

@end enumerate

@node Protection, Automatic Op, User Levels, Levels
@subsubsection Protection

A user added via Scheme, the @file{bot.users} file, or
@command{!adduser} may be protected from being deoped, kicked, or
banned. The user list and IRC commands use the numeric codes, Scheme
uses the symbolic names.

@enumerate 0
@item @code{bot:protection/none} No protection
@item @code{bot:protection/no-ban} No ban. If a user is banned the bot will unban him..
@item @code{bot:protection/no-kick} No kick. The user may still be kicked but the bot will kickban
the user who kicked the protected user.
@item @code{bot:protection/no-deop} No deop. The bot will ensure that the user always maintains
operator status.
@end enumerate

@node Automatic Op, Shit Levels, Protection, Levels
@subsubsection Automatic Op

A user may be automatically given operator status upon entering a
channel. Scheme uses the symbolic name, the user list
(@file{bot.users}) and IRC commands use the numeric value.

@enumerate 0
@item @code{bot:aop/no} Do not automatically op the user
@item @code{bot:aop/yes} Do automatically op the user
@end enumerate

@node Shit Levels,  , Automatic Op, Levels
@subsubsection Shit Levels

The shit list and shit list related commands use different levels to
define how much the bot hates a user. Scheme uses the symbolic names,
the shit list and IRC commands use the numbers.

@enumerate 0
@item @code{bot:shit/none} The bot doesn't hate the user (this is the
normal level)
@item @code{bot:shit/no-op} The bot will deop the user any time he
gains operator priviliges in the channel
@item @code{bot:shit/no-join} The bot will kick and ban the user when he
joins the channel
@item @code{bot:shit/no-deban} The bot will kick and ban usre when he
joins the channel, and will prevent other users from debanning him.
@end enumerate

@node Built-In Commands,  , Concepts, Using the Bot
@section Built-In Commands

Bobot++ has many built-in commands that make it useful without
scripting support. The reference leaves off the command char; remember
to use whatever you defined the command char to be in
@file{bot.conf}. 

If a command needs the channel name then you must specify the channel
as the first argument to the command when private messaging the bot a
command. If, however, you are using the command in a channel you may
omit the channel argument, and the bot will use the current channel.

@menu
* Bot Control Commands::        
* Message Commands::            
* Channel Control::             
* Spylist Commands::            
* User List Commands::          
* Server List Commands::        
* Shit List Commands::          
* Channel Info::                
* Scripting Commands::          
* Authentication Commands::     
* Miscellaneous Commands::      
@end menu

@node Bot Control Commands, Message Commands, Built-In Commands, Built-In Commands
@subsection Bot Control Commands

These commands are used to control the behaviour of the bot.

@deffn Command cycle channel
Makes the bot leave and join @var{channel}.
@end deffn

@deffn Command die
Makes the bot stop immediately.
@end deffn

@deffn Command join channel
Makes the bot join @var{channel}.
@end deffn

@deffn Command nick newnick
Makes the bot use nickname @var{new-nick}.
@end deffn

@deffn Command setfloodrate messages-per-second
Sets the flood rate to @var{messages-per-second}.  The bot will
consider users sending more than @var{messages-per-second} messges in
a second to be flooding and will ignore them.
@end deffn

@deffn Command setversion version-info
Sets the string returned when someone requestions the version info of
the bot.
@end deffn


@node Message Commands, Channel Control, Bot Control Commands, Built-In Commands
@subsection Message Commands

These commands cause the bot to send messages (e.g. sending a message
to a channel or performing an action). For all commands @var{target}
may be either a user or a channel.

@deffn Command action target do
Makes the bot to perform the action @var{do} in a message sent to
@var{target}.
@end deffn

@deffn Command do command
Sends a raw irc command. @var{command} is the IRC command you wish to
send (e.g. @samp{PRIVMSG #foo Hello!}).
@end deffn

@deffn Command msg target message
@deffnx Command say target message
Makes the bot say @var{message} to @var{target}.
@end deffn

@node Channel Control, Spylist Commands, Message Commands, Built-In Commands
@subsection Channel Control

@deffn Command ban channel mask
Bans @var{mask} from @var{channel}. You must be a trusted user to ban
using a host mask, but a normal user may ban individual nicks.
@end deffn

@deffn Command deban channel mask
Debans @var{mask} from @var{channel}. You must be a trusted user to
deban with a @var{mask}.
@end deffn

@deffn Command deop channel mask
Deops @var{mask} on @var{channel}.
@end deffn

@deffn Command invite nick channel
Invites @var{nick} to @var{channel}.
@end deffn

@deffn Command keep channel modes
Sets the @var{modes} that the bot will keep for @var{channel}.
@end deffn

@deffn Command kick channel mask reason
@deffnx Command kickban channel mask reason
Kicks @var{mask} out of @var{channel}, because of
@var{reason}. @command{kickban} also bans @var{mask}.You must be a
trusted user to use a mask.
@end deffn

@deffn Command lock channel
Locks topic on @var{channel}
@end deffn

@deffn Command mode channel modes
Sets mode of @var{channel} to the mode string @var{modes}.
@end deffn

@deffn Command op channel nick
Ops @var{nick} on @var{channel}
@end deffn

@deffn Command part channel
Makes the bot leave @var{channel}.
@end deffn

@deffn Command tban channel mask time
@deffnx Command tkban channel mask time
Bans @var{mask} from @var{channel} for @var{time}
seconds. @command{tkban} also kicks the user. You must be a trusted
user to use a mask.
@end deffn

@deffn Command topic channel [topic]
Sets the topic in @var{channel} to @var{topic}. If @var{topic} is not
supplied the current topic is sent as a notice to the user calling the
command.
@end deffn

@deffn Command unlock channel
Unlocks the topic on @var{channel}
@end deffn

@node Spylist Commands, User List Commands, Channel Control, Built-In Commands
@subsection Spylist Commands

@itemize

@item @command{spylist}    Shows the bot's spylist.

@item @command{spymessage}    Adds you to the spylist

@item @command{rspymessage}    Removes you from the spy
list.

@end itemize


@node User List Commands, Server List Commands, Spylist Commands, Built-In Commands
@subsection User List Commands

@deffn Command adduser mask
Adds the user 
@end deffn

@command{deluser}    Removes @var{nick} or
@var{mask} from the userlist.

@deffn Command save
Saves the userlist.
@end deffn

@command{userlist}    Shows the bot's userlist

@node Server List Commands, Shit List Commands, User List Commands, Built-In Commands
@subsection Server List Commands

@itemize 

@item @command{addserver}    Adds the server specified by
@var{host name} or @var{ip address} to the server list.

@item @command{delserver}    Deletes server from server
list whose number in the server list is @var{server number}.

@item @command{nextserver}    Makes the bot connect to the
next server in its server list.

@item @command{reconnect}    Makes the bot reconnect to
its current server.

@item @command{server}    Select the server to connect
to. @var{server number} is the number of the server in the serverlist.

@item @command{serverlist}    Shows the bot's serverlist.

@end itemize

@node Shit List Commands, Channel Info, Server List Commands, Built-In Commands
@subsection Shit List Commands

@itemize 

@item @command{addshit}   

@item @command{delshit}    Removes @var{nick} or
@var{mask} from the shitlist

@item @command{shitlist}    Shows the bot's shitlist.

@end itemize

@node Channel Info, Scripting Commands, Shit List Commands, Built-In Commands
@subsection Channel Info

@itemize

@item @command{banlist}   

@item @command{channels}    Prints the channel(s) where
the bot is currently.

@item @command{names}  Yes   Shows the nicknames and
status of users on @var{channel}.

@item @command{stats}  Yes   Gives @var{channel}'s statistics.
@end itemize

@node Scripting Commands, Authentication Commands, Channel Info, Built-In Commands
@subsection Scripting Commands

@itemize

@item @command{execute}    @strong{Only available if scripting support is enabled}

@item @command{load}    Reloads the userlist from disk.

@item @command{loadscript}    @strong{Only available if scripting support is enabled}

@end itemize

@node Authentication Commands, Miscellaneous Commands, Scripting Commands, Built-In Commands
@subsection Authentication Commands

@itemize

@item @command{ident}    Identifies you on the bot. Note
that you should not use this command in public @dots{}

@item @command{password}    Changes your password on the
bot. Use @code{NONE} as password if you want to clear it. Do not use this
command in public!

@end itemize

@node Miscellaneous Commands,  , Authentication Commands, Built-In Commands
@subsection Miscellaneous Commands

@itemize 

@item @command{alias}    Makes an alias, and adds the
function @var{new name}, that will do exactly the same command as
@var{old name}.

@item @command{dcclist}    Gives the list of all DCC Chat
connections.

@item @command{help}   

@item @command{nslookup}    Does a nameserver query about
@var{nick} host, @var{host} or @var{ip address}.


@item @command{who}  Yes   Show your level on @var{channel}

@item @command{whois}  Yes   Shows information about
@var{nick} on @var{channel}

@end itemize

@node Scripting, Concept Index, Using the Bot, Top
@chapter Scripting

Bobot++'s most powerful feature is its scripting system. You write
scripts using Guile Scheme. This manual does not cover how to use
Guile or how to learn Scheme. @xref{Top, , Guile Reference Manual,
guile, The Guile Reference Manual}, for the Guile reference manual and
@url{http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme.html} for
a good tutorial on Scheme. 

Note that in previous versions the scripting commands where in the
form @code{bot-@var{function}}. They are now in the form
@code{bot:@var{function}}. The old names are still available, but are
deprecated and will be removed in Bobot++ 3.0. New commands are only
available with the @code{bot:} prefix. The command @command{perl -pi
-e ``s/bot-/bot:/g'' @var{your-files}} should be enough to convert
your code to use the new functions.

@strong{NOTE}: All arguments to functions and hooks called by the bot
are strings unless otherwise specified.

@menu
* Adding New Commands::         
* Hooks::                       
* Sending Messages::            
* Misc Scripting Stuff::        
* Scheme Commands::             
* Query Functions::             
@end menu

@node Adding New Commands, Hooks, Scripting, Scripting
@section Adding New Commands

Adding a new command is simple. To register a new command use
@code{bot:addcommand}.

@defun bot:addcommand name func needs-channel? num-of-args min-level

The @var{name} is a string representing the name of the command being
added.  @var{func} is a function accepting @var{num-of-args}
arguments. @var{needs-channel?} is a bool that is true if the function
needs the channel name as its first arg, and false otherwise.
@var{num-of-args} is the number of args @var{func} will take and must
be within zero (0) and twenty (20).  @var{min-level} is one of the
@ref{User Levels}.  A user must be at least a @var{min-level} user to
use the new command.  None of the arguments are guaranteed to be
passed; if they aren't they are set to the empty string @code{""}.  An
example of a new command would be:

@example
(define (hello channel name)
  (if (string=? name "")
    (bot:say channel "Hello world!")
    (bot:say channel (string-append "Hello " name "!")))

(bot:addcommand "hello" hello #t 2 0)
@end example

This will display ``Hello World!'' if called as @kbd{!hello} and
``Hello World @var{USER}'' if called as @kbd{!hello @var{USER}}.
@end defun

@node Hooks, Sending Messages, Adding New Commands, Scripting
@section Hooks

@cindex Background on Hooks
Hooks are a powerful feature of Bobot++. Hooks are a hybrid of ircII
and tiny fugue (a MUD bot) hooks with a little bit of extra stuff
added in. A hook is called when a regular expression is matched
against a message sent to or by the bot.

Bobot++ uses different hook types for each IRC message type, and also
includes a hook for accessing raw irc messages. Hooks are tagged with
a priority and a flag that specifies whether to call the next hook
that matches after calling the current one or to stop
processing. 

Hooks are processed from the highest to lowest priority, with
fallthrough hooks of equal priority to non-fallthrough hooks being
executed first.

@menu
* Creating a Hook::             
* Hook Types::                  
@end menu

@node Creating a Hook, Hook Types, Hooks, Hooks
@subsection Creating a Hook

To add a new hook you use the function @code{bot:addhook}.

@defun bot:addhook type regex function [pri fall name]
@var{type} specifies the type of hook (the types of hooks are listed
in @ref{Hook Types}). 

@var{regex} is a standard regular expression. If
@var{regex} is matched, @var{function} will be called. 

@var{function} will take a different number of args depending on the
hook type. 

@var{pri} specifies the priority of the hook---higher priority hooks
are executed first. This argument is optional and defaults to
@code{0}. 

@var{fall} is @code{#t} if the hook is a fallthrough hook and
@code{#f} is the hook is not a fallthrough hook. This arg is also
optional and defaults to @code{#t}.

@var{name} is the optional name of the hook that defaults to
@code{"DEFAULT"}. If you set the name then you can have more than
one hook that matches the same regexp, as long as they have the same
name. E.g. in a log script you could have the regexps for the log
function all be @code{".*"} and set their names to @code{"log"} to
avoid a conflict with other hooks.
@end defun

@node Hook Types,  , Creating a Hook, Hooks
@subsection Hook Types

The following sections document the different hooks Bobot++ exposes.

The general format of each hook description is as if it were a
function to be defined, but these describe the function to be passed
to @code{bot:add-hook}.  Do @emph{not} name your functions these
names.

That said, here is the list of available hooks functions.
FIXME: write docs

@menu
* Received Message Hooks::      
* Sent Message Hooks::          
* DCC CHAT Hooks::              
* Miscellaneous Hooks::         
@end menu

@node Received Message Hooks, Sent Message Hooks, Hook Types, Hook Types
@subsubsection Receieved Message Hooks

The following hooks are triggered when a mesage is received by the bot.

@defun hooks/action from to action
This hook is triggered when someone performs an action.

@var{from} is the nickname the person that performed the
action.

@var{to} is the target of the action, which is either a channel or the
Bot's nick if the user private messages the bot.

@var{action} is the text of the action. E.g. if someone did @samp{*
foobar does baz}, then @var{action} would be the string @code{"does
baz"}.
@end defun

@defun hooks/nickname old-nick new-nick
This hook is called when someone changes his nickname from
@var{old-nick} to @var{new-nick}.
@end defun

@defun hooks/signoff nick message
This hook is called when someone signs off of IRC.

@var{nick} is the nickname of the person signing off.

@var{message} is his quit message
@end defun

@defun hooks/ctcp nick to command rest
This hook is called when a CTCP request is received by the bot.

@var{nick} is the nickname of the sender.

@var{to} is the target of the CTCP request. This will either be a
channel the bot is in, or the nickname of the bot.

@var{command} is the CTCP command issued.

@var{rest} contains the arguments to the CTCP command.
@end defun

@defun hooks/ctcp-reply nick command rest
This hook is called when a CTCP REPLY is received. This occurs when
the bot has sent a CTCP request to another client. The CTCP REPLY is
always addressed to the bot directly.

@var{nick} is the nickname of the person who replied.

@var{command} is the command to which @var{nick} is replying.

@var{rest} contains the body of the reply.
@end defun

@defun hooks/disconnect server intentional
This is called when the bot is disconnected from a server.

@var{server} is the hostname of the server from which the bot was
disconnected.

@var{intentional} is a flag set to @code{#t} when the bot disonnected
from the server as the result of a command (issued by a user from IRC,
SIGHUP, or from a script), or @code{#f} when the bot disconnected from
the server unintentionally..
@end defun

@defun hooks/invite nick channel
This hook is called when a user invited the bot to join a channel.

@var{nick} is the nickname of the user who sent the invite.

@var{channel} is the channel to which the bot was invited.
@end defun

@defun hooks/join nick channel
This is called when a user or the bot joins a channel.

@var{nick} is the nickname of the user who joined @var{channel}. This
may be the bot's nickname (the IRC server sends the JOIN command back
to the the bot after it joins a channel).

@var{channel} is the channel that was joined
@end defun

@defun hooks/kick target from channel reason
This hook is called when a user, including the bot, is kicked out of a
channel.

@var{target} is the nick of the user who was kicked. This may be the
bot's nick.

@var{from} is the nick of the user who issued the kick. This may also
be the bot's nick.

@var{channel} is the channel the kick was issued in.

@var{reason} is the reason the user was kicked.
@end defun

@defun hooks/part nick channel
This hook is called when a user parts a channel.

@var{nick} is the user who parted the channel. This may be the bot.

@var{channel} is the channel from which the user parted.
@end defun

@defun hooks/mode nick target modes
This hook is called when someone sets the modes of @var{target}.

@var{nick} is the user who set the modes. This may be the bot.

@var{target} is the target of the MODE command. This may be a
channel or a user. If it is a user, it may be the bot.

@var{modes} is the MODE string.
@end defun

@defun hooks/message nick message
This hook is called when someone sends a private message to the bot.

@var{nick} is the nickname of the user who sent the message.

@var{message} is the message the user sent.
@end defun

@defun hooks/notice nick message
This hook is called when a user send a private notice to the bot.

@var{nick} is the user who sent the notice.

@var{message} is the message the user sent.
@end defun

@defun hooks/public nick channel message
This hook is called when a user sends a normal message to a channel.

@var{nick} is the user who sent the message.

@var{channel} is the channel to which the message was sent.

@var{message} is the message that was sent.
@end defun

@defun hooks/public-notice nick channel message
This hook is called when a user send a notice to a channel.

@var{nick} is the user who sent the notice.

@var{channel} is the channel to which the notice was sent.

@var{message} is the message that was sent.
@end defun

@defun hooks/raw raw-message
This hook is called every time a message is received. This matches on
the raw message text and passes the hook function the raw IRC message.

@var{raw-message} is the raw IRC message.
@end defun

@defun hooks/topic nick channel new-topic
This hook is called when a user changes the topic in a channel.

@var{nick} is the user who set the topic. This may be the bot.

@var{channel} is the channel that's topic was changed.

@var{new-topic} is the new topic.
@end defun

@node Sent Message Hooks, DCC CHAT Hooks, Received Message Hooks, Hook Types
@subsubsection Sent Message Hooks

These hooks are called when the bot sends a message. @var{mynick} is
always the bot's nick and will not be documented in each hook
description.

@defun hooks/send/public mynick channel message
This hook is called when the bot sends a normal message to a channel.

@var{channel} is the channel to which the bot sent the message.

@var{message} is the message the bot sent.
@end defun

@defun hooks/send/message mynick to message
This hook is called when the bot sends a private message to a user.

@var{to} is the nick of the user to whom the message was sent.

@var{message} is the message that was sent.
@end defun

@defun hooks/send/action mynick to message
This hook is called when the bot sents an action to a channel or a
user.

@var{to} is the channel or nick of the user to which the action was
sent.

@var{message} is the text of the action.
@end defun

@defun hooks/send/ctcp mynick to command message
This hook is called when the bot sends a CTCP message @emph{other
than} an ACTION to a channel or user.

@var{to} is the channel or nick of the user to which the CTCP was
sent.

@var{command} is the CTCP command that was sent.

@var{message} is a string containing the arguments to the CTCP command.
@end defun

@defun hooks/send/who who
This is called when the bot sends a WHO message. The regex is matched
on @var{who}, which is also passed as the only argument to your
function.

@var{who} is the channel or nick that was WHOed.
@end defun

@defun hooks/send/whois nick
This is called when the bot sends a WHOIS message. The regex is
matched on @var{nick}, which is also passed as the only argument to
your function.

@var{nick} is the nickname of the person who was WHOISed.
@end defun

@node DCC CHAT Hooks, Miscellaneous Hooks, Sent Message Hooks, Hook Types
@subsubsection DCC CHAT Hooks

These hooks are called when a user initializes a DCC CHAT and when the
bot receives messages from the user in a DCC CHAT.

@defun hooks/dcc/chat-begin from
This hook is called when a user begins a DCC CHAT with the bot.
@var{from} is the user's address in the form @samp{nick!user@@host}.
@end defun

@defun hooks/dcc/chat-end address
This hook is called when a DCC CHAT is purged after being idle for a
while, or when the user closes the DCC CHAT. As such, you cannot write
any more data to the DCC CHAT.

@var{address} is the address (nick!user@@host) of the person on the
other side of the DCC.
@end defun

@defun hooks/dcc/chat-message from message
This hook is called when a user sends a message to the bot through
a DCC CHAT.

@var{from} is the user's address in the form @samp{nick!user@@host}.

@var{message} is the message the user sent to the bot.
@end defun

@node Miscellaneous Hooks,  , DCC CHAT Hooks, Hook Types
@subsubsection Miscellaneous Hooks

@defun hooks/flood nick
This hook is called when a user is detected flooding the bot.

@var{nick} is the nickname of the user flooding the bot.
@end defun

@defun hooks/timer time
This hook is called once a minute. The regex is @strong{not} used.

@var{time} is the in zero-padded @code{hh:mm} format.
@end defun


@node Sending Messages, Misc Scripting Stuff, Hooks, Scripting
@section Sending Messages

There are several types of messages you can send with Bobot++ from
scripts. They are split into High and Low level message sending
functions. Most bots will only use the high level functions, but the
low level ones are provided for when a bot needs to do things like
send raw IRC messages or CTCP commands.

@menu
* High Level Message Functions::  
* Low Level Message Functions::  
@end menu

@node High Level Message Functions, Low Level Message Functions, Sending Messages, Sending Messages
@subsection ``High Level'' Message Functions

@defun bot:action channel message
Send an ``action'' type  @var{message} to @var{channel}
@end defun


@defun bot:msg target message
@defunx bot:say target message
Send a public or private message to @var{target}.

@var{target} may be a channel or a nickname. 

In versions of Bobot++ prior to 2.1.8 @code{bot:say} could only send
to channels, and @code{bot:msg} could only send private messages to
users. They are aliases of the same command now, but it may be worth
using them as they used to for clarity.
@end defun

@defun bot:notice target message
Sends @var{message} as a NOTICE to @var{target}. @var{target} may be a
user (nick) or a channel.
@end defun

@node Low Level Message Functions,  , High Level Message Functions, Sending Messages
@subsection ``Low Level'' Message Functions

@c Add a url for rfc2812
The ``Low Level'' messaging functions allow you to do things like send
CTCP messages. You probably want to read rfc 2812 and the CTCP spec
before using these. If you have no idea what these do, read rfc 2812
(IRC Client Protocol) and CTCP spec. These functions all return
@code{*unspecified*} always, so don't use the return value for
anything.

@defun bot:ctcp to command message
@var{to} is the target of your CTCP message, @var{command} is the
CTCP command, and @var{message} is the message (or arguments) of the
command. Make sure to @code{bot:ctcp-quote} the message!
@end defun

@defun bot:ctcp-reply to command message
@var{to} is the target of your CTCP reply, @var{command} is the
CTCP command, and @var{message} is the message (or arguments) of the
command. Make sure to @code{bot:ctcp-quote} the message!

This is used to reply to a ctcp that the bot has received.
@end defun

@node Misc Scripting Stuff, Scheme Commands, Sending Messages, Scripting
@section Misc. Scripting Stuff

These are a few useful things that I thought people writing scripts
might want to know.

@vindex exit-hook
If you want to execute code when the bot exits, just do
@code{add-hook! bot:exit-hook @var{thunk}} where @var{thunk} is an
argumentless procedure (a thunk). When the bot exits your thunk will
be called.


@menu
* Scheme Commands::             
* Query Functions::             
@end menu

@node Scheme Commands, Query Functions, Misc Scripting Stuff, Scripting
@section Scheme Commands

These scheme functions are the same as the commands.
They allow you to execute bot commands from scheme scripts.

@defun bot:adduser nick-or-mask cbannel-mask level prot auto-op
Adds an user to the userlist, for a @code{nick!user@@host} matching the
one given, on a channel matching the @var{channelMask} given.

@multitable @columnfractions 0.33 0.33 0.33
@item The @var{level} can be: @tab The @var{prot} can be:  @tab The @var{auto-op} can be: 
@item  0 - No level      @tab   0 - No protection @tab  0 - No auto-op
@item  1 - User          @tab   1 - No ban        @tab  1 - Op on join
@item  2 - Trusted User  @tab   2 - No kick       @tab
@item  3 - Friend        @tab   3 - No deop       @tab
@item  4 - Master        @tab                     @tab
@end multitable

@end defun

@c (3, 4, 0)
@defun bot:addserver hostname ip-address [portnumber]
Adds the server specified by @var{hostname} or @var{ip-address} to
the server list.
@end defun

@c (3, 2, 0)
@defun bot:addshit nick-or-mask channel-mask level [time reason]
Adds an user to the shitlist, for a nick!user@@host matching the
one given, on a channel matching the @var{channelMask} given.

@display
The @var{level} can be:
  0 - No shit
  1 - No op
  2 - Kick and Ban on join
  3 - Kick and Ban on join, no deban
@end display

@end defun

@c (2, 0, 0)
@defun bot:ban channel mask-or-nick
Bans @var{mask} or @var{nick} from @var{channel}. You must be a trusted
user to ban with a @var{mask}.
@end defun

@c (2, 0, 0)
@defun bot:change-command-level nick-or-mask channel-mask new-level
Gives @var{nick} or @var{mask} level @var{new-level} on channel(s)
@var{channel-mask}. Note that you can not change level for someone
whose level is greater than yours, and that you can not give a
level greater than yours.
@end defun

@c (1, 0, 0)
@defun bot:cycle channel
Makes the bot leave and join @var{channel}.
@end defun

@c (2, 0, 0)
@defun bot:deban channel mask-or-nick
Debans @var{mask} or @var{nick} from @var{channel}. You must be a trusted
user to deban with a @var{mask}.
@end defun

@c (1, 0, 0)
@defun bot:delserver server-number
Deletes server from server list whose number in the server list
is @var{server-number}
@end defun

@c (2, 0, 0)
@defun bot:deluser nick-or-mask channel-mask
Removes @var{nick} or @var{mask} from the userlist.
@end defun

@c (2, 0, 0)
@defun bot:delshit nick-or-mask channel-mask
Removes @var{nick} or @var{mask} from the shitlist.
@end defun

@c (2, 0, 0)
@defun bot:deop channel mask-or-nick
Deops @var{mask} or @var{nick} on @var{channel}.
@end defun

@c (1, 0, 0)
@defun bot:die reason
Makes the bot stop immediately.
@end defun

@c (1, 0, 0)
@defun bot:do ?
@end defun

@c (2, 0, 0)
@defun bot:invite channel nick
Invites @var{nick} on @var{channel}.
@end defun

@c (1, 1, 0)
@defun bot:join channel
Makes the bot join @var{channel}.
@end defun

@c (2, 0, 0)
@defun bot:keep channel modes
Sets the @var{modes} that the bot will keep for @var{channel}.
See also STATS.
@end defun

@c (2, 1, 0)
@defun bot:kick channel mask-or-nick [reason]
Kicks @var{mask} or @var{nick} out of @var{channel}, because of @var{reason}.
You must be a trusted user to use a @var{mask}.
@end defun

@c (2, 1, 0)
@defun bot:kickban channel mask-or-nick [reason]
Bans then kicks @var{mask} or @var{nick} out of @var{channel},
because of @var{reason}.
You must be a trusted user to use a @var{mask}.
@end defun

@c (1, 0, 0)
@defun bot:lock channel
Locks topic on @var{channel}.
@end defun

@c (2, 0, 0)
@defun bot:mode channel mode-string
Sends @var{mode-string} as mode for @var{channel}.
@end defun

@c (0, 0, 0)
@defun bot:nextserver
Makes the bot connect to the next server in its server list.
@end defun

@c (1, 0, 0)
@defun bot:nick nick
Makes the bot use nickname @var{nick}.
@end defun

@c (2, 0, 0)
@defun bot:op channel nick
Ops @var{nick} on @var{channel}.
@end defun

@c (1, 0, 0)
@defun bot:part channel
Makes the bot leave @var{channel}.
@end defun

@c (0, 0, 0)
@defun bot:reconnect
Makes the bot reconnect to its current server.
@end defun

@c (1, 0, 0)
@defun bot:server server-number
Select the server to connect to. @var{server-number} is the number of
the server in the serverlist.
@end defun

@c (1, 0, 0)
@defun bot:setfloodrate ?
@end defun

@c (1, 0, 0)
@defun bot:setversion ?
@end defun

@c (3, 0, 0)
@defun bot:tban channel nick-or-mask time
Bans @var{nick} or @var{mask} from @var{channel} for @var{time} seconds.
@end defun

@c (3, 1, 0)
@defun bot:tkban channel nick-or-mask time [reason]
Bans @var{nick} or @var{mask} from @var{channel} for @var{time} seconds,
then kicks him/them because of @var{reason}.
@end defun

@c (2, 0, 0)
@defun bot:topic channel topic
If no @var{topic} is given, prints @var{channel}'s topic. Otherwise,
the bot will change @var{channel}'s topic to @var{topic}.
@end defun

@defun bot:unlock channel
Makes the bot unlock topic on @var{channel}.
@end defun

@defun bot:who target
Sends a WHO command to @var{target}. @var{target} may be either a
channel or a user.
@end defun

@defun bot:whois nick
Sends a WHOIS command to @var{nick}. @var{nick} @strong{must} be a
nickname, you cannot send a WHOIS to a channel.
@end defun



@c (1, 0, 0)
@defun bot:delcommand
[ Probably deletes a command added with @code{bot:addcommand} ? ]
@end defun



@node Query Functions,  , Scheme Commands, Scripting
@section Query Functions

@quotation
[ I didn't know where to put any of these, so I just stuck them in
here.

There probably needs to be several sections added, like dealing with
users (kicking, added, etc), dealing with the bot (channels, nickname
of the bot, etc), server issues (serverlist), useful tools (nslookup,
whois), and do on. ]
@end quotation

These functions allow scripts to get various bits of information.

@c (0, 0, 0)
@defun bot:logport
[ Probably returns the log port? ]
@end defun

@c (0, 0, 0)
@defun bot:getnickname
[ Gets the bot's nickname? ]
@end defun

@c (0, 0, 0)
@defun bot:getserver
@end defun

@c (0, 0, 0)
@defun bot:getserverlist
@end defun

@c (0, 0, 0)
@defun bot:flush
[ Flushes the socket to the server? ]
@end defun

@c (0, 0, 0)
@defun bot:flushport
[ Flushes the log port? ]
@end defun

@c (1, 0, 0)
@defun bot:random ?
[ Returns a random number?  What range?  Why? ]
@end defun

@c (2, 0, 0)
@defun bot:addtimer ?  ?
@end defun

@c (1, 0, 0)
@defun bot:deltimer ?
@end defun

@c (2, 0, 0)
@defun bot:dcc-chat-send ? ?
@end defun

@quotation
[ And what about the stuff defined in @file{bobot-utils.scm} ? I just
added it here so it could be somewhere.  There should also be a
section dealing with modules.  How to use them.  What module scripts
are in.  What module bobot++ provided primites are in.  And so on. ]
@end quotation

@defun bot:log . messages
Write as many @var{messages} as you want to the log.  If the arg is a
thunk it will be executed and it's output will be written to the log.
@end defun

@defun bot:load file
@end defun

@defun bot:load-module module-spec
@end defun

@defun bot:use-module module-spec
@end defun

@defun bot:match-not-channel regex
@code{bot:match-not-channel} adds a prefix regex to your @var{regex} so it
doesn't match the sender or channel in a PUBLIC message
@end defun

@defun bot:match-to-me regex
@code{bot:match-to-me} matches text that was addressed to the bot with a
':',  ',',  or nothing after the bot name.
@end defun

@defun bot:sent-to-me? message
@end defun

@defun bot:ctcp-quote message
Returns the CTCP quoted message
Input @emph{MUST NOT} contain the trailing @code{\r\n}
(it is added by the message sending code).
@end defun


@defvar %bot:loadpath
@end defvar

@defun %bot:load-extensions
@end defun



@node Concept Index, Function Index, Scripting, Top
@unnumbered Concept Index
@printindex cp

@node Function Index, Variable Index, Concept Index, Top
@unnumbered Function Index
@printindex fn

@node Variable Index,  , Function Index, Top
@unnumbered Variable Index
@printindex vr

@bye
