unseenet-bots
Bots that keep Unseenet channels filled with current content, and an example of how to build a bot on the Unseenet core library.
Status: early. Six sources work, listed below.
Idea
- One bot is one key, a poster in a channel (never the owner), with
bot: truein its profile (UN-RFC 0030 section 6). - One source per bot: fetch, turn into a post with a credit line (author, source, licence, link), post on a schedule.
- Built only on the public core API of unseenet/unseenet, so it doubles as an example for anybody writing their own bot.
- Readers can comment if the channel has
comments: open(UN-RFC 0030).
Running it
pip install unseenet-bots
cp bots.example.toml bots.toml # fill in groups and key files
unseenet-bots -c bots.toml new-key ~/.config/unseenet-bots/news.key
# -> make the printed key a poster in the channel (Make poster)
unseenet ripen --key-file ~/.config/unseenet-bots/news.key --to 0 \
--node NODE.onion --publish # once: 7-11 minutes, see below
unseenet-bots -c bots.toml run --dry-run # see what would be posted
unseenet-bots -c bots.toml run # post what is new
A new key ripens first (UN-RFC 0025): nodes take posts only from keys
that have done a few minutes of work, which is what keeps throwaway keys
from spamming. Do it once at setup with unseenet ripen as above; its
chain goes in <key file>.state.json, beside the key, where the runner
finds it (it holds nothing secret). A first run without it would ripen
then, and take as long. Ripening on to level 3 removes the extra postage
a young key pays: unseenet ripen --key-file KEY --to 3 --node NODE --publish
in the background, about 2.5-4 days on one core at low priority.
Each run fetches every source once and posts what has not been posted
before (remembered in a state file, and checked against the channel's
newest threads). Schedule it, e.g. every hour, with the systemd units in
contrib/. It starts its own Tor, or uses a running one if
UNSEENET_TOR_SOCKS names its SOCKS port. Sources are fetched directly
from the web, not over Tor.
| Source | Posts | Licence |
|---|---|---|
wikipedia-news |
one post per story in Wikipedia's In the news | CC BY-SA 4.0 |
wikipedia-onthisday |
one post a day with the day's anniversaries | CC BY-SA 4.0 |
globalvoices |
whole stories from Global Voices, credited at the top | CC BY 3.0 |
theconversation |
the opening paragraphs of articles from The Conversation, and a link to the rest; use max_per_day, as their terms do not allow republishing every article |
CC BY-ND 4.0 |
eff |
whole posts from EFF's Deeplinks blog | CC BY 4.0 |
nasa-iotd |
NASA's Image of the Day: the caption and a link to the picture | not copyrighted |
Images are left out of every post, because they often have licences of
their own; each post links to the original. Only items from the last two
days are posted (max_age_hours), so a new bot does not fill its channel
with old news.
Open the channel for comments (Edit group → Readers may comment on posts, UN-RFC 0030) so readers can talk about each post.
Writing a source
A source is a class with a name and fetch(today) -> list[Item] in
src/unseenet_bots/sources/. An Item has a stable id (so nothing is
posted twice), a subject and a markdown body that ends with the
credit line its licence asks for. See wikipedia.py, and Writing a bot
in the Unseenet docs for the core API underneath.
Content and licences
Only sources whose licences allow reposting are used, and each post credits its source as the licence asks. News agencies whose terms forbid redistribution are not used. The first sources are listed in issue #1.
Whoever runs a bot is responsible for its content and for following the source's licence.
Versions and releases
Versions follow semantic versioning on the same
principles as unseenet:
tags vX.Y.Z on main, the changes in CHANGELOG.md, and
releases on PyPI. Each release names the
minor version of unseenet it works with (unseenet>=0.4.1,<0.5).
To release: move the entries under ## [Unreleased] in CHANGELOG.md to a
new ## [X.Y.Z] - YYYY-MM-DD section, set __version__ in
src/unseenet_bots/__init__.py, commit, then
git tag -a vX.Y.Z -m "unseenet-bots X.Y.Z" && git push origin vX.Y.Z.
Licence
The code is licensed under the Apache License 2.0. Content posted by the bots keeps the licence of its source.
Metadata
Release files for unseenet-bots 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| unseenet_bots-0.1.0.tar.gz | 22.5 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| unseenet_bots-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 42.2 kB
Release files / unseenet_bots-0.1.0.tar.gz
| Download URL | unseenet_bots-0.1.0.tar.gz |
|---|---|
| Size | 22.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
45b2a78c21dd38946a0964c768bd6f6b062bc869914da7afbb1b8b1850f5b6d6
|
|
BLAKE2b-256 checksum How to use checksums |
cc6726a9ce1eaecd064e5a1e4cc169582725b1c21468def7d6a23d6d2f2f22ea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / unseenet_bots-0.1.0-py3-none-any.whl
| Download URL | unseenet_bots-0.1.0-py3-none-any.whl |
|---|---|
| Size | 19.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e9075096225e2cfd7401849988792ca71244282c233e70b06a0ccf048b65cdd5
|
|
BLAKE2b-256 checksum How to use checksums |
e967a8415fbfbe5694f3e7a44c99fc8b6e9cad95432cf2a9ecd854d221e700a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logSecurity for unseenet-bots 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for unseenet_bots-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.