Difference between revisions of "Nanobot manual"

From Insomnia 24/7 Wiki
Jump to: navigation, search
imported>Wikiadmin
imported>Wikiadmin
Line 1: Line 1:
 
== Environment ==
 
== Environment ==
:All you need for this bot to run is a Perl environment.
+
:To run the bot you need to have Ruby installed. Specific plugins may requires additional gems
:You you don't already have Perl installed, please do that first.
+
:If you have plugins you want to load, take a directory named "plugins" in the same folder where your nanobot.rb resides, and place your plugin files in there.
:If you have modules you want to load, make a directory named "modules" in the same folder where your nanobot.pl resides, and place your module files in there.
 
 
 
  
  
 
== Configuration ==
 
== Configuration ==
:To configure your bots settings like the server and nickname, open nanobot.pl in a text editor.
+
:To configure your bots settings like the server and nickname, open config.rb in a text editor.
 
:Just a few lines into the file, you will find this block of text:
 
:Just a few lines into the file, you will find this block of text:
 
<pre>
 
<pre>
$version = "Nanobot 3.0";
+
def initialize( status, output )
$server = 'irc.insomnia247.nl';
+
@nick = "nanobot" # Bot nickname
$port = 6667;
+
@user = "nanobot" # IRC username
$sslport = 6669;
+
@pass = "" # NickServ password
$botnick = 'nanobot';
+
@version = "Nanobot 4" # Version
$botuser = 'nanobot';
+
 
$nsp = '';
+
@command = '\!' # Character prefix for commands (escape special chars)
@channels = ("#bots", "#yourchannel");
+
 
@opers = ("insomnia247.nl", "rootedker.nl", "fbi.gov", "eye.spy");
+
@server = "irc.insomnia247.nl" # IPv4 address
$modchan = '#yourchannel';
+
@server6 = "irc6.insomnia247.nl" # IPv6 address
$datadir = 'botdata';
+
@port = 6667 # Normal port
$moddir = 'modules';
+
@sslport = 6697 # SSL port
@autoload = ();
+
@serverpass = "" # Server connect password
$wisecrack_seen_botnick = "I'm right here. I mean ... really, how did you miss that one?";
+
@connectopt = "" # Extra stuff to send on connect
$wisecrack_seen_self = "I can see you! You're right there! That's right, I can see.";
+
 
$wait_for_ping = 0;
+
@channels = [ "#bot", "#test" ] # Autojoin channel list
$connect_timeout = 120;
+
 
$ping_timeout = 300;
+
@opers = [ "insomnia247.nl" ] # Opers list
 +
 
 +
@data = "data" # Data directory
 +
@plugins = "plugins" # Plugin directory
 +
@autoload = [ "core", "toolbox" ] # Plugin autoload list
 +
 
 +
@antiflood = true # Attempt to mitigate people flooding bot with commands
 +
@floodtime = 5 # Seconds withing which the flood limit is triggered
 +
@floodcut = 30 # Limit on the number of seconds delay before starting to drop
 +
 
 +
@throttle = true # Throttle output to avoid flooding from the bot
 +
 
 +
@autorejoin = true # Rejoin on kick
 +
@rejointime = 3 # Time to wait before rejoin (seconds)
 +
 
 +
@pingwait = false # Wait for server's first PING
 +
@conn_time = 20 # Connect timeout
 +
@timeout = 300 # IRC timeout
 +
 
 +
@use_thread = true # Prefer threading
 +
@use_ipv6 = false # Prefer IPv6
 +
@use_ssl = true # Prefer SSL
 +
@verif_ssl = false # Verify SSL certificate
 +
@rootcert = "/etc/ssl/certs/ca-certificates.crt" # Path to openssl root certs (Needed if verify_ssl is enabled)
 +
 
 +
@threadfb = true # Allow fallback to sequential processing when threads aren't available
 +
@sslfback = false # Allow fallback to insecure connect when OpenSSL library isn't available
 +
 
 +
@status = status # System object, do not modify
 +
@output = output # System object, do not modify
 +
end
 
</pre>
 
</pre>
:These are the variables that hold the bots configuration, we will now go over each of these values and what they do
+
:These are the variables that hold the bots configuration, a few of the ones you may want to have a look at are:
:'''version''': This is the version number of the bot, normally you will not have to change this.
+
:'''nick''': This is bots own nickname.
:'''server''': This holds the value of the server you want your bot to connect to.
+
:'''pass''': If you've registered the bot's nick with NickServ, put the password here.
::This can be either a hostname (irc.myircserver.com), an IPv4 address (127.0.0.1) or an IPv6 address (::1).
+
:'''command''': This is the character commands are prefixed with on IRC. So "@command = '\!'" means on irc you would do things like "!help" and "!version"
:'''port''': The port number of the IRC server you want to connect to. (Usually 6667.)
+
:'''server''': The server the bot connects to
:'''sslport''': The port number the IRC server uses for SSL connections. (Can be ignored if you don't use SSL.)
+
:'''server6''': If the server's IPv6 address is different you can specify that here.
:'''botnick''': The bots nickname. This is how the bot will show up in channels etc.
+
:'''port''': The port the bot connect on without SSL
:'''botuser''': Username for the bot. In IRC terms, it is "nickname!username@hostname".
+
:'''sslport''': The port the bot connect on with SSL
:'''nsp''': NickServ password for your bot's nickname. Can be left blank if the bot's nick is not registered, or if you do not want it to identify with NickServ.
+
:'''channels''': List of channels the bot will join when it connects to the server.
:'''channels''': List of channels the bot will join when it connects to the server. ''@channels = ("#frist", "#second", "#third");''
+
:'''opers''': Hostnames or hostmasks for bot admins. Note that they must appear as the bot sees them.
:'''opers''': Hostnames or hostmasks for bot admins. Note that they must appear as the bot sees them. ''@opers = ("my.ip.here", "and.some.vhost.com");''
 
 
::Only the hostname should be added. (So if you are someguy!bob@SOMEHASH-my.isp.com you should add "SOMEHASH-my.isp.com".)
 
::Only the hostname should be added. (So if you are someguy!bob@SOMEHASH-my.isp.com you should add "SOMEHASH-my.isp.com".)
:'''modchan''': This is the bots main channel, auto voice, auto oper and auto kick will be preformed here.
+
:'''autoload''': The list of plugins that will automatically be loaded when the bot starts up.
:'''datadir''': Directory where the bot stores data for it's modchan. (Will be created if it doesn't exist.)
 
:'''moddir''': Directory where the bot will look for modules. (Will be created if it doesn't exist.)
 
:'''autoload''': List of modules that should be loaded automatically when the bot starts up. (Module name only.) ''@autoload = ("mymodule", "kickban", "anothermodule");''
 
:'''wisecrack_seen_botnick''': Line the bot will say when the !seen command is given for the bots own nickname.
 
:'''wisecrack_seen_self''': Line the bot will say when the !seen command is given for the users own nickname.
 
:'''wait_for_ping''': Used to tell the bot if it needs to wait for a PING request before joining channels. (0 = No, 1 = Yes)
 
::If your bot seems to connect, but isn't joining channels, this might well be your problem.
 
:'''connect_timeout''': Time in seconds before giving up trying to connect to the IRC server.
 
:'''ping_timeout''': Time in seconds the bot will wait before assuming a network timeout and tries to reconnect.
 
 
 
  
 +
:All the other values can be tweaked as required but usually this isn't needed.
  
 
== Starting command ==
 
== Starting command ==
:To start the bot, simply go into the directory where the nanobot.pl file is located and type:
+
:To start the bot simply go into the directory where the nanobot.rb file is located and type:
   perl nanobot.pl
+
   ruby nanobot.rb
 
 
  
  
 
=== Commandline options ===
 
=== Commandline options ===
The following options may be appended:
+
The following options may be used:
:'''-s''' or '''--ssl''': Tell the bot to use Secure Socket Layers for it's connection.
+
:'''-h''' or '''--help'''      : Print this help and quit.
:'''-h''' or '''--help''': Print a short help on which functions are available.
+
:'''-s''' or '''--ssl'''       : Enable SSL connections. The default for this setting is held in config.rb's @use_ssl setting.
:'''-v''' or '''--version''': Print the version number and exit.
+
:'''-4''' or '''--ipv4'''      : Pick the @server variable as the server to connect to.
:'''-q''' or '''--quiet''': Don't generate any output.
+
:'''-6''' or '''--ipv6'''      : Pick the @server6 variable as the server to connect to. The default for choosing IPv4 or IPv6 is held in config.rb's @use_ipv6 setting.
:'''-d''' or '''--debug''': Print debugging lines. May be used twice to see all incomming and outgoing traffic.
+
:'''-t''' or '''--thread'''     : Enable threading.
 +
:'''-nt''' or '''--no-threads''': Disable threading. Normally there is no reason to disable threading and doing so breaks some functionality that relies on threads. (Like timered actions, the interactive console, output queuing and input throttling.) The default for choosing threading or not is held in config.rb's @use_thread setting.
 +
:'''-q''' or '''--quiet'''     : Disable normal output. Only errors will be shown
 +
:'''-c''' or '''--colour'''    : Disable coloured output. This may be required for some very old terminals.
 +
:'''-n''' or '''--no-console''' : Disable interactive console.
 +
:'''-p''' or '''--printconfig''': Show current configuration and quit.
 +
:'''-d''' or '''--debug'''     : Show debug output. Use once to show normal debug messages, twice to show all input and output over the IRC socket and three times to join all threads back to the main thread when they finish, show a stacktrace and quit when a thread crashes.
  
 
Short and long options may be interchanged.
 
Short and long options may be interchanged.
  
 
:Example:
 
:Example:
   perl nanobot.pl --ssl -d --debug
+
   ruby nanobot.rb --ssl -d --debug
:This would start the bot with Secure Socket Layers, and it's most verbose level of debugging.
+
:This would start the bot with Secure Socket Layers, and it's 2nd most verbose level of debugging.
 
 
 
 
 
 
== Bot commands ==
 
:Commands: '''!command'''
 
:Example '''!help'''
 
  
:Command arguments: ''[argument]''
 
:Example: '''!voice''' ''Bobby''
 
  
:Multiple options for the same argument: ''[argument 1|argument 2]''
+
== Built in bot commands ==
:Example: '''!bot''' ''on''
+
By itself the bot only has the bare essential commands required to operate. Most of the common others are implemented in the 'core' plugin.
 +
How the commands are called is defiled by the @command setting in config.rb. Here we will assume '\!' is set.
  
 +
:'''!quit''' ''message'' Instruct the bot to quit. The quit message may be specified, if omitted a default one is used.
 +
:'''!load''' ''plugin'' Load a plugin.
 +
:'''!unload''' ''plugin'' Unload a plugin.
 +
:'''!reload''' ''plugin'' Shortcut to unload and load a plugin.
 +
:'''!autoload''' Loads all modules in the @autoload list. Normally you don't need to use this command as it is executed automatically when the bot starts.
 +
:'''!loaded''' Show the list of currently loaded plugins.
 +
:'''!available''' Show the list of all plugins in the plugins directory.
  
 +
The order of looking for looking for commands is as follows:
 +
:Internal commands => Core plugin => Other plugins function => Other plugins main<br/>
 +
(In reality it will first resolve aliases but well look at that in the '''Aliases plugin''' section later.)
  
=== Public commands ===
 
:'''!help''' Sends available commands to the user.
 
:'''!version''' Sends the running version to the user.
 
:'''!seen''' ''[nickname]'' Shows when the user was last seen, and what he said.
 
  
 +
Examples:
 +
!load demo
 +
Will find there is a 'load' function internally and use that<br/>
 +
!kick user
 +
Will look for an internal command 'kick' but find none, then continue to look for a 'kick' in the core plugin and there find a function to execute.
 +
!demo function
 +
Will look for but not find a 'demo' function either internally or in the core and then proceed to look for a plugin called 'demo', find that and sees that it indeed has a function called 'function' which it can execute.
 +
!demo arguments
 +
Much the same as the previous except it will find there is no function called 'arguments' in the demo plugin. It then looks for a 'main' function in the demo plugin and executes that with 'arguments' as the function arguments to 'main'.
  
  
=== Admin commands ===
+
=== Plugins ===
:'''!quit''' ''[message]'' Stop the bot. (Message arguement may be ignored.)
+
Loading a plugin will give your bot the added functionality from this plugin. To call functions from a plugin you can use the following syntax:
:'''!join''' ''[channel]'' Join specified channel.
+
!plugin_name function_name arguments list
:'''!part''' ''[channel]'' Part specified channel.
+
This means the bot will look in ''plugins/plugin_name.rb'' for a function called ''function_name'' that it can call with the options ''arguments list''.
:'''!topic''' ''[topic]'' Set new topic in current channel.
+
Some functions will be called automatically in the event of certain actions:
:'''!mode''' ''[modeline]'' Raw IRC mode line. Example: !mode #mychannel +i Bobby
+
:'''initialize''': This function gets called when the plugin is loaded into memory and an instance is created of the class.
:'''!nick''' ''[botnick]'' Change the bots nickname.
+
:'''main''': This is the function that gets called when the plugin is called without any function name. For example just '''!plugin_name'''.
:'''!loadlist''' Load lists containing hostmasks for auto-oper, auto-voice etc. for the modchan.
+
:'''unload''': Called just before the module is unloaded or reloaded in order to do any required cleanup.
:'''!modchan''' ''[channel]'' Set active channel. Returms current modchan when no arguemnet is given.
+
:'''messaged''': When someone sends any message the bot receives.
:'''!bot''' ''[on|off]'' Switch bot on or off. (Auto voice, auto oper, seen command etc.) On by default.
+
:'''noticed''': When someone sends a notice the bot receives.
:'''!all''' ''[op|hop|voice]'' Give this status to every user who enters the modchan.
+
:'''joined''': When a user joins a channel the bot is on.
:'''!none''' ''[op|hop|voice]'' Undo for the !all command.
+
:'''parted''': When a user parts a channel the bot is on.
:'''!add''' ''[op|hop|voice|kick]'' ''[hostmask]'' Add hostmask to the specified list.
+
:'''kicked''': When a user is kicked from a channel the bot is on.
:'''![op|deop|hop|dehop|voice|devoice]''' ''[nick]'' Give/take ops, half-ops and voice. When no nickname is given, action is preformed on yourself.
+
:'''quited''': When a user quits from a channel the bot is on.
:'''!kick''' ''[nick]'' Kick user from the channel.
+
:'''servermsg''': When the bot receives an IRC server message for which some parsing exists.
:'''![ban|unban]''' ''[hostmask]'' Ban/unban hosts from the current channel.
+
:'''miscservermsg''': When the bot receives an IRC server message for which no parsing exists.
:'''!admin''' ''[add|del]'' ''[hostmask]'' Control admin access to the bot. When no hostmask is given, the current list of admins is returned.
+
:'''misc''': When the bot receives something from the IRC socket that it has no idea what to do with.
:'''!raw''' ''[data]'' Send raw data to the IRC server.
+
:'''help''': Can be called manually but may also be called by the help plugin. (More on this later.)
  
  
 +
=== Core plugin ===
 +
The core plugin is a special case. It contains many common IRC bot commands. Use '''!help core''' to get the full list. The reason it is special is that it is always the first plugin to be checked for the existence of a command and it does not need to be called as '''!core function'''. Functions in the core may be called directly with '''!function'''.
  
=== Module commands ===
 
:'''![load|unload|reload]''' ''[module]'' Load / unload / reload a module. (Bare module name only, no directory name or .pm)
 
:'''!loaded''' List currently loaded modules.
 
:'''!available''' List all available modules.
 
:'''!pubmods''' ''[on|off]'' Switch public usage of modules on or off. (This effectively makes everyone a bot admin for the modules.)
 
  
 +
=== Help plugin ===
 +
This plugin contains the help for the core plugin but can also attempt to locate any help function in a loaded plugin. For example '''!help demo''' would look for the ''help'' function in the ''demo'' plugin and execute that. This means that '''!help demo''' and '''!demo help''' will effectively have the same result.
  
;Calling a command in a module follows this syntax:
 
:'''!modulename.command''' ''[Args]''
 
:Arguments may or may not be needed, this depends on the command and the module.
 
  
:When only '''!modulename''' is called, it will execute the module's "help" command if one is available.
+
=== Aliases plugin ===
 +
This is another special plugin. It has no functions that can be called directly but instead contains a list of aliases to make calling certain commands more convenient.
 +
For example you may find that '''!demo function''' is an extremely popular command, you can specify an alias that would make it possible to use the command '''!func''' as a shorthand for '''!demo function'''. You would simply add
 +
"func"  => "demon function",
 +
to the @alias list in the aliases plugin. Whenever the bot then receives a command starting with '''!func''' it will internally rewrite this to '''!demo function'''.<br/>
 +
'''Make sure aliases are still unique!''' if you use something as an alias that is not unique you can introduce a conflict. For example if you use just '''f''' as an alias for '''demo function''' it will pick up anything starting with an f. So a command '''!foo bar''' would be rewritten to '''demo functionoo bar'''. Clearly this is not what our intention for the alias was.

Revision as of 10:07, 22 August 2014

Environment

To run the bot you need to have Ruby installed. Specific plugins may requires additional gems
If you have plugins you want to load, take a directory named "plugins" in the same folder where your nanobot.rb resides, and place your plugin files in there.


Configuration

To configure your bots settings like the server and nickname, open config.rb in a text editor.
Just a few lines into the file, you will find this block of text:
	def initialize( status, output )
		@nick		= "nanobot"					# Bot nickname
		@user		= "nanobot"					# IRC username
		@pass		= ""						# NickServ password
		@version	= "Nanobot 4"					# Version

		@command	= '\!'						# Character prefix for commands (escape special chars)

		@server		= "irc.insomnia247.nl"				# IPv4 address
		@server6	= "irc6.insomnia247.nl"				# IPv6 address
		@port		= 6667						# Normal port
		@sslport	= 6697						# SSL port
		@serverpass = ""						# Server connect password
		@connectopt = ""						# Extra stuff to send on connect

		@channels	= [ "#bot", "#test" ]				# Autojoin channel list

		@opers		= [ "insomnia247.nl" ]				# Opers list

		@data		= "data"					# Data directory
		@plugins	= "plugins"					# Plugin directory
		@autoload	= [ "core", "toolbox" ]				# Plugin autoload list

		@antiflood	= true						# Attempt to mitigate people flooding bot with commands
		@floodtime	= 5						# Seconds withing which the flood limit is triggered
		@floodcut	= 30						# Limit on the number of seconds delay before starting to drop

		@throttle	= true						# Throttle output to avoid flooding from the bot

		@autorejoin	= true						# Rejoin on kick
		@rejointime	= 3						# Time to wait before rejoin (seconds)

		@pingwait	= false						# Wait for server's first PING
		@conn_time	= 20						# Connect timeout
		@timeout	= 300						# IRC timeout

		@use_thread	= true						# Prefer threading
		@use_ipv6	= false						# Prefer IPv6
		@use_ssl	= true						# Prefer SSL
		@verif_ssl	= false						# Verify SSL certificate
		@rootcert	= "/etc/ssl/certs/ca-certificates.crt"		# Path to openssl root certs (Needed if verify_ssl is enabled)

		@threadfb	= true						# Allow fallback to sequential processing when threads aren't available
		@sslfback	= false						# Allow fallback to insecure connect when OpenSSL library isn't available

		@status		= status					# System object, do not modify
		@output		= output					# System object, do not modify
	end
These are the variables that hold the bots configuration, a few of the ones you may want to have a look at are:
nick: This is bots own nickname.
pass: If you've registered the bot's nick with NickServ, put the password here.
command: This is the character commands are prefixed with on IRC. So "@command = '\!'" means on irc you would do things like "!help" and "!version"
server: The server the bot connects to
server6: If the server's IPv6 address is different you can specify that here.
port: The port the bot connect on without SSL
sslport: The port the bot connect on with SSL
channels: List of channels the bot will join when it connects to the server.
opers: Hostnames or hostmasks for bot admins. Note that they must appear as the bot sees them.
Only the hostname should be added. (So if you are someguy!bob@SOMEHASH-my.isp.com you should add "SOMEHASH-my.isp.com".)
autoload: The list of plugins that will automatically be loaded when the bot starts up.
All the other values can be tweaked as required but usually this isn't needed.

Starting command

To start the bot simply go into the directory where the nanobot.rb file is located and type:
 ruby nanobot.rb


Commandline options

The following options may be used:

-h or --help  : Print this help and quit.
-s or --ssl  : Enable SSL connections. The default for this setting is held in config.rb's @use_ssl setting.
-4 or --ipv4  : Pick the @server variable as the server to connect to.
-6 or --ipv6  : Pick the @server6 variable as the server to connect to. The default for choosing IPv4 or IPv6 is held in config.rb's @use_ipv6 setting.
-t or --thread  : Enable threading.
-nt or --no-threads: Disable threading. Normally there is no reason to disable threading and doing so breaks some functionality that relies on threads. (Like timered actions, the interactive console, output queuing and input throttling.) The default for choosing threading or not is held in config.rb's @use_thread setting.
-q or --quiet  : Disable normal output. Only errors will be shown
-c or --colour  : Disable coloured output. This may be required for some very old terminals.
-n or --no-console : Disable interactive console.
-p or --printconfig: Show current configuration and quit.
-d or --debug  : Show debug output. Use once to show normal debug messages, twice to show all input and output over the IRC socket and three times to join all threads back to the main thread when they finish, show a stacktrace and quit when a thread crashes.

Short and long options may be interchanged.

Example:
 ruby nanobot.rb --ssl -d --debug
This would start the bot with Secure Socket Layers, and it's 2nd most verbose level of debugging.


Built in bot commands

By itself the bot only has the bare essential commands required to operate. Most of the common others are implemented in the 'core' plugin. How the commands are called is defiled by the @command setting in config.rb. Here we will assume '\!' is set.

!quit message Instruct the bot to quit. The quit message may be specified, if omitted a default one is used.
!load plugin Load a plugin.
!unload plugin Unload a plugin.
!reload plugin Shortcut to unload and load a plugin.
!autoload Loads all modules in the @autoload list. Normally you don't need to use this command as it is executed automatically when the bot starts.
!loaded Show the list of currently loaded plugins.
!available Show the list of all plugins in the plugins directory.

The order of looking for looking for commands is as follows:

Internal commands => Core plugin => Other plugins function => Other plugins main

(In reality it will first resolve aliases but well look at that in the Aliases plugin section later.)


Examples:

!load demo

Will find there is a 'load' function internally and use that

!kick user

Will look for an internal command 'kick' but find none, then continue to look for a 'kick' in the core plugin and there find a function to execute.

!demo function

Will look for but not find a 'demo' function either internally or in the core and then proceed to look for a plugin called 'demo', find that and sees that it indeed has a function called 'function' which it can execute.

!demo arguments

Much the same as the previous except it will find there is no function called 'arguments' in the demo plugin. It then looks for a 'main' function in the demo plugin and executes that with 'arguments' as the function arguments to 'main'.


Plugins

Loading a plugin will give your bot the added functionality from this plugin. To call functions from a plugin you can use the following syntax:

!plugin_name function_name arguments list

This means the bot will look in plugins/plugin_name.rb for a function called function_name that it can call with the options arguments list. Some functions will be called automatically in the event of certain actions:

initialize: This function gets called when the plugin is loaded into memory and an instance is created of the class.
main: This is the function that gets called when the plugin is called without any function name. For example just !plugin_name.
unload: Called just before the module is unloaded or reloaded in order to do any required cleanup.
messaged: When someone sends any message the bot receives.
noticed: When someone sends a notice the bot receives.
joined: When a user joins a channel the bot is on.
parted: When a user parts a channel the bot is on.
kicked: When a user is kicked from a channel the bot is on.
quited: When a user quits from a channel the bot is on.
servermsg: When the bot receives an IRC server message for which some parsing exists.
miscservermsg: When the bot receives an IRC server message for which no parsing exists.
misc: When the bot receives something from the IRC socket that it has no idea what to do with.
help: Can be called manually but may also be called by the help plugin. (More on this later.)


Core plugin

The core plugin is a special case. It contains many common IRC bot commands. Use !help core to get the full list. The reason it is special is that it is always the first plugin to be checked for the existence of a command and it does not need to be called as !core function. Functions in the core may be called directly with !function.


Help plugin

This plugin contains the help for the core plugin but can also attempt to locate any help function in a loaded plugin. For example !help demo would look for the help function in the demo plugin and execute that. This means that !help demo and !demo help will effectively have the same result.


Aliases plugin

This is another special plugin. It has no functions that can be called directly but instead contains a list of aliases to make calling certain commands more convenient. For example you may find that !demo function is an extremely popular command, you can specify an alias that would make it possible to use the command !func as a shorthand for !demo function. You would simply add

"func"  => "demon function",

to the @alias list in the aliases plugin. Whenever the bot then receives a command starting with !func it will internally rewrite this to !demo function.
Make sure aliases are still unique! if you use something as an alias that is not unique you can introduce a conflict. For example if you use just f as an alias for demo function it will pick up anything starting with an f. So a command !foo bar would be rewritten to demo functionoo bar. Clearly this is not what our intention for the alias was.