Created
February 19, 2025 10:37
-
-
Save jbreuer/06727609ba65444ecdd7254ca9032668 to your computer and use it in GitHub Desktop.
Updating Sitecore using the Authoring API and updating Umbraco with the Management API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Net.Http.Headers; | |
using System.Text; | |
using System.Text.Json; | |
using IdentityModel.Client; | |
var builder = WebApplication.CreateBuilder(args); | |
// Register necessary services | |
builder.Services | |
.AddLogging(logging => logging.AddConsole()) | |
.AddHttpClient(); | |
var app = builder.Build(); | |
// ------------------------------------------------------------------------- | |
// Configuration - Sitecore | |
// ------------------------------------------------------------------------- | |
string sitecoreIdentityServer = "https://sitecore-id-server.dev.local/"; | |
string sitecoreClientId = "SitecorePassword"; | |
string sitecoreClientSecret = "sitecore-client-secret"; | |
string sitecoreUserName = @"sitecore\admin"; | |
string sitecoreUserPass = "b"; | |
string sitecoreGraphQLEndpoint = "https://sitecore-cm-server.dev.local/sitecore/api/authoring/graphql/v1"; | |
string sitecoreFaqItemId = "{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}"; | |
// ------------------------------------------------------------------------- | |
// Endpoint: Receive Umbraco Webhook -> Update Sitecore | |
// ------------------------------------------------------------------------- | |
app.MapPost("/api/webhooks/umbraco", async (HttpContext context, ILogger<Program> logger) => | |
{ | |
// 1) Read the raw JSON body | |
var doc = await context.Request.ReadFromJsonAsync<JsonDocument>(); | |
// 2) Parse JSON for the "FAQ" data | |
// Fields are in: | |
// properties.title | |
// properties.text.markup | |
string? title = null; | |
string? textMarkup = null; | |
var root = doc.RootElement; | |
// Title | |
if (root.TryGetProperty("properties", out var propsElem) && | |
propsElem.TryGetProperty("title", out var titleElem)) | |
{ | |
title = titleElem.GetString(); | |
} | |
// Text markup | |
if (propsElem.TryGetProperty("text", out var textElem) && | |
textElem.TryGetProperty("markup", out var markupElem)) | |
{ | |
textMarkup = markupElem.GetString(); | |
} | |
// 3) Update Sitecore using the parsed fields | |
var httpFactory = context.RequestServices.GetRequiredService<IHttpClientFactory>(); | |
// (a) Get a token from Sitecore Identity | |
var sitecoreToken = await GetSitecoreTokenAsync( | |
httpFactory, | |
sitecoreIdentityServer, | |
sitecoreClientId, | |
sitecoreClientSecret, | |
sitecoreUserName, | |
sitecoreUserPass); | |
// (b) Define a GraphQL mutation that uses two variables: $title and $text | |
// We pass them into fields: [ { name:"Title", value: $title }, ... ]. | |
var mutation = $@" | |
mutation UpdateItem($title: String, $text: String) {{ | |
updateItem( | |
input: {{ | |
itemId: ""{sitecoreFaqItemId}"" | |
fields: [ | |
{{ name: ""Title"", value: $title }}, | |
{{ name: ""Text"", value: $text }} | |
] | |
}} | |
) {{ | |
item {{ | |
name | |
}} | |
}} | |
}}"; | |
// (c) Build a request object with the query and variables | |
var reqPayload = new | |
{ | |
query = mutation, | |
variables = new | |
{ | |
title, | |
text = textMarkup | |
} | |
}; | |
// (d) Serialize to JSON | |
var client = httpFactory.CreateClient(); | |
client.DefaultRequestHeaders.Authorization = | |
new AuthenticationHeaderValue("Bearer", sitecoreToken); | |
var reqJson = JsonSerializer.Serialize(reqPayload); | |
var content = new StringContent(reqJson, Encoding.UTF8, "application/json"); | |
// (e) Send the POST to Sitecore GraphQL | |
var response = await client.PostAsync(sitecoreGraphQLEndpoint, content); | |
var responseBody = await response.Content.ReadAsStringAsync(); | |
logger.LogInformation("Sitecore item updated successfully"); | |
return Results.Ok("Umbraco data used to update Sitecore successfully!"); | |
}); | |
// ----------------------------------------------------------------------- | |
// Helper: Acquire a token from Sitecore Identity (Password Grant) | |
// ----------------------------------------------------------------------- | |
static async Task<string?> GetSitecoreTokenAsync( | |
IHttpClientFactory httpFactory, | |
string identityServer, | |
string clientId, | |
string clientSecret, | |
string userName, | |
string userPass) | |
{ | |
using var tokenClient = httpFactory.CreateClient(); | |
tokenClient.BaseAddress = new Uri(identityServer); | |
var req = new PasswordTokenRequest | |
{ | |
Address = "/connect/token", | |
ClientId = clientId, | |
ClientSecret = clientSecret, | |
GrantType = IdentityModel.OidcConstants.GrantTypes.Password, | |
Scope = "openid sitecore.profile sitecore.profile.api", | |
UserName = userName, | |
Password = userPass | |
}; | |
var resp = await tokenClient.RequestPasswordTokenAsync(req); | |
return resp.AccessToken; | |
} | |
// ------------------------------------------------------------------------- | |
// Configuration - Umbraco | |
// ------------------------------------------------------------------------- | |
string umbracoHost = "https://localhost:44392"; | |
string umbracoClientId = "umbraco-back-office-my-client"; | |
string umbracoClientSecret = "umbraco-client-secret"; | |
string umbracoFaqDocId = "e75d2a2b-295c-48e6-bea0-f83c5100682b"; | |
string umbracoTitleAlias = "title"; | |
string umbracoTextAlias = "text"; | |
// ------------------------------------------------------------------------- | |
// Endpoint: Receive Sitecore Webhook -> Update Umbraco | |
// ------------------------------------------------------------------------- | |
app.MapPost("/api/webhooks/sitecore", async (HttpContext context, ILogger<Program> logger) => | |
{ | |
// 1) Read the raw JSON body | |
var doc = await context.Request.ReadFromJsonAsync<JsonDocument>(); | |
// 2) Parse JSON for Title/Text. You can get it from: | |
// - "Item.VersionedFields" | |
string? titleFromSitecore = null; | |
string? textFromSitecore = null; | |
// Look in "VersionedFields" array | |
if (doc.RootElement.TryGetProperty("Item", out var itemElem) && | |
itemElem.TryGetProperty("VersionedFields", out var versionedFieldsElem) && | |
versionedFieldsElem.ValueKind == JsonValueKind.Array) | |
{ | |
foreach (var fieldElem in versionedFieldsElem.EnumerateArray()) | |
{ | |
if (!fieldElem.TryGetProperty("Id", out var fieldIdElem)) continue; | |
var fieldId = fieldIdElem.GetString() ?? string.Empty; | |
// Title field | |
if (fieldId.Equals("75577384-3c97-45da-a847-81b00500e250", StringComparison.OrdinalIgnoreCase)) | |
{ | |
if (fieldElem.TryGetProperty("Value", out var valElem)) | |
{ | |
titleFromSitecore = valElem.GetString(); | |
} | |
} | |
// Text field | |
else if (fieldId.Equals("a60acd61-a6db-4182-8329-c957982cec74", StringComparison.OrdinalIgnoreCase)) | |
{ | |
if (fieldElem.TryGetProperty("Value", out var valElem)) | |
{ | |
textFromSitecore = valElem.GetString(); | |
} | |
} | |
} | |
} | |
// 3) Update Umbraco using the parsed fields | |
var httpFactory = context.RequestServices.GetRequiredService<IHttpClientFactory>(); | |
// (a) Acquire an Umbraco token (Client Credentials) | |
var umbracoToken = await GetUmbracoTokenAsync(httpFactory, umbracoHost, umbracoClientId, umbracoClientSecret); | |
// (b) Build the JSON for the Umbraco PUT | |
// We'll update "title" and "text". | |
var valuesList = new List<object>(); | |
if (!string.IsNullOrEmpty(titleFromSitecore)) | |
{ | |
valuesList.Add(new | |
{ | |
alias = umbracoTitleAlias, | |
value = titleFromSitecore | |
}); | |
} | |
if (!string.IsNullOrEmpty(textFromSitecore)) | |
{ | |
valuesList.Add(new | |
{ | |
alias = umbracoTextAlias, | |
value = textFromSitecore | |
}); | |
} | |
var bodyObject = new | |
{ | |
values = valuesList.ToArray(), | |
variants = new[] | |
{ | |
new | |
{ | |
name = "FAQ item" | |
} | |
} | |
}; | |
var updateJson = JsonSerializer.Serialize(bodyObject, new JsonSerializerOptions | |
{ | |
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, | |
WriteIndented = true | |
}); | |
// (c) Send the PUT to Umbraco | |
var client = httpFactory.CreateClient(); | |
client.BaseAddress = new Uri(umbracoHost); | |
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", umbracoToken); | |
var content = new StringContent(updateJson, Encoding.UTF8, "application/json"); | |
var response = await client.PutAsync($"/umbraco/management/api/v1/document/{umbracoFaqDocId}", content); | |
var responseBody = await response.Content.ReadAsStringAsync(); | |
logger.LogInformation("Umbraco FAQ updated successfully"); | |
return Results.Ok("Sitecore data used to update Umbraco successfully!"); | |
}); | |
// ----------------------------------------------------------------------- | |
// Helper: Acquire a token from Umbraco Management API (Client Credentials) | |
// ----------------------------------------------------------------------- | |
static async Task<string?> GetUmbracoTokenAsync( | |
IHttpClientFactory httpFactory, | |
string umbracoHost, | |
string clientId, | |
string clientSecret) | |
{ | |
using var tokenClient = httpFactory.CreateClient(); | |
tokenClient.BaseAddress = new Uri(umbracoHost); | |
var req = new ClientCredentialsTokenRequest | |
{ | |
Address = "/umbraco/management/api/v1/security/back-office/token", | |
ClientId = clientId, | |
ClientSecret = clientSecret | |
}; | |
var resp = await tokenClient.RequestClientCredentialsTokenAsync(req); | |
return resp.AccessToken; | |
} | |
app.Run(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment