mirror of
https://github.com/pragma-/pbot.git
synced 2024-12-23 19:22:40 +01:00
3d97dc2c33
"Applet" is a much better name for the external command-line scripts and programs that can be loaded as PBot commands. They will no longer be confused with Perl modules. https://en.wikipedia.org/wiki/Applet
430 lines
19 KiB
Markdown
430 lines
19 KiB
Markdown
# PBot
|
|
PBot is a pragmatic IRCv3 Bot written in Perl
|
|
|
|
<!-- md-toc-begin -->
|
|
* [Installation / Quick Start](#installation--quick-start)
|
|
* [Features](#features)
|
|
* [IRCv3 capable](#ircv3-capable)
|
|
* [Powerful command interpreter](#powerful-command-interpreter)
|
|
* [Piping](#piping)
|
|
* [Substitution](#substitution)
|
|
* [Variables](#variables)
|
|
* [Selectors](#selectors)
|
|
* [Inline invocation](#inline-invocation)
|
|
* [Chaining](#chaining)
|
|
* [Background processing](#background-processing)
|
|
* [Output customization](#output-customization)
|
|
* [Newlines in messages](#newlines-in-messages)
|
|
* [Truncating long messages](#truncating-long-messages)
|
|
* [Extensible](#extensible)
|
|
* [Factoids](#factoids)
|
|
* [Code factoids](#code-factoids)
|
|
* [Plugins](#plugins)
|
|
* [Applets](#applets)
|
|
* [Functions](#functions)
|
|
* [Scripting interface](#scripting-interface)
|
|
* [Virtual machine to safely execute user-submitted code](#virtual-machine-to-safely-execute-user-submitted-code)
|
|
* [Powerful user management](#powerful-user-management)
|
|
* [Useful IRC quality-of-life improvements](#useful-irc-quality-of-life-improvements)
|
|
* [Channel management and protection](#channel-management-and-protection)
|
|
* [Easy configuration](#easy-configuration)
|
|
* [Live reloading of core modules or data files](#live-reloading-of-core-modules-or-data-files)
|
|
* [Documentation](#documentation)
|
|
* [Frequently Asked Questions](#frequently-asked-questions)
|
|
* [Support](#support)
|
|
* [License](#license)
|
|
<!-- md-toc-end -->
|
|
|
|
## Installation / Quick Start
|
|
To get up-and-running quickly, check out the [Quick Start guide](doc/QuickStart.md).
|
|
|
|
## Features
|
|
|
|
### IRCv3 capable
|
|
PBot supports several features of the IRCv3 specification.
|
|
|
|
* client capability negotiation
|
|
* SASL authentication
|
|
* account-notify, extended-join, and more.
|
|
|
|
### Powerful command interpreter
|
|
PBot has a powerful command interpreter with useful functionality, and tons of
|
|
built-in commands.
|
|
|
|
For more information, see the [Commands documentation.](doc/Commands.md)
|
|
|
|
#### Piping
|
|
You can pipe output from one command as input into another command, indefinitely.
|
|
|
|
<pragma-> !echo hello world | {sed s/world/everybody/} | {uc}
|
|
<PBot> HELLO EVERYBODY
|
|
|
|
[Learn more.](doc/Commands.md#piping)
|
|
|
|
#### Substitution
|
|
You can insert the output from another command at any point within a command. This
|
|
substitutes the command with its output at the point where the command was used.
|
|
|
|
<pragma-> !echo This is &{echo a demonstration} of command substitution
|
|
<PBot> This is a demonstration of command substitution
|
|
|
|
For example, suppose you want to make a Google Image Search command. The naive
|
|
way would be to simply do:
|
|
|
|
<pragma-> !factadd img /call echo https://google.com/search?tbm=isch&q=$args
|
|
|
|
Unfortuately this would not support queries containing spaces or certain symbols. But
|
|
never fear! We can use command substitution and the `uri_escape` function from the
|
|
`func` command.
|
|
|
|
Note that you must escape the command substitution to insert it literally into the
|
|
factoid otherwise it will be expanded first.
|
|
|
|
<pragma-> !factadd img /call echo https://google.com/search?tbm=isch&q=\&{func uri_escape $args}
|
|
|
|
<pragma-> !img spaces & stuff
|
|
<PBot> https://google.com/search?tbm=isch&q=spaces%20%26%20stuff
|
|
|
|
[Learn more.](doc/Commands.md#substitution)
|
|
|
|
#### Variables
|
|
You can use factoids as variables and interpolate them within commands.
|
|
|
|
<pragma-> !factadd greeting "Hello, world"
|
|
|
|
<pragma-> !echo greeting is $greeting
|
|
<PBot> greeting is Hello, world
|
|
|
|
PBot variable interpolation supports [expansion modifiers](doc/Factoids.md#expansion-modifiers), which can be chained to
|
|
combine their effects.
|
|
|
|
<pragma-> !echo $greeting:uc
|
|
<PBot> HELLO, WORLD
|
|
|
|
[Learn more.](doc/Factoids.md#list-variables)
|
|
|
|
#### Selectors
|
|
You can select a random item from a selection list and interpolate the value within commands.
|
|
|
|
<pragma-> !echo This is a %(neat|cool|awesome) bot.
|
|
<PBot> This is a cool bot.
|
|
|
|
[Learn more.](doc/Commands.md#selectors)
|
|
|
|
#### Inline invocation
|
|
You can invoke up to three commands inlined within a message. If the message
|
|
is addressed to a nick, the output will also be addressed to them.
|
|
|
|
<pragma-> newuser13: Check the !{version} and the !{help} documentation.
|
|
<PBot> newuser13: PBot version 2696 2020-01-04
|
|
<PBot> newuser13: To learn all about me, see https://github.com/pragma-/pbot/tree/master/doc
|
|
|
|
[Learn more.](doc/Commands.md#command-invocation)
|
|
|
|
#### Chaining
|
|
You can execute multiple commands sequentially as one command.
|
|
|
|
<pragma-> !echo Test! ;;; me smiles. ;;; version
|
|
<PBot> Test! * PBot smiles. PBot version 2696 2020-01-04
|
|
|
|
[Learn more.](doc/Commands.md#chaining)
|
|
|
|
#### Background processing
|
|
Suppose you make a Plugin that provides a command that may potentially take a long time to complete?
|
|
Not a problem! You can use the [`cmdset`](doc/Admin.md#cmdset) command to set the `background-process` [command metadata](doc/Admin.md#command-metadata-list)
|
|
and the command will now run as a background process, allowing PBot to carry on with its duties.
|
|
|
|
The familiar [`ps`](doc/Admin.md#ps) and [`kill`](doc/Admin.md#kill) commands can be used to list and kill the background processes.
|
|
|
|
You can also [`cmdset`](doc/Admin.md#cmdset) the `process-timeout` [command metadata](doc/Admin.md#command-metadata-list) to set the timeout, in seconds, before the command is automatically killed. Otherwise the `processmanager.default_timeout` [registry value](doc/Registry.md) will be used.
|
|
|
|
### Output customization
|
|
#### Newlines in messages
|
|
By default, PBot replaces newlines in command output with spaces. This can be customized on a per-channel or global basis
|
|
to instead preserve the newlines and output each line as a distinct message.
|
|
|
|
[Learn more.](doc/FAQ.md#how-do-i-change-how-the-bot-outputs-multi-line-messages)
|
|
|
|
#### Truncating long messages
|
|
Output that is longer than the maximum length of an IRC message will be pasted,
|
|
with all formatting preserved, to a web paste service. The IRC message itself
|
|
will be truncated, with enough room to append the paste URL.
|
|
|
|
When `preserve_newlines` is enabled, if there are more lines available than `max_newlines` then
|
|
all of the lines will be pasted, with formatting preserved, to a web paste service. PBot will then
|
|
output up to `max_newlines` lines as distinct messages and then output the URL to the paste.
|
|
|
|
### Extensible
|
|
Additional commands and functionality can be added to PBot in the following ways.
|
|
|
|
#### Factoids
|
|
Factoids are a very special type of command. Anybody interacting with PBot
|
|
can create, edit, delete and invoke factoids.
|
|
|
|
A simple factoid merely displays the text the creator sets.
|
|
|
|
<pragma-> !factadd hello /say Hello, $nick!
|
|
<PBot> hello added to global channel.
|
|
|
|
<pragma-> PBot, hello
|
|
<PBot> Hello, pragma-!
|
|
|
|
Significantly more complex factoids can be built by using `$variables`, command-substitution,
|
|
command-piping, `/code` invocation, command prefixes such as `/say`, `/me`, `/msg`, and more!
|
|
|
|
PBot factoids include these advanced features:
|
|
|
|
* [undo/redo history](doc/Factoids.md#factundo)
|
|
* [changelog history](doc/Factoids.md#factlog)
|
|
* [channel namespaces](doc/Factoids.md#channel-namespaces)
|
|
* [`factadd`](doc/Factoids.md#factadd) and [`factchange`](doc/Factoids.md#factchange) commands accept a `-url` option that sets the factoid contents from a paste website. In other words, you can edit a factoid's contents using your local editor, preserving line-breaks and indentation.
|
|
* [advanced `$variable` interpolation](doc/Factoids.md#expansion-modifiers) (`$var:lc` to lowercase contents, `$var:ucfirst` to uppercase first letter, etc)
|
|
* [factoid-based variable lists](doc/Factoids.md#list-variables) (e.g., add a factoid `colors` containing "red green blue" and then `!echo $colors` will randomly pick one)
|
|
* [advanced argument processing](doc/Factoids.md#special-variables-1) (indexing, splicing, etc)
|
|
* [metadata](doc/Factoids.md#factoid-metadata) (e.g. owner, times used, last used date, locked, etc)
|
|
* [special commands](doc/Factoids.md#special-commands) (`/say`, `/me`, `/msg`, `/code`, etc)
|
|
* and much, much more!
|
|
|
|
For more information, see the [Factoids documentation](doc/Factoids.md).
|
|
|
|
#### Code factoids
|
|
Code factoids are a special type of factoid that executes its contents within a sandboxed virtual machine.
|
|
|
|
The contents of code factoids must begin with the `/code` command:
|
|
|
|
/code <language> <code>
|
|
|
|
For example, the venerable `rot13` function:
|
|
|
|
<pragma-> !factadd rot13 /code sh echo "$@" | tr a-zA-Z n-za-mN-ZA-M
|
|
<PBot> rot13 added to global channel.
|
|
|
|
<pragma-> !rot13 Pretty neat, huh?
|
|
<PBot> Cerggl arng, uhu?
|
|
|
|
Making a `choose` command:
|
|
|
|
<pragma-> !factadd choose /code zsh _arr=($args); print $_arr[$((RANDOM % $#_arr + 1))]
|
|
<PBot> choose added to global channel.
|
|
|
|
Using the `choose` command via an [inlined command](doc/Commands.md#inline-invocation):
|
|
|
|
<pragma-> hmm, what should I have for dinner? !{choose chicken "roast beef" pizza meatloaf}
|
|
<PBot> pizza
|
|
|
|
You can even pipe output from other commands to Code Factoids.
|
|
|
|
<pragma-> !echo test | {rot13}
|
|
<PBot> grfg
|
|
|
|
For more information, see the [Code Factoid documentation](doc/Factoids.md#code).
|
|
|
|
#### Plugins
|
|
PBot can dynamically load and unload Perl modules to alter its behavior.
|
|
|
|
These are some of the plugins that PBot has; [there are many more](lib/PBot/Plugin):
|
|
|
|
Plugin | Description
|
|
--- | ---
|
|
[ActionTrigger](lib/PBot/Plugin/ActionTrigger.pm) | Lets admins set regular expression triggers to execute PBot commands or factoids.
|
|
[GoogleSearch](lib/PBot/Plugin/GoogleSearch.pm) | Performs Internet searches using the Google search engine.
|
|
[Quotegrabs](lib/PBot/Plugin/Quotegrabs.pm) | Grabs channel messages as quotes for posterity. Can grab messages from anywhere in the channel history. Can grab multiple messages at once!
|
|
[RemindMe](lib/PBot/Plugin/RemindMe.pm) | Lets people set up reminders. Lots of options.
|
|
[Weather](lib/PBot/Plugin/Weather.pm) | Fetches and shows weather data for a location.
|
|
[Wolfram](lib/PBot/Plugin/Wolfram.pm) | Queries Wolfram\|Alpha for answers.
|
|
[Wttr](lib/PBot/Plugin/Wttr.pm) | Advanced weather Plugin with tons of options. Uses wttr.in.
|
|
[UrlTitles](lib/PBot/Plugin/UrlTitles.pm) | When a URL is seen in a channel, intelligently display its title. It will not display titles that are textually similiar to the URL, in order to maintain the channel signal-noise ratio.
|
|
|
|
There are even a few games!
|
|
|
|
Plugin | Description
|
|
--- | ---
|
|
[Battleship](lib/PBot/Plugin/Battleship.pm) | The classic Battleship board game, simplified for IRC
|
|
[Connect4](lib/PBot/Plugin/Connect4.pm) | The classic Connect-4 game.
|
|
[Spinach](lib/PBot/Plugin/Spinach.pm) | An advanced multiplayer Trivia game engine with a twist! A question is shown. Everybody privately submits a false answer. All false answers and the true answer is shown. Everybody tries to guess the true answer. Points are gained when people pick your false answer!
|
|
|
|
#### Applets
|
|
Applets are external command-line executable programs and scripts that can be
|
|
loaded as PBot commands.
|
|
|
|
Suppose you have the [Qalculate!](https://qalculate.github.io/) command-line
|
|
program and you want to provide a PBot command for it. You can create a _very_ simple
|
|
shell script containing:
|
|
|
|
#!/bin/sh
|
|
qalc "$*"
|
|
|
|
And let's call it `qalc.sh` and put it in PBot's `applets/` directory.
|
|
|
|
Then you can load it with the [`load`](doc/Admin.md#load) command.
|
|
|
|
!load qalc qalc.sh
|
|
|
|
Now you have a [Qalculate!](https://qalculate.github.io/) calculator in PBot!
|
|
|
|
<pragma-> !qalc 2 * 2
|
|
<PBot> 2 * 2 = 4
|
|
|
|
These are just some of the applets PBot comes with; there are several more:
|
|
|
|
Applet | Description
|
|
--- | ---
|
|
[C-to-English translator](applets/c2english) | Translates C code to natural English sentences.
|
|
[C precedence analyzer](applets/paren) | Adds parentheses to C code to demonstrate precedence.
|
|
[C Jeopardy! game](applets/cjeopardy) | C programming trivia game based on the Jeopardy! TV game show.
|
|
[C Standard citations](applets/c11std.pl) | Cite specified sections/paragraphs from the C standard.
|
|
[Virtual machine](applets/compiler_vm) | Executes arbitrary code and commands within a virtual machine.
|
|
[dict.org Dictionary](applets/dict.org.pl) | Interface to dict.org for definitions, translations, acronyms, etc.
|
|
[Urban Dictionary](applets/urban) | Search Urban Dictionary for definitions.
|
|
[Manpages](applets/man.pl) | Display a concise formatting of manual pages (designed for C functions)
|
|
|
|
For more information, see the [Applets documentation](doc/Applets.md).
|
|
|
|
#### Functions
|
|
Functions are commands that accept input, manipulate it and then output the result. They are extremely
|
|
useful with [piping](#piping) or [command substituting](#substitution).
|
|
|
|
For example, the `uri_escape` function demonstrated in the [Substitution](#substitution) section earlier
|
|
makes text safe for use in a URL.
|
|
|
|
<pragma-> uri_escape thing's & words
|
|
<PBot> thing%27s%20%26%20words
|
|
|
|
We also saw the `sed` and `uc` functions demonstrated in [Piping](#piping). The `sed` function
|
|
replaces text using a substitution regex. The `uc` function uppercases the text.
|
|
|
|
<pragma-> echo Hello world! | {sed s/world/universe/} | {uc}
|
|
<PBot> HELLO UNIVERSE!
|
|
|
|
Here's a short list of the Functions that come with PBot.
|
|
|
|
Name | Description
|
|
--- | ---
|
|
`uri_escape` | Percent-encodes unsafe URI characters.
|
|
`sed` | Performs sed-like regex substitution.
|
|
`grep` | Searches a string, using a regex, and prints the matching whole-word (e.g. `echo pizza hamburger hotdog \| {grep burger}` outputs `hamburger`).
|
|
`pluralize` | Intelligently makes a word or phrase plural.
|
|
`unquote` | Removes surrounding quotation marks.
|
|
`title` | Title-cases text. That is, lowercases the text then uppercases the first letter of each word.
|
|
`ucfirst` | Uppercases the first character of the text.
|
|
`uc` | Uppercases all characters.
|
|
`lc` | Lowercases all characters.
|
|
|
|
Additional Functions can easily be added by making a very simple PBot Plugin.
|
|
|
|
For more information, see the [Functions documentation](doc/Functions.md).
|
|
|
|
#### Scripting interface
|
|
PBot uses [Plang](https://github.com/pragma-/Plang) as a scripting language. You can use the
|
|
scripting language to construct advanced commands that are capable of interacting with PBot
|
|
internal API functions.
|
|
|
|
[Learn more.](doc/Plugins/Plang.md)
|
|
|
|
### Virtual machine to safely execute user-submitted code
|
|
PBot can integrate with a virtual machine to safely execute arbitrary user-submitted
|
|
operating system commands or code.
|
|
|
|
PBot supports [several shells and languages](doc/Factoids.md#supported-languages) out of the box!
|
|
|
|
One of PBot's most powerful features, [Code Factoids](#code-factoids), would not be possible without this.
|
|
|
|
<pragma-> !sh echo Remember rot13? | tr a-zA-Z n-za-mN-ZA-M
|
|
<PBot> Erzrzore ebg13?
|
|
|
|
<!-- -->
|
|
|
|
<nil> !go package main\nimport "fmt"\nfunc main() { fmt.Print("foo" == "foo"); }
|
|
<PBot> true
|
|
|
|
<!-- -->
|
|
|
|
<pragma-> !python print('Hello there!')
|
|
<PBot> Hello there!
|
|
|
|
PBot has extensive support for the C programming language. For instance, the C programming language
|
|
plugin is integrated with the GNU Debugger. It will print useful debugging information.
|
|
|
|
<pragma-> !cc char *p = 0; *p = 1;
|
|
<PBot> runtime error: store to null pointer of type 'char'
|
|
Program received signal SIGSEGV, Segmentation fault at
|
|
statement: *p = 1; <local variables: p = 0x0>
|
|
|
|
It can display the value of the most recent statement if there is no program output.
|
|
|
|
<pragma-> !cc sizeof (int)
|
|
<PBot> no output: sizeof(int) = 4
|
|
|
|
For more information about the C programming language plugin, see [the `cc` command in the Applets documentation.](doc/Applets.md#cc)
|
|
|
|
For more information about the virtual machine, see the [Virtual Machine documentation.](doc/VirtualMachine.md)
|
|
|
|
### Powerful user management
|
|
PBot has powerful yet simple user management functionality and commands.
|
|
|
|
* instead of generic access-levels, [fine-grained user capabilities](doc/Admin.md#user-capabilities) limit what users may do
|
|
* user accounts can be global or channel-specific
|
|
* users can be recognized by hostmask or required to login with password
|
|
* users can adjust their [user-metadata](doc/Admin.md#user-metadata-list) with the [`my`](doc/Commands.md#my) command
|
|
* and much, much more!
|
|
|
|
For more information, see the [Admin documentation.](doc/Admin.md#user-management-commands)
|
|
|
|
### Useful IRC quality-of-life improvements
|
|
* [`mode`](doc/Admin.md#mode) command can take wildcards, e.g. `mode +ov foo* bar*` to op nicks beginning with `foo` and voice nicks beginning with `bar`
|
|
* `unban <nick>` and `unmute <nick>` will remove all bans/mutes matching their current or previously seen hostmasks or accounts
|
|
* [`ban`](doc/Admin.md#banmute) and [`mute`](doc/Admin.md#banmute) will intelligently set banmasks; supports timeouts
|
|
* [`ban`](doc/Admin.md#banmute) and [`mute`](doc/Admin.md#banmute) can take a comma-separate list of nicks. Will intelligently group them into multiple `MODE +bbbb` commands
|
|
* [`kick`](doc/Admin.md#kick) can take a comma-separated list of nicks; also accepts wildcards
|
|
* and much, much more!
|
|
|
|
For more information, see the [Admin documentation.](doc/Admin.md)
|
|
|
|
### Channel management and protection
|
|
PBot can perform the typical channel management tasks.
|
|
|
|
* opping/deopping known users, etc
|
|
* channel-mode tracking/protection
|
|
* [user hostmask/alias tracking](doc/Admin.md#message-historyuser-tracking)
|
|
* [ban-evasion detection](doc/Admin.md#akalink)
|
|
* [flood detection](doc/AntiAbuse.md)
|
|
* whitelisting, blacklisting, etc
|
|
* spam/advertisement detection
|
|
* and much, much more!
|
|
|
|
For more information, see the [Channels documentation](doc/Admin.md#channel-management-commands) and the [Anti-abuse documentation](doc/AntiAbuse.md)
|
|
|
|
### Easy configuration
|
|
PBot's settings are contained in a central registry of key/value pairs grouped by sections.
|
|
|
|
These settings can easily be configured via several methods:
|
|
|
|
* [PBot's command-line arguments](doc/Registry.md#overriding-registry-values-via-command-line)
|
|
* [simple built-in commands (`regset`, `regunset`, etc)](doc/Registry.md#registry-commands)
|
|
* [editing](doc/Registry.md#editing-registry-file) the [`$data_dir/registry`](data/registry) plain-text JSON file
|
|
|
|
For more information, see the [Registry documentation.](doc/Registry.md)
|
|
|
|
### Live reloading of core modules or data files
|
|
Suppose you edit some PBot source file, be it a core file such as [PBot/Core/Interpreter.pm](lib/PBot/Core/Interpreter.pm) or
|
|
a Plugin such as [PBot/Plugin/Wttr.pm](lib/PBot/Plugin/Wttr.pm). Or suppose there's a PBot update available. Most simple
|
|
bots would require you to shut down the bot and restart it in order to see the modifications.
|
|
|
|
Not PBot! you can simply use the [`refresh`](doc/Admin.md#refresh) command to reload all modified
|
|
PBot core files and Plugins without bot restart.
|
|
|
|
You can also use the [`reload`](doc/Admin.md#reload) command to reload any modified
|
|
configuration or data files.
|
|
|
|
## Documentation
|
|
See the [PBot documentation](doc) for more information.
|
|
|
|
## Frequently Asked Questions
|
|
If you have a question, try the [PBot FAQ](doc/FAQ.md)!
|
|
|
|
## Support
|
|
For additional questions and support, feel free to join the `#pbot` channel on the [Libera.Chat](https://libera.chat/guides) IRC network ([Web Chat](https://web.libera.chat/#pbot)).
|
|
|
|
## License
|
|
PBot is licensed under the [MIT license](LICENSE).
|