Metadata-Version: 2.4
Name: wbiztool-client
Version: 1.1.0
Summary: Python client for the WbizTool WhatsApp messaging API
Home-page: https://github.com/anuragmeena92/wbiztool-client
Author: Anurag Meena
Author-email: anuragmeena92@gmail.com
Project-URL: Documentation, https://wbiztool.com/docs/
Project-URL: Source, https://github.com/anuragmeena92/wbiztool-client
Project-URL: Tracker, https://github.com/anuragmeena92/wbiztool-client/issues
Project-URL: Official Website, https://wbiztool.com
Project-URL: Support, https://wbiztool.com/contact
Keywords: wbiztool,whatsapp,api,client,messaging,communication
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Communications :: Chat
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25.0
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license-file
Dynamic: project-url
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# WbizTool Client

A Python client library for the [WbizTool](https://wbiztool.com) API, making it easy to integrate WhatsApp messaging capabilities into your Python applications.

## About WbizTool

[WbizTool](https://wbiztool.com) is a powerful platform that provides WhatsApp API integration for businesses. With WbizTool, you can automate your WhatsApp messaging workflow and engage with your customers more effectively.

Visit [wbiztool.com](https://wbiztool.com) to create an account and get your API credentials.

## Installation

```bash
pip install wbiztool-client
```

## Authentication

You'll need an API key and client ID from your [WbizTool account](https://wbiztool.com/login):

1. Log in to your WbizTool account
2. Go to API Keys section
3. Generate a new API key if you don't have one

### Using Environment Variables

You can set your credentials as environment variables:

```bash
export WBIZTOOL_API_KEY=your_api_key
export WBIZTOOL_CLIENT_ID=your_client_id
```

The client will automatically use these variables if not provided explicitly during initialization.

## Quick Start

```python
from wbiztool_client import WbizToolClient

# Option 1: Initialize with explicit credentials
client = WbizToolClient(
    api_key='your_api_key',
    client_id=12345  # Your API Client ID (Settings -> API keys); every call except health_check() needs it
)

# Option 2: Initialize using environment variables
client = WbizToolClient()  # Will use WBIZTOOL_API_KEY and WBIZTOOL_CLIENT_ID

# Option 3: Initialize and validate credentials immediately
try:
    client = WbizToolClient(validate_credentials=True)
    print("Credentials are valid!")
except ValueError as e:
    print(f"Invalid credentials: {e}")

# Check if API is operational
status = client.health_check()
print(status)

# Send a simple text message
response = client.send_message(
    phone='919876543210',  # Include country code
    msg='Hello from Python!',
    msg_type=0  # 0 for text message
)
print(response)
```

## Errors

Every failed request raises `wbiztool_client.WbizToolError`: HTTP errors (400, 403, 429, 500 ...) and the
refusals the API answers with HTTP 200 and `"status": 0` (most errors of scheduling, cancelling and bulk
sends come back that way). It subclasses both `requests.exceptions.HTTPError` and `ValueError`, so code
written for 1.0.x keeps working.

```python
from wbiztool_client import WbizToolClient, WbizToolError

try:
    client.cancel_message(msg_id=9817263)
except WbizToolError as e:
    print(e.message)      # the API's message, e.g. "Msg has been Sent"
    print(e.status_code)  # HTTP status (200 for a status-0 refusal)
    print(e.data)         # the full JSON body
```

Two endpoints are different: `get_message_status()` returns the message's state in `status` (0 = still
queued, also returned for an unknown ID: check `message`), and `get_whatsapp_client_status(id)` returns
`{"message": "Disconnected", "status": 0}` for a disconnected number instead of raising.

## Features

- Send text messages
- Send image messages with captions
- Send document/file messages with captions
- Upload files directly from your local system
- Send messages to multiple individual recipients
- Send messages to WhatsApp groups
- Schedule messages for future delivery
- Cancel scheduled messages
- Check message delivery status
- Get reports of sent messages
- Manage WhatsApp clients

## API Methods

### Authentication and Status

- `health_check()` - Check if the API is operational
- `check_credentials(whatsapp_client=None)` - Verify API credentials (and optionally a WhatsApp number ID)

### Messaging

- `send_message(phone, msg, ...)` - Send a WhatsApp message to an individual
- `send_message_to_group(group_name, msg, ...)` - Send a message to a WhatsApp group
- `send_bulk_messages(phones, msg, ...)` - Send to multiple individual recipients
- `schedule_message(phone, msg, schedule_time, timezone=..., ...)` - Schedule a message (to a number or a `group_name`)
- `cancel_message(msg_id)` - Cancel a scheduled message
- `get_message_status(msg_id)` - Get delivery status

### Reporting

- `get_messages_report(start_date, end_date, ...)` - Get sent messages report

### WhatsApp Clients

- `get_whatsapp_client_status(whatsapp_client_id=None)` - Get status of a specific client, or of all clients when no ID is given
- `get_specific_whatsapp_client_status(whatsapp_client_id)` - Alias for checking a specific client status
- `get_whatsapp_accounts()` - Every WhatsApp number with its status (`connected` / `not_connected`)
- `list_whatsapp_clients()` - List the WhatsApp numbers connected right now
- `create_whatsapp_client(whatsapp_number, webhook_url, login_method=None, whatsapp_client_id=None)` - Connect a WhatsApp number by QR code or pairing code (Advanced Plan required)

## Examples

### Sending a Text Message

```python
response = client.send_message(
    phone='919876543210',
    msg='Hello, this is a simple text message',
    country_code='91',
    msg_type=0,  # 0 for text
    webhook='https://your-webhook.com/callback'  # Optional webhook for delivery notifications
)
```

### Sending an Image with Caption

```python
# Using an image URL
response = client.send_message(
    phone='919876543210',
    msg='Check out this image!',
    country_code='91',
    msg_type=1,  # 1 for image
    img_url='https://example.com/path/to/image.jpg'
)

# OR upload a local image file
response = client.send_message(
    phone='919876543210',
    msg='Check out this image!',
    country_code='91',
    msg_type=1,  # 1 for image
    file_path='/path/to/local/image.jpg'
)
```

### Sending a Document/File with Caption

```python
# Using a file URL
response = client.send_message(
    phone='919876543210',
    msg='Please see the attached document',
    country_code='91',
    msg_type=2,  # 2 for document/file
    file_url='https://example.com/path/to/document.pdf',
    file_name='Important Document.pdf'
)

# OR upload a local file
response = client.send_message(
    phone='919876543210',
    msg='Please see the attached document',
    country_code='91',
    msg_type=2,  # 2 for document/file
    file_path='/path/to/local/document.pdf'
)
```

### Message with Expiry Time

```python
# Message will expire if not delivered within 1 hour (3600 seconds)
response = client.send_message(
    phone='919876543210',
    msg='This message will expire if not delivered within 1 hour',
    country_code='91',
    expire_after_seconds=3600
)
```

### Sending a Message to a WhatsApp Group

```python
# Send a text message to a WhatsApp group
response = client.send_message_to_group(
    group_name='Family Group',
    msg='Hello everyone in the group!',
    msg_type=0  # 0 for text
)

# Send a document to a WhatsApp group
response = client.send_message_to_group(
    group_name='Work Team',
    msg='Here is the report for everyone',
    msg_type=2,  # 2 for document/file
    file_url='https://example.com/path/to/report.pdf',
    file_name='Team Report.pdf'
)
```

### Sending to Multiple Individual Recipients

```python
# Send the same message to multiple phone numbers (group names can be in the list too)
response = client.send_bulk_messages(
    phones=['919876543210', '919876543211', '919876543212'],
    msg='This message goes to multiple individuals',
    country_code='91',
    whatsapp_client=123,  # required by this endpoint
    msg_type=0  # 0 for text
)
print(response['msg_ids'])
```

Bulk sends and scheduled messages take images and files by URL (`img_url` / `file_url`) only; to upload a
local file use `send_message(file_path=...)`.

### Checking WhatsApp Client Status

```python
# Get status of all WhatsApp clients
all_clients_status = client.get_whatsapp_client_status()
for number in all_clients_status['whatsapp_clients']:
    print(number['whatsapp_client_id'], number['whatsapp_number'], number['status'])

# Get status of a specific WhatsApp client
specific_client_status = client.get_whatsapp_client_status(whatsapp_client_id=123)
# Or using the alias method
specific_client_status = client.get_specific_whatsapp_client_status(whatsapp_client_id=123)
print(specific_client_status)
```

### Scheduling a Message

```python
from datetime import datetime, timedelta, timezone

# A wall-clock time in a named timezone
response = client.schedule_message(
    phone='9876543210',
    msg='This is a scheduled message',
    schedule_time='2026-12-24 09:00',   # or '24/12/2026 09:00', or a datetime
    timezone='Asia/Kolkata',            # IANA name or IST, UTC, EST, PST, CET ... (default: UTC)
    country_code='91',
    whatsapp_client=123                 # required by this endpoint
)
print(response['msg_id'])

# Or an exact moment: an aware datetime is sent in UTC
response = client.schedule_message(
    phone='919876543210',
    msg='Reminder in one hour',
    schedule_time=datetime.now(timezone.utc) + timedelta(hours=1),
    whatsapp_client=123
)

# A WhatsApp group instead of a number
response = client.schedule_message(
    group_name='Sales Team Mumbai',
    msg='Team meeting starts in 15 minutes.',
    schedule_time='2026-12-24 14:45',
    timezone='Asia/Kolkata',
    whatsapp_client=123
)
```

The API schedules to the minute: seconds are dropped. A time in the past is sent straight away.

### Getting Message Reports

```python
# Get message history for a specific date range
report = client.get_messages_report(
    start_date='01-05-2023',  # DD-MM-YYYY format (or a date object)
    end_date='01-06-2023',    # DD-MM-YYYY format; this day itself isn't included
    whatsapp_client=123,      # Optional: specific WhatsApp client ID
    page=1                    # For pagination, 200 messages per page
)

# Print the total count of messages
print(f"Found {report['total']} messages")

# Process the message history
for message in report.get('history', []):
    print(f"Message {message['id']}: {message['message_status']}")
```

### Canceling a Message

```python
from wbiztool_client import WbizToolError

# Cancel a scheduled or pending message
try:
    client.cancel_message(msg_id=123)
    print("Message canceled successfully")
except WbizToolError as e:
    print(f"Failed to cancel message: {e.message}")  # e.g. "Msg has been Sent"
```

### Creating a WhatsApp Client

```python
# Create a new WhatsApp client (Advanced Plan required)
# The QR code (or, with login_method='phone', the pairing code) is posted to webhook_url
try:
    result = client.create_whatsapp_client(
        whatsapp_number='919876543210',  # used with login_method='phone', ignored for a QR code
        webhook_url='https://your-webhook.com/whatsapp-events',
        login_method='phone'
    )
    print(f"New WhatsApp client created with ID: {result['whatsapp_client_id']}")
except WbizToolError as e:
    print(f"Failed to create WhatsApp client: {e.message}")
```

### Listing WhatsApp Clients

```python
# Get all WhatsApp clients for your account
result = client.list_whatsapp_clients()

for wa_client in result['whatsapp_clients']:
    print(f"Client ID: {wa_client['whatsapp_client_id']}")
    print(f"Number: {wa_client['whatsapp_client_number']}")
    print(f"Connected: {wa_client['is_connected']}")
    print("---")
```

### Checking if credentials are valid at any time

```python
# Check if credentials are valid at any time
try:
    result = client.check_credentials()
    print("Credentials are valid!")
except ValueError as e:
    print(f"Credential error: {e}")
```

## Development

```bash
python -m unittest discover -s tests -v   # no network: HTTP is mocked
```

## Additional Resources

- [WbizTool Official Website](https://wbiztool.com)
- [API Documentation](https://wbiztool.com/docs)
- [Support](https://wbiztool.com/contact)

## License

MIT License 
