使用Adobe I/O Runtime操作处理AEM事件

了解如何使用Adobe I/O Runtime操作处理接收的AEM事件。 此示例增强了前面的示例Adobe I/O Runtime Action和AEM Events,请确保您已完成它,然后再继续此示例。

在此示例中,事件处理将原始事件数据和接收的事件作为活动消息存储在Adobe I/O Runtime存储中。 但是,如果事件是​ 修改的内容片段 ​类型,则它还会调用AEM创作服务来查找修改详细信息。 最后,它在单页应用程序(SPA)中显示事件详细信息。

先决条件

要完成本教程,您需要:

IMPORTANT
AEM as a Cloud Service事件仅适用于处于预发行模式的注册用户。 要在您的AEM as a Cloud Service环境中启用AEM事件,请联系AEM事件团队

AEM Events processor操作

在此示例中,事件处理器操作执行以下任务:

  • 将收到的事件解析为活动消息。
  • 如果收到的事件是​ 修改的内容片段 ​类型,请回调AEM创作服务以查找修改详细信息。
  • 在Adobe I/O Runtime存储中保留原始事件数据、活动消息和修改详细信息(如果有)。

要执行上述任务,我们先从向项目添加操作开始,开发JavaScript模块以执行上述任务,最后更新操作代码以使用开发的模块。

有关完整代码,请参阅附加的WKND-AEM-Eventing-Runtime-Action.zip文件,以下部分突出显示关键文件。

添加操作

  • 要添加操作,请运行以下命令:

    code language-bash
    aio app add action
    
  • 选择@adobe/generator-add-action-generic作为操作模板,将操作命名为aem-event-processor

    添加操作

开发JavaScript模块

为了执行上述任务,让我们开发以下JavaScript模块。

  • src/dx-excshell-1/actions/aem-event-processor/eventValidator.js模块确定收到的事件是否为​ 修改的内容片段 ​类型。

    code language-javascript
    async function needsAEMCallback(aemEvent) {
    // create a Logger
    const logger = Core.Logger('eventValidator', {
        level: 'info',
    });
    
    let isValid = false;
    
    // verify the event is a Content Fragment Modified event
    if (
        aemEvent
        && aemEvent.ContentType === 'contentFragment'
        && aemEvent.EventName === 'modified'
    ) {
        logger.info('Processing Content Fragment Modified Event');
        isValid = true;
    }
    
    return isValid;
    }
    
    module.exports = needsAEMCallback;
    
  • src/dx-excshell-1/actions/aem-event-processor/loadEventDetailsFromAEM.js模块调用AEM作者服务以查找修改详细信息。

    code language-javascript
    ...
    const auth = require('@adobe/jwt-auth');
    ...
    // Get AEM Service Credentials aka Technical Account details.
    // These are passed to the action as params and added in .env file.
    const clientId = params.AEM_SERVICECREDENTIALS_TECHNICALACCOUNT_CLIENTID;
    const technicalAccountId = params.AEM_SERVICECREDENTIALS_ID;
    const orgId = params.AEM_SERVICECREDENTIALS_ORG;
    const clientSecret = params.AEM_SERVICECREDENTIALS_TECHNICALACCOUNT_CLIENTSECRET;
    // Private key is passed as a string with \n and \r characters escaped.
    const privateKey = params.AEM_SERVICECREDENTIALS_PRIVATEKEY.replace(
        /\\n/g,
        '\n',
    ).replace(/\\r/g, '\r');
    const metaScopes = params.AEM_SERVICECREDENTIALS_METASCOPES.split(',');
    const ims = `https://${params.AEM_SERVICECREDENTIALS_IMSENDPOINT}`;
    
    // Get the access token from IMS using Adobe I/O SDK
    const { access_token } = await auth({
        clientId,
        technicalAccountId,
        orgId,
        clientSecret,
        privateKey,
        metaScopes,
        ims,
    });
    ...
    // Call AEM Author service to get the CF details using AEM Assets API
    const res = await fetch(
        `${aemAuthorHost}${cfPath.replace('/content/dam/', '/api/assets/')}.json`,
    {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${access_token}`,
      },
    },
    );
    
    let newValuesOfCFPropertiesAddedOrModified = {};
    // If the response is OK, get the values of the CF properties that were added or modified
    if (res.ok) {
        logger.info('AEM Event Details loaded from AEM Author instance');
        const responseJSON = await res.json();
    
        // Get the values of the CF properties that were added or modified
        if (
        responseJSON
        && responseJSON.properties
        && responseJSON.properties.elements
        ) {
        const allCurrentCFProperties = responseJSON.properties.elements;
    
        newValuesOfCFPropertiesAddedOrModified = cfPropertiesAddedOrModified.map(
            (key) => ({
            key,
            value: allCurrentCFProperties[key],
            }),
        );
        }
    }
    ...
    

    请参阅AEM服务凭据教程以了解详细信息。 此外,用于管理密钥和操作参数的App Builder配置文件

  • src/dx-excshell-1/actions/aem-event-processor/storeEventData.js模块将原始事件数据、活动消息和修改详细信息(如果有)存储在Adobe I/O Runtime存储中。

    code language-javascript
    ...
    const filesLib = require('@adobe/aio-lib-files');
    ...
    
    const files = await filesLib.init();
    
    const eventDataAsJSON = JSON.stringify({
        activity: activityMessage,
        aemEvent,
        aemEventDetails,
    });
    
    // store details in a folder named YYYY-MM-DD and a file named <eventID>.json
    const bytesWritten = await files.write(
        `${formattedDate}/${aemEvent.getEventID()}.json`,
        eventDataAsJSON,
    );
    ...
    

更新操作代码

最后,更新src/dx-excshell-1/actions/aem-event-processor/index.js处的操作代码以使用开发的模块。

...
// handle the challenge probe request, they are sent by I/O to verify the action is valid
if (params.challenge) {
    logger.info('Challenge probe request detected');
    responseMsg = JSON.stringify({ challenge: params.challenge });
} else {
    logger.info('AEM Event request received');

    // create AEM Event object from request parameters
    const aemEvent = new AEMEvent(params);

    // get AEM Event as activity message using the helper method
    const activityMessage = aemEvent.getEventAsActivityMessage();

    // determine if AEM Event requires callback to AEM Author service
    const callbackAEMForEventDetails = await needsAEMCallback(aemEvent);

    let eventDetails = {};
    if (callbackAEMForEventDetails) {
    // call AEM Author service to get specifics about the event
    eventDetails = await loadEventDetailsFromAEMAuthorService(
        aemEvent,
        params,
    );
    }

    // store AEM Event and Event details in the file system
    const storageDetails = await storeEventData(
    activityMessage,
    aemEvent,
    eventDetails || {},
    );
    logger.info(`Storage details: ${JSON.stringify(storageDetails)}`);

    // create response message
    responseMsg = JSON.stringify({
    message: 'AEM Event processed',
    activityMessage,
    });

    // response object
    const response = {
    statusCode: 200,
    body: responseMsg,
    };
    logger.info('Adobe I/O Runtime action response', response);

    // Return the response to the caller
    return response;
}
...

其他资源

  • src/dx-excshell-1/actions/model文件夹包含aemEvent.jserrors.js个文件,操作使用这些文件分别分析收到的事件和处理错误。
  • src/dx-excshell-1/actions/load-processed-aem-events文件夹包含操作代码,SPA使用此操作从Adobe I/O Runtime存储中加载已处理的AEM事件。
  • src/dx-excshell-1/web-src文件夹包含SPA代码,该代码显示已处理的AEM事件。
  • src/dx-excshell-1/ext.config.yaml文件包含操作配置和参数。

概念和关键要点

虽然事件处理要求因项目而异,但本示例的关键要求包括:

  • 可以使用Adobe I/O Runtime操作完成事件处理。
  • 运行时操作可以与系统(如内部应用程序、第三方解决方案和Adobe解决方案)通信。
  • 运行时操作是围绕内容更改设计的业务流程的入口点。
recommendation-more-help
4859a77c-7971-4ac9-8f5c-4260823c6f69