Skip to main content

what3words on Alerts

Every operator alert carries the what3words address of its origin, for example ///filled.count.soap. That is the unique name of the 3 m × 3 m square under the pin. Crews can read three words over a radio or phone far more reliably than a pair of decimal coordinates. Similar-sounding addresses are deliberately far apart, so a mis-heard word does not land next door.

Where the address comes from​

Frontend.API looks it up at the moment the alert's position is set:

WhenHandlerWhat happens
Alert createdCreateAlertMessageCommandHandlerLookup runs in parallel with the map-image upload, then is stored with the alert.
Alert moved (alert-update)UpdateAlertMessageCommandHandlerLookup for the new position. On failure NULL is stored: the old address names the old square, and no address is better than a wrong one.

The lookup is IWhat3WordsClient.ConvertTo3waAsync (Infrastructure, HttpClients/What3WordsClient.cs). It makes one attempt with no retries and is bounded by What3WordsOptions:TimeoutSeconds (3 s). Any failure returns null: no key, timeout, quota, outage, or a malformed answer. An alert is never blocked or failed by what3words; it goes out without an address.

The address is computed server-side rather than sent by the browser. That way the stored address always matches the stored coordinates, whichever client created or moved the alert.

Where it is stored and shown​

PlaceFieldNotes
SQL dbo.AlertMessageWhat3Words NVARCHAR(64) NULLWritten by AlertMessageInsert / AlertMessageUpdate (@What3Words, default NULL).
Email{{What3WordsBlock}} under Lat/Longwhat3words: ///filled.count.soap, linked to https://w3w.co/filled.count.soap.
SMSSecond line of the bodyLocation: ///filled.count.soap https://w3w.co/filled.count.soap (SMS is currently disabled by NotificationOptions:SmsEnabled).
Phone callSpoken after the alert type"The location's what three words address is: filled. count. soap." The full stops make the voice pause between words. The address reaches the call-automation callback as ?w3w= on the callback URL. That endpoint is anonymous, so only a well-formed address is ever spoken.
External-client webhookwhat3wordscamelCase JSON, null when unknown.
ArcGIS Alerts layerwhat3words attributeWritten on create; rewritten on move (emptied if the lookup fails). The layer needs the field (see rollout).

All channel text lives in Alert.CA.Notification/Extensions/What3WordsNotificationText.cs. With no valid address, every channel is byte-for-byte what it was before.

Configuration​

Key (App Configuration)Value
What3WordsOptions:ApiKeyKey Vault reference to secret What3WordsApiKey. This is the same secret the web frontend's BFF reads.
What3WordsOptions:TimeoutSecondsOptional, default 3.
What3WordsOptions:BaseUrlOptional, default https://api.what3words.com/v3.

Cost. One convert-to-3wa call per alert create or move, which is tens a day. Conversions to 3 words are unlimited on paid plans, so there is no quota exposure. Latency is under 0.5 s typically and 3 s worst case, overlapped with the map-image upload on create. Storage is ≤ 64 bytes per alert row.

Rollout order (per environment)​

Merging to development triggers the Infrastructure (database) and API pipelines in parallel. New API code calls the stored procedures with @What3Words, which an old database rejects, so the order matters:

  1. ArcGIS Online: add a String field named what3words (length 64) to the Alerts layer: ALERTCalifornia_Alerts_Test, ALERTCalifornia_Alerts_UAT and ALERTCalifornia_ALERTS_for_Operational_Platform_View. Do this before step 4, so the field exists before alerts start sending the attribute.
  2. Key Vault: create secret What3WordsApiKey in the environment's vault. Do this before step 5: every app that loads App Configuration fails to start on a dangling Key Vault reference.
  3. Database PR: merge the Alert.CA.Infrastructure.Data change alone (column + both procedures). The procedures default @What3Words to NULL, so the API that is running keeps working.
  4. Code PR: Infrastructure + Frontend.API + Notification. Until step 5 the key is empty, lookups are skipped and alerts go out without an address. Note: moving an alert writes what3words to the layer (empty when there is no address), which is why the field must exist first (step 1).
  5. Terraform: apply What3WordsOptions:ApiKey, then restart Frontend.API (App Configuration is read at start-up).

Check: create a test alert. The email should show a what3words: row, the AlertMessage row should have What3Words set, and the Frontend.API logs should have no what3words convert-to-3wa warnings.