Nanobot code help

From Insomnia 24/7 Wiki
Revision as of 14:52, 1 March 2011 by imported>Wikiadmin (Demo module)
Jump to: navigation, search

Demo module

This is the demo.pm module, which is used to demonstrate a modules capabilities and provide an example implementation. A version with syntax highlighting may be found here.

#!/usr/local/bin/perl
 
# These are the variables passed to each function call.
#
# $_[0] = name for this module (surely you already know this, but still)
# $_[1] = sending nickname
# $_[2] = sending username
# $_[3] = sending hostmask
# $_[4] = sending channel (or botnick in case of PM)
# $_[5] = current value for $modchan
# $_[6] = current value for $botnick
# $_[7] = arguments given in IRC
 
# The package name must match the filename + .pm, so this file should be called "demo.pm".
package demo;
 
if ( $firstcall == 0 ) {
	# Here is some code that is executed when the module is loaded and when a function is called.
	nanobot::snd("PRIVMSG #bot :Demo module was loaded!");
	$firstcall == 1;
}
 
# sub join {} is a special name, if you implement this you will receive JOIN info trough this subroutine
# Implementing the join subroutine is optional.
 
# Example implemetation of join:
sub join {
	nanobot::snd("PRIVMSG $_[4] :Hello $_[1], welcome to $_[4]!");
}
 
 
# sub mesg {} is a special name, if you implement this you will receive all messages that don't start with ! (since these are bot commands)
# Implementing the mesg subroutine is optional.
 
 
# sub notice {} is a special name, if you implement this you will receive notices to the bot.
# Implementing the notice subroutine is optional.
 
 
# sub raw {} is a special name, if you implement this you will receive all the raw data the bot receives.
# This is all raw IRC data, so the normal variables will not be available, this means you'll have to parse this data yourself!
# The raw data will be available in the subroutine in the variable $_
# Use this function with caution.
# Implementing the raw subroutine is optional.
 
 
# sub public {} is a special name, this function should contain an array of publicly available function names.
# When this subroutine is not implemented, all functions will only be available to bot opers.
sub public {
	@public = ("help", "function");
}
 
 
# sub help {} is a special name, if you implement this subroutine it will be called when your module is called with no parameters.
# Implementing the mesg subroutine is optional, but highly reckomended.
sub help {
	nanobot::snd("NOTICE $_[1] :Commands: help, function, listargs");
}
 
# Every subroutine is a function that can be called from IRC.
sub function {
	# You can use nanobot::function to use the functions from nanobot. (obviously)
	nanobot::snd("PRIVMSG $_[4] :Message from demo module!");
}
 
# This command is only available to bot opers or when pubmods is set.
sub listargs {
	nanobot::snd("PRIVMSG $_[4] :@_");
}
 
# A module must always end with the line "1;", Perl demands it.
1;

What a module MUST have

Package name

You need to define your module as a Perl package, so the bot will be able to call it.
All you need to do this is add the line package yourpackagename; to the top of your module file.

File name

The bot needs to have a filename for your module that matches the package name, so if your module has package awesomemodule; your module file will need to be called awesomemodule.pm.

The last line

Every Perl module must end with the line 1; this is so that Perl can keep track of where modules end.


What modules should have

Help

Though implementing the help subroutine is optional, it is highly recommended.
The bot will call this subroutine when it receives no fucntion call to a module call. (When someone uses !examplemodule instead of !examplemodule.function.)
The help subroutine is ALWAYS a public command!

Public

The public subroutine is also optional. This subroutine will be called when a non-admin user calls a command. The subroutine should contain an array (@public) of commands that you want to be be available to all users.

sub public {
	@public = ("function1", "function2");
}

In this example function1 and function2 can be called by any user, but no other functions are available to the public.

Writing subroutines

How does a subroutine get called

You will almost always want to add a new subroutine to your module in order to make a command available to you and/or your users.
The commands you give it in IRC translate directly to package(module) names and functions.
For example:

!hello.world

Will call a module hello and it's subroutine world.
Arguements given to the command will be available as the variable $_[7] in the module. (See next section.)

What variables are available

The module receives an array of arguments whenever a function is called: $_[0] The modules name. $_[1] The nickname of the person sending the command. $_[2] The username of the preson sending the command. $_[3] The hostmast of the person sending the command. $_[4] The channel from where the command was received. If the command was sent directly to the bot, this will be the bots nickname. $_[5] The active channel that's currently set. ($modchan) $_[6] The bots own nickname $_[7] Any arguements given to the command in IRC.

If more than one argument is given, the entire arguement string will be in this variable.


How to use nanobot's functions

Nanobot's functions can be called much like the functions of any other package in Perl. This means you can call all of nanobot's subroutines like this: nanobot::subname();. The ones you will probably need commonly are msg, ntc and snd, for privatemessage, notice and send.

msg

This send a normal message to a user or channel.

nanobot::msg("#channel", "Message to send");

ntc

This will send a notice to a user or channel.

nanobot::ntc("nickame", "Message to send");

snd

This command can be used to send raw data to the IRC server.
Unlike the msg and ntc functions, this function does not create the correct IRC syntax for you. You will need to specify the correct syntax yourself. This gives you both great freedom in what you can send, but also means you must make sure you send valid commands, as some IRC servers may disconnect you for sending an invalid command.

# Send a message to the $modchan.
nanobot::snd("PRIVMSG $_[5] :Hello world!");

Optional subroutines

The following subroutines do not need to be implemented. They are exist only to make your life easier when you are writing a module.

Mesg

The mesg subroutine will receive any message sent to the bot or one of the channels it is in, provided the message does not start with an "!", since this character is reserved for commands sent to the bot.
Example:

sub mesg {
    # Echo the message back to a specified channel.
    nanobot::msg("#mychannel", "$_[1] said $_[7]");
}

Notice

The notice subroutine will catch any notices sent to the bot or to a channel the bot is on.
Example:

sub notice {
    # Forward notices to a user
    nanobot::ntc("myowner", "Received notice from $_[1] containing: $_[7]");
}

Join

This subroutine will be called whenever a user joins the channel.
Example:

sub join {
	# Notify $modchan when a user joins any other channel the bot is on.
	nanobot::msg("$_[5]", "Looks like $_[1] just joined $_[4]");
}

Raw

This subroutine is called whenever the bot receives data.
It is a very powerful subroutine, since it allows you to grab and modify any data the bot has access to.

This is the only subroutine where the normal variables are not available, as they have not yet been processed and split. Instead the variable $_ is available which contains the raw data from the socket.

Warning: When using the raw subroutine, you can modify the actual data the rest of the bot receives, so make to only work with copies of variables when this is not your intention.

Example:

sub raw {
	# Send data to terminal screen for debugging
	nanobot::logts("$_\n");
}

First call

This is a demo construction of how to make a function that will only be called once when the module loads:

if ( $firstcall == 0 ) {
	# Here is some code that is executed when the module is loaded.
	nanobot::snd("PRIVMSG #bot :Module was loaded!");
	$firstcall == 1;
}