Connector API
CEO itself is a headless CMS based around a robust API. As a headless CMS it has a number of was of notifying front end systems of changes.
One of the easiest to integrate is the Connector. The receiving end must be able to:
- Process and verify JWT.
- Process and parse JSON data.
First, tell CEO where to send your data
You'll need to update the ceo-core
config with your new endpoint. When looking at that config file, you should see something like:
'connector' => [
[
'key' => "MY-KEY",
'url' => 'https://my.site.tld/ceo/connector/',
]
],
To add a second endpoint, update the key to connectors
and send it an array of configuration options:
'connectors' => [
[
'key' => 'MY-KEY',
'url' => 'https://my.site.tld/ceo/connector/'
],
[
'key' => 'MY-OTHER-KEY',
'url' => 'https://my.othersite.tld/some/endpoint'
]
]
The value of key
will be used to sign and verify your JWT, so treat that like a password and ensure it's sufficiently random.
Custom Connectors
It's possible to leverage connectors to push data to other authenticated endpoints, for example, Apple News:
'connectors' => [
[
'key' => 'pub:priv',
'url' => 'none',
'connector' => \Ceo\Core\Connectors\AppleNewsConnector::class
]
]
Wait for the data to roll in
Every time content, containers, channels or entires are updated in CEO, your connector endpoint will see POST data. Keep in mind that changes can come quickly, so you may want to implement mutex transactions to keep from running into race conditions.
There are two components to each webhook call. First is the JWT and the second is the post data.
JWT
The JWT is used to authenticate the transaction, it allows you to be sure that the data came from CEO and not an outside source.
CEO passes the JWT as a Bearer Authorization header.
Verify that the signer used the same shared key configured above, that it's not expired, and the Audience is your endpoint.
Additionally, the following Claims will be set:
action
- one ofcreate
,update
, ordelete
srn
- the object's unique identifier
JSON Data
The JSON data will be transmitted via the POST body. It follows the same format as all API data. Examples are provided in the API docs.
Example
A full example may take the form of:
POST /my/endpoint HTTP/1.1
Content-Type: application/json
Authorization: Bearer XXXXXXXX
{
"id": "9999",
"uuid": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"title": "...",
"slug": "...",
"type": "article",
"version": "2",
"weight": "0",
"abstract": "",
"abstract_raw": "",
"content": "...",
"content_raw": "...",
"created_at": "YYYY-MM-DD HH:MM:SS",
"modified_at": "YYYY-MM-DD HH:MM:SS",
"published_at": null,
"state": "0",
"url_id": null,
"assignment_id": null,
"title_url": "...",
"seo_title": "",
"seo_description": "",
"seo_url": "",
"layout_template": null,
"click_through": null,
"srn": "srn:snw:ceo-core/content:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"export": {
...
},
"authors": [
{
...
}
],
"tags": [
...
],
"user": {
...
},
"urls": [],
"lock": false,
"versions": [
...
],
"audit": [
...
],
"relatedContent": [
...
],
"keywords": [
...
],
"ssts_path": "..."
}