Skip to main content

ReplyFast

Signal messaging library for Python using Presage (Rust).

Installation

uv pip install replyfast

# With optional dependencies
uv pip install replyfast[scheduler]  # For cron scheduling
uv pip install replyfast[qrcode]     # For QR code display
uv pip install replyfast[all]        # Everything

Contents

Quick Start

from replyfast import SignalClient

# Create client
client = SignalClient("./data")

# Link as secondary device (first time only)
def on_url(url):
    print(f"Scan this QR code with Signal app: {url}")

client.link_device_sync("MyDevice", on_url)

# Send a message
client.send_message_sync("recipient-uuid", "Hello!")

# Or find contact by phone/name first
contact = client.find_contact_by_phone_sync("+1234567890")
if contact:
    client.send_message_sync(contact.uuid, "Hello!")

# Receive messages
def on_message(msg):
    if msg.is_queue_empty:
        print("Initial sync complete")
        return True

    print(f"From: {msg.sender}, Body: {msg.body}")
    return True  # Return True to continue, False to stop

client.receive_messages_sync(on_message)

API Reference

SignalClient

Method Description
is_registered_sync() Check if device is linked
link_device_sync(name, callback) Link as secondary device
send_message_sync(uuid, message) Send message to contact
send_group_message_sync(group_id, message) Send message to group
receive_messages_sync(callback) Receive messages with callback
get_contacts_sync() List synced contacts
get_groups_sync() List groups
find_contact_by_phone_sync(phone) Find contact by phone number
find_contacts_by_name_sync(name) Find contacts by name
whoami_sync() Get account info

Message

Field Type Description
sender str Sender's UUID
body str | None Message text
timestamp int Unix timestamp (ms)
group_id str | None Group ID if group message
is_read_receipt bool Is read receipt
is_typing_indicator bool Is typing indicator
is_queue_empty bool Initial sync complete marker

Signal Handling

The library handles SIGINT (Ctrl+C) cleanly. When you press Ctrl+C during receive_messages_sync(), it will:

  1. Stop the receive loop gracefully
  2. Raise KeyboardInterrupt in Python
  3. Allow cleanup code to run
try:
    client.receive_messages_sync(on_message)
except KeyboardInterrupt:
    pass  # Clean exit

print("Stopped")

Scheduler

Send messages at scheduled times using cron syntax.

Scheduler with Message Receiving

When running a bot that both receives messages and runs scheduled tasks, start the scheduler after the initial sync is complete (indicated by is_queue_empty):

import time
from replyfast import SignalClient, Scheduler

client = SignalClient("./data")
scheduler = Scheduler()

# Define scheduled task
def periodic_task():
    client.send_message_sync("recipient-uuid", "Scheduled message!")

# Register jobs before starting
scheduler.register(
    "*/5 * * * *",  # Every 5 minutes
    periodic_task,
    name="periodic-task"
)

# Message handler that starts scheduler after sync
def on_message(msg):
    # Start scheduler once initial sync is complete
    if msg.is_queue_empty:
        print("Ready to receive messages")
        scheduler.start()  # Start scheduler in background
        return True

    if msg.body:
        print(f"From: {msg.sender}: {msg.body}")
        # Handle commands here

    return True

# Run with reconnection loop for long-running bots
reconnect_delay = 5

while True:
    try:
        client.receive_messages_sync(on_message)
        break  # Normal exit
    except KeyboardInterrupt:
        break  # Ctrl+C
    except Exception as e:
        print(f"Connection error: {e}")
        print(f"Reconnecting in {reconnect_delay}s...")
        time.sleep(reconnect_delay)
        reconnect_delay = min(reconnect_delay * 2, 300)  # Max 5 min

scheduler.stop()
print("Stopped")

Scheduler Only (No Message Receiving)

from replyfast import SignalClient, Scheduler

client = SignalClient("./data")
scheduler = Scheduler()

def send_greeting():
    contact = client.find_contact_by_phone_sync("+1234567890")
    if contact:
        client.send_message_sync(contact.uuid, "Good morning!")

scheduler.register(
    "0 9 * * *",  # cron: minute hour day month weekday
    send_greeting,
    name="morning-greeting"
)

# Run scheduler (blocking)
scheduler.run()

# Or run in background
scheduler.start()
# ... do other things ...
scheduler.stop()

Cron Expression Format

┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, 0=Sunday)
│ │ │ │ │
* * * * *

Examples:

  • */5 * * * * - Every 5 minutes
  • 0 9 * * * - Every day at 9:00 AM
  • 0 9 * * 1-5 - Weekdays at 9:00 AM
  • 30 */2 * * * - Every 2 hours at minute 30

Decorator Syntax

from replyfast import schedule, get_scheduler

@schedule("0 9 * * *")
def daily_task():
    print("Runs every day at 9 AM")

get_scheduler().start()

Examples

The examples/ directory contains complete working examples:

example.py

Basic usage showing how to list contacts, groups, and receive messages with proper signal handling:

python examples/example.py

Demonstrates:

  • Checking registration status
  • Getting account info with whoami_sync()
  • Listing contacts and groups
  • Receiving messages with callback
  • Handling typing indicators and read receipts
  • Clean Ctrl+C shutdown

demo_bot.py

A bot that sends system stats on a schedule while also responding to commands:

DEMO_RECIPIENT=<uuid> python examples/demo_bot.py

Demonstrates:

  • Scheduler with message receiving (starts after is_queue_empty)
  • Multiple scheduled jobs (df -h every 5 min, free -m every hour)
  • Interactive commands (ping, df, free, help)
  • Reconnection loop with exponential backoff
  • Proper cleanup on shutdown

Requirements

  • Python 3.10+
  • Rust toolchain (for building from source)

License

AGPL-3.0-or-later

Download files

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

Source Distribution

replyfast-0.4.0.tar.gz (70.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

replyfast-0.4.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (9.9 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ x86-64

replyfast-0.4.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (10.5 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

replyfast-0.4.0-cp310-abi3-macosx_11_0_arm64.whl (9.1 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

replyfast-0.4.0-cp310-abi3-macosx_10_12_x86_64.whl (9.1 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

Details for the file replyfast-0.4.0.tar.gz.

File metadata

  • Download URL: replyfast-0.4.0.tar.gz
  • Upload date:
  • Size: 70.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for replyfast-0.4.0.tar.gz
Algorithm Hash digest
SHA256 276e6bfdbda9cf3baae39c02150b1f4150bde30c023cd8b3d7012acaf3fb9f82
MD5 bc81423ece352e5a7f77eeba453630b2
BLAKE2b-256 8b3cc796b74095fb50b94dab998eebe97a7635a78ac0c19e45ecc9027b1c499c

See more details on using hashes here.

Provenance

The following attestation bundles were made for replyfast-0.4.0.tar.gz:

Publisher: release.yml on kushaldas/replyfast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file replyfast-0.4.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for replyfast-0.4.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 624ebcbfb1e45939f9aef0adf50d2f49004bd1e0ce8d3d6213db4b80c0481064
MD5 e82565a98608b963b1f9c8b83a74913a
BLAKE2b-256 b18db46e86026a3d65230e9d97c3d0e5254c487404962786fca38b05c29c57ba

See more details on using hashes here.

Provenance

The following attestation bundles were made for replyfast-0.4.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on kushaldas/replyfast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file replyfast-0.4.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for replyfast-0.4.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1bb9fc0b0632db568c2785cbddf93626c2cc1e5efb802af0d00c683b0cb32e9c
MD5 c11011d21b83ac860254b3f27dee3ae4
BLAKE2b-256 2e4c278b44e51ca6add39a3f383431bbde07c7d9dfe765328a42a7e0f746e561

See more details on using hashes here.

Provenance

The following attestation bundles were made for replyfast-0.4.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on kushaldas/replyfast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file replyfast-0.4.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for replyfast-0.4.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 16b4049c5321e6b362e557a3a26af854bbaa4928ede1c15b215807131c8729a4
MD5 6c3e5dfebe58f1bf8a37393e3934cbdb
BLAKE2b-256 8a7dc1d133ba40d77f950277c48ced160b56b25b64de716415c157d9bde1695f

See more details on using hashes here.

Provenance

The following attestation bundles were made for replyfast-0.4.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on kushaldas/replyfast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file replyfast-0.4.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for replyfast-0.4.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 4da3883663729a072425c784b65f11e44ecbae33e19b0f2c3d7ba92f27412a46
MD5 fe9b377fe1aeeb6a0013da64c1449ab3
BLAKE2b-256 e83aabb1ddbd6f55713a6be15d51badbee16f61c5e3203f433658a02aab7500d

See more details on using hashes here.

Provenance

The following attestation bundles were made for replyfast-0.4.0-cp310-abi3-macosx_10_12_x86_64.whl:

Publisher: release.yml on kushaldas/replyfast

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.4.0 This release

5 files

0.3.0

5 files

0.1.0

5 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page