Plugins are enabled or disabled under plugins..enabled in config.yaml. !help prints a compact one-line index; use !help for details. !alias prints aliases without flooding the channel.
- correction: IRC-style spelling corrections
- banter: optional replies when GoBot is directly addressed
- welcome: optional, probability-based join greetings with a per-channel cooldown
- urltitle: page titles and YouTube metadata
- youtube: single-result YouTube video and music search
- cve: NVD CVE lookup with CVSS and affected software
- ipinfo: IP/ASN context through IP-API
- acronym: local operator-maintained acronym expansion
- weather: Open-Meteo weather, no key required
- steam: Steam game search, genre links, and most-played lookup, no key required
- news: NewsAPI headlines and search
- ask: source-grounded questions with optional AI rewriting
- wikipedia: English Wikipedia summaries
- horoscope: daily zodiac horoscopes
- urban: Urban Dictionary definitions
- reddit: compact Reddit post metadata
- foods: local food, cuisine, beer, coffee, tea, and wine suggestions
- sports: broad local sports suggestions
- car: broad local make, model, and production-span suggestions
- define: short English dictionary definitions
- calc: safe local arithmetic and unit conversion
- github: compact public GitHub repository, issue, release, user, commit, and search lookups
- grab: save, replay, search, and randomly show memorable channel lines
- note: private per-account notes with bounded persistence and expiry
- linux: current Linux kernel release lines from kernel.org
- weapons: high-level local firearm and weapons-name catalog
- paste: create bounded pastes through a configured Opengist instance
- crypto: local hashes, Base64, and URL encoding utilities
- pkg: Go, npm, and PyPI package metadata lookups
- port: local bidirectional well-known port/service lookup
- audit: package vulnerability discovery through OSV
- docker: Docker Hub image metadata lookup
- status: local connection, uptime, and counter status
- xkcd: latest or numbered XKCD comics
- lastfm: current or recently played Last.fm tracks
- cats: short cat facts
- eightball: customizable Magic 8-Ball answers
- fun: local yo-momma jokes, one-liners, puns, and wisdom
- attack: playful target-based actions and messages
- luv: persistent blue-heart points for spreading kindness
- scramble: local first-correct-answer word game
- cheer: family-friendly cheers
- seen, tell, karma, and dice: channel utilities
- quote, choose, and time: lightweight utilities
- channelstats: persistent per-channel statistics
- help and alias: command discovery
- blackjack, pool, poll, remind, and duckhunt: games and activities
Most command responses are rate-limited. See Configuration.
Every command in the six plugins below emits exactly one bounded IRC line per
invocation. Third-party text is sanitized, and summaries use truncation or a
+ N more suffix rather than sending additional lines.
!paste <text> creates a paste through an Opengist-compatible server. If the
argument is an HTTP or HTTPS URL, GoBot fetches a bounded amount of its content
before creating the paste. Configure the server and token out of band:
plugins:
paste:
enabled: true
provider: opengist
base_url: "https://paste.example.net"
default_visibility: unlisted
max_input_length: 4096Set BOT_PASTE_BASE_URL and BOT_PASTE_TOKEN in .env or the service
environment. The token is never read from config.yaml; oversized input is
truncated and reported in the single response line. URL fetching is an
outbound request made from the bot host, follows HTTP redirects, and can reach
any address permitted by that host's network. Do not enable URL pasting for
untrusted users without restricting egress at the host or network firewall;
disable the plugin with plugins.paste.enabled: false if that boundary cannot
be enforced. To insert real line breaks into inline IRC text, enable
hard_wrap and choose a hard_wrap_width (80 by default). URL-fetched content
is left unchanged unless hard_wrap_urls: true is also configured; softwrap in
the Opengist editor remains a display preference and does not change file
content.
The crypto plugin performs local-only operations with the Go standard
library:
!hash sha256 hello
!md5 hello
!sha1 hello
!sha256 hello
!sha512 hello
!b64encode hello world
!b64decode aGVsbG8=
!urlencode hello world
!urldecode hello+world
Input is capped at 512 characters and results are sanitized before being sent to IRC. Invalid input returns one error line. These commands make no network requests.
Use !pkg go, !pkg npm, or !pkg pip for current registry metadata, with an
optional version for a specific release. !package is an alias. The plugin
uses the public Go module proxy, npm registry, and PyPI endpoints, requires no
API keys, and bounds both request time and response length. The Go module proxy
response is handled using its canonical Version field, so paths such as
gopkg.in/irc.v3 work correctly.
Examples:
!pkg go github.com/variablenix/GoBot
!pkg npm lodash
!pkg pip requests 2.32.3
!pkg go irc
Responses include the registry version, a sanitized description when present,
and the canonical package page. If an exact name is not found, GoBot performs a
bounded best-effort search and returns possible Go, npm, or PyPI matches with
links; use the suggested full name for metadata. !package is the only alias.
!port 443 looks up a port number and !port ssh looks up a service name.
!ports is an alias. The catalog is local and can be maintained in
data/ports.txt; it does not make network requests. The catalog includes every
port from 0 through 1023 plus common higher-numbered services. Output is
bounded to one line and the plugin has no configurable max_length.
!audit <go|npm|pip> <package> [version] queries OSV for known package
vulnerabilities. !vuln and !osv are aliases. Without a version, GoBot also
checks the package's current registry version and reports whether that latest
version is affected. Set max_vulns_shown to control the number of CVEs shown
in the one-line summary; timeout_seconds and max_length also apply. No API
key is required. With no version, the request omits the OSV version field,
then fetches the latest registry version and evaluates OSV affected ranges.
With a version, it performs an exact OSV query. Severity comes from OSV's
database-specific or severity fields, and fixed versions are shown when OSV
provides them. If the package cannot be resolved exactly, GoBot returns a
bounded list of possible Go, npm, or PyPI package names; it does not audit all
fuzzy matches automatically.
!docker nginx looks up an official Docker Hub image, while
!docker traefik/traefik looks up a user or organization image. !hub and
!dockerhub are aliases. The plugin uses Docker Hub's public repository and
tag APIs, formats pull counts compactly, and keeps the response to one IRC
line. An image without a slash uses Docker Hub's library namespace and links
to hub.docker.com/_/<image>; an image containing one slash is treated as a
user or organization image and links to hub.docker.com/r/<user>/<image>.
The full !help menu is kept short in channels. If it would exceed one
message, GoBot sends the complete menu to the requesting user's PM and posts a
brief notice in the channel. Plugin-specific help uses the same behavior.
With banter enabled, address the bot in a channel:
GoBot hello, how are you?
@GoBot hello
Banter is intentionally random and will not respond to every message. Commands can be sent in a channel or by direct message where supported:
!help
!weather Seattle
!quote
!tell username hello
!tell queues a message for the next time the addressed nickname speaks:
!tell GoBot you are awesome
GoBot confirms that it will tell GoBot the next time they speak. When GoBot next sends a message, the pending message is delivered in that channel or conversation. Pending messages are stored in BoltDB and survive restarts.
If the addressed nickname is GoBot's own configured nickname, it replies with a short humorous message instead of queueing a message for itself. A queued tell is delivered when that nickname next sends either a channel message or a private message to GoBot.
The note plugin stores small, user-invoked notes by authenticated IRC account:
!note add vegas https://example.com
!note vegas
!note list
!note delete vegas
!note clear
!notes is an alias for !note. Notes are not announced automatically and are
stored separately for each user. A note response sent in a channel is visible
there, so use a private message when the note is sensitive. When account tags
are unavailable, GoBot falls back to the network and nickname. Notes are limited
to 50 per user by default, with 400 characters per note, and unused notes expire
after 180 days. Operators can change these limits with plugins.note.max_notes,
plugins.note.max_note_length, and plugins.note.expiry_days; set
expiry_days: 0 to disable expiry.
The optional welcome plugin posts a short, playful line when another user
joins a channel. It is disabled by default. Enable it in config.yaml:
plugins:
welcome:
enabled: true
probability: 0.15
cooldown_seconds: 120
messages_file: "data/welcome.txt"probability is the chance that an individual join produces a greeting. The
cooldown is tracked separately for each channel, so a busy channel cannot be
flooded by a greeting for every arrival. The catalog contains short original
lines and supports the {nick} placeholder:
The Evil Has Landed.
A wild Pzycho appeared!
There is no command to enable it at runtime. Once enabled, it applies to channels where GoBot is present. The bot's own join is ignored, and the normal post-join warmup also suppresses replayed events during startup.
Use familiar IRC correction syntax immediately after the message to correct:
I need a wiiifee
s/wiiifee/wife/
Add /g for every matching occurrence:
s/wiiifee/wife/g
The correction history is kept in memory and controlled by history_size.
When someone posts an HTTP or HTTPS URL, GoBot fetches a title. It prefers Open Graph and Twitter metadata, then falls back to the HTML title element. YouTube links are formatted with title, channel, and duration when available:
[YouTube] Video title | Channel: Example Channel | 1m 37s
An optional YouTube Data API v3 key gives the most reliable title, channel, and duration data. Without it, GoBot uses public oEmbed, player metadata, and HTML fallbacks; restricted or dynamically rendered videos may not expose duration. Sites that block automated requests may not provide a title. Access-denied and error titles are suppressed rather than posted.
Keep the key out of Git:
BOT_YOUTUBE_API_KEY=your-youtube-data-api-keyThe key needs YouTube Data API v3 enabled. GoBot requests only snippet and contentDetails for the linked video.
Search YouTube for one regular video or music video and receive a concise short link:
!yt SMOKE WEED EVERYDAY
!youtube Linux server setup
The response is labeled [YouTube], includes the channel, title, and a
https://youtu.be/... link. When BOT_YOUTUBE_API_KEY is configured, GoBot
also adds the video's public view and like totals when YouTube exposes them.
The statistics are best-effort: a missing like count, an API limitation, or a
temporary statistics lookup failure does not prevent the search result from
being returned. The command searches video results, which includes music
videos and other YouTube video content. GoBot uses the key for the official
Data API search and statistics lookup, then falls back to YouTube's public
results page when the key is unavailable or the API cannot be used. Configure
plugins.youtube.max_length and plugins.youtube.timeout_seconds as needed.
The API key is optional, but improves search reliability and avoids depending
on changes to YouTube's public results HTML.
The cve plugin queries the NVD's public CVE 2.0 API and requires no API key:
!cve CVE-2024-3094
!vuln CVE-2024-3094
GoBot returns the CVE ID, the best available CVSS score and severity, up to three affected vendor/product/version labels, and the NVD detail link. NVD records may not have a score yet, and CPE applicability data can be broad, so the response omits fields that are unavailable. The lookup accepts only a single CVE identifier and never fetches a user-supplied URL. For keyword or broader searches, use the NVD CVE search page.
plugins:
cve:
enabled: true
timeout_seconds: 8
max_length: 360Use !ip or !asn with an IP address or hostname:
!ip 8.8.8.8
!asn 1.1.1.1
!ip resolver.example.net
The response includes the resolved address, ASN, organization, country,
datacenter/hosting and proxy/VPN/Tor indicators, plus reverse DNS when the
provider supplies it. GoBot uses IP-API's free keyless JSON endpoint and
spaces requests to respect its public rate limit. The free endpoint is HTTP,
so do not use this command for sensitive private data; the lookup target is
sent to IP-API. Hostnames are passed to IP-API for resolution, but arbitrary
URLs, paths, and line breaks are rejected. !asn is an output alias for an
address lookup; it does not accept a bare ASN number as a separate BGP query.
plugins:
ipinfo:
enabled: true
timeout_seconds: 8
max_length: 320acronym is a local, offline text-file expander for common business, medical,
education, government, science, internet/chat, finance, and technology terms:
!acronym MTTR
!acro rDNS
!acronym API
!acronym API technology
!acronym htpp
Entries use ACRONYM|expansion[|context] per line. Blank lines and # comments
are ignored, matching is case-insensitive, and malformed entries are skipped.
The first entry for an acronym is the common/default meaning; additional
meanings can be selected with a context, such as !acronym API medical.
Multi-word keys such as PCI DSS are supported. If an exact lookup fails,
GoBot performs a bounded local fuzzy check and returns at most one suggestion,
for example: [acronym] no exact match for htpp; did you mean HTTP? It does
not silently substitute the suggestion or make a network request.
The bundled catalog is intentionally local, versioned, fast, and deterministic.
Operators can edit or replace data/acronyms.txt to add organization-specific
jargon without an API key or runtime dependency. Its broad common-term catalog
was researched offline using public references including the Section508
acronym list, NIST
CSRC, IETF RFCs, and the CNCF Cloud Native Glossary.
plugins:
acronym:
enabled: true
data_file: "data/acronyms.txt"
max_length: 320Start a local channel round with:
!scramble
!scramble status
GoBot chooses a local word, scrambles it, and awards the first exact answer in
that channel one persisted karma point. A round expires after five minutes;
!scramble status shows the active scramble without revealing the answer.
The word list is local and editable, and the winning karma plus a separate
scramble win record are stored in BoltDB. The bundled list focuses on computing,
networking, security, and operations vocabulary. No external API or answer text
is sent anywhere.
plugins:
scramble:
enabled: true
data_file: "data/scramble.txt"
timeout_minutes: 5
max_length: 240Weather uses Open-Meteo and does not require an API key:
!weather Seattle
!wx Seattle
!forecast Seattle
!temp Seattle
!weather set Las Vegas
!weather
!wx
!weather clear
Use !weather set <city> to save a personal default location. Quoted city names
are supported, so !weather set 'Las Vegas' works too. After saving it, use
!weather or any weather alias without a city. Setting it again replaces the
previous default; !weather clear removes it. Defaults are saved by your
authenticated IRC account when available, or by network and nickname, and
survive bot restarts. Set default_units to metric or imperial.
Steam lookups use Steam's public store and charts endpoints and do not require an API key:
!steam Portal 2
!game Baldur's Gate 3
!steam info 620
!steam info https://store.steampowered.com/app/620/
!steam genre FPS
!steam genre RPG
!steam top
A title search returns one best match, its Steam store link, and a more matches search link for sequels, DLC, or similarly named games. genre opens
the matching Steam tag page. top reports the current #1 most-played Steam
game and its recent peak when available, plus a link to the full most-played
charts. Game details are kept concise; if a
requested details response exceeds the configured IRC message limit, GoBot
sends the full response by private message and tells the channel that it is
messaging the requester. Configure plugins.steam.timeout_seconds and
plugins.steam.max_length as needed.
Fetch today's horoscope by zodiac sign. The sign is saved for your nickname:
!horoscope aries
!horoscope
!zodiac
The public daily horoscope API requires no key. GoBot keeps the response to one
compact IRC message and allows a fuller paragraph when it fits the configured
preview length. If the paragraph is longer, it is shortened and gets a
readable Read more link for the sign's daily horoscope page. The preview
length defaults to 360 characters and can be changed with
plugins.horoscope.max_summary_length (120–400 characters). For example, a
Virgo response links to the Virgo daily horoscope
page.
Look up a slang term. Add a result number for another definition:
!urban yeet
!u yeet 2
!ud doomscrolling
GoBot returns one shortened definition and permalink. User-submitted text is
treated as untrusted: IRC control characters are stripped and output length
is bounded. The 1/10 notation means the first definition out of ten returned
by Urban Dictionary; it is not random. Add a number to select another result,
such as !urban yeet 2.
!xkcd
!xkcd latest
!xkcd 353
GoBot uses XKCD's official JSON interface and returns the number, title, date, and link. The interface supports latest and numbered comics, not full-text search.
Last.fm requires a free API key:
plugins:
lastfm:
enabled: true
api_key: ""Use a Last.fm username once; GoBot remembers it for your nickname:
!lastfm username
!lastfm
!np
The response reports the current track or the most recently played track. GoBot does not collect passwords or OAuth credentials.
!cats
!cat
The Cats plugin uses the public catfact.ninja endpoint, requires no key, returns one cleaned and length-limited message, and does not download images.
These commands use only GoBot's local state and do not call an external service:
!status
!uptime
!ping
The response includes connection state, process uptime, configured network, and message/command counters. It is useful for a quick IRC-side health check.
Look up one English word using the public Free Dictionary API:
!define resilient
!def resilient
!dictionary resilient
GoBot returns the first concise definition and part of speech in one bounded message. No API key is required. The lookup is English-only and third-party text is cleaned before it is sent to IRC.
Calculator expressions are evaluated locally with a small parser; GoBot never executes shell commands or arbitrary code:
!calc 2*(3+4)
!math 100 / 4
!convert 10 km to mi
!convert 32 f to c
Supported conversions include temperature, length, mass, and volume. Keep
expressions short and use +, -, *, /, and parentheses.
Posting a Reddit URL still uses the automatic URL-title plugin. Use !reddit
when you want Reddit-specific metadata for a particular post or one current
post from a subreddit:
!reddit https://www.reddit.com/r/golang/comments/example/post-title/
!r https://www.reddit.com/r/golang/comments/example/post-title/
!reddit r/linux
!reddit https://www.reddit.com/r/linux/
!r r/golang
!r top r/linuxmemes
!r r/linuxmemes rising
The response contains the post title, author, subreddit, score, comment count,
and canonical Reddit URL in one compact message. Both r/subreddit and full
Reddit subreddit URLs are accepted. GoBot prefers Reddit's public JSON
endpoint, then falls back to the corresponding public RSS feed when JSON is
temporarily blocked or throttled. RSS does not reliably include scores or
comment counts, so those fields are omitted rather than shown as false zeroes.
For individual posts, a final oEmbed title fallback can still provide the
title when Reddit rate-limits both metadata endpoints.
For subreddit lookups, an optional sort selects the first post from Reddit's
best, hot, new, top, or rising listing. Put the sort before or after
the subreddit; for example, !r top r/linuxmemes returns the current #1 post
from the subreddit’s top listing, while plain !r r/linuxmemes remains the
newest-post lookup. Sort modifiers are only for subreddit lookups, not
individual post URLs. Explicit non-default sorts are labeled in the response.
Only recognized Reddit hosts and paths are accepted; arbitrary URL fetching is
not performed by this command.
The GitHub plugin uses the public GitHub REST API and keeps every response to one bounded IRC message. It accepts repository names, GitHub URLs, issues, pull requests, releases, commits, users, and repository searches:
!github variablenix/GoBot
!gh https://github.com/variablenix/GoBot/issues/1
!github variablenix/GoBot#12
!github variablenix/GoBot releases
!github user octocat
!github search go irc bot
Repository responses include a short description, stars, forks, open issues, language, and a link. Issue and pull-request responses include the title, state, author, comments, and link. Search returns up to three compact repository matches. Invalid hosts and malformed references are rejected locally; GitHub response text is cleaned before it reaches IRC.
Authentication is optional. A token can increase the public API rate limit,
but GoBot only performs read-only lookups and never needs repository write
permissions. Keep the token out of config.yaml in deployments:
BOT_GITHUB_TOKEN=your-optional-read-only-tokenThe token is sent only to api.github.com over HTTPS. Leave it empty when the
anonymous public API limit is sufficient.
The grab plugin lets users save memorable lines without keeping a complete
transcript of the channel in memory. GoBot remembers only the latest message
from each nickname in the current channel; a line is written to BoltDB only
when someone explicitly grabs it:
!grab Alice
!lgrab Alice
!grabr
!grabr Alice
!grabs deployment
!grab <nick> saves that nickname's latest message. !lgrab repeats their
most recently saved line, !grabr shows a random saved line, and !grabs
searches saved nicknames and text. Search results are limited to three compact
matches so the plugin cannot flood a channel. Duplicate lines are ignored and
each nickname is limited to the configured number of saved lines. The plugin
supports ordinary messages and /me actions, strips IRC control characters,
and adds a zero-width separator after the first nickname character to avoid
unwanted highlights.
plugins:
grab:
enabled: true
max_length: 320
max_quotes_per_user: 20The saved lines are scoped by network and channel and survive restarts. The plugin does not expose a command to dump the entire database.
!linux and !kernel fetch the current release-line summary from
kernel.org and return it as one bounded IRC message:
!linux
!kernel
The lookup is read-only, has a short timeout, limits the response body, and does not accept arbitrary URLs. It requires no API key:
plugins:
linux:
enabled: true
timeout_seconds: 8
max_length: 260Foods is a local, data-driven suggestion plugin. It does not call a food API or send user input to a third-party service. Each request produces one short IRC message:
!food
!food ramen
!food pork
!food steak
!beer guinness
!beer
!korean
!japanese
!sushi
!ramen
!chinese
!cantonese
!mandarin
!sichuan
!hunan
!shanghai
!beijing
!dongbei
!yunnan
!xinjiang
!burrito
!vietnamese
!filipino
!french
!spanish
!turkish
!middle-eastern
!german
!british
!irish
!polish
!portuguese
!greek
!soda
!juice
!water
!smoothie
!mocktail
!pizza
!tea nickname
The built-in lists include a broad food collection, beer styles from pale
ales and IPAs through lagers, stouts, sours, Belgian, farmhouse, and historical
styles, plus Korean, Japanese, sushi, ramen, Chinese, Indian, Thai, Mexican,
Italian, Mediterranean, American, pizza, taco, burrito, burger, pasta, dessert,
snack, coffee, tea, wine, Vietnamese, Filipino, French, Spanish, Turkish,
Ethiopian, Brazilian, Caribbean, Indonesian, Persian, and Middle Eastern
categories. European lists include German, British, Irish, Scottish, Welsh,
Portuguese, Greek, Polish, Ukrainian, Russian, Swedish, Norwegian, Danish,
Finnish, Dutch, Belgian, Austrian, Swiss, Czech, Hungarian, Romanian, and
Georgian dishes. The catalog also includes Moroccan, Nigerian, South African,
Peruvian, Argentinian, Chilean, Colombian, Venezuelan, Cuban, Canadian,
Australian, New Zealand, Malaysian, Pakistani, Bangladeshi, Sri Lankan, and
Nepalese dishes. Chinese regional lists include Cantonese, Northern Chinese
(available as !mandarin), Sichuan, Hunan, Shanghai, Beijing, Dongbei,
Yunnan, and Xinjiang dishes. !foods is an alias for !food; country and regional aliases
such as !de, !uk, !ie, !pt, !gr, !pl, !ua, !ru, !se, !no,
!dk, !fi, !nl, !be, !at, !ch, !cz, !hu, !ro, !br, !pe,
!ar, !cl, !co, !ve, and !nz are also available.
The cuisine lists are intentionally broad and easy to extend. They include
common dishes, regional specialties, street food, desserts, and familiar
variants such as double cheeseburger, triple cheeseburger, and several
burrito styles. Add one dish per line to a list in data/foods/; changes are
loaded when GoBot starts.
Drink lists are local and include everyday beverages as well as international
styles. Use !drinks for a general suggestion or a focused command such as
!soda, !juice, !water, !smoothie, !milkshake, !lemonade,
!mocktail, !energy-drink, !sports-drink, !hot-chocolate, !kombucha,
or !bubble-tea. Coffee and tea remain available through !coffee and
!tea, while alcoholic suggestions remain under !beer and !wine.
Each drink list is one item per line under data/foods/, and the output is
bounded to one IRC message just like the cuisine lists.
!food accepts a search term as well as a category. For example, !food pork
searches the complete catalog for matching dishes, while !beer guinness
searches only the beer list. Matching is case-insensitive and supports
multi-word terms. If no item matches, the command keeps its friendly random
suggestion behavior and treats the text as an optional nickname.
!sports returns one random sport from the local catalog. !sport is a short
alias, and an optional nickname makes the response more personal:
!sports
!sport Alex
The catalog covers team sports, individual and racket sports, combat sports,
water and winter sports, motorsports, strength sports, adaptive sports, and
esports. Add one sport per line to data/sports.txt; the file is loaded when
GoBot starts. Every response is bounded to one IRC message.
!car returns one random entry from the local car catalog; !cars is an
alias. Entries cover affordable daily drivers, trucks, SUVs, EVs, luxury cars,
classics, and sports and supercars. Each entry includes an approximate
production span. The bundled catalog includes hundreds of entries from brands
such as Bugatti, Ferrari, Lamborghini, McLaren, Pagani, Porsche, Rolls-Royce,
Koenigsegg, Rimac, Lucid, and major international manufacturers:
!car
!cars Alex
The catalog is intentionally local and easy to extend rather than pretending
to be a perfect worldwide vehicle registry. Add one make/model entry per line
to data/cars.txt; entries can include a year range such as
Toyota Corolla (1966-present). The optional configuration is:
plugins:
car:
enabled: true
data_file: "data/cars.txt"
max_length: 240Lists are plain text, one item per line, under data/foods/. Operators can
extend or replace them without changing Go code:
plugins:
foods:
enabled: true
data_dir: "data/foods"
max_length: 240An optional nickname after a category produces a single targeted suggestion,
such as Tea pick for Sam: genmaicha. The plugin is bounded to one response
and local list lookups, so it does not create an external-request or flooding
hotspot.
!8ball Will this deploy cleanly?
!8 Should I order pizza?
!eightball Is the channel ready?
Responses come from quotes/eightball.txt, one per line. Prefix a response with green|, yellow|, or red| to control its IRC color. Unprefixed responses remain readable without color. Each request produces one bounded message.
Pool's separate 8-ball mode uses !pool 8 <nick>, !pool8 <nick>, or
!8pool <nick>; !8ball is reserved for questions to the magic 8-ball.
The fun plugin provides local text without making an external request. Each
command returns one randomly selected, bounded line. The yo-momma catalog is
organized around classic joke categories such as size, age, smell, silliness,
work, food, technology, and everyday mishaps. It is playful and non-targeted:
operators should remove any entries that do not fit their channel's tone.
!yomomma
!yo
!oneliner
!one
!pun
!puns
!wisdom
!wise
The catalogs are stored under data/fun/:
yo_momma.txt: categorized yo-momma jokes, including fat, skinny, tall, short, old, smelly, stupid/silly, loud, broke, clumsy, food, technology, school, sports, and other classic joke themesone_liners.txt: short original one-linerspuns.txt: short original punswisdom.txt: original/adapted wisdom lines without questionable attribution
They are intentionally curated rather than presented as an exhaustive list of every joke or quotation. Add one line per entry; GoBot loads the files when it starts. The plugin is configured as follows:
plugins:
fun:
enabled: true
data_dir: "data/fun"
max_length: 240The catalogs are local and editable, so operators can remove a line or adapt the tone of a channel without changing Go code.
The attack plugin provides short, playful target-based actions and messages:
!attack slap Alice
!slap Alice
!hug Alice
!flirt Alice
!compliment Alice
!high5 Alice
!gift Alice
!spank Alice
!attack pokemon Alice
!strax
The canonical form is !attack <style> [nick]; most styles require a nickname.
Aliases include !bite,
!fight, !glomp, !insult, !kill, !lart, !present, !spank,
!stab, !bdsm, !clinton, !trump, !lurve, and !pokemon, plus
CloudBot-style aliases such as !end, !sexup, !jackmeoff, !dominate,
!spar, !challenge, and !luff. !strax, !nk, and !westworld
also work without a target. Action styles use standard IRC CTCP ACTION
formatting, so clients usually render them like /me messages; compliment,
flirt, insult, lurve, pokemon, strax, nk, and westworld use ordinary messages.
Targets must be a single IRC-style nickname. Targeting GoBot or self makes
GoBot perform the playful action toward the sender. Templates are built in,
capped to short safe text, and contain no real-world instructions.
The weapons plugin is a lightweight reference/randomizer for firearm and
weapons terminology. It returns names and broad categories only; it does not
provide instructions, construction details, acquisition advice, or tactical
guidance. Generic commands choose from the whole catalog, while category
aliases narrow the result:
!firearm
!guns pistol
!rifle
!shotgun
!smg
!grenade
!explosives
The catalog includes civilian, historical, sporting, military, launcher,
grenade, and high-level explosive terms. Keep the default output limit in
place to ensure one short IRC response. Operators can edit data/weapons.txt
or disable the plugin with plugins.weapons.enabled: false.
plugins:
weapons:
enabled: true
data_file: "data/weapons.txt"
max_length: 240!cheer
!yay
GoBot also responds to a message containing \o/, with a per-channel cooldown:
plugins:
cheer:
enabled: true
cheers_file: "quotes/cheers.txt"
automatic_cooldown_seconds: 15Responses come from quotes/cheers.txt, one family-friendly response per line.
Ask GoBot a general question with any of these aliases:
!ask how dangerous is extreme dehydration?
!question what is the Linux kernel?
!q what does TLS protect?
GoBot first looks for a concise English Wikipedia summary and can fall back to
DuckDuckGo's public Instant Answer data. The default source-only mode needs no
API key. It replies in one compact IRC message and includes a Read more link
when the source provides one. A sender-specific cooldown prevents repeated
lookups from becoming a flood source.
The plugin is configured under plugins.ask:
plugins:
ask:
enabled: true
wikipedia_first: true
duckduckgo_fallback: true
ai_rewrite: false
provider: none # none, openrouter, openai, gemini, ollama
max_length: 360
max_response_chars: 240
timeout_seconds: 12
cooldown_seconds: 15ai_rewrite is optional. When enabled, GoBot gives the selected provider the
retrieved source and asks it to turn that source into a concise, factual,
single-paragraph answer. It does not use an AI provider when provider: none
is selected, and it falls back to the source summary if the provider is
unavailable. BOT_ASK_PROVIDER and BOT_ASK_AI_REWRITE override the
corresponding nested config values; this means provider: none and
ai_rewrite: false can remain in the tracked example while a deployment
enables rewriting through .env. Keep provider credentials out of
config.yaml:
BOT_ASK_PROVIDER=openrouter
BOT_ASK_AI_REWRITE=true
BOT_OPENROUTER_API_KEY=...
# A specific instruction-tuned free model is more consistent than a random
# free-model router for this short source-rewrite task.
BOT_OPENROUTER_MODEL=google/gemma-4-31b-it:freeOpenAI uses BOT_OPENAI_API_KEY and BOT_OPENAI_MODEL; Gemini uses
BOT_GEMINI_API_KEY and BOT_GEMINI_MODEL. For a local Ollama instance, use
BOT_ASK_PROVIDER=ollama, BOT_OLLAMA_URL, and BOT_OLLAMA_MODEL. The output
limits still apply regardless of provider. If a provider returns meta-text
such as “the user asks” or “the source does not”, GoBot makes one stricter
correction request within the original timeout. If that still fails, or the
provider returns INSUFFICIENT_SOURCE, GoBot rejects it and keeps the
source-grounded answer instead. The question and retrieved source are treated
as untrusted data in the rewrite prompt; instructions contained in them are
not followed.
To verify that the key is actually being used, check the service log after one
fresh !ask request:
ask AI rewrite requested ... provider=openrouter ... api_key_configured=true
ask AI rewrite used ... provider=openrouter ...
If the provider call fails, GoBot logs ask AI rewrite unavailable; using source summary and still returns the source answer. The API key is never written to
the log. A source-only response is usually faster; an AI rewrite adds one
external request, and free models may take longer when they are cold or busy.
Use BOT_ASK_AI_REWRITE=false to compare source-only behavior.
The daily plugin adds a persistent !daily command:
plugins:
daily: {enabled: true, bonus_xp: 25}Each authenticated account can claim once per UTC calendar day, regardless of channel or network. Users without an authenticated account are limited by network and nickname. Different users may claim independently; this is not a single shared server-wide claim. The reward is added to the Duck Hunt XP profile for the channel where the claim is made, so Duck Hunt must be enabled globally and in that channel. Claims survive restarts through the configured Bolt database. Daily tracks the consecutive UTC-day claim streak separately from Duck Hunt's XP and level progression.
After changing config.yaml, an owner can send GoBot a private reload
message to apply reloadable plugin settings without reconnecting. Changes to
.env still require a service restart because systemd reads that file when the
process starts.
Search English Wikipedia with either alias:
!wiki Linux
!wikipedia FreeBSD
GoBot tries an exact article title, then searches Wikipedia if needed. max_summary_length controls response length.
!seen nickname
!tell nickname message for them
!karma project
!luv nickname
project++
project--
!roll d20
!roll 2d6
!quote
!choose pizza | tacos | burgers
!time America/Los_Angeles
!time Seoul
!time Bangkok
!car
!stats
!chanstats
!channelstats
!status
!define resilient
!calc 2+2
!convert 10 km to mi
!reddit https://www.reddit.com/r/example/comments/abc123/post/
- seen reports where and when a nickname last spoke. Records are stored in BoltDB.
- tell queues a message and delivers it when the addressed nickname next speaks.
- karma tracks case-insensitive thing++ and thing-- changes.
- luv awards the named nickname one persistent blue-heart point with
!luv nickname; totals are case-insensitive and scoped to the current IRC network. Responses use 💕 for the kindness action and 💙 for the recipient's score, for example:💕 me spreads kindness to nick. nick now has 58 💙 points! - thing++ and thing-- also work as standalone ordinary chat messages. GoBot
confirms each update in one compact line, replacing
<nickname>with the actual nickname being changed, such as🆙 Karma boost! KnownSyntax gained 1 karma ✨ (🎯 1 in #chat | 🌐 2 global); command messages are not treated as karma changes. - In a channel, Karma reports the channel total and the global total, for
example
🎯 9 in #chat | 🌐 19 global; private messages report global Karma. - Positive karma milestones at +10, +25, +50, and +100 add a highlighted trophy notice when the total crosses the threshold.
- dice accepts NdN notation or a single number such as !roll 20, meaning 1d20. It allows up to 100 dice and 10,000 sides per die and uses secure random values.
- quote reads the configured quote sources; see Banter and fortune.
- choose randomly selects between two to twenty pipe- or comma-separated options.
- time accepts full IANA timezone names and common city shortcuts such as
Seoul,Bangkok,Tokyo,London, andNew York; full names such asAsia/Seoulremain supported. Weather already accepts city names through Open-Meteo geocoding. - channelstats reports message totals, distinct users, and the top five users for the current channel. It is persisted in BoltDB.
!help
!help weather
!help blackjack
!alias
!alias wiki
!help shows the compact plugin index. !help gives detailed usage, and !alias [command] lists aliases without scanning a long response.