An IRC bot in C. Features a key-value store backed by SQLite3, weather lookups via wttr.in, stock quotes, calculator, time, user tracking, and AI-powered replies. https://zynk.org/
  • C 98%
  • CMake 2%
Find a file
hanez d59d4dc46c Add !yt YouTube title lookup command via oEmbed API. (0.41.0)
Added new !yt command (cmd_yt.h) that fetches the title and channel name
of a YouTube video using the YouTube oEmbed API. The video URL is
percent-encoded via a new yt_url_encode() helper before being passed as a
query parameter. The JSON response is parsed for 'title' and 'author_name'
fields using the existing json_find() helper, and the result is formatted
as 'Title - Channel'.

- New file: cmd_yt.h with yt_url_encode() and cmd_yt() command handler
- CMakeLists.txt: added WITH_YT feature toggle (ON by default)
- zynk.c: added conditional #include for cmd_yt.h
- irc.h: added cmd_yt() dispatch in handle_privmsg()
- cmd_help.h: added !yt <url> to the help listing
- zynk.c: added doc comments to json_find() function
- cmd_yt.h: added doc comments to yt_url_encode() and cmd_yt()
- CHANGELOG.md: added 0.41.0 entry documenting all changes
- README.md: updated feature summary, features list, feature toggles
  table, minimal build command, and IRC commands utilities table
2026-07-25 02:17:59 +02:00
.gitignore Commit links for !gitlog, full changelog link for !changelog, CMake, multi-file refactor 2026-07-23 01:46:37 +02:00
AGENTS.md Commit links for !gitlog, full changelog link for !changelog, CMake, multi-file refactor 2026-07-23 01:46:37 +02:00
ai.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
CHANGELOG.md Add !yt YouTube title lookup command via oEmbed API. (0.41.0) 2026-07-25 02:17:59 +02:00
CMakeLists.txt Add !yt YouTube title lookup command via oEmbed API. (0.41.0) 2026-07-25 02:17:59 +02:00
cmd_ai.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_calc.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_changelog.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_code.h Commit links for !gitlog, full changelog link for !changelog, CMake, multi-file refactor 2026-07-23 01:46:37 +02:00
cmd_forecast.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_gitlog.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_greeting_or_chat.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_help.h Add !yt YouTube title lookup command via oEmbed API. (0.41.0) 2026-07-25 02:17:59 +02:00
cmd_ping.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_quit.h Secure file ops, TLS hardening, input validation, security docs. (0.40.7) 2026-07-24 03:21:49 +02:00
cmd_rebuild.h Secure file ops, TLS hardening, input validation, security docs. (0.40.7) 2026-07-24 03:21:49 +02:00
cmd_reload.h Secure file ops, TLS hardening, input validation, security docs. (0.40.7) 2026-07-24 03:21:49 +02:00
cmd_restart.h Secure file ops, TLS hardening, input validation, security docs. (0.40.7) 2026-07-24 03:21:49 +02:00
cmd_seen.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_stock.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_tell.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_time.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_uptime.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_version.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_weather.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
cmd_yt.h Add !yt YouTube title lookup command via oEmbed API. (0.41.0) 2026-07-25 02:17:59 +02:00
cmd_zynk.h Nick-prefixed channel replies for all non-admin commands. (0.40.8) 2026-07-24 04:03:04 +02:00
db.h Reduced MAX_HISTORY, moved LOAD_FUNC macro, added irc_reply docs. (0.40.9) 2026-07-24 19:55:36 +02:00
irc.h Add !yt YouTube title lookup command via oEmbed API. (0.41.0) 2026-07-25 02:17:59 +02:00
LICENSE update LICENSE / README 2026-06-07 01:52:28 +02:00
net.h Commit links for !gitlog, full changelog link for !changelog, CMake, multi-file refactor 2026-07-23 01:46:37 +02:00
README.md Add !yt YouTube title lookup command via oEmbed API. (0.41.0) 2026-07-25 02:17:59 +02:00
tls.h Secure file ops, TLS hardening, input validation, security docs. (0.40.7) 2026-07-24 03:21:49 +02:00
zynk.c Add !yt YouTube title lookup command via oEmbed API. (0.41.0) 2026-07-25 02:17:59 +02:00
zynk.h Reduced MAX_HISTORY, moved LOAD_FUNC macro, added irc_reply docs. (0.40.9) 2026-07-24 19:55:36 +02:00

zynk - An IRC bot

An IRC bot in C. Features a key-value store backed by SQLite3, weather lookups via wttr.in, stock quotes, calculator, time, user tracking, YouTube title lookups, and AI-powered replies.

This is a fork!

This is a fork from my good friend Armin's calc bot. He started the project, but he is working on a lot of awesome other things like plugins (VST and AU) for your DAW right now. So, I forked this awesome code, and I am working on this now.

I want to thank Armin for his work and for sharing his code with me. Take a look at his profile here to see his awesome work.

Features

  • Key-Value Store: Persist facts, notes, or any data with !zynk key = value; Overwrite existing keys with !zynk! key = value
  • Weather: Current conditions and 3-day forecasts via wttr.in
  • Stock Quotes: Real-time stock prices via Yahoo Finance
  • Calculator: Evaluate math expressions with !calc
  • Time: Show current time in any timezone with !time
  • User Tracking: Track when users were last seen with !seen
  • Offline Messages: Leave messages for offline users with !tell
  • AI Queries: Ask questions via !ai or by addressing the bot; powered by opencode
  • Code Changes: AI-powered code editing with auto-recompile and hot reload
  • YouTube Titles: Look up video titles with !yt <url> (via YouTube oEmbed API)
  • Chat Greetings: Responds to hi, hello, hey, bye, and more
  • Hot Reload: Reload or restart without leaving channels, losing your nick, or dropping voice mode
  • TLS: Secure connections via OpenSSL
  • Rate Limiting: Per-nick protection against spam
  • Reconnection: Auto-reconnect with exponential backoff
  • Single File: Easy to deploy and modify

Requirements

  • gcc (or any C99 compiler)
  • libssl-dev (OpenSSL)
  • libdl (dynamic linker)
  • libsqlite3 (loaded at runtime via dlopen)
  • curl (for weather, forecast, and stock lookups)
  • bc (for the calculator command)
  • git (for the gitlog command)
  • date (for timezone-aware time lookups)
  • tzdata (optional — without it, !time falls back to 45 built-in timezones)
  • opencode (for AI queries)

Build

Quick build

cmake -B build && cmake --build build

The binary is placed in build/zynk.

Install

cmake --build build --target install

Feature toggles

All commands are enabled by default. Disable any command at build time with -DWITH_<FEATURE>=OFF:

cmake -B build -DWITH_WEATHER=OFF -DWITH_AI=OFF
cmake --build build

Available options (the !command shown in parentheses):

Option Command Description Default
WITH_ZYNK !zynk Key-value store ON
WITH_PING !ping Ping/pong ON
WITH_VERSION !version Version info ON
WITH_HELP !help Help listing ON
WITH_QUIT !quit / !die Shut down the bot ON
WITH_WEATHER !weather Weather lookup (requires curl) ON
WITH_FORECAST !forecast 3-day forecast (requires curl) ON
WITH_STOCK !stock Stock quotes (requires curl) ON
WITH_CALC !calc Calculator (requires bc) ON
WITH_TIME !time Time/timezone lookup ON
WITH_SEEN !seen User tracking ON
WITH_TELL !tell Offline messages ON
WITH_GITLOG !gitlog Recent git commits ON
WITH_CHANGELOG !changelog Changelog entries ON
WITH_AI !ai AI questions (requires opencode) ON (can not be disabled)
WITH_CODE !code AI code changes (ops only) OFF
WITH_REBUILD !rebuild Rebuild & restart (ops only) OFF
WITH_UPTIME !uptime Uptime display ON
WITH_RELOAD !reload Hot reload (ops only) ON
WITH_RESTART !restart Restart (ops only) ON
WITH_YT !yt YouTube title lookup (requires curl) ON
WITH_GREETING_OR_CHAT <nick>: <text> Greeting/chat with AI fallback ON (can not be disabled)

Minimal build

Disable everything except the core store, quit, and help:

cmake -B build \
  -DWITH_PING=OFF -DWITH_VERSION=OFF -DWITH_WEATHER=OFF -DWITH_FORECAST=OFF \
  -DWITH_STOCK=OFF -DWITH_CALC=OFF -DWITH_TIME=OFF -DWITH_SEEN=OFF \
  -DWITH_TELL=OFF -DWITH_GITLOG=OFF -DWITH_CHANGELOG=OFF -DWITH_AI=OFF \
  -DWITH_CODE=OFF -DWITH_REBUILD=OFF -DWITH_UPTIME=OFF -DWITH_RELOAD=OFF \
  -DWITH_RESTART=OFF -DWITH_YT=OFF -DWITH_GREETING_OR_CHAT=OFF
cmake --build build

Clean

rm -rf build

Usage

./zynk [options]

Options

Option Description
-ssl Enable TLS (auto-enabled on ports 6697/7000)
-noverify Skip TLS certificate verification
-server <host> IRC server (default: irc.libera.chat)
-port <p> Port (default: 6697)
-pass <p> Server password
-nick <n> Nickname (default: zynk)
-join <c> Auto-join channels, comma-separated (default: #zynk)
-opencode <p> Path to opencode binary (default: /usr/bin/opencode)
-h Show help

Example

./zynk -ssl -nick mybot -join "#mychan,#myotherchan"

IRC Commands

General

Command Description
!help List all available commands
!version Show the bot version
!ping Responds with pong
!uptime Show bot uptime
!quit / !die Shut down the bot (ops only)

Key-Value Store

Command Description
!zynk <key> Look up a stored value
!zynk <key> = <value> Store a value (key is lowercased)
!zynk! <key> = <value> Overwrite an existing value (ops in channels)
!zynk Get a random stored entry

Weather & Finance

Command Description
!weather [city] Current weather (default: Berlin)
!forecast [city] [full] 3-day forecast; full adds weather description, sunrise/sunset, moonrise/moonset (default: Berlin)
!stock <SYMBOL>[,SYMBOL...] Stock quotes, up to 3 symbols (e.g. !stock AAPL,MSFT)

Utilities

Command Description
!calc <expression> Evaluate math (see below)
!time [timezone] Show current time (see below)
!seen <nick> Check when a user was last seen
!tell <nick> <message> Leave a message for an offline user
!yt <url> Show YouTube video title and channel name
!gitlog [count] Show recent git commits with links (default: 1, max: 10)
!changelog [count] Show changelog entries (default: 1, max: 10)

Time (!time)

Shows the current date and time. Without arguments, displays the bot's local time. With a timezone argument, displays the time in that timezone using POSIX TZ format.

Output format: YYYY-MM-DD HH:MM:SS

Examples:

Command Description
!time Bot's local time
!time UTC Current UTC time
!time US/Eastern US Eastern time
!time US/Pacific US Pacific time
!time Europe/Berlin Central European time
!time Europe/London UK time
!time Asia/Tokyo Japan time
!time Australia/Sydney Australian Eastern time

If the system has tzdata installed, any IANA/Olson timezone name works. Otherwise, the bot falls back to a built-in table with the following timezones:

Built-in timezones (no tzdata required):

Timezone Region Offset DST
UTC / GMT Global +0 No
EST / CST / MST / PST / HST US (fixed) -5 to -10 No
US/Eastern US Eastern -5 / -4 Yes
US/Central US Central -6 / -5 Yes
US/Mountain US Mountain -7 / -6 Yes
US/Pacific US Pacific -8 / -7 Yes
US/Alaska US Alaska -9 / -8 Yes
US/Honolulu US Hawaii -10 No
Canada/Toronto Canada Eastern -5 / -4 Yes
Canada/Vancouver Canada Pacific -8 / -7 Yes
America/Sao_Paulo Brazil -3 / -2 Yes
America/Mexico_City Mexico -6 / -5 Yes
America/Argentina/Buenos_Aires Argentina -3 No
Europe/London UK 0 / +1 Yes
Europe/Berlin Central Europe +1 / +2 Yes
Europe/Paris France +1 / +2 Yes
Europe/Moscow Russia +3 No
Europe/Istanbul Turkey +3 No
Asia/Tokyo Japan +9 No
Asia/Shanghai China +8 No
Asia/Kolkata India +5:30 No
Asia/Dubai UAE +4 No
Asia/Singapore Singapore +8 No
Asia/Seoul South Korea +9 No
Asia/Hong_Kong Hong Kong +8 No
Asia/Taipei Taiwan +8 No
Australia/Sydney Australia Eastern +10 / +11 Yes
Australia/Melbourne Australia Eastern +10 / +11 Yes
Australia/Brisbane Australia Eastern +10 No
Australia/Perth Australia Western +8 No
Australia/Adelaide Australia Central +9:30 / +10:30 Yes
Australia/Darwin Australia Central +9:30 No
Pacific/Auckland New Zealand +12 / +13 Yes
Pacific/Honolulu Hawaii -10 No
Pacific/Fiji Fiji +12 / +13 Yes
Africa/Cairo Egypt +2 No
Africa/Johannesburg South Africa +2 No
Africa/Lagos West Africa +1 No
Africa/Nairobi East Africa +3 No
Atlantic/Reykjavik Iceland +0 No

Calculator (!calc)

The calculator uses bc -l (POSIX arbitrary-precision calculator with the math library). Any valid bc expression works.

Basic arithmetic:

Expression Result
!calc 2+2 4
!calc 100-37 63
!calc 6*7 42
!calc 100/3 33.3333333333333333333
!calc 10%3 1

Parentheses for grouping:

Expression Result
!calc (3+7)*2 20
!calc (100-50)/5 10

Powers:

Expression Result
!calc 2^10 1024
!calc 3^3 27

Constants:

Expression Description
!calc pi() Pi (3.14159...)
!calc pi()*2 Circumference of a unit circle
!calc pi()^2 Pi squared

Math library functions (enabled by -l):

Expression Description
!calc s(1) Sine of 1 (radians)
!calc c(0) Cosine of 0
!calc a(1) Arctangent of 1
!calc l(100) Natural logarithm of 100
!calc e(1) e^1

Scale (decimal places):

Expression Description
!calc scale=4; 1/3 0.3333

Variables and multi-statement:

Expression Description
!calc x=5; x*2 10
!calc 2+2; 3*3 4 (first line of output)

AI

Command Description
!ai <question> Ask the AI a question (plan mode, read-only)
!code <instruction> AI code change with auto-recompile (ops only, in channels)
<nick>: <question> Address the bot by nick to ask the AI

Admin (Ops Only)

Command Description
!reload Hot reload (preserve IRC session, fork-in-place)
!restart Restart the bot (preserves session, same as !reload)
!rebuild [pull] Rebuild and restart (ops only, in channels; pull runs Git pull before rebuilding)
!code <instruction> Make AI-powered code changes

Chat

Command Description
<nick>: hi/hello/hey Greeting response
<nick>: bye Farewell response
<nick>: <anything> AI-powered conversation

Database

Data is stored in zynk.db (SQLite3) in the working directory. The bot creates four tables:

  • zynk - key-value pairs with nick and timestamp metadata
  • ai_pending - single-row table for managing in-flight AI queries
  • seen - tracks when users were last seen (nick, timestamp, channel, action)
  • tell - stores pending offline messages for delivery

Architecture

zynk uses a single poll() loop with a 100 ms timeout. AI queries fork a child process that runs the opencode CLI; the parent picks up the result on the next poll iteration. SQLite3 is loaded at runtime via dlopen to avoid a compile-time dependency. The bot supports hot reload: !reload and !restart fork without exec, so the child inherits the live socket and SSL session — the bot stays connected, keeps its nick, and remains voiced in channels. !rebuild/!code do a clean QUIT+exec since the binary changed on disk.

License

MIT - see LICENSE file.