{"id":48047931,"url":"https://github.com/zorael/kameloso","last_synced_at":"2026-04-04T14:19:14.368Z","repository":{"id":15096393,"uuid":"77649813","full_name":"zorael/kameloso","owner":"zorael","description":"IRC bot with Twitch support","archived":false,"fork":false,"pushed_at":"2025-05-19T22:33:29.000Z","size":19388,"stargazers_count":8,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-07T13:49:59.560Z","etag":null,"topics":["bot","dlang","irc","irc-bot","twitch","twitch-bot"],"latest_commit_sha":null,"homepage":"","language":"D","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zorael.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE_1_0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-12-30T01:10:15.000Z","updated_at":"2025-05-19T22:30:03.000Z","dependencies_parsed_at":"2023-12-09T16:29:35.296Z","dependency_job_id":"5ed1920e-3f74-41ee-b730-16b32c12665f","html_url":"https://github.com/zorael/kameloso","commit_stats":null,"previous_names":[],"tags_count":86,"template":false,"template_full_name":null,"purl":"pkg:github/zorael/kameloso","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zorael%2Fkameloso","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zorael%2Fkameloso/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zorael%2Fkameloso/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zorael%2Fkameloso/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zorael","download_url":"https://codeload.github.com/zorael/kameloso/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zorael%2Fkameloso/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31402291,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot","dlang","irc","irc-bot","twitch","twitch-bot"],"created_at":"2026-04-04T14:19:13.685Z","updated_at":"2026-04-04T14:19:14.349Z","avatar_url":"https://github.com/zorael.png","language":"D","funding_links":[],"categories":[],"sub_categories":[],"readme":"# kameloso [![Linux/macOS/Windows](https://img.shields.io/github/actions/workflow/status/zorael/kameloso/d.yml?branch=master\u0026logo=github\u0026maxAge=3600)](https://github.com/zorael/kameloso/actions?query=workflow%3AD) [![Linux](https://img.shields.io/circleci/project/github/zorael/kameloso/master.svg?logo=circleci\u0026maxAge=3600)](https://circleci.com/gh/zorael/kameloso) [![Windows](https://img.shields.io/appveyor/ci/zorael/kameloso/master.svg?logo=appveyor\u0026maxAge=3600)](https://ci.appveyor.com/project/zorael/kameloso) [![Commits since last release](https://img.shields.io/github/commits-since/zorael/kameloso/v3.14.159.svg?logo=github\u0026maxAge=3600)](https://github.com/zorael/kameloso/compare/v3.14.159...master)\n\n**kameloso** is an IRC bot.\n\n### So what does it do\n\n* real-time chat monitoring\n* channel polls, user quotes, `!seen`, custom counters, oneliner commands, recurring announcements, [...](https://github.com/zorael/kameloso/wiki/Current-plugins)\n* notes to offline users that get played back when they come online\n* reporting titles of pasted links, YouTube video information\n* `s/this/that/` substitution of messages\n* [Twitch support](#twitch) with [several](#twitch-bot) common bot features\n* logs\n* bugs\n\nAll of the above [are runtime plugins](source/kameloso/plugins) and can be disabled or even omitted from compilation entirely. It is modular and easy to extend. A skeletal *Hello World* plugin is [less than 30 lines of code](source/kameloso/plugins/hello.d).\n\n**Please report bugs. Unreported bugs can only be fixed by accident.**\n\n### tl;dr\n\n```\n-n       --nickname Nickname\n-s         --server Server address [irc.libera.chat]\n-P           --port Server port [6667]\n-A        --account Services account name\n-p       --password Services account password\n           --admins Administrators' services accounts, comma-separated\n-H   --homeChannels Home channels to operate in, comma-separated\n-C  --guestChannels Non-home channels to idle in, comma-separated\n           --bright Adjust colours for bright terminal backgrounds\n            --color Use colours in terminal output (auto|always|never)\n             --save Write configuration to file\n```\n\nPrebuilt binaries for Windows and Linux can be found under [**Releases**](https://github.com/zorael/kameloso/releases). (64-bit only)\n\nTo compile it yourself:\n\n```shell\n$ dub run kameloso -- --server irc.libera.chat --homeChannels \"#mychannel\" --guestChannels \"#d\"\n\n## alternatively, guaranteed latest\n$ git clone https://github.com/zorael/kameloso.git\n$ cd kameloso\n$ dub build\n$ ./kameloso --server irc.libera.chat --homeChannels \"#mychannel\" --guestChannels \"#d\"\n```\n\nIf there's anyone talking it should show on your screen.\n\n---\n\n## Table of contents\n\n* [Getting started](#getting-started)\n  * [Prerequisites](#prerequisites)\n    * [**gdc**](#gdc)\n    * [Compiler versions](#compiler-versions)\n    * [SSL libraries on Windows](#ssl-libraries-on-windows)\n  * [Downloading source](#downloading-source)\n  * [Compiling](#compiling)\n    * [Compiler choice](#compiler-choice)\n    * [Build configurations](#build-configurations)\n* [How to use](#how-to-use)\n  * [Configuration](#configuration)\n    * [Configuration file](#configuration-file)\n    * [Command-line arguments](#command-line-arguments)\n    * [Display settings](#display-settings)\n    * [Other files](#other-files)\n  * [Example use](#example-use)\n    * [Online help and commands](#online-help-and-commands)\n    * [***Except nothing happens***](#except-nothing-happens)\n    * [Hostmasks](#hostmasks)\n  * [**Twitch**](#twitch)\n    * [**Copy/paste-friendly concrete setup from scratch**](#copy-paste-friendly-concrete-setup-from-scratch)\n    * [Example configuration](#example-configuration)\n    * [Long story](#long-story)\n    * [Twitch bot](#twitch-bot)\n      * [Song requests](#song-requests)\n      * [Certain commands require higher permissions](#certain-commands-require-higher-permissions)\n  * [Further help](#further-help)\n* [Known issues](#known-issues)\n  * [Windows](#windows)\n    * [OpenSSL](#openssl)\n    * [Certificate authority bundle](#certificate-authority-bundle)\n  * [YouTube song request playlist integration errors](#youtube-song-request-playlist-integration-errors)\n* [Roadmap](#roadmap)\n* [Built with](#built-with)\n* [License](#license)\n* [Acknowledgements](#acknowledgements)\n\n---\n\n## Getting started\n\nGrab a prebuilt Windows or Linux binary from under [**Releases**](https://github.com/zorael/kameloso/releases) (64-bit only); alternatively, download the source and compile it yourself.\n\n### Prerequisites\n\nThe program can be built using the [**D**](https://dlang.org) reference compiler [**dmd**](https://dlang.org/download.html), with the LLVM-based [**ldc**](https://github.com/ldc-developers/ldc/releases) and with the GCC-based [**gdc**](https://gdcproject.org/downloads). **dmd** offers *very* fast compilation, while **ldc** and **gdc** are both slower at compiling but produce faster code. The latter two additionally support more target architectures than **dmd** does (e.g. ARM). See [here](https://wiki.dlang.org/Compilers) for an overview of the available compiler vendors.\n\nThe package manager [**dub**](https://code.dlang.org) is used to facilitate compilation and dependency management. On Windows it is included in the compiler archive, while on Linux it may need to be installed separately. Refer to your repositories.\n\n#### gdc\n\nTo build with **gdc** you need to clone the [`github.com:zorael/asdf`](https://github.com/zorael/asdf) fork of [`asdf`](https://github.com/libmir/asdf) and add it to your local **dub** registry. Upstream `asdf` throws a deprecation warning during compilation, which **gdc** treats as an error. The fork merely silences the deprecation warning.\n\n```shell\ngit clone https://github.com/zorael/asdf.git\ndub add-local asdf 0.7.18\ndub upgrade  # in project root\n```\n\n#### Compiler versions\n\nStarting with `v4.0.0`, a more recent compiler version is required. This is to allow for use of named arguments and to enable some compiler preview switches.\n\nYou need a compiler based on D version **2.108** or later (April 2024). For **ldc** this translates to a minimum of version **1.38**. It's not easy to find information on **gdc** versions, but **14.2** is known to be recent enough.\n\nIf your repositories (or other software sources) don't have compilers recent enough, you can use the official [`install.sh`](https://dlang.org/install.html) installation script to download current ones, or any version of choice. (**gdc** is not available via this script.)\n\nReleases of the bot prior to `v4.0.0` remain available for older compilers.\n\n#### SSL libraries on Windows\n\nSee the [known issues](#windows) section for extra steps required to create secure connections.\n\n(**tl;dr**: Run the program with [`--get-openssl`](#openssl) and [`--get-cacert`](#certificate-authority-bundle) to download what is needed as a one-time setup.)\n\n### Downloading source\n\n```shell\ngit clone https://github.com/zorael/kameloso.git\n```\n\nIt can also be downloaded as a [`.zip` archive](https://github.com/zorael/kameloso/archive/master.zip).\n\n### Compiling\n\n```shell\ndub build\n```\n\nThis will compile the bot in the default **debug** build type, which adds some extra code and debugging symbols. You can omit these and have the compiler perform some optimisations by building it in **release** mode, by calling `dub build -b release`. Mind that build times will increase.\n\nRefer to the output of `dub --annotate --print-builds` for more build types.\n\n#### Compiler choice\n\nIt is recommended that you use **ldc** for release builds.\n\n* **gdc** is very slow to compile (but is not otherwise a poor choice).\n* **ldc** optimisations are *objectively* better than those of **dmd**.\n\nSpecify which compiler you want to use with the `--compiler` switch. You may have to refer to **ldc** as **ldc2** on some systems.\n\n#### Build configurations\n\nThere are two primary configurations in which the bot may be built.\n\n* `application` is the base configuration\n* `twitch` additionally includes the Twitch plugin and the required support for Twitch servers\n\nBoth configurations come in `-lowmem` variants; `application-lowmem` and `twitch-lowmem`; that lower compilation memory required at the cost of increased build times. This may help on memory-constrained systems, such as the Raspberry Pi.\n\nList configurations with `dub --annotate --print-configs`. You can specify which to compile with the `-c` switch. Not supplying one will make it build the default `application` configuration.\n\n```shell\ndub build -c twitch\n```\n\nIf you want to trim down the program and customise your own build to only compile the plugins you want to use, see the larger `versions` lists in `dub.sdl`. Simply add a character to the lines corresponding to the plugins you want to omit, thus invalidating the version identifiers and effectively disabling the code they relate to. Mind that disabling any of the **_\\*Service_** plugins may/will break the bot in subtle ways. All other plugins are completely optional.\n\n## How to use\n\n### Configuration\n\nThe bot ideally wants the [*services account name*](#except-nothing-happens) of one or more administrators of the bot, and/or more importantly one or more *home* channels to operate in. Without either it's just a read-only log bot, which is admittedly also a completely valid and fully-supported use-case, but it's probably not what you want.\n\nTo define these you can either supply them on the command line by use of flags listed by calling the program with `--help`, or by generating a configuration file with `--save` and entering them in there.\n\n```shell\n./kameloso --save\n```\n\nA new `kameloso.conf` will be created in a directory dependent on your platform.\n\n#### Configuration file\n\n* **Linux** and other Posix: `$HOME/.config/kameloso/` (overridden by `$XDG_CONFIG_HOME`)\n* **Windows**: `%APPDATA%\\kameloso\\`\n* **macOS**: `$HOME/Library/Preferences/kameloso/`\n\nOpen the file in your text editor of choice.\n\nAs a shortcut you can pass `--gedit` to attempt to automatically open it in a **g**raphical **edit**or, or `--edit` to open it in your default terminal one, as defined in the `$EDITOR` environment variable (where available).\n\n#### Command-line arguments\n\nYou can make changes to your configuration file in-place by specifying some settings at the command line at the same time as `--save`.\n\n```shell\n$ ./kameloso \\\n    --server irc.libera.chat \\\n    --nickname \"mybot\" \\\n    --admins \"me\" \\\n    --homeChannels \"#mychannel\" \\\n    --guestChannels \"#d,##networking\" \\\n    --color=never \\\n    --save\n\n[12:34:56] Configuration written to /home/user/.config/kameloso/kameloso.conf\n```\n\nSettings not touched will keep their values, but any comments in the file will be lost.\n\n#### Display settings\n\nText colours are by default set to go well with terminal themes with dark backgrounds. If you instead have a bright background theme, text may be difficult to read (e.g. white on white), depending on your terminal emulator program. If so, try passing the `--bright` argument, or modify the configuration file and enable `brightTerminal` under `[Core]` to make the setting persistent.\n\nIf only some colours work, try limiting colouring some by disabling `extendedColours`, also under `[Core]`. If one or more colours are still too dark or too bright even with the right `brightTerminal` setting, please refer to your terminal appearance settings.\n\nAn alternative is to disable colours with `--color=never`.\n\n#### Other files\n\nMore server-specific resource files will be created the first time you connect to a server. Where these are placed is platform-dependent.\n\n* **Linux** and other Posix: `$HOME/.local/share/kameloso/` (overridden by `$XDG_DATA_HOME`)\n* **Windows**: `%LOCALAPPDATA%\\kameloso\\`\n* **macOS**: `$HOME/Library/Application Support/kameloso/`\n\n### Example use\n\nRefer to [the wiki](https://github.com/zorael/kameloso/wiki/Current-plugins) for more information on available plugins and their commands. Additionally, see [this section about permissions](#except-nothing-happens) if nothing happens when you try to invoke commands.\n\n```\n      you joined #channel\n kameloso sets mode +o you\n\n      \u003cyou\u003e I am a fish\n      \u003cyou\u003e s/fish/snek/\n \u003ckameloso\u003e you | I am a snek\n\n    \u003cblarf\u003e I am a snek too\n      \u003cyou\u003e !addquote blarf I am a snek too\n \u003ckameloso\u003e Quote added at index #4.\n      \u003cyou\u003e !quote blarf\n \u003ckameloso\u003e I am a snek too (blarf #4 2022-04-04)\n      \u003cyou\u003e !quote blarf #3\n \u003ckameloso\u003e A Møøse once bit my sister (blarf #3 2022-02-01)\n      \u003cyou\u003e !quote blarf barnes and noble\n \u003ckameloso\u003e i got kicked out of barnes and noble once for moving all the bibles into the fiction section (blarf #0 2019-08-21)\n\n      \u003cyou\u003e !seen\n \u003ckameloso\u003e Usage: !seen [nickname]\n      \u003cyou\u003e !seen MrOffline\n \u003ckameloso\u003e I last saw MrOffline 1 hour and 34 minutes ago.\n\n \u003cMsOnline\u003e !note\n \u003ckameloso\u003e Usage: !note [nickname] [note text]\n \u003cMsOnline\u003e !note MrOffline About the thing you mentioned, yeah no\n \u003ckameloso\u003e Note added.\n MsOnline left #channel\nMrOffline joined #channel\n \u003ckameloso\u003e MrOffline! MsOnline left note 4 hours and 28 minutes ago: \"About the thing you mentioned, yeah no\"\n\n      \u003cyou\u003e !operator add bob\n \u003ckameloso\u003e Added BOB as an operator in #channel.\n      \u003cyou\u003e !whitelist add alice\n \u003ckameloso\u003e Added Alice as a whitelisted user in #channel.\n      \u003cyou\u003e !blacklist del steve\n \u003ckameloso\u003e Removed steve as a blacklisted user in #channel.\n\n      \u003cyou\u003e !automode\n \u003ckameloso\u003e Usage: !automode [add|clear|list] [nickname/account] [mode]\n      \u003cyou\u003e !automode add ray +o\n \u003ckameloso\u003e Automode modified! ray on #channel: +o\n      ray joined #channel\n kameloso sets mode +o ray\n\n      \u003cyou\u003e !oneliner new\n \u003ckameloso\u003e Usage: !oneliner new [trigger] [type] [optional cooldown]\n      \u003cyou\u003e !oneliner new info random\n \u003ckameloso\u003e Oneliner !info created! Use !oneliner add to add lines.\n      \u003cyou\u003e !oneliner add info @$nickname: for more information just use Google\n \u003ckameloso\u003e Oneliner line added.\n      \u003cyou\u003e !oneliner add info @$nickname: for more information just use Bing\n \u003ckameloso\u003e Oneliner line added.\n      \u003cyou\u003e !oneliner new vods ordered\n \u003ckameloso\u003e Oneliner !vods created! Use !oneliner add to add lines.\n      \u003cyou\u003e !oneliner add vods See https://twitch.tv/zorael/videos for $streamer's on-demand videos (stored temporarily)\n \u003ckameloso\u003e Oneliner line added.\n      \u003cyou\u003e !oneliner new source ordered\n \u003ckameloso\u003e Oneliner !source created! Use !oneliner add to add lines.\n      \u003cyou\u003e !oneliner add source I am $bot. Peruse my source at https://github.com/zorael/kameloso\n \u003ckameloso\u003e Oneliner line added.\n      \u003cyou\u003e !info\n \u003ckameloso\u003e @you: for more information just use Google\n      \u003cyou\u003e !info\n \u003ckameloso\u003e @you: for more information just use Bing\n      \u003cyou\u003e !oneliner modify\n \u003ckameloso\u003e Usage: !oneliner modify [trigger] [type] [optional cooldown]\n      \u003cyou\u003e !oneliner modify info random 10\n \u003ckameloso\u003e Oneliner !info modified to type random, cooldown 10 seconds\n      \u003cyou\u003e !vods\n \u003ckameloso\u003e See https://twitch.tv/zorael/videos for Channel's on-demand videos (stored temporarily)\n      \u003cyou\u003e !oneliner alias\n \u003ckameloso\u003e Usage: !oneliner alias [trigger] [existing trigger to alias]\n      \u003cyou\u003e !oneliner alias vods vod\n \u003ckameloso\u003e Oneliner !vod created as an alias to !vods!.\n      \u003cyou\u003e !vod\n \u003ckameloso\u003e See https://twitch.tv/zorael/videos for Channel's on-demand videos\n      \u003cyou\u003e !commands\n \u003ckameloso\u003e Available commands: !info, !vods, !source\n      \u003cyou\u003e !oneliner del vods\n \u003ckameloso\u003e Oneliner !vods removed.\n\n      \u003cyou\u003e !timer new\n \u003ckameloso\u003e Usage: !timer new [name] [type] [condition] [message threshold] [time threshold] [stagger message count] [stagger time]\n      \u003cyou\u003e !timer new mytimer ordered both 100 600 0 0\n \u003ckameloso\u003e New timer added! Use !timer add to add lines.\n      \u003cyou\u003e !timer add mytimer This is an announcement on a timer\n \u003ckameloso\u003e Line added to timer mytimer.\n      \u003cyou\u003e !timer add mytimer It is sent after 100 messages have been seen *AND* 600 seconds have passed\n \u003ckameloso\u003e Line added to timer mytimer.\n(...time passes with activity in chat...)\n \u003ckameloso\u003e This is an announcement on a timer\n(...time passes with activity in chat...)\n \u003ckameloso\u003e It is sent after 100 messages have been seen *AND* 600 seconds have passed\n      \u003cyou\u003e !timer suspend mytimer\n \u003ckameloso\u003e Timer suspended. Use !timer resume mytimer to resume it.\n      \u003cyou\u003e !timer resume mytimer\n \u003ckameloso\u003e Timer resumed!\n      \u003cyou\u003e !timer modify\n \u003ckameloso\u003e Usage: !timer modify [name] [type] [condition] [message count threshold] [time threshold] [stagger message count] [stagger time]\n      \u003cyou\u003e !timer modify mytimer random either 500 1h 50 5m\n \u003ckameloso\u003e Timer \"mytimer\" modified to type random, condition either, message threshold 500, time threshold 3600 seconds, stagger message count 50, stagger time 300 seconds\n\n      \u003cyou\u003e !poll\n \u003ckameloso\u003e Usage: !poll [seconds] [choice1] [choice2] ...\n      \u003cyou\u003e !poll 2m snik snek\n \u003ckameloso\u003e Voting commenced! Please place your vote for one of: snek, snik (2 minutes)\n      \u003cBOB\u003e snek\n    \u003cAlice\u003e snek\n      \u003cray\u003e snik\n \u003ckameloso\u003e Voting complete, results:\n \u003ckameloso\u003e snek : 2 (66.6%)\n \u003ckameloso\u003e snik : 1 (33.3%)\n\n      \u003cyou\u003e https://github.com/zorael/kameloso\n \u003ckameloso\u003e [github.com] GitHub - zorael/kameloso: IRC bot\n      \u003cyou\u003e https://youtu.be/ykj3Kpm3O0g\n \u003ckameloso\u003e [youtube.com] Uti Vår Hage - Kamelåså (HD) (uploaded by Prebstaroni)\n\n(context: playing a video game)\n      \u003cyou\u003e !counter\n \u003ckameloso\u003e Usage: !counter [add|del|format|list] [counter word]\n      \u003cyou\u003e !counter add deaths\n \u003ckameloso\u003e Counter deaths added! Access it with !deaths.\n      \u003cyou\u003e !deaths+\n \u003ckameloso\u003e deaths +1! Current count: 1\n      \u003cyou\u003e !deaths+3\n \u003ckameloso\u003e deaths +3! Current count: 4\n      \u003cyou\u003e !deaths\n \u003ckameloso\u003e Current deaths count: 4\n      \u003cyou\u003e !deaths=0\n \u003ckameloso\u003e deaths count assigned to 0!\n      \u003cyou\u003e !counter format\n \u003ckameloso\u003e Usage: !counter format [counter word] [one of ?, +, - and =] [format pattern]\n      \u003cyou\u003e !counter format deaths ? strimmer has so far died $count times! D:\n \u003ckameloso\u003e Format pattern updated.\n      \u003cyou\u003e !counter format deaths + oh no, another death!\n \u003ckameloso\u003e Format pattern updated.\n      \u003cyou\u003e !deaths+\n \u003ckameloso\u003e oh no, another death!\n      \u003cyou\u003e !deaths+\n \u003ckameloso\u003e oh no, another death!\n      \u003cyou\u003e !deaths\n \u003ckameloso\u003e strimmer has so far died 2 times! D:\n      \u003cyou\u003e !counter format deaths ? -\n \u003ckameloso\u003e Format pattern cleared.\n\n      \u003cyou\u003e !stopwatch start\n \u003ckameloso\u003e Stopwatch started!\n      \u003cyou\u003e !stopwatch\n \u003ckameloso\u003e Elapsed time: 18 minutes and 42 seconds\n      \u003cyou\u003e !stopwatch stop\n \u003ckameloso\u003e Stopwatch stopped after 1 hour, 48 minutes and 10 seconds.\n\n      \u003cyou\u003e !time\n \u003ckameloso\u003e The time is currently 11:04 locally.\n      \u003cyou\u003e !time Europe/London\n \u003ckameloso\u003e The time is currently 10:04 in Europe/London.\n      \u003cyou\u003e !time Tokyo\n \u003ckameloso\u003e The time is currently 18:05 in Tokyo.\n      \u003cyou\u003e !setzone Helsinki\n \u003ckameloso\u003e Timezone changed to Europe/Helsinki.\n      \u003cyou\u003e !time\n \u003ckameloso\u003e The time is currently 12:05 in Europe/Helsinki.\n```\n\n#### Online help and commands\n\nUse the `!help` command of the [**Help**](https://github.com/zorael/kameloso/wiki/Current-plugins#help) plugin for a summary of available bot commands, and `!help [plugin] [command]` for a brief description of a specific one. The shorthand `!help !command` also works.\n\nThe *command prefix* (here \"`!`\") is configurable; refer to your configuration file. Common alternatives are `.` (dot), `~` (tilde) and `?`, making it `.note`, `~quote` and `?counter` respectively.\n\n```ini\n[Core]\nprefix                      \"!\"\n```\n\nIt can technically be any string and not just one character. It may include spaces if enclosed within quotes.\n\nAdditionally, prefixing commands with the bot's nickname also always works, as in `kameloso: seen MrOffline`. Some commands require it. If no command prefix is set, commands may only be invoked by prefixing them with the nickname this way.\n\n#### ***Except nothing happens***\n\nBefore allowing *anyone* to trigger *any* restricted functionality, the bot will try to identify the accessing user by querying the server for what [*services account*](https://en.wikipedia.org/wiki/IRC_services) that user is logged onto, if not already known. For full and global administrative privileges, you will need to be logged into services with an account listed in the `admins` field in the configuration file. Other users may have permissions defined per-channel in the [`users.json`](#other-files) file, placed in your resource directory. These can also be managed online by commands provided by the [**Admin**](https://github.com/zorael/kameloso/wiki/Current-plugins#admin) plugin.\n\nIf a user is not logged onto services, they are considered as not being uniquely identifiable, and thus cannot be resolved to an account.\n\n#### Hostmasks\n\nNot all servers offer services, and in those cases you can enable [*hostmasks mode*](https://github.com/zorael/kameloso/wiki/On-servers-without-services-(e.g.-no-NickServ)). This is a weaker solution to user identification, but it's better than nothing if services aren't available. With it enabled, the above still applies but \"accounts\" are derived from user hostmasks.\n\nSee the `!hostmask` command of the same [**Admin**]((https://github.com/zorael/kameloso/wiki/Current-plugins#admin)) plugin (and the [`hostmasks.json`](#other-files) resource file) for how to map hostmasks to would-be accounts.\n\n### **Twitch**\n\n\u003e **If you're interested in trying the bot but don't want to run it yourself, [contact me](mailto:zorael@gmail.com?subject=Hosting+a+kameloso+instance) and I will host an instance for you on a headless server.**\n\n#### **Copy paste-friendly concrete setup from scratch**\n\nPrebuilt binaries for Windows and Linux can be found under [**Releases**](https://github.com/zorael/kameloso/releases) (64-bit only).\n\n```shell\n./kameloso --setup-twitch\n```\n\nThe `--setup-twitch` flag creates a configuration file with the server address and port already set to connect to Twitch, then opens it up in a text editor.\n\nOn Windows it additionally downloads and launches an installer for [**OpenSSL for Windows**](#openssl) as well as downloads a [**certificate authority bundle**](#certificate-authority-bundle) file, both of which are [required](#windows) to create secure connections. Make sure to choose to *install to Windows system directories* when asked.\n\n**A line with a leading `#` is disabled, so remove any `#`s from the start of lines you want to enable.**\n\n* Add your channel to `homeChannels`. Channel names are account names (which are always lowercase) with a `#` in front, so the Twitch user `streamer123_jp` with a display name of `配信者` would have the channel `#streamer123_jp`.\n* Optionally add one or more account names to the list of `admins` to give them global low-level control of the bot. Owners of channels (broadcasters) automatically have high privileges in the scope of their own channels, so it's not strictly needed for general use, but it may be a good idea to have while you're setting things up.\n* You can ignore `nickname`, `user`, `realName`, `account` and `password`, as they're not applicable on Twitch. *Do not enter your Twitch password **anywhere** in this file.*\n* Peruse the file for other settings if you want; you can always get back to it by passing `--gedit` (short for **g**raphical **edit**or).\n\nThe program can then be run normally, though a few preparatory steps remain.\n\n```shell\n./kameloso\n```\n\nIt should now start a terminal wizard requesting a new *authorisation token*, upon detecting it's missing one. If it doesn't, force it with `--set twitch.keygen`. See the [long story](#long-story) section below for details.\n\n**Note that it will request a token for the user you are currently logged in as in your browser**. If you want one for a different **bot user** instead, open up a private/incognito window and log into Twitch normally *with the bot account* there. Copy the address of the page it opened for your other account ([this link](https://id.twitch.tv/oauth2/authorize?response_type=token\u0026client_id=tjyryd2ojnqr8a51ml19kn1yi2n0v1\u0026redirect_uri=http://localhost\u0026scope=moderator:manage:chat_messages+moderator:manage:banned_users+user:manage:whispers+channel:moderate+chat:edit+chat:read+whispers:edit+whispers:read+moderator:read:followers+user:read:follows\u0026force_verify=true\u0026state=kameloso)), then follow it in that browser window instead. Refer to the terminal instructions again to continue.\n\nAfter obtaining a token and verifying it, it will save it to your configuration file and reconnect to the server. Provided there were no errors, the bot should now enter your channel. Say something in your chat in your browser and it should show in your terminal. If there were errors or snags, or if something was simply unintuitive, [please file an issue](https://github.com/zorael/kameloso/issues/new) so the process can be improved upon.\n\nIf you don't like the terminal colours, `--color=never` disables them.\n\n#### Example configuration\n\n```ini\n[IRCClient]\nnickname                    doesntmatter\nuser                        ignored\nrealName                    likewise\n\n[IRCBot]\n#account\n#password                   (ignore; do NOT enter your Twitch account password!)\npass                        (twitch.keygen authorisation token for bot account)\nadmins                      mainaccount\nhomeChannels                #mainaccount,#botaccount\n#guestChannels\n\n[IRCServer]\naddress                     irc.chat.twitch.tv\nport                        6697\n\n[Twitch]\nenabled                     true\necount                      true\nwatchtime                   true\nwatchtimeExcludesLurkers    true\nsongrequestMode             youtube\nsongrequestPermsNeeded      whitelist\nmapWhispersToChannel        false\npromoteBroadcasters         true\npromoteModerators           true\npromoteVIPs                 true\nworkerThreads               3\n```\n\nThe port to use for secure connections is **6697** (or rarely **443**). For a non-encrypted connection, while heavily discouraged, use the default port **6667**.\n\n#### **Long story**\n\nTo connect to Twitch servers, you must first compile the `twitch` build configuration to include Twitch support. **All pre-compiled binaries available from under [Releases](https://github.com/zorael/kameloso/releases) are already built this way.**\n\nYou will also require an [*authorisation token*](https://en.wikipedia.org/wiki/OAuth). Assuming you have a configuration file set up to connect to Twitch, such as with `--setup-twitch`, it will automatically start a terminal wizard requesting one on program startup, **if** none is present. Run the bot with `--set twitch.keygen` to force it if it doesn't, which it won't if you already have a token and it merely expired. (They last about 60 days.)\n\nIf you are not already logged into Twitch in your browser, it will open a browser window with the Twitch login page. Verify that it's truly Twitch by checking the page address; it should end with `.twitch.tv`, with the little lock symbol showing the connection is secure.\n\n\u003e Do note that at no point is the bot privy to your Twitch login credentials! The logging-in is wholly done on Twitch's own servers, and no information is sent to any third parties. The code that deals with all this is open for audit; [`requestTwitchKey` in `plugins/twitch/providers/twitch.d`](source/kameloso/plugins/twitch/providers/twitch.d).\n\nLogging in should lead you to a page where you must authorise the bot to perform certain actions on behalf of your (bot) account, such as reading and sending messages, performing moderator actions, etc.\n\nClick **Authorize** and you will be redirected to an empty \"`this site can't be reached`\" or \"`unable to connect`\" page. **Copy the URL address** of that page and **paste** it into the terminal, which you should be prompted to do. Hit enter and it will parse the address, extract your authorisation token, verify it, save it to your configuration file, and then finally connect to the server.\n\nIf you prefer to generate the token manually, [here is the URL you need to follow](https://id.twitch.tv/oauth2/authorize?response_type=token\u0026client_id=tjyryd2ojnqr8a51ml19kn1yi2n0v1\u0026redirect_uri=http://localhost\u0026scope=moderator:manage:chat_messages+moderator:manage:banned_users+user:manage:whispers+channel:moderate+chat:edit+chat:read+whispers:edit+whispers:read+moderator:read:followers+user:read:follows\u0026force_verify=true\u0026state=kameloso). The key generation wizard only opens it for you, as well as automates saving the resulting token to your configuration file (as `pass` under `[IRCBot]`).\n\nMind that the authorisation token should still be kept secret. It's not possible to derive your Twitch account password from it, but anyone with access to it can chat as if they were you. This is part of why it's recommended to use a bot account instead.\n\n#### Twitch bot\n\n**Please make the bot a moderator to prevent its messages from being as aggressively rate-limited.**\n\nAssuming a prefix of `!`, commands to test are:\n\n* `!uptime`\n* `!followage`\n* `!vanish`\n* `!repeat`\n* `!ecount`\n* `!watchtime`\n* `!nuke`\n* `!songrequest`\n* `!settitle`\n* `!setgame`\n* `!shoutout`\n* `!startpoll`/`!endpoll` (*highly* experimental and unlikely to work until we can perform some live testing, which requires the help of a Twitch affiliate)\n* `!commercial` (also requires affiliate testing)\n* `!subs`\n\n...alongside `!oneliner`, `!counter`, `!timer`, `!poll` (chat variant), `!time`, `!stopwatch`, and other non-Twitch-specific commands. Try `!help` or [the wiki](https://github.com/zorael/kameloso/wiki/Current-plugins).\n\nNote that `.` (dot) and `/` (slash) prefixes will not work on Twitch.\n\n##### Song requests\n\nTo be able to serve song requests, you will need to register an *application* to interface with [Google (YouTube)](https://console.cloud.google.com/projectcreate) and/or [Spotify](https://developer.spotify.com/dashboard) servers individually. To initiate the wizards for this, pass `--set twitch.googleKeygen` for YouTube and `--set twitch.spotifyKeygen` for Spotify, and follow the on-screen instructions. (They behave much like `--set twitch.keygen`.)\n\nYou may set up access tokens for both song request providers, but only one provider may be enabled at any one time. To control which, set `songrequestMode` to either `youtube` or `spotify` in your configuration file (under `[Twitch]`). A value of `disabled` disables the feature.\n\n##### Certain commands require higher permissions\n\nSome functionality, such as setting the channel title or currently played game, require elevated credentials with the permissions of the channel owner (broadcaster), as opposed to those of any moderator. If you want to use such commands, you will need to generate a separate authorisation token for *your main account*, much as you generated one to be able to connect with the bot account.\n\n```shell\n./kameloso --set twitch.superKeygen\n```\n\nThis will request a token from Twitch with different permissions, and the authorisation browser page should reflect this.\n\nMind that you need to be logged into Twitch (in your browser) with your *main (broadcaster) account* while doing this, or the token obtained will be with permissions for the wrong channel. This is in contrast to `--set twitch.keygen`, with which it is recommended you use a separate bot account with only moderator status.\n\nAll keygens can be triggered at the same time, but care must be taken which account you are logged into when you click the respective `Authorize` buttons; you want the bot account for the normal `twitch.keygen` and the broadcaster account for `twitch.superKeygen`.\n\n```shell\n./kameloso \\\n    --set twitch.keygen \\\n    --set twitch.superKeygen \\\n    --set twitch.googleKeygen \\\n    --set twitch.spotifyKeygen\n```\n\n### Further help\n\nFor more information and help, first refer to [the wiki](https://github.com/zorael/kameloso/wiki).\n\nIf you still can't find what you're looking for, or if you have suggestions on how to improve the bot, you can...\n\n* ...start a thread under [Discussions](https://github.com/zorael/kameloso/discussions).\n* ...file a [GitHub issue](https://github.com/zorael/kameloso/issues/new).\n\n## Known issues\n\n### Windows\n\n#### OpenSSL\n\nThe dependency we use to create secure connections in turn requires [**OpenSSL**](https://www.openssl.org) to be installed. It is *the* standard library for such on every major platform -- except for Windows, which has its own solution in the form of Windows Secure Channel. Help is needed to support that.\n\nRun the program with the `--get-openssl` flag to download and launch the installer for [**OpenSSL for Windows v3.\\* _(Light)_**](https://slproweb.com/products/Win32OpenSSL.html). When asked, make sure to opt to *install to Windows system directories*. This only needs to be done once.\n\n#### Certificate authority bundle\n\nSaid dependency does not have the ability to retrieve certificates from Windows' own certificate storage, so in addition to the system-wide installation of **OpenSSL**, you will also need a *certificate authority bundle* file. Pass `--get-cacert` on the command line and the program will download a copy of [`cacert.pem`](https://curl.se/ca/cacert.pem), as extracted from Mozilla Firefox [by the **curl** project](https://curl.se/docs/caextract.html). It will be saved next to your configuration file.\n\nYou can pass both `--get-openssl` and `--get-cacert` at the same time for a one-time setup.\n\n### YouTube song request playlist integration errors\n\nIf you're seemingly doing everything right and you still get permissions errors when attempting to add a YouTube video clip to a playlist, redo the Google keygen. When you're asked to pick one of your accounts late in the process, make sure that you select a *YouTube account*, as opposed to an overarching *Google account*. It should say **YouTube** underneath the option.\n\n## Roadmap\n\n* please send help: Windows Secure Channel SSL\n* **more pairs of eyes**; if you don't test it, it's broken\n\n## Built with\n\n* [**D**](https://dlang.org)\n* [`dialect`](https://github.com/zorael/dialect) ([dub](https://code.dlang.org/packages/dialect))\n* [`lu`](https://github.com/zorael/lu) ([dub](https://code.dlang.org/packages/lu))\n* [`requests`](https://github.com/ikod/dlang-requests) ([dub](https://code.dlang.org/packages/requests))\n\n## License\n\nThis project is licensed under the **Boost Software License 1.0** - see the [LICENSE_1_0.txt](LICENSE_1_0.txt) file for details.\n\n## Acknowledgements\n\n* [Kamelåså](https://youtu.be/ykj3Kpm3O0g)\n* [`#d` on Libera.Chat](irc://irc.libera.chat:6697/#d)\n* [IRC Definition Files](http://defs.ircdocs.horse) and [`#ircdocs` on Libera.Chat](irc://irc.libera.chat:6667/#ircdocs)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzorael%2Fkameloso","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzorael%2Fkameloso","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzorael%2Fkameloso/lists"}