Weitersager


NameWeitersager JSON
Version 1.0.1 PyPI version JSON
download
home_pageNone
SummaryA proxy to forward messages received via HTTP to IRC
upload_time2025-01-07 02:16:15
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords irc webhook
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ===========
Weitersager
===========

.. image:: https://raw.githubusercontent.com/homeworkprod/weitersager/main/assets/weitersager_logo.svg
   :alt: Weitersager logo
   :height: 200
   :width: 200

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.

.. _syslog2IRC: http://homework.nwsnet.de/releases/c474/#syslog2irc


Website
=======

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


Code Status
===========

|badge_github-actions_test|
|badge_scrutinizer-ci_coverage|
|badge_scrutinizer-ci_quality-score|
|badge_code-climate_maintainability|

.. |badge_github-actions_test| image:: https://github.com/homeworkprod/weitersager/actions/workflows/test.yml/badge.svg
   :alt: Testing Status
   :target: https://github.com/homeworkprod/weitersager/actions/workflows/test.yml

.. |badge_scrutinizer-ci_coverage| image:: https://scrutinizer-ci.com/g/homeworkprod/weitersager/badges/coverage.png?b=main
   :alt: Scrutinizer Code Coverage
   :target: https://scrutinizer-ci.com/g/homeworkprod/weitersager/?branch=main

.. |badge_scrutinizer-ci_quality-score| image:: https://scrutinizer-ci.com/g/homeworkprod/weitersager/badges/quality-score.png?b=main
   :alt: Scrutinizer Code Quality
   :target: https://scrutinizer-ci.com/g/homeworkprod/weitersager/?branch=main

.. |badge_code-climate_maintainability| image:: https://api.codeclimate.com/v1/badges/f45b29ee321c1920a85c/maintainability
   :alt: Code Climate
   :target: https://codeclimate.com/github/homeworkprod/weitersager


Requirements
============

- Python 3.9+
- Dependencies: blinker_, irc_, rtoml_, Werkzeug_

.. _blinker: http://pythonhosted.org/blinker/
.. _irc: https://bitbucket.org/jaraco/irc
.. _rtoml: https://github.com/samuelcolvin/rtoml
.. _Werkzeug: https://palletsprojects.com/p/werkzeug/


Installation
============

Weitersager and its dependencies can be installed via pip_:

.. code:: sh

    $ pip install weitersager

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

.. code:: sh

    $ pip install -U weitersager

.. _pip: http://www.pip-installer.org/


Usage
=====

Start Weitersager with a configuration file:

.. code:: sh

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

.. code:: toml

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

    [irc.bot]
    nickname = "Weitersager"

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

A lot more can be configured, though:

.. code:: toml

    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"

.. _TOML: https://toml.io/


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:

.. code:: json

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

.. _JSON: https://www.json.org/

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

.. code:: sh

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

.. _HTTPie: https://httpie.org/


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:

.. code:: sh

    $ 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:

.. code:: http

    Authorization: Bearer <a token of your choosing>

Example authorization header:

.. code:: http

    Authorization: Bearer e72CbijlYLqjaRIv0uMNBpgZKl397FEp-Y8PNEXn5vM

Example HTTPie_ call with authorization header:

.. code:: sh

    $ 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:

.. code:: toml

    [[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):

.. code:: sh

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

.. _Slack: https://slack.com/
.. _Discord: https://discord.com/


Run in a Docker Container
=========================

Build a container image, tagged ``weitersager``:

.. code:: sh

    $ 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:

.. code:: sh

    $ 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`_.

.. _bind mount: https://docs.docker.com/storage/bind-mounts/


Using Docker Compose
--------------------

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

.. code:: sh

    $ 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-2025 `Jochen Kupperschmidt
<http://homework.nwsnet.de/>`_

Weitersager is licensed under the `MIT License
<https://choosealicense.com/licenses/mit/>`_.

The license text is provided in the `LICENSE <LICENSE>`_ file.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "Weitersager",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "irc, webhook",
    "author": null,
    "author_email": "Jochen Kupperschmidt <homework@nwsnet.de>",
    "download_url": "https://files.pythonhosted.org/packages/7d/bd/3dbcc45d89b41271573b3057cecd4385971bbfbdc0bd5e93c3df3095e766/weitersager-1.0.1.tar.gz",
    "platform": null,
    "description": "===========\nWeitersager\n===========\n\n.. image:: https://raw.githubusercontent.com/homeworkprod/weitersager/main/assets/weitersager_logo.svg\n   :alt: Weitersager logo\n   :height: 200\n   :width: 200\n\nA proxy that receives text messages via JSON over HTTP and shows them on\nIRC.\n\nWeitersager emerged from syslog2IRC_ and offers a generic, not\nsyslog-specific input interface.\n\n.. _syslog2IRC: http://homework.nwsnet.de/releases/c474/#syslog2irc\n\n\nWebsite\n=======\n\nThe official micro website is at https://homework.nwsnet.de/releases/1cda/#weitersager.\n\n\nCode Status\n===========\n\n|badge_github-actions_test|\n|badge_scrutinizer-ci_coverage|\n|badge_scrutinizer-ci_quality-score|\n|badge_code-climate_maintainability|\n\n.. |badge_github-actions_test| image:: https://github.com/homeworkprod/weitersager/actions/workflows/test.yml/badge.svg\n   :alt: Testing Status\n   :target: https://github.com/homeworkprod/weitersager/actions/workflows/test.yml\n\n.. |badge_scrutinizer-ci_coverage| image:: https://scrutinizer-ci.com/g/homeworkprod/weitersager/badges/coverage.png?b=main\n   :alt: Scrutinizer Code Coverage\n   :target: https://scrutinizer-ci.com/g/homeworkprod/weitersager/?branch=main\n\n.. |badge_scrutinizer-ci_quality-score| image:: https://scrutinizer-ci.com/g/homeworkprod/weitersager/badges/quality-score.png?b=main\n   :alt: Scrutinizer Code Quality\n   :target: https://scrutinizer-ci.com/g/homeworkprod/weitersager/?branch=main\n\n.. |badge_code-climate_maintainability| image:: https://api.codeclimate.com/v1/badges/f45b29ee321c1920a85c/maintainability\n   :alt: Code Climate\n   :target: https://codeclimate.com/github/homeworkprod/weitersager\n\n\nRequirements\n============\n\n- Python 3.9+\n- Dependencies: blinker_, irc_, rtoml_, Werkzeug_\n\n.. _blinker: http://pythonhosted.org/blinker/\n.. _irc: https://bitbucket.org/jaraco/irc\n.. _rtoml: https://github.com/samuelcolvin/rtoml\n.. _Werkzeug: https://palletsprojects.com/p/werkzeug/\n\n\nInstallation\n============\n\nWeitersager and its dependencies can be installed via pip_:\n\n.. code:: sh\n\n    $ pip install weitersager\n\nTo update an installed copy of Weitersager to the most recent release:\n\n.. code:: sh\n\n    $ pip install -U weitersager\n\n.. _pip: http://www.pip-installer.org/\n\n\nUsage\n=====\n\nStart Weitersager with a configuration file:\n\n.. code:: sh\n\n    $ weitersager config.toml\n\n\nConfiguration\n-------------\n\nConfiguration is done as a file in TOML_ format.\n\nA very basic configuration is very short. By default, the HTTP server\nruns on port 8080 on ``localhost``. All that needs to be specified are\nthe IRC server host, bot nickname, and channel(s) to join.\n\n.. code:: toml\n\n    [irc.server]\n    host = \"irc.server.example\"\n\n    [irc.bot]\n    nickname = \"Weitersager\"\n\n    [[irc.channels]]\n    name = \"#lobby\"\n\nA lot more can be configured, though:\n\n.. code:: toml\n\n    log_level = \"debug\"         # optional; default: `\"debug\"`\n\n    [http]\n    host = \"127.0.0.1\"          # optional; default: `\"127.0.0.1\"`\n    port = 8080                 # optional; default: `8080`\n    api_tokens = [ \"123xyz\" ]   # optional; default: `[]`\n\n    [irc.server]\n    host = \"irc.server.example\"\n    port = 6667                 # optional; default: `6667`\n    ssl = false                 # optional; default: `false`\n    password = \"secret\"         # optional; default: no password\n    rate_limit = 0.5            # optional; limit of messages\n                                # per second; default: no limit\n\n    [irc.bot]\n    nickname = \"Weitersager\"\n    realname = \"Weitersager\"    # optional; default: `\"Weitersager\"`\n\n    [irc]\n    commands = [                # optional; default: `[]`\n      \"MODE Weitersager +i\",\n    ]\n\n    [[irc.channels]]\n    name = \"#party\"\n\n    [[irc.channels]]\n    name = \"#secretlab\"\n    password = \"555-secret\"\n\n.. _TOML: https://toml.io/\n\n\nIRC Dummy Mode\n--------------\n\nIf no value for ``irc.server.host`` is set, Weitersager will not attempt\nto connect to an IRC server and start in IRC dummy mode. It will still\naccept messages, but it will write them to STDOUT. This can be useful\nfor testing.\n\n\nHTTP API\n--------\n\nTo send messages to IRC, send an HTTP POST request to URL path ``/`` at\nthe address and port the application is listening on.\n\nThe body has to be in JSON_ format and contain two keys, ``channel`` and\n``text``, with string values:\n\n.. code:: json\n\n   {\n     \"channel\": \"#party\",\n     \"text\": \"Oh yeah!\"\n   }\n\n.. _JSON: https://www.json.org/\n\nExample HTTPie_ call to send a message to Weitersager on localhost, port\n8080:\n\n.. code:: sh\n\n   $ http --json post :8080 channel='#party' text='Oh yeah!'\n\n.. _HTTPie: https://httpie.org/\n\n\nAuthorization\n~~~~~~~~~~~~~\n\nTo protect the HTTP API a bit, requests can be required to include an\nauthorization header with a valid token to be accepted.\n\nThe authorization check becomes active if at least one API token is\nconfigured. A command line tool is provided to generate secure tokens:\n\n.. code:: sh\n\n    $ weitersager-token\n    e72CbijlYLqjaRIv0uMNBpgZKl397FEp-Y8PNEXn5vM\n\nMultiple API tokens can be configured so that each legitimate client\ncan be given its own token which can than be revoked (by removing it\nfrom the configuration, and restarting) individually.\n\nHeader format:\n\n.. code:: http\n\n    Authorization: Bearer <a token of your choosing>\n\nExample authorization header:\n\n.. code:: http\n\n    Authorization: Bearer e72CbijlYLqjaRIv0uMNBpgZKl397FEp-Y8PNEXn5vM\n\nExample HTTPie_ call with authorization header:\n\n.. code:: sh\n\n    $ http --json post :8080 Authorization:'Bearer e72CbijlYLqjaRIv0uMNBpgZKl397FEp-Y8PNEXn5vM' channel='#party' text='Oh yeah!'\n\nNote that Weitersager itself only uses unencrypted HTTP, so the API\ntokens are passed in the clear. That might suffice if you run it on the\nsame host as the HTTP clients. Otherwise you might want to look into\nhiding Weitersager behind a web server or proxy that can add TLS\nencryption.\n\n\nChannel Tokens\n~~~~~~~~~~~~~~\n\nWeitersager supports an alternative HTTP endpoint using a secret token\nas part of the URL instead of an authorization header. This makes it a\nbit easier to use for clients.\n\nEach secret token is mapped to a channel, so each URL already implicitly\n(though intransparently, for the caller) defines the channel the\nsubmitted text should be sent to.\n\nThis pattern is also used by popular messaging services like Slack_ and\nDiscord_ for incoming webhooks.\n\nTo expose a channel via this endpoint, just add one or more tokens to it:\n\n.. code:: toml\n\n    [[irc.channels]]\n    name = \"#secretlab\"\n    tokens = [\n      \"A2x23NmcdQgWJ8-5PivbvPX4KmdL9oa7Sy8Jj_9ldoY\",\n      \"JMApghB7wkHCtw0TcQ1Bu7zY-wG03os61bBDXfAZ4Yc\",\n    ]\n\nTo generate a token, use the ``weitersager-token`` command. Feel free to\nuse a separate token for each client/app that calls the endpoint to be\nable to revoke tokens separately (by simply removing them from the\nconfiguration) if need be.\n\nAs a result, these endpoints become available:\n\n- ``/ct/A2x23NmcdQgWJ8-5PivbvPX4KmdL9oa7Sy8Jj_9ldoY``\n- ``/ct/JMApghB7wkHCtw0TcQ1Bu7zY-wG03os61bBDXfAZ4Yc``\n\nCall them like this (note that neither the ``Authorization`` header nor\nthe ``channel`` key in the payload are specified):\n\n.. code:: sh\n\n    $ http --json post :8080/ct/A2x23NmcdQgWJ8-5PivbvPX4KmdL9oa7Sy8Jj_9ldoY text='Oh yeah!'\n\n.. _Slack: https://slack.com/\n.. _Discord: https://discord.com/\n\n\nRun in a Docker Container\n=========================\n\nBuild a container image, tagged ``weitersager``:\n\n.. code:: sh\n\n    $ docker build -t weitersager .\n\nStart the container, using configuration file\n``config_example_docker.toml`` (which should expose Weitersager *inside\nthe container* on host ``0.0.0.0`` and port 8080), exposing Weitersager\n*on the Docker host* on host ``127.0.0.1`` and port 9000:\n\n.. code:: sh\n\n    $ docker run -d \\\n      --mount type=bind,source=\"$(pwd)\"/config_example_docker.toml,destination=/app/config.toml,readonly \\\n      -p 127.0.0.1:9000:8080 \\\n      weitersager\n\nThe local configuration file is made available to the container through\na `bind mount`_.\n\n.. _bind mount: https://docs.docker.com/storage/bind-mounts/\n\n\nUsing Docker Compose\n--------------------\n\nA configuration file for Docker Compose, ``compose.yaml``, is also\navailable. Adjust as necessary, then run Weitersager in a container\nusing:\n\n.. code:: sh\n\n    $ docker-compose up --detach\n\n\nImplementation Details\n======================\n\n\nA Note on Threads\n-----------------\n\nThis tool uses threads. Besides the main thread, there are two\nadditional threads: one for the message receiver and one for the IRC\nbot. Both are configured to be daemon threads.\n\nThe dummy bot, on the other hand, does not run in a thread.\n\nA Python application exits if no more non-daemon threads are running.\n\nThe user has to manually interrupt the application to exit.\n\nFor details, see the documentation on the ``threading`` module that is\npart of Python's standard library.\n\n\nAuthor\n======\n\nWeitersager was created, and is developed and maintained, by Jochen\n\"Y0Gi\" Kupperschmidt.\n\n\nLicense\n=======\n\nCopyright (c) 2007-2025 `Jochen Kupperschmidt\n<http://homework.nwsnet.de/>`_\n\nWeitersager is licensed under the `MIT License\n<https://choosealicense.com/licenses/mit/>`_.\n\nThe license text is provided in the `LICENSE <LICENSE>`_ file.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A proxy to forward messages received via HTTP to IRC",
    "version": "1.0.1",
    "project_urls": {
        "Changelog": "https://github.com/homeworkprod/weitersager/blob/main/CHANGES.rst",
        "Homepage": "https://homework.nwsnet.de/releases/1cda/#weitersager",
        "Source code": "https://github.com/homeworkprod/weitersager"
    },
    "split_keywords": [
        "irc",
        " webhook"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "ab0292091a5d6289b33d2ae7deeb87162102e1e2251ace0aa42497c76368388c",
                "md5": "62ca9a9d858fc10132a8fe0221c26497",
                "sha256": "2fa9ada43d5e3a10aa3671e62cb5501c202989a493163a9f400d8a21f9e3014f"
            },
            "downloads": -1,
            "filename": "weitersager-1.0.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "62ca9a9d858fc10132a8fe0221c26497",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 14497,
            "upload_time": "2025-01-07T02:16:12",
            "upload_time_iso_8601": "2025-01-07T02:16:12.758470Z",
            "url": "https://files.pythonhosted.org/packages/ab/02/92091a5d6289b33d2ae7deeb87162102e1e2251ace0aa42497c76368388c/weitersager-1.0.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7dbd3dbcc45d89b41271573b3057cecd4385971bbfbdc0bd5e93c3df3095e766",
                "md5": "0dbf2be34d580fe7a3e76b59536b5bd1",
                "sha256": "321e91d8603f50ba1b90819810c1d227cfc2f841cd6f72cd04bb193179280495"
            },
            "downloads": -1,
            "filename": "weitersager-1.0.1.tar.gz",
            "has_sig": false,
            "md5_digest": "0dbf2be34d580fe7a3e76b59536b5bd1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 11360,
            "upload_time": "2025-01-07T02:16:15",
            "upload_time_iso_8601": "2025-01-07T02:16:15.372569Z",
            "url": "https://files.pythonhosted.org/packages/7d/bd/3dbcc45d89b41271573b3057cecd4385971bbfbdc0bd5e93c3df3095e766/weitersager-1.0.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-01-07 02:16:15",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "homeworkprod",
    "github_project": "weitersager",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "weitersager"
}
        
Elapsed time: 9.50585s