Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Reference client

tools/client.py drives the gRPC and REST flows by hand, the way a phone app would. It keeps tokens and key pools in tools/db.json between runs.

pip install -r requirements.txt
python -m tools.client <COMMAND> [ARGS]

Connection options

OptionDefaultDoes
--host, --port127.0.0.1, 6000gRPC server
--tlsoffUse TLS for gRPC
--rest-apihttp://localhost:16000REST API base URL
--platform, -pNonePlatform name, such as gmail
--phone-numberNonePhone number, for phone number-based authentication (PNBA), such as for Telegram
--request-identifierNoneOptional request identifier

Linking accounts

CommandDoes
get-oauth2-urlPrints the OAuth2 authorization URL
exchange-oauth2-code --code <CODE>Exchanges the code and stores the token
revoke-oauth2-tokenRevokes a stored OAuth2 token
get-pnba-code [--auth-channel signal]Requests a PNBA one-time code
exchange-pnba-code --code <CODE> [--password <PASSWORD>]Exchanges the code and stores the token; --password for two-step verification
revoke-pnba-tokenRevokes a stored PNBA token
sync-keysReplaces the token’s 256 client and 256 server ephemeral keys
python -m tools.client get-oauth2-url --platform gmail
python -m tools.client exchange-oauth2-code --platform gmail --code <AUTH_CODE>
python -m tools.client get-pnba-code --platform telegram --phone-number +237600000000
python -m tools.client exchange-pnba-code --platform telegram --phone-number +237600000000 --code <OTP>

With several stored tokens, sync-keys and the revoke commands ask which one to use. Pass --token to choose up front.

Publishing

send encrypts a message and posts it to POST /v1/publications with --address as the sender. With an attachment, the payload is split into SMS-sized segments sent --interval seconds apart.

python -m tools.client send --platform gmail --address +237600000000 \
    --to friend@example.com --subject "Hello" --body "Test message"

python -m tools.client send --platform gmail --address +237600000000 \
    --to friend@example.com --subject "Hello" --body "See attached" --attachment ./file.pdf --interval 2.5 --shuffle

python -m tools.client send --offline --platform rmail --address +237600000000 \
    --to friend@example.com --subject "Hello" --body "No token needed" --tag <SECRET>
OptionDoes
--addressSender’s number in E.164 format (required)
--bodyMessage body (required)
--toRecipient email or number, for email and messaging platforms
--subjectSubject, for email platforms
--attachmentFile to attach, sent as several segments
--intervalSeconds between segments (default 1.0)
--shuffleSends segments out of order
--dry-runPrints the segments and their order without sending
--tokenRaw token (base64), instead of choosing interactively
--offlineUses offline-first encryption, which needs no linked token (rmail only)
--tagThe server’s OFFLINE_PUBLISH_SHARED_SECRET, when it sets one

Each online send uses up one ephemeral key pair. Run sync-keys when the pool runs low. Offline sends use none.

--shuffle --dry-run shows the segment order before a live send, to check the server reassembles out-of-order segments.