Go to file
Pragmatic Software 8e3652bc8e
pbot-vm: gdb() needs __asm__() instead of asm()
2024-04-17 00:37:36 -07:00
Docker Update applets/cdecl.pl command and add cdecl to Dockerfile 2024-04-10 13:32:16 -07:00
Plang@5afe33a14c Update Plang submodule 2023-11-23 16:05:40 -08:00
applets pbot-vm: gdb() needs __asm__() instead of asm() 2024-04-17 00:37:36 -07:00
bin Update copyright 2023-02-20 21:31:52 -08:00
data Multiple bugfixes 2024-04-07 20:55:04 -07:00
doc pbot-vm: update documentation about how to start PBot VM after reboot 2024-04-10 13:09:58 -07:00
lib/PBot pbot-vm: gdb() needs __asm__() instead of asm() 2024-04-17 00:37:36 -07:00
misc Update WordMorph 2022-08-26 00:33:41 -07:00
updates Factoids: add `keep-quotes` metadata for applet commands 2022-06-27 19:52:38 -07:00
.gitattributes Update .gitattributes 2021-11-19 18:31:44 -08:00
.gitignore update .gitignores 2020-01-31 15:39:40 -08:00
.gitmodules Replace applets/qrpn with submodule (#72) 2023-01-02 16:54:27 -08:00
LICENSE Relicense under MIT 2021-07-10 15:00:22 -07:00
README.md Add Wordle plugin; update games section of README 2024-03-07 03:17:07 -08:00
cpanfile Update cpanfile 2024-03-16 17:32:37 -07:00

README.md

PBot

PBot is a pragmatic IRCv3 Bot written in Perl

Installation / Quick Start

To get up-and-running quickly, check out the Quick Start guide.

Features

IRCv3 capable

PBot supports several features of the IRCv3 specification.

  • client capability negotiation
  • SASL authentication
  • account-tag, account-notify, extended-join, message-tags, 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.

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.

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.

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, which can be chained to combine their effects.

<pragma-> !echo $greeting:uc
   <PBot> HELLO, WORLD

Learn more.

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.

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.

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.

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 command to set the background-process command metadata and the command will now run as a background process, allowing PBot to carry on with its duties.

The familiar ps and kill commands can be used to list and kill the background processes.

You can also cmdset the process-timeout command metadata to set the timeout, in seconds, before the command is automatically killed. Otherwise the processmanager.default_timeout registry value 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.

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:

For more information, see the Factoids documentation.

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:

<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.

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:

Plugin Description
ActionTrigger Lets admins set regular expression triggers to execute PBot commands or factoids.
GoogleSearch Performs Internet searches using the Google search engine.
Quotegrabs Grabs channel messages as quotes for posterity. Can grab messages from anywhere in the channel history. Can grab multiple messages at once!
RemindMe Lets people set up reminders. Lots of options.
Weather Fetches and shows weather data for a location.
Wolfram Queries Wolfram|Alpha for answers.
Wttr Advanced weather Plugin with tons of options. Uses wttr.in.
UrlTitles 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 The classic Battleship board game, simplified for IRC. Multiple players can compete at once on the same battlefield!
Connect4 The classic two-player Connect-4 game.
Spinach 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!
Wordle Guess a word by submitting words for clues about which letters belong to the word.
WordMorph Solve a path between two words by changing one letter at a time.

Applets

Applets are external command-line executable programs and scripts that can be loaded as PBot commands.

Suppose you have the Qalculate! 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 lets call it qalc.sh and put it in PBots applets/ directory.

Then you can load it with the load command.

!load qalc qalc.sh

Now you have a Qalculate! 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 Translates C code to natural English sentences.
C precedence analyzer Adds parentheses to C code to demonstrate precedence.
C Jeopardy! game C programming trivia game based on the Jeopardy! TV game show.
C Standard citations Cite specified sections/paragraphs from the C standard.
Virtual machine Executes arbitrary code and commands within a virtual machine.
dict.org Dictionary Interface to dict.org for definitions, translations, acronyms, etc.
Urban Dictionary Search Urban Dictionary for definitions.
Manpages Display a concise formatting of manual pages (designed for C functions)

For more information, see the Applets documentation.

Functions

Functions are commands that accept input, manipulate it and then output the result. They are extremely useful with piping or command substituting.

For example, the uri_escape function demonstrated in the 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. 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!

Heres 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.

Scripting interface

PBot uses 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.

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 out of the box!

One of PBots most powerful features, 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.

For more information about the virtual machine, see the Virtual Machine documentation.

Powerful user management

PBot has powerful yet simple user management functionality and commands.

  • instead of generic access-levels, PBot uses fine-grained user capabilities, which can be grouped into roles such as Admin, ChanOp, Moderator, etc
  • 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 with the my command
  • and much, much more!

For more information, see the Admin documentation.

Useful IRC quality-of-life improvements

  • 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 and mute will intelligently set banmasks; supports timeouts
  • ban and mute can take a comma-separate list of nicks. Will intelligently group them into multiple MODE +bbbb commands
  • kick can take a comma-separated list of nicks; also accepts wildcards
  • and much, much more!

For more information, see the Admin documentation.

Channel management and protection

PBot can perform the typical channel management tasks.

For more information, see the Channels documentation and the Anti-abuse documentation

Easy configuration

PBots settings are contained in a central registry of key/value pairs grouped by sections.

These settings can easily be configured via several methods:

For more information, see the Registry documentation.

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 or a Plugin such as PBot/Plugin/Wttr.pm. Or suppose theres 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 command to reload all modified PBot core files and Plugins without bot restart.

You can also use the reload command to reload any modified configuration or data files.

Documentation

See the PBot documentation for more information.

Frequently Asked Questions

If you have a question, try the PBot FAQ!

Support

For additional questions and support, feel free to join the #pbot channel on the Libera.Chat IRC network (Web Chat).

License

PBot is licensed under the MIT license.