Installation:
composer require webklex/laravel-imap
php artisan vendor:publish --provider="Webklex\IMAP\IMAPServiceProvider"
Configure .env with IMAP credentials:
IMAP_HOST=smtp.example.com
IMAP_PORT=993
IMAP_ENCRYPTION=ssl
IMAP_USERNAME=user@example.com
IMAP_PASSWORD=yourpassword
First Use Case: Fetch unread emails in a controller:
use Webklex\IMAP\ClientManager;
public function fetchUnreadEmails()
{
$client = app(ClientManager::class)->client();
$emails = $client->getMailbox('INBOX')->search(['UNSEEN']);
return view('emails.index', compact('emails'));
}
Key Files to Review:
config/imap.php (default settings)app/Providers/IMAPServiceProvider.php (customization)Email Fetching & Processing:
// Fetch all emails in a mailbox
$mailbox = $client->getMailbox('INBOX');
$emails = $mailbox->getEmails(['BODY[]', 'FROM', 'SUBJECT']);
// Process each email
foreach ($emails as $email) {
$body = $email->getBody();
$from = $email->getFrom();
// Parse/Store logic...
}
Real-Time Listeners:
// Listen for new emails (requires IMAP IDLE support)
$client->listen(function ($mailbox, $email) {
// Handle new email (e.g., trigger a job)
dispatch(new ProcessEmailJob($email));
});
Attachment Handling:
$attachments = $email->getAttachments();
foreach ($attachments as $attachment) {
Storage::put('attachments/' . $attachment->getFilename(), $attachment->getContent());
}
Search & Filtering:
// Search for emails with attachments
$emails = $mailbox->search(['HAVE', 'attachment']);
// Search by date range
$emails = $mailbox->search([
'SINCE', '01-Jan-2023',
'BEFORE', '01-Feb-2023'
]);
foreach ($emails as $email) {
ProcessEmail::dispatch($email)->onQueue('emails');
}
throttle middleware for API endpoints triggered by IMAP events.$client->setLogger(app(\Monolog\Logger::class));
Webklex\IMAP\Testing\TestIMAP trait for unit tests:
use Webklex\IMAP\Testing\TestIMAP;
public function testEmailFetching()
{
$this->actingAsIMAPUser();
// Assertions...
}
Connection Issues:
imap_open() fails silently..env credentials and ensure the PHP imap extension is enabled (php -m | grep imap).config/imap.php:
'log' => [
'enabled' => true,
'path' => storage_path('logs/imap.log'),
],
Memory Limits:
Allowed memory size exhausted when fetching large mailboxes.getEmails(['UID']) to fetch only UIDs first, then load bodies separately.Timezone Mismatches:
config/imap.php:
'timezone' => 'America/New_York',
IMAP Server Quirks:
imap_last_error() for debugging:
$client->getMailbox('INBOX')->search(['UNSEEN']);
error_log(imap_last_error());
$client->setDebug(true); // Logs raw IMAP commands/responses
$capabilities = $client->getCapabilities();
// Verify 'IDLE' is supported for real-time listening.
try {
$emails = $mailbox->getEmails();
} catch (\Webklex\IMAP\Exceptions\ConnectionException $e) {
// Retry or notify admin
}
Custom Mailbox Classes:
Extend \Webklex\IMAP\Mailbox to add domain-specific methods:
class CustomMailbox extends \Webklex\IMAP\Mailbox
{
public function getSupportTickets()
{
return $this->search(['SUBJECT', 'ticket:']);
}
}
Bind it in IMAPServiceProvider:
$this->app->bind(\Webklex\IMAP\Mailbox::class, function ($app) {
return new CustomMailbox($app->make(\Webklex\IMAP\Client::class));
});
Event Listeners:
Subscribe to IMAP events (e.g., imap.message.fetched):
// In EventServiceProvider
public function boot()
{
event(new \Webklex\IMAP\Events\MessageFetched($email));
}
Custom IMAP Commands:
Use the low-level rawCommand() method for unsupported IMAP extensions:
$response = $client->rawCommand('UID SEARCH CHANGEDSINCE "01-Jan-2023"');
Mocking for Tests:
Use the Webklex\IMAP\Testing\FakeIMAP class to simulate IMAP responses:
$fakeImap = new FakeIMAP();
$fakeImap->shouldReceive('getMailbox')->andReturnSelf();
$fakeImap->shouldReceive('search')->andReturn([1, 2, 3]);
How can I help you explore Laravel packages today?