$client->liveEvents
Every method in this namespace: its signature, its parameters, what it returns and an example.
Methods
Follow the mailbox as it changes, without polling: one event each time a message arrives or is sent, each time a conversation changes or is deleted, and each time the delivery of a sent email moves on, resumed where it left off after a dropped connection.
liveEvents->stream
Follow the mailbox as it changes
stream( array|string|null $types = null, ?string $address = null, ?string $lastEventId = null, ?string $apiKey = null,): GeneratorReturns a Generator that opens the live event stream, GET /live-events as server-sent events, and yields one event per step for as long as you read it: message.received when a message is filed for an address, message.sent when a message sent from an address is filed in its Sent folder, thread.changed when a conversation gains or loses labels (read, starred, archived, moved, snoozed or labelled), thread.deleted when one is deleted for good, and message.status_changed when the delivery of an email sent from an address moves on, with its status: delivered, delivery_delayed, bounced, complained, failed, suppressed or cancelled. Each event is an array with id, type, occurredAt and data, where data['addresses'] names the addresses it concerns and threadId and messageId the conversation and the message, where there is one. No content travels in an event, so read the conversation with threads->get or the message with threads->getMessage when you need it. Nextmail\Constants\LiveEventTypes and Nextmail\Constants\LiveSendStatuses name the types and the statuses.
Nothing is sent until the loop starts, and the loop never ends by itself. The server closes the stream after 30 minutes, when the credential stops being valid, or when the connection drops, and the generator opens it again and resumes where it left off through Last-Event-ID: at once after the server closes it, though never sooner than the server's retry hint after the previous attempt began, and with backoff after a failure. When the server can no longer replay from that point, which happens once the event is more than 10 minutes or 1,000 events back, the generator yields an event whose type is reset before the next events: anything may have changed in between, so list again what you keep in sync. Break out of the loop to close the connection.
The built-in cURL client hands each event over as soon as it arrives. A client you pass as httpClient: has to implement Nextmail\Http\StreamingHttpClient to stream. Psr18HttpClient does not, so with it the first step of the loop throws an InvalidArgumentException.
A key or an app limited to particular addresses gets only the events of the addresses it reaches, enforced on the server for every event.
Parameters
typesstring|string[]Only these kinds of event, as
Nextmail\Constants\LiveEventTypesvalues:message.received,message.sent,thread.changed,thread.deletedandmessage.status_changed. An array is sent comma separated. Left out, all of them. A reset always comes.addressstringOnly the events of this address. One the key does not reach delivers nothing rather than failing.
lastEventIdstringResume after this event id, the
idof the last event an earlier stream yielded, sent as theLast-Event-IDheader. Left out, the stream starts with what happens from now on.apiKeystringOverrides the client's API key for this stream, on every reconnection too.
Returns
A Generator that yields one array per event, with id, type, occurredAt and data. data always holds addresses, threadId and messageId, and by type labelIds (received), emailId (sent), addedLabelIds and removedLabelIds (changed), or emailId, status and recipients (status changed, where threadId may be null). A reset yields id, type set to reset, occurredAt and data with reason, expired or unknown as in Nextmail\Constants\LiveResetReasons.
Example
use Nextmail\Constants\LiveEventTypes; $resumeFrom = null; foreach ($client->liveEvents->stream(types: [LiveEventTypes::MESSAGE_RECEIVED], address: '[email protected]') as $event) { if ($event['type'] === 'reset') { echo 'Some events were missed, so list the inbox again', PHP_EOL; continue; } $resumeFrom = $event['id']; $thread = $client->threads->get($event['data']['threadId']); echo 'New mail in ', $thread['id'], PHP_EOL; break;} echo 'Carry on later with lastEventId: ', $resumeFrom, PHP_EOL;Notes
One key, app or session holds at most 5 open streams, and a workspace at most 50. Past that the stream is refused with 429
too_many_streams, which the generator waits out like any 429.The server sends a keepalive every 25 seconds and a
retryhint of 3 seconds. Events are kept for resuming for 10 minutes and at most 1,000 per workspace.A network failure, a 408, a 429 and a 5xx answer are retried for as long as you read, waiting about a second at first and doubling up to 30 seconds, or longer when
Retry-Afterasks, up to 5 minutes. The client'smaxRetries:does not apply. When no byte arrives for 60 seconds, the generator drops the connection and opens it again.Any other error, such as a 400, 401, 403, 404 or 422, throws its
ApiExceptioninstead of retrying, so an expired or revoked credential ends the loop the next time the stream opens. So does a 200 that is nottext/event-stream, with the codeunrecognised_response.The client's
timeout:covers only the wait for the stream to open. Once it is open, only the 60 second limit on silence applies.
Google Workspace