What service do I need to use to write something custom to the document history?

How do I display a custom message in the history section on a content node?

How would I for example say add a message/line item to this.
That has a badge value of say Locked or Unlocked with by the user who performed the action and the date/time.

For example in this screenshot there are other message types

I’ve only used it in Umb13 so can’t speak for later versions (hopefully it’s the same), but the IAuditService can add these for pages. I use it when a page gets modified by an import.

Example:

_auditService.Add(AuditType.Custom, userId ?? -1, existingPage.Id, UmbracoObjectTypes.Document.GetName() ?? string.Empty, "Page updated from the Importer", "Page updated from the Importer");

I’ve had to add the message in the Comment and Parameters argument for it to appear in the log but wouldn’t have expected that to be needed.

2 Likes

Thanks Ben,
This looks like what I need. I will try it out later today/tomorrow and if its all good I will mark you answer as the solution :slight_smile:

Do you know if we can have a different label than Custom or is that all we are allowed to use/set from Umbraco ?

It was an enum for the type (the first argument), so there is some level of customisation (again, presuming they all work. But since it’s just an Add function I don’t see why it wouldn’t).

I’m not sure if there’s a way to make it something completely custom as the tag, i.e. changing the name/colour. But it’s a string column in the Database for the log type (umbracoLog > logHeader). I don’t know enough about how that’s then used to know if can be customised further

I thought could get round this by using the AuditRepository but also the AuditItem itself takes the AuditType Enum as well. So Custom is looking like my only option for now. :frowning:

Thanks again Ben this works as you suggested, it is a bit weird the last two parameters to the method are the same value though ?!

Using IAuditService with IUserIdKeyResolver & IIdKeyMap

public async Task LockContentAsync(Guid contentKey, Guid userKey)
{
    _logger.LogInformation("Locking content {contentKey} for user {userKey}", contentKey, userKey);

    try
    {
        using (var scope = _scopeProvider.CreateScope(autoComplete: true))
        {
            await scope.Database.SaveAsync(new ContentLocks { 
                ContentKey = contentKey,
                UserKey = userKey,
                LockedAtDate = DateTime.Now
            });
        }

        // Convert Key to old style int's to use with AuditService
        var userAsAnId = await _userIdKeyResolver.GetAsync(userKey); // Inject and use IUserIdKeyResolver
        var contentNodeAsAnId = _idKeyMap.GetIdForKey(contentKey, UmbracoObjectTypes.Document).Result; // Inject and use IIdKeyMap
        _auditService.Add(AuditType.Custom, userAsAnId, contentNodeAsAnId, Umbraco.Cms.Core.Constants.ObjectTypes.Strings.Document, "Page Locked", "Page Locked");
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error locking content {contentKey} for user {userKey}", contentKey, userKey);
        throw;
    }
}

Screenshot of result

1 Like

Glad to help. I only found it a while ago myself.

Yeah, it’s a bit odd that both are needed for custom messages. If you look at what’s being stored for system events then only the comment is in the row and parameters is null. Perhaps it is because they are custom that they are needed. I’ve not tried passing an empty paramater string in, just in case it’s not wanting a null value. Something to test.