Skip to main content

A proxy to forward messages received via HTTP to to IRC

Project description

Weitersager logo

A proxy that receives text messages via JSON over HTTP and shows them on IRC.

Weitersager emerged from syslog2IRC and offers a generic, not syslog-specific input interface.

Website

The official micro website is at https://homework.nwsnet.de/releases/1cda/#weitersager.

Code Status

Testing Status Scrutinizer Code Coverage Scrutinizer Code Quality Code Climate

Requirements

Installation

Weitersager and its dependencies can be installed via pip:

$ pip install weitersager

To update an installed copy of Weitersager to the most recent release:

$ pip install -U weitersager

Usage

Start Weitersager with a configuration file:

$ weitersager config.toml

Configuration

Configuration is done as a file in TOML format.

A very basic configuration is very short. By default, the HTTP server runs on port 8080 on localhost. All that needs to be specified are the IRC server host, bot nickname, and channel(s) to join.

[irc.server]
host = "irc.server.example"

[irc.bot]
nickname = "Weitersager"

[[irc.channels]]
name = "#lobby"

A lot more can be configured, though:

log_level = "debug"         # optional; default: `"debug"`

[http]
host = "127.0.0.1"          # optional; default: `"127.0.0.1"`
port = 8080                 # optional; default: `8080`
api_tokens = [ "123xyz" ]   # optional; default: `[]`

[irc.server]
host = "irc.server.example"
port = 6667                 # optional; default: `6667`
ssl = false                 # optional; default: `false`
password = "secret"         # optional; default: no password
rate_limit = 0.5            # optional; limit of messages
                            # per second; default: no limit

[irc.bot]
nickname = "Weitersager"
realname = "Weitersager"    # optional; default: `"Weitersager"`

[irc]
commands = [                # optional; default: `[]`
  "MODE Weitersager +i",
]

[[irc.channels]]
name = "#party"

[[irc.channels]]
name = "#secretlab"
password = "555-secret"

IRC Dummy Mode

If no value for irc.server.host is set, Weitersager will not attempt to connect to an IRC server and start in IRC dummy mode. It will still accept messages, but it will write them to STDOUT. This can be useful for testing.

HTTP API

To send messages to IRC, send an HTTP POST request to URL path / at the address and port the application is listening on.

The body has to be in JSON format and contain two keys, channel and text, with string values:

{
  "channel": "#party",
  "text": "Oh yeah!"
}

Example HTTPie call to send a message to Weitersager on localhost, port 8080:

$ http --json post :8080 channel='#party' text='Oh yeah!'

Authorization

To protect the HTTP API a bit, requests can be required to include an authorization header with a valid token to be accepted.

The authorization check becomes active if at least one API token is configured. A command line tool is provided to generate secure tokens:

$ weitersager-token
e72CbijlYLqjaRIv0uMNBpgZKl397FEp-Y8PNEXn5vM

Multiple API tokens can be configured so that each legitimate client can be given its own token which can than be revoked (by removing it from the configuration, and restarting) individually.

Header format:

Authorization: Bearer <a token of your choosing>

Example authorization header:

Authorization: Bearer e72CbijlYLqjaRIv0uMNBpgZKl397FEp-Y8PNEXn5vM

Example HTTPie call with authorization header:

$ http --json post :8080 Authorization:'Bearer e72CbijlYLqjaRIv0uMNBpgZKl397FEp-Y8PNEXn5vM' channel='#party' text='Oh yeah!'

Note that Weitersager itself only uses unencrypted HTTP, so the API tokens are passed in the clear. That might suffice if you run it on the same host as the HTTP clients. Otherwise you might want to look into hiding Weitersager behind a web server or proxy that can add TLS encryption.

Channel Tokens

Weitersager supports an alternative HTTP endpoint using a secret token as part of the URL instead of an authorization header. This makes it a bit easier to use for clients.

Each secret token is mapped to a channel, so each URL already implicitly (though intransparently, for the caller) defines the channel the submitted text should be sent to.

This pattern is also used by popular messaging services like Slack and Discord for incoming webhooks.

To expose a channel via this endpoint, just add one or more tokens to it:

[[irc.channels]]
name = "#secretlab"
tokens = [
  "A2x23NmcdQgWJ8-5PivbvPX4KmdL9oa7Sy8Jj_9ldoY",
  "JMApghB7wkHCtw0TcQ1Bu7zY-wG03os61bBDXfAZ4Yc",
]

To generate a token, use the weitersager-token command. Feel free to use a separate token for each client/app that calls the endpoint to be able to revoke tokens separately (by simply removing them from the configuration) if need be.

As a result, these endpoints become available:

  • /ct/A2x23NmcdQgWJ8-5PivbvPX4KmdL9oa7Sy8Jj_9ldoY

  • /ct/JMApghB7wkHCtw0TcQ1Bu7zY-wG03os61bBDXfAZ4Yc

Call them like this (note that neither the Authorization header nor the channel key in the payload are specified):

$ http --json post :8080/ct/A2x23NmcdQgWJ8-5PivbvPX4KmdL9oa7Sy8Jj_9ldoY text='Oh yeah!'

Run in a Docker Container

Build a container image, tagged weitersager:

$ docker build -t weitersager .

Start the container, using configuration file config_example_docker.toml (which should expose Weitersager inside the container on host 0.0.0.0 and port 8080), exposing Weitersager on the Docker host on host 127.0.0.1 and port 9000:

$ docker run -d \
  --mount type=bind,source="$(pwd)"/config_example_docker.toml,destination=/app/config.toml,readonly \
  -p 127.0.0.1:9000:8080 \
  weitersager

The local configuration file is made available to the container through a bind mount.

Using Docker Compose

A configuration file for Docker Compose, compose.yaml, is also available. Adjust as necessary, then run Weitersager in a container using:

$ docker-compose up --detach

Implementation Details

A Note on Threads

This tool uses threads. Besides the main thread, there are two additional threads: one for the message receiver and one for the IRC bot. Both are configured to be daemon threads.

The dummy bot, on the other hand, does not run in a thread.

A Python application exits if no more non-daemon threads are running.

The user has to manually interrupt the application to exit.

For details, see the documentation on the threading module that is part of Python’s standard library.

Author

Weitersager was created, and is developed and maintained, by Jochen “Y0Gi” Kupperschmidt.

License

Copyright (c) 2007-2024 Jochen Kupperschmidt

Weitersager is licensed under the MIT License.

The license text is provided in the LICENSE file.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

weitersager-0.11.1.tar.gz (11.3 kB view details)

Uploaded Source

Built Distribution

weitersager-0.11.1-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file weitersager-0.11.1.tar.gz.

File metadata

  • Download URL: weitersager-0.11.1.tar.gz
  • Upload date:
  • Size: 11.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.4.27

File hashes

Hashes for weitersager-0.11.1.tar.gz
Algorithm Hash digest
SHA256 ff464fbdaa0666f1fcef405fd99ab292be96a806f1af75286355b87b34457dc3
MD5 328517438867d2d386a9f8270fdafc7a
BLAKE2b-256 dd369ca20c22f899aae904fedad3728752c8e63b2d51ebb3d36c635037aba5fc

See more details on using hashes here.

File details

Details for the file weitersager-0.11.1-py3-none-any.whl.

File metadata

File hashes

Hashes for weitersager-0.11.1-py3-none-any.whl
Algorithm Hash digest
SHA256 4271665544e9ee0a2db2f69cad2a17a796507e133ea6aabbf78cf5252002c8f8
MD5 50d5f297ea04ffddc2363227ed29fd40
BLAKE2b-256 84154a856c2f8ce7fa7c367d0e38566149dc3bb6ab3344d8d6375a6c9e2a98b2

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page