Skip to content

The modules

The service is a single Rust binary. One process starts three things: the API (axum), the poller and the emission worker.

The module map

Shared

Talking to networks

The ones that work alone

HTTP surface

Entry points

main.rs

starts all three

cli.rs

operational commands

api/

routes and handlers

auth/

identity and capabilities

poller.rs

every N hours

emision/

takes the queue and publishes

latidos.rs

«still alive»

ingesta/

fetch

redes/

publish

instagram/

browser + yt-dlp

cuentas.rs

platforms and sign-up

archivo.rs

bytes on disk

cripto.rs

AES-256-GCM

alertas/

notify

cauce/

export and import

probe/

probes

What each one does

Fetching material — ingesta/

One module per source, all behind the same shape: given an account and its cursor, return what is new.

ModuleSourceHow
ingesta/cliente.rsInstagram with a tokenGraph API, Business/Creator accounts
ingesta/instagram_publico.rsInstagram without a tokenHeadless browser over the public profile
ingesta/telegram.rsTelegramBot API (getUpdates)
ingesta/rss.rsAny feedfeed-rs, RSS and Atom
ingesta/web.rsYour own siteThe Antisionista API

Instagram has two modules and not one. With a token the official API is used, which is fast and stable. Without a token —a public account that gave permission but cannot hand over business credentials— the profile is opened with a browser. They are different paths with different costs, and the marker for which one to use is explicit (config.via = 'navegador'), never inferred from a missing credential: inferring it would turn a revoked token into scraping without anyone deciding so.

Publishing — redes/

ModuleDestination
redes/mastodon.rsMastodon and compatibles
redes/telegram.rsChannels and groups
redes/identidad.rs“Who am I with this token?” — verifies before signing an account up
redes/segmentacion.rsSplits a long video into publishable pieces
redes/falso.rsA fake destination, for the tests

The probes — probe/

They answer “would this work?” without publishing anything. They are split into origen and destino because those are different questions: whether you can read, and whether you can write.

A probe never returns “ok” without having touched the network. It may return no_verificado, which is neither good nor bad: there was nothing to check it with. Having it as a state of its own is what stops “could not look” from being counted as “it is fine”.

How the emission pieces relate

originates

receives

authorises

source

destination

uses

1

1

1

1

1

1

0..*

0..*

0..*

1

1

0..*

Emision

+id: Uuid

+item_id: Uuid

+cuenta_destino_id: Uuid

+estado: String

+ronda: i32

+intentos: i32

+aprobado_por: Option<String>

+detener: bool

Item

+id: Uuid

+cuenta_origen_id: Uuid

+permalink: Option<String>

+tags: Vec<String>

+autor: Option<String>

+regimen: String

+archivo_estado: String

+pasa_condicion() : bool

Ruta

+clave: String

+origen_id: Uuid

+destino_id: Uuid

+condicion: Option<Json>

+activa: bool

+auto_publica: bool

Cuenta

+plataforma: String

+rol: String

+credenciales_cifradas: Option<Bytes>

+config: Json

+salud: String

+admite(rol) : bool

Consentimiento

+otorgado_por: String

+otorgado_en: DateTime

+revocado_en: Option<DateTime>

+cuentas_destino: Vec<Uuid>

+vigente() : bool

«interface»

ClienteDeRed

+publicar(item) : Result

+identidad() : Result

Mastodon

Telegram

Web

The tap (max_por_hora) lives on the destination ACCOUNT, not on the route. The limit belongs to whoever receives: if three different flows point at the same Mastodon account, the ceiling is set by Mastodon and not by each flow separately. Putting it on the route would have let three routes “of 4 per hour” do 12.

The two surfaces: HTTP and CLI

They do similar things and they are not interchangeable.

CLI (on the server)

Panel (HTTP)

same function

sign accounts up

approve emissions

grant permissions

export cauce

WITHOUT credentials

sign accounts up

export cauce

WITH encrypted credentials

import and restore

historical backfill

The backup with encrypted credentials only comes out through the CLI. Over HTTP the tokens always come out empty. That cut is what leaves the invariant “this service has no endpoint that returns ciphertext” without exceptions: the only path that touches them is not an endpoint.

The CLI does not get a free pass for running on the server. Import and restore validate identity against the host and require the administration capability. Only export and validate are exempt, because a backup has to be able to run from cron.