Skip to main content

Signal messaging library for Python using Presage (Rust)

Project description

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

Project details


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.3.0.tar.gz (68.6 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.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (8.9 MB view details)

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

replyfast-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (8.9 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64

replyfast-0.3.0-cp310-abi3-macosx_11_0_arm64.whl (7.2 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

replyfast-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl (7.4 MB view details)

Uploaded CPython 3.10+macOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: replyfast-0.3.0.tar.gz
  • Upload date:
  • Size: 68.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for replyfast-0.3.0.tar.gz
Algorithm Hash digest
SHA256 dc2bef046756f2711ed013f7247a5bf133733d90f60578365bf4c1eb99852850
MD5 3552760be26daff5f8963591142970f7
BLAKE2b-256 e4503d9ed340eac9e9f5276fe277d9528adf3816f18e6c4e3046640054d76686

See more details on using hashes here.

Provenance

The following attestation bundles were made for replyfast-0.3.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.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for replyfast-0.3.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 ddc02172fe0d907acdb48d5f18ba32ca70d5d04f6ecaf3db3f274279f76cec5b
MD5 63b4773dd282fd549e3e019ed60b2dee
BLAKE2b-256 b3daedc8ebb7538bb8bbaf3804c2ea04de04c69be62893767db7a10bba6c2385

See more details on using hashes here.

Provenance

The following attestation bundles were made for replyfast-0.3.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.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for replyfast-0.3.0-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4d4e4d2d82ea670830d57cf7e7253ca4c1541f9ccbbfbb904e365fcc8e0898e3
MD5 181981213369633eb31d01d9b76395fe
BLAKE2b-256 a471e8dc8eb35b5e3bd76e06c017b0e82091324e01e9a82b17b6fb1c66dadd55

See more details on using hashes here.

Provenance

The following attestation bundles were made for replyfast-0.3.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.3.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for replyfast-0.3.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 cd647323463bae6581ed1678f72ce384ca03b71ac2a9cbb52f28bc9f7d32079c
MD5 defa753b5b5a074e33fb5ecfcbb640b2
BLAKE2b-256 4a146f43669e6c0429028f69930600596ff8d68f9df7ba43576a6627b23460da

See more details on using hashes here.

Provenance

The following attestation bundles were made for replyfast-0.3.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.3.0-cp310-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for replyfast-0.3.0-cp310-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 d827c05e12864c319c60b43b7259f7b22ae9ac616c9c65c0c292359370951c47
MD5 32d6411f50a7403e80fb17be09ca9059
BLAKE2b-256 fe76de87ebfbb750a9eb2d73f782d4189a11beab8d4d6fc129b05a2ee9ab679f

See more details on using hashes here.

Provenance

The following attestation bundles were made for replyfast-0.3.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.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page