I am experiencing an issue with records that are currently published, but an unpublished change was made to the record that caused a āpublishā webhook event to fire.
Steps to reproduce:
Published a record
Make modifications to the record via the CMA, but donāt publish those changes
The interface in DatoCMS still shows the record as having āunpublished changesā, but we receive webhooks telling us it was published.
Is this expected behavior? If so, how can one the system that is processing webhooks request know whether or not the changes it received were published or not? Is āstatusā a safe field to rely on for that information?
I ask because it is not always clear to me when loading records from the CMA whether a record has a published version or not. Iām guessing that the āpublished_atā field is the best way to tell as that seems to only be set if a record has a published version. My assumption is that if the āstatusā is āupdatedā, but the āpublished_atā meta field is setā¦then the record is āpublishedā with āunpublished changesā. Is that a correct assumption?
Could this be related to having multiple locales on that model? Each locale can be published individually. If that happens:
When the record is saved, it fires an update event with meta.status=updated
If one locale is selectively published but another one is still in draft, it fires a publish event but meta.status=updated
If all locales are published (ie the entire record has no more unpublished changes and is showing up green in the Dato UI), then it fires a publish event with meta.status=published
In general, status=updated means one or more locales has saved but unpublished changes. status=published means everything is published. You can use published_at to determine the last publish (of any locale), but that doesnāt tell you which locale changed. I think generally itās clearer (easier to think about) if you just assume that status=updated means āthe record is not fully published yetā. Then you can look through the changes and determine if anything should be rebuilt.
update events (but not publish events) will have a previous_entity property that you can diff against the current entity to determine what changed. If thatās not enough, you can make a CMA call in the webhook receiver to retrieve a specific record version: Retrieve a record version ā Record version ā Content Management API
Edit: If you can link to the specific webhook & model in question, we can take a deeper look with you too. Feel free to post it here, DM me, or email support@datocms.com (whichever you prefer)
Our developer looked into this and identified several rarer situations where a publish webhook could be fired. Iām asking if any of these will explicitly cause an updated state, but in the meantime, do you think any of these could be likely culprits?
Events that triggers a publish webhooks on items:
publishing a record (obviously :D)
destroying a parent record in a tree-structure item type (this is not the case)
when the item has a published version and the customer changes some meta attribute (e.g. created_at time, first published_at time, the creator, the workflow stage, basically, everything that is present in the item right sidebar)**
when the item has a published version and the customer changes its position in a sortable or tree structure item type (this is not the case)
when a model is removed from a link/links/structured text field list of valid models. We have to cycle all over the versions and remove from those fields any reference to the removed model
when a block model is removed from a rich_text/single_block/structured_text field. We have to cycle all over the versions and remove from those fields any blocks of that removed block model (this may currently be bugged ā weāre checking ā but thatās the intent)
when the customer edits an upload contained in a published version and now the published version is not valid anymore (or becomes valid)
when the item has a published version and a textual field contains an absolute URL of an upload and the customer replace the assets with a new one, so we have to update the absolute URL in the version. This happens also when a customer activates a custom upload bucket (very rare case) - when the item has a published version and contains a link to another record via a link/links/structured_text field. If this fieldās validation has a rule that says āwhen a linked item is destroyed (or unpublished), remove the referenceā and the referenced record is being unpublished / destroyed, then we have to adjust the referencing item and trigger a publish event
when you destroy a model and its records are being linked by other items via link/links/structured_text fields. we have to remove those references and we have to trigger a publish event, if the updated item has a published version already
Iāll let you know if the dev is able to identify specific scenarios that cause both a publish event and an updated state.
when the item has a published version and the customer changes some meta attribute (we send a date/time for āfirst_published_atā for most update requests via the content management API)
when a block model is removed from a rich_text/single_block/structured_text field. We have to cycle all over the versions and remove from those fields any blocks of that removed block model (due to limitations in how our legacy system works, we send a fresh block object instead of the block id when updating a record via the content management API. we donāt have a way to store/remember block ids in our system, so it just sends the whole block in case anything has changed)
Thank you, @jearle. I just wanted you to know that weāre still discussing this internally.
If this is a time-sensitive situation, I think that checking the item status on the publish webhook (i.e., making sure status is published instead of updated) should be a viable workaround for now.
But Iām still trying to understand why this behavior even exists, and once I find out, Iāll report back. Thanks for your patience with this and all the details!
Hello! Iām seeing the same behavior where when a record with draft/publish system enabled in a single locale is saved, the webhook events that are firing are sending publish for the event type. Is there any update on why that happens, and is the best workaround still checking entity.meta.status to distinguish records that are actually published?
Unfortunately, yes, basically diffing the webhook against either the previous_entity (if present in a particular webhook body), or the current record state, is the only surefire way to determine what exactly was published.
There are various things that can cause a partial publish event even if the record status, overall, is still updated. Several of them were mentioned in this thread, and there are a few other ones (like record re-ordering in a manually-sorted collection)ā¦
It isnāt an ideal system, I know Itās something we are aware of internally and trying to find better solutions for, but right now thatās the way it is, sorry!
If there is a particular use case youāre trying to make this work for, please email us the details at support@datocms.com (like the particular model/record, along with sample webhook code and request/responses) so we can better understand it, and weāll try to help you write a proper āparserā for it.