Getting delivery notifications¶
Translation takes hours to days. You have two ways to find out when it's done: poll, or let Eurotext call you.
Option A: webhook (preferred if you can receive one)¶
Pass a url when you create the project:
$client->createProject('Spring catalogue', type: 'order',
webhookUrl: 'https://my.app/api/eurotext/webhook');
Eurotext then POSTs to that URL on project status updates, so you don't poll at
all. Treat the callback as a "something changed, go look" signal: on receipt,
re-read the project with getProject() and act on that authoritative state.
Also make the endpoint defensive: verify it's really Eurotext (shared secret in
the URL or a header you agree on), respond 2xx fast, and do the actual work
async. A webhook you can't receive (local dev, no public URL) is useless — fall
back to polling there.
Option B: polling (always works)¶
Store the project id, then check on a schedule from a cron job or queue worker — never from a web request.
// e.g. a Symfony console command run every 30 min by cron
foreach ($this->openProjects() as $row) {
$project = $client->getProject($row->eurotextProjectId);
$status = ProjectStatus::fromProject($project);
match ($status) {
ProjectStatus::DELIVERED => $this->importAndClose($row, $project),
ProjectStatus::FAILED => $this->flagForReview($row),
ProjectStatus::IN_PROGRESS,
ProjectStatus::PENDING => null, // check again next tick
};
}
A polling policy that holds up in production¶
- Interval: 30 minutes is plenty. Delivery is measured in hours; polling every minute just burns rate limit for nothing.
- Backoff: if a poll fails (5xx/timeout), back off exponentially (30m → 1h → 2h) rather than hammering. A 4xx like 404 means the project is gone — stop polling it, don't retry.
- Give up eventually: set a deadline (e.g. 14 days) after which you stop
polling and raise an alert for a human. Otherwise a stuck project polls forever.
Store
submitted_atand check it each tick. - Partial delivery: items finish independently. You can import the ones in
finishedearly and keep polling for the rest — just record which item ids you've imported so you don't double-write (see12-idempotency.md). - Re-fetching is safe:
GET /projectandGET /itemare read-only, so polling the same project repeatedly costs nothing and changes nothing. The non-idempotent part is the write-back into your own system — make that idempotent on your side.
Belt and braces¶
Registering a webhook and running a slow safety-net poll (say every few hours) is a reasonable setup: the webhook gives you fast turnaround, the poll catches anything a missed or failed callback would otherwise strand.