Automate RSS Feed to Sitecore XM Cloud: Logic App, Next.js API & Authoring API Integration
Hello everyone, In this blog, we will see a pratical use case of reading RSS feed and creating the respective items in Sitecore XM Cloud. To accomplish the task, we will use Logic App, an API created in Next JS and lastly calling the Authoring API to execute mutation query for Item Creation in Sitecore.
Let's divide the process into 2 parts:
- Logic App : This will mostly focus on fetching the feed from RSS, performing transformation, storing the result in array of json object and pushing the data to next js api endpoint.
- Next JS API Development : This will take care of calling the authoring api of XM Cloud instance and performing the create item mutation query on the recieved data from Logic App.
Logic App
Azure Logic App is a cloud-based service provided by Microsoft Azure that allows you to automate workflows and integrate applications, data, services, and systems without writing complex code. It enables you to create automated workflows visually through a drag-and-drop designer, making it easy to build, schedule, and manage tasks or business processe
So let's start designing our workflow. Navigate to Azure Portal --> Search Logic App --> Create Blank Logic App(Choose Consumption Base Plan) --> Choose Designer --> Start Creating Workflow
Step 1: Workflow Image 1
Let's understand each step in the above workflow image 1.
Recuurence Action : This step will work as scheduler to fetch rss feed in regular interval of time.
Http Action (Fetch RSS Feed) : This step will actuall call the feed url and fetch the content. In my case the output was XMl format content
InitializeVariable Action (Http Output Assigned to rssContent variable) : This step will hold the output of previous step by assigning the response body to variable as shown below
InitializeVariable Action (Hold JSON Object and assign to jsonArrayObject) : This step will hold the final result of array of JSON object extracted from XML feed. For now, we are just initializing it. This will be used in later steps.
Step 2: Workflow Image 2
Let's understand each step in the above workflow image 2.
Compose Action (XML Convert) : This step will convert the response of previous step into readable XML format which logic app understand.
Compose Action (XPath Query Extraction For Fetching Items) : This step will convert the response of previous step into json object of Encoded string. Logic app when used XPath query will convert the result into encoded format for better security.
Foreach Control (Iterating Through Encoded Array Of Content) : This step will iterate through the encoded array output of previous step.
Compose Action (Convert Item To JSON Object) : This step is created under For Each Loop. This step will take care of converting each encoded item into json object.
AppendToArrayVariable action : This step assigned the result of previous step into global jsonArrayObject declared previously.
Step 3: Workflow Image 3
Let's understand each step in the above workflow image 3.
Compose Action (Custom News Feed Array Object) : This step will create the output of jsonArrayObject to our custom required object which will be sent to an endpoint.
Http Action (Call Next JS Endpoint) : This step will post the output of previous step to next js endpoint.
Now let's run the logic app and we can see the result of each step. If it succeed then you will see all step work in green status and if it fails, it will clearly show which step fail as shown in below screenshot. Every step will show the input output which can be refer in next coming steps
Success Workflow
Error Workflow
Step Output
Next JS API Development
This step will be mostly focus on creating an api under src --> pages --> api --> {api name which in our case newsfeed} in your next js project. This will recieve the news feed from logic app in timely manner in array of json object. Now we will extract our required data and call the XM Cloud authoring api to create items using create mutation query. This is next js code so I will not deep dive to explain.
Create newsfeed.ts file under api folder
import { NextApiRequest, NextApiResponse } from 'next';
import { GraphQLClient } from 'graphql-request';
import { NewsItem, MutationResponse } from '../../data/newsfeed';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
const { newsFeed } = req.body;
// Handle null or undefined newsFeed
if (!newsFeed || !Array.isArray(newsFeed)) {
return res.status(400).json({ message: 'newsFeed is required' });
}
// Do something with the newsFeed (e.g., save to database or display on a page)
console.log(newsFeed);
//Execute Mutation Logic here
const graphqlClient = getGraphQLClient();
try {
const mutationResults = await Promise.all(
newsFeed.map(async (item) => {
// Dynamically create the input based on the newsFeed item
const input = createInput(item.item);
console.log(input);
// Get the mutation query string
const mutationQuery = getMutationQuery();
// Execute GraphQL mutation and get the result
return graphqlClient.request(mutationQuery, { input });
})
);
// Process all the results here (for logging, etc.)
console.log(mutationResults);
// Send a response
res
.status(200)
.json({ message: 'News feed processed successfully', results: mutationResults });
} catch (error) {
console.error('Error processing news feed:', error);
res.status(500).json({ message: 'Error processing news feed', error });
}
} else {
res.setHeader('Allow', ['POST']);
res.status(405).end(`Method ${req.method} not allowed`);
}
}
function getGraphQLClient(): GraphQLClient {
const authurl: string = process.env.GRAPH_QL_AUTHORING_ENDPOINT!;
const access_token = process.env.GRAPH_QL_BEARER_TOKEN || '';
const client = new GraphQLClient(authurl);
client.setHeader('Authorization', `Bearer ${access_token}`);
return client;
}
function getMutationQuery(): string {
const mutation_query = `
mutation($input: CreateItemInput!) {
createItem(
input: $input
) {
item {
itemId
name
path
fields(ownFields: true, excludeStandardFields: true) {
nodes {
name
value
}
}
}
}
}
`;
return mutation_query;
}
function createInput(item: NewsItem) {
console.log('Inside Create Item Fucnction : ', item);
// Create a dynamic input object for the GraphQL mutation based on the newsFeed item
const fields = [
{ name: 'title', value: item.title || 'Default Title' },
{ name: 'description', value: item.description || 'Default Description' },
];
return {
name: item.title?.replace(/[^a-zA-Z0-9 ]/g, '').trim() || 'Mutation Testing',
templateId: '{}', // Update template ID as needed
parent: '{}', // Update parent ID as needed
language: 'en', // Adjust the language code as needed
fields,
};
}
Create newsfeed.ts file under data folder
export interface NewsItem {
title: string;
description: string;
}
export interface MutationResponse {
createItem: {
item: {
itemId: string;
name: string;
path: string;
fields: {
nodes: {
name: string;
value: string;
}[];
};
};
};
}
Referrence Image
Once the above step is completed, make sure to have a publicly access url for the api. In my case, I deployed the changes to vercel. Make sure to add the authoring url and access token in vercel environment variable for successful testing.
Now you can do an end to end testing and see the items getting created in Sitecore XM Cloud
Vercel logs to verify the authoring api execution
Sitecore Output
This blog is lengthy but I believe it will give you good insight of integration that we have tried to achieve. This is just for POC purpose.Thanks for reading and keep learning!!
You can check my other blogs too if interested. Blog Website
Referrences
Comments
Post a Comment