Metadata-Version: 2.4
Name: helpscout-mailbox
Version: 1.0.2
Summary: Python client for the HelpScout Mailbox API v2
Project-URL: Homepage, https://connectify.github.io/helpscout-mailbox/
Project-URL: Documentation, https://connectify.github.io/helpscout-mailbox/
Project-URL: Repository, https://github.com/Connectify/helpscout-mailbox
Project-URL: Issues, https://github.com/Connectify/helpscout-mailbox/issues
Author-email: Connectify <devops@connectify.com>
License-Expression: BSD-3-Clause
License-File: LICENSE
Keywords: api,client,customer-service,helpscout,mailbox,support
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: requests>=2.28.0
Provides-Extra: dev
Requires-Dist: autoflake>=2.0; extra == 'dev'
Requires-Dist: autopep8>=2.0; extra == 'dev'
Requires-Dist: bandit[toml]>=1.7; extra == 'dev'
Requires-Dist: black>=24.0; extra == 'dev'
Requires-Dist: flake8>=7.0; extra == 'dev'
Requires-Dist: isort>=5.0; extra == 'dev'
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pre-commit>=3.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: pyupgrade>=3.0; extra == 'dev'
Requires-Dist: responses>=0.23.0; extra == 'dev'
Requires-Dist: types-requests>=2.28; extra == 'dev'
Provides-Extra: docs
Requires-Dist: pdoc>=14.0; extra == 'docs'
Description-Content-Type: text/markdown

# helpscout-mailbox

[![PyPI](https://img.shields.io/pypi/v/helpscout-mailbox.svg?cacheSeconds=3600)](https://pypi.org/project/helpscout-mailbox/)
[![Python Versions](https://img.shields.io/pypi/pyversions/helpscout-mailbox.svg?cacheSeconds=3600)](https://pypi.org/project/helpscout-mailbox/)
[![License](https://img.shields.io/pypi/l/helpscout-mailbox.svg?cacheSeconds=3600)](https://github.com/Connectify/helpscout-mailbox/blob/main/LICENSE)
[![Tests](https://github.com/Connectify/helpscout-mailbox/actions/workflows/test.yml/badge.svg?cacheSeconds=3600)](https://github.com/Connectify/helpscout-mailbox/actions/workflows/test.yml)

A Python client for the [HelpScout Mailbox API v2](https://developer.helpscout.com/mailbox-api/).

> **Disclaimer:** This package is **unofficial** and **not associated with or endorsed by HelpScout**. It is provided "as is" without warranty of any kind. Please use [GitHub Discussions](https://github.com/Connectify/helpscout-mailbox/discussions) for support — there is no guarantee that Connectify staff will respond.

## Features

- **OAuth2 client-credentials authentication** with automatic token refresh
- **Retry logic** for rate limiting (429), server errors (5xx), and transient failures
- **Conversation management**: search, read, snooze, tag
- **Thread operations**: notes, replies, drafts, attachments
- **Clean API** with type hints and comprehensive docstrings

## Installation

```bash
pip install helpscout-mailbox
```

## Quick Start

```python
import os
from datetime import date, datetime, timedelta, timezone
from helpscout_mailbox import HelpScoutClient

# Set credentials (create app at HelpScout → Your Profile → My Apps)
os.environ["HELPSCOUT_APP_ID"] = "your-app-id"
os.environ["HELPSCOUT_APP_SECRET"] = "your-app-secret"

# Initialize client (fetches OAuth2 token automatically)
client = HelpScoutClient()

# Search conversations
for conv in client.search_conversations('subject:"Invoice"', since=date(2026, 6, 1)):
    print(f"#{conv['number']}: {conv['subject']}")

# Get conversation details
conversation = client.get_conversation(12345)
print(conversation["subject"])

# Add a note
client.add_note(12345, "Processed invoice #INV-001")

# Snooze until tomorrow
tomorrow = datetime.now(timezone.utc) + timedelta(days=1)
client.snooze_conversation(12345, tomorrow)

# Add tags
client.add_tags(12345, ["billing", "processed"])
```

## API Coverage

### Conversations

- `search_conversations(query, since)` - Search with client-side date filtering
- `get_conversation(conversation_id)` - Fetch conversation details
- `snooze_conversation(conversation_id, snoozed_until)` - Snooze conversation
- `add_tags(conversation_id, tags)` - Add tags (preserves existing)

### Threads

- `conversation_threads(conversation_id)` - List threads (cached)
- `conversation_body(conversation_id)` - Concatenated HTML body
- `add_note(conversation_id, text)` - Create note thread
- `update_thread_text(conversation_id, thread_id, text)` - Update thread body
- `create_reply(conversation_id, customer_id, text, draft)` - Create reply
- `send_draft(conversation_id, thread_id)` - Send draft reply

### Attachments

- `attachment_data(conversation_id, attachment_id)` - Download attachment bytes

## Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `HELPSCOUT_APP_ID` | Yes | OAuth2 app ID (from My Apps) |
| `HELPSCOUT_APP_SECRET` | Yes | OAuth2 app secret (from My Apps) |

## Authentication

The client uses OAuth2 client-credentials flow. Create an app at **HelpScout → Your Profile → My Apps**:

1. Click "Create My App"
1. Give it a name (e.g., "Invoice Processor")
1. Copy the **App ID** and **App Secret**
1. Set them as environment variables

The client automatically:

- Fetches access tokens on initialization
- Refreshes tokens before expiry
- Retries on 401 with fresh token

## Error Handling

All API errors raise `HelpScoutError`:

```python
from helpscout_mailbox import HelpScoutClient, HelpScoutError

try:
    client = HelpScoutClient()
    client.get_conversation(99999)
except HelpScoutError as e:
    print(f"API error: {e}")
```

The client automatically retries:

- **429 rate limits** (respects `Retry-After` header)
- **5xx server errors** (exponential backoff)
- **Transport failures** (connection resets, timeouts)

## Documentation

Full API documentation: [https://connectify.github.io/helpscout-mailbox/](https://connectify.github.io/helpscout-mailbox/)

HelpScout API reference: [https://developer.helpscout.com/mailbox-api/](https://developer.helpscout.com/mailbox-api/)

## Development

```bash
# Clone repository
git clone https://github.com/Connectify/helpscout-mailbox.git
cd helpscout-mailbox

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run linters
pre-commit run --all-files

# Build documentation
pip install -e ".[docs]"
pdoc -o docs/ helpscout_mailbox
```

## Contributing

Patches via pull request are welcome — please file an issue first to discuss the change before submitting a PR. Issues are not for technical support; use [Discussions](#support) for that. See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

## License

BSD-3-Clause. See [LICENSE](LICENSE) for details.

## Support

- **Discussions**: [GitHub Discussions](https://github.com/Connectify/helpscout-mailbox/discussions) — for questions and support
- **HelpScout API Docs**: [developer.helpscout.com](https://developer.helpscout.com/mailbox-api/)
