Skip to content

postalsys/emailengine-php

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EmailEngine PHP SDK

Tests PHP Version License

Modern PHP SDK for EmailEngine - the self-hosted email gateway that provides a REST API for IMAP and SMTP operations.

Requirements

  • PHP 8.1 or higher
  • Composer
  • EmailEngine instance

Installation

composer require postalsys/emailengine-php

Quick Start

use Postalsys\EmailEnginePhp\EmailEngine;

$client = new EmailEngine(
    accessToken: 'your-access-token',
    baseUrl: 'http://localhost:3000',
);

// List all accounts
$accounts = $client->accounts->list();

// Send an email
$result = $client->messages->submit('account-id', [
    'from' => ['name' => 'Sender', 'address' => 'sender@example.com'],
    'to' => [['name' => 'Recipient', 'address' => 'recipient@example.com']],
    'subject' => 'Hello from EmailEngine PHP SDK',
    'text' => 'This is a test email.',
    'html' => '<p>This is a test email.</p>',
]);

Configuration

Constructor Parameters

$client = new EmailEngine(
    accessToken: 'your-access-token',      // Required: API access token
    baseUrl: 'http://localhost:3000',       // EmailEngine base URL (default: localhost:3000)
    serviceSecret: 'your-service-secret',   // For hosted authentication URLs
    redirectUrl: 'http://your-app/callback', // Default redirect URL for auth
    timeout: 30,                            // Request timeout in seconds
);

Factory Method (Legacy Compatibility)

$client = EmailEngine::fromOptions([
    'access_token' => 'your-access-token',
    'ee_base_url' => 'http://localhost:3000',
    'service_secret' => 'your-service-secret',
    'redirect_url' => 'http://your-app/callback',
]);

Resources

The SDK provides access to all EmailEngine API endpoints through resource classes:

Resource Description
$client->accounts Account management (CRUD, sync, reconnect)
$client->messages Message operations (list, read, send, search)
$client->mailboxes Mailbox management (create, rename, delete)
$client->outbox Queued message management
$client->settings System and webhook settings
$client->tokens Access token management
$client->templates Email template management
$client->gateways SMTP gateway configuration
$client->oauth2 OAuth2 application management
$client->webhooks Webhook route management
$client->stats System statistics and utilities
$client->blocklists Blocklist management

Examples

Account Management

// Create a new account
$account = $client->accounts->create([
    'account' => 'my-account',
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'imap' => [
        'host' => 'imap.example.com',
        'port' => 993,
        'secure' => true,
        'auth' => ['user' => 'john@example.com', 'pass' => 'password'],
    ],
    'smtp' => [
        'host' => 'smtp.example.com',
        'port' => 465,
        'secure' => true,
        'auth' => ['user' => 'john@example.com', 'pass' => 'password'],
    ],
]);

// Get account info
$info = $client->accounts->get('my-account');
echo "Account state: " . $info['state'];

// List all accounts
$accounts = $client->accounts->list(['page' => 0, 'pageSize' => 20]);

// Force reconnection
$client->accounts->reconnect('my-account');

// Delete account
$client->accounts->delete('my-account');

Messages

// List messages in INBOX
$messages = $client->messages->list('my-account', [
    'path' => 'INBOX',
    'pageSize' => 50,
]);

// Get message details
$message = $client->messages->get('my-account', 'message-id', [
    'textType' => 'html',
]);

// Search messages
$results = $client->messages->search('my-account', [
    'path' => 'INBOX',
    'search' => [
        'unseen' => true,
        'from' => 'important@example.com',
    ],
]);

// Update message flags
$client->messages->update('my-account', 'message-id', [
    'flags' => ['add' => ['\\Seen', '\\Flagged']],
]);

// Move message
$client->messages->move('my-account', 'message-id', 'Archive');

// Delete message
$client->messages->delete('my-account', 'message-id');

// Bulk operations
$client->messages->bulkUpdate('my-account', [
    'path' => 'INBOX',
    'messages' => ['msg-1', 'msg-2', 'msg-3'],
    'flags' => ['add' => ['\\Seen']],
]);

Sending Emails

// Basic email
$result = $client->messages->submit('my-account', [
    'from' => ['name' => 'Sender', 'address' => 'sender@example.com'],
    'to' => [['name' => 'Recipient', 'address' => 'recipient@example.com']],
    'cc' => [['address' => 'cc@example.com']],
    'subject' => 'Test Subject',
    'text' => 'Plain text content',
    'html' => '<p>HTML content</p>',
]);

// With attachments
$result = $client->messages->submit('my-account', [
    'from' => ['address' => 'sender@example.com'],
    'to' => [['address' => 'recipient@example.com']],
    'subject' => 'Email with attachment',
    'text' => 'Please see attached.',
    'attachments' => [
        [
            'filename' => 'document.pdf',
            'content' => base64_encode(file_get_contents('document.pdf')),
            'contentType' => 'application/pdf',
        ],
    ],
]);

// Using templates
$result = $client->messages->submit('my-account', [
    'to' => [['name' => 'John', 'address' => 'john@example.com']],
    'template' => 'welcome-email',
    'render' => [
        'name' => 'John',
        'company' => 'Acme Inc',
    ],
]);

// With idempotency key (prevents duplicates)
$result = $client->messages->submit('my-account', [
    'to' => [['address' => 'recipient@example.com']],
    'subject' => 'Important email',
    'text' => 'Content',
], [
    'idempotencyKey' => 'unique-key-12345',
]);

// Scheduled send
$result = $client->messages->submit('my-account', [
    'to' => [['address' => 'recipient@example.com']],
    'subject' => 'Scheduled email',
    'text' => 'This will be sent later',
    'sendAt' => '2024-12-25T10:00:00Z',
]);

Download Attachments

// Download and stream an attachment directly to the browser
$client->download("/v1/account/my-account/attachment/AAAAAQAABRQ");

Mailbox Management

// List mailboxes
$mailboxes = $client->mailboxes->list('my-account', ['counters' => true]);

// Create mailbox
$client->mailboxes->create('my-account', 'INBOX/Projects');

// Rename mailbox
$client->mailboxes->rename('my-account', 'INBOX/OldName', 'INBOX/NewName');

// Delete mailbox
$client->mailboxes->delete('my-account', 'INBOX/ToDelete');

// Subscribe/unsubscribe
$client->mailboxes->subscribe('my-account', 'Archive');
$client->mailboxes->unsubscribe('my-account', 'Spam');

Webhook Settings

// Get webhook settings
$webhooks = $client->settings->getWebhooks();

// Configure webhooks
$client->settings->setWebhooks([
    'enabled' => true,
    'url' => 'https://your-app.com/webhooks',
    'events' => ['messageNew', 'messageUpdated', 'messageSent'],
    'headers' => ['Received', 'List-ID'],
    'text' => 2048, // Include first 2KB of text content
]);

Hosted Authentication

Generate URLs for EmailEngine's hosted authentication form:

$client = new EmailEngine(
    accessToken: 'your-token',
    baseUrl: 'http://localhost:3000',
    serviceSecret: 'your-service-secret',
    redirectUrl: 'http://your-app/auth-callback',
);

// Generate auth URL
$authUrl = $client->getAuthenticationUrl([
    'account' => null, // null = auto-generate account ID
    'name' => 'User Name',
    'email' => 'user@example.com',
]);

// Redirect user to $authUrl
header('Location: ' . $authUrl);

Outbox Management

// List queued messages
$queue = $client->outbox->list(['account' => 'my-account']);

// Get queued message details
$item = $client->outbox->get('queue-id');

// Cancel scheduled message
$client->outbox->cancel('queue-id');

System Statistics

// Get system stats
$stats = $client->stats->get();
echo "EmailEngine version: " . $stats['version'];
echo "Connected accounts: " . $stats['connections']['connected'];

// Auto-discover email settings
$config = $client->stats->autoconfig('user@gmail.com');

Error Handling

The SDK throws specific exceptions for different error types:

use Postalsys\EmailEnginePhp\Exceptions\AuthenticationException;
use Postalsys\EmailEnginePhp\Exceptions\AuthorizationException;
use Postalsys\EmailEnginePhp\Exceptions\NotFoundException;
use Postalsys\EmailEnginePhp\Exceptions\ValidationException;
use Postalsys\EmailEnginePhp\Exceptions\RateLimitException;
use Postalsys\EmailEnginePhp\Exceptions\ServerException;
use Postalsys\EmailEnginePhp\Exceptions\EmailEngineException;

try {
    $account = $client->accounts->get('unknown-account');
} catch (NotFoundException $e) {
    echo "Account not found: " . $e->getMessage();
    echo "Error code: " . $e->getErrorCode();
} catch (AuthenticationException $e) {
    echo "Invalid API token";
} catch (ValidationException $e) {
    echo "Validation error: " . $e->getMessage();
    print_r($e->getDetails());
} catch (RateLimitException $e) {
    echo "Rate limited. Retry after: " . $e->getRetryAfter() . " seconds";
} catch (EmailEngineException $e) {
    echo "API error: " . $e->getMessage();
}

Raw API Requests

For endpoints not covered by resource classes:

// GET request
$response = $client->request('GET', '/v1/some-endpoint', query: ['param' => 'value']);

// POST request
$response = $client->request('POST', '/v1/some-endpoint', data: ['key' => 'value']);

// With custom headers
$response = $client->request('POST', '/v1/some-endpoint',
    data: ['key' => 'value'],
    headers: ['X-Custom-Header' => 'value']
);

Testing

Local Testing

# Install dependencies
make install

# Run unit tests
make test

# Run tests with coverage
make test-coverage

# Run static analysis
make phpstan

# Check code style
make lint

Docker Testing

Test across multiple PHP versions using Docker:

# Run unit tests on PHP 8.3
make docker-test

# Run tests on all PHP versions (8.1, 8.2, 8.3, 8.4)
make docker-test-all

# Run integration tests with real EmailEngine
make docker-integration

Integration Testing

Integration tests run against a real EmailEngine instance:

# Start EmailEngine and Redis
make docker-up

# Run integration tests (auto-generates access token)
make docker-integration

# View EmailEngine logs
make docker-logs

# Stop services
make docker-down

Note: EmailEngine without a license suspends workers after 15 minutes. Integration tests are designed to complete within this time window. If you need more time, restart EmailEngine:

docker compose restart emailengine

Manual Integration Testing

To run integration tests against your own EmailEngine instance:

# Generate a token using EmailEngine CLI
emailengine tokens issue -d "Test" -s "*" --dbs.redis="redis://localhost:6379"

# Run tests with your token
EMAILENGINE_ACCESS_TOKEN="your-token" \
EMAILENGINE_BASE_URL="http://localhost:3000" \
./vendor/bin/phpunit --testsuite integration

Legacy Compatibility

The SDK maintains backward compatibility with the old API:

// Old way (still works, but deprecated)
use EmailEnginePhp\EmailEngine;

$ee = new EmailEngine([
    'access_token' => 'token',
    'ee_base_url' => 'http://localhost:3000',
    'service_secret' => 'secret',
    'redirect_url' => 'http://callback.url',
]);

$ee->get_webhook_settings();
$ee->set_webhook_settings(['enabled' => true]);
$ee->get_authentication_url(['account' => null]);

License

MIT License - see LICENSE file.

Links

About

PHP library for EmailEngine

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •