[集成]{class="badge positive"}

集成AEM Headless和Target

[AEM Headlessas a Cloud Service]{class="badge informative"}

了解如何将AEM内容片段导出到Adobe Target,从而将AEM Headless与Adobe Target集成,并使用Adobe Experience Platform Web SDK的alloy.js使用它们来个性化Headless体验。 React WKND应用程序用于探索如何将使用内容片段选件的个性化Target活动添加到体验中,以促进WKND冒险。

本教程介绍了设置AEM和Adobe Target所涉及的步骤:

Adobe IMS配置 adobe-ims-configuration

Adobe IMS配置,它有利于AEM和Adobe Target之间的身份验证。

查看文档以了解有关如何创建Adobe IMS配置的分步说明。

Adobe TargetCloud Service adobe-target-cloud-service

在AEM中创建Adobe TargetCloud Service,以便于将内容片段导出到Adobe Target。

查看文档以了解有关如何创建Adobe TargetCloud Service的分步说明。

配置资源文件夹 configure-asset-folders

在上下文感知配置中配置的Adobe TargetCloud Service,必须应用于包含要导出到Adobe Target的AEM Assets文件夹层次结构。

有关分步说明,请展开
  1. 以DAM管理员身份登录到​ AEM作者服务
  2. 导航到​ Assets >文件,找到已应用/conf的资源文件夹
  3. 选择资产文件夹,然后从顶部操作栏中选择​ 属性
  4. 选择​ Cloud Service ​选项卡
  5. 确保将云配置设置为包含Adobe TargetCloud Service配置的上下文感知配置(/conf)。
  6. 从​ Cloud Service配置 ​下拉列表中选择​ Adobe Target
  7. 选择右上方的​ 保存并关闭

许可AEM Target集成 permission

Adobe Target集成(显示为developer.adobe.com项目)必须被授予Adobe Admin Console中的​ 编辑者 ​产品角色,才能将内容片段导出到Adobe Target。

有关分步说明,请展开
  1. 以可在Adobe Admin Console中管理Adobe Target产品的用户的身份登录Experience Cloud
  2. 打开Adobe Admin Console
  3. 选择​ 产品,然后打开​ Adobe Target
  4. 在​ 产品配置文件 ​选项卡上,选择​ 默认工作区
  5. 选择​ API凭据 ​选项卡
  6. 在此列表中找到您的developer.adobe.com应用,并将其​ 产品角色 ​设置为​ 编辑者

将内容片段导出到目标 export-content-fragments

存在于配置的AEM Assets文件夹层次结构下的内容片段可以作为内容片段选件导出到Adobe Target。 这些内容片段选件(Target中特殊形式的JSON选件)可以在Target活动中使用,以在Headless应用程序中提供个性化体验。

有关分步说明,请展开
  1. 以DAM用户身份登录到​ AEM作者

  2. 导航到​ Assets >文件,并在“启用Adobe Target”文件夹下找到要导出为JSON到Target的内容片段

  3. 选择要导出到Adobe Target的内容片段

  4. 从顶部操作栏中选择​ 导出到Adobe Target选件

    • 此操作将内容片段的完全水合JSON表示形式作为“内容片段选件”导出到Adobe Target

    • 可以在AEM中查看完全水合的JSON表示形式

      • 选择内容片段
      • 展开侧面板
      • 在左侧面板中选择​ 预览 ​图标
      • 导出到Adobe Target的JSON表示形式将显示在主视图中
  5. 使用Adobe Target编辑器角色中的用户登录Adobe Experience Cloud

  6. Experience Cloud中,从右上方的产品切换器中选择​ Target ​以打开Adobe Target。

  7. 确保在右上方的​ Workspace切换器 ​中选择默认Workspace。

  8. 在顶部导航中选择​ 选件 ​选项卡

  9. 选择​ 类型 ​下拉列表,然后选择​ 内容片段

  10. 验证从AEM导出的内容片段是否显示在列表中

    • 将鼠标悬停在选件上,然后选择​ 查看 ​按钮
    • 查看​ 选件信息 ​并查看​ AEM深层链接,该链接直接在AEM创作服务中打开内容片段

使用内容片段选件的Target活动 activity

在Adobe Target中,可创建一个使用内容片段选件JSON作为内容的活动,允许在Headless应用程序中通过AEM中创建和管理内容提供个性化体验。

在本例中,我们使用简单的A/B活动,但可以使用任何Target活动。

有关分步说明,请展开
  1. 在顶部导航中选择​ 活动 ​选项卡

  2. 选择​ +创建活动,然后选择要创建的活动类型。

    • 此示例创建一个简单的​ A/B测试,但内容片段选件可以为任何活动类型提供支持
  3. 在​ 创建活动 ​向导中

    • 选择​ Web
    • 在​ 选择体验编辑器 ​中,选择​ 表单
    • 在​ 选择Workspace ​中,选择​ 默认Workspace
    • 在​ 选择属性 ​中,选择活动可用的属性,或选择​ 无属性限制 ​以允许在所有属性中使用它。
    • 选择​ 下一步 ​以创建该活动
  4. 通过选择左上角的​ 重命名 ​重命名该活动

    • 为活动提供一个有意义的名称
  5. 在初始体验中,为要定位的活动设置​ 位置1

    • 在此示例中,定位名为wknd-adventure-promo的自定义位置
  6. 在​ 内容 ​下,选择默认内容,然后选择​ 更改内容片段

  7. 选择要为此体验提供的导出内容片段,然后选择​ 完成

  8. 查看内容文本区域中的内容片段选件JSON,这是通过内容片段的预览操作在AEM创作服务中提供的相同JSON。

  9. 在左边栏中,添加一个体验,然后选择要提供的其他内容片段选件

  10. 选择​ 下一步,并根据活动需要配置定位规则

    • 在此示例中,将A/B测试保留为手动的50/50拆分。
  11. 选择​ 下一步,并完成活动设置

  12. 选择​ 保存并关闭 ​并为其指定一个有意义的名称

  13. 在Adobe Target的“活动”中,从右上角的“不活动/激活/存档”下拉列表中选择​ 激活

现在,可以在AEM Headless应用程序中集成和公开针对wknd-adventure-promo位置的Adobe Target活动。

数据流IDExperience Platform datastream-id

AEM Headless应用程序需要Adobe Experience Platform数据流 ID才能使用AdobeWeb SDK与Adobe Target交互。

有关分步说明,请展开
  1. 导航到Adobe Experience Cloud

  2. 打开​ Experience Platform

  3. 选择​ 数据收集>数据流 ​并选择​ 新建数据流

  4. 在“新建数据流”向导中,输入:

    • 名称:AEM Target integration
    • 描述: Datastream used by the Adobe Web SDK to serve personalized Content Fragments Offers.
    • 事件架构: Leave blank
  5. 选择​ 保存

  6. 选择​ 添加服务

  7. 在​ 服务 ​中选择​ Adobe Target

    • 已启用:
    • 属性令牌: 留空
    • 目标环境ID: 留空
      • 可在Adobe Target中的​ 管理>主机 ​处设置Target环境。
    • 目标第三方ID命名空间: 留空
  8. 选择​ 保存

  9. 在右侧,复制​ 数据流ID ​以用于AdobeWeb SDK配置调用。

向AEM Headless应用程序添加个性化设置 code

本教程探讨如何通过Adobe Experience Platform Web SDK使用Adobe Target中的内容片段选件对简单的React应用程序进行个性化。 此方法可用于个性化任何基于JavaScript的Web体验。

Android™和iOS移动体验可以使用Adobe的Mobile SDK按照类似的模式进行个性化。

先决条件

设置

  1. Github.com下载示例React应用程序的源代码

    code language-shell
    $ mkdir -p ~/Code
    $ git clone git@github.com:adobe/aem-guides-wknd-graphql.git
    
  2. 在收藏的IDE中打开位于~/Code/aem-guides-wknd-graphql/personalization-tutorial的代码库

  3. 更新您希望应用连接到~/Code/aem-guides-wknd-graphql/personalization-tutorial/src/.env.development的AEM服务主机

    code language-none
    ...
    REACT_APP_HOST_URI=https://publish-p1234-e5678.adobeaemcloud.com/
    ...
    
  4. 运行应用程序,并确保它连接到配置的AEM服务。 在命令行中,执行:

    code language-shell
    $ cd ~/Code/aem-guides-wknd-graphql/personalization-tutorial
    $ npm install
    $ npm run start
    
  5. AdobeWeb SDK安装为NPM包。

    code language-shell
    $ cd ~/Code/aem-guides-wknd-graphql/personalization-tutorial
    $ npm install @adobe/alloy
    

    Web SDK可在代码中使用,以按活动位置获取内容片段选件JSON。

    配置Web SDK时,需要两个ID:

    • edgeConfigId,即数据流ID
    • orgId可在​ Experience Cloud>配置文件>Adobe信息>当前组织ID ​中找到的AEM as a Cloud Service/Target组织ID

    调用Web SDK时,必须将Adobe Target活动位置(在我们的示例中,wknd-adventure-promo)设置为decisionScopes数组中的值。

    code language-javascript
    import { createInstance } from "@adobe/alloy";
    const alloy = createInstance({ name: "alloy" });
    ...
    alloy("config", { ... });
    alloy("sendEvent", { ... });
    

实施

  1. 创建React组件AdobeTargetActivity.js以显示Adobe Target活动。

    src/components/AdobeTargetActivity.js

    code language-javascript
    import React, { useEffect } from 'react';
    import { createInstance } from '@adobe/alloy';
    
    const alloy = createInstance({ name: 'alloy' });
    
    alloy('configure', {
      'edgeConfigId': 'e3db252d-44d0-4a0b-8901-aac22dbc88dc', // AEP Datastream ID
      'orgId':'7ABB3E6A5A7491460A495D61@AdobeOrg',
      'debugEnabled': true,
    });
    
    export default function AdobeTargetActivity({ activityLocation, OfferComponent }) {
      const [offer, setOffer] = React.useState();
    
      useEffect(() => {
        async function sendAlloyEvent() {
          // Get the activity offer from Adobe Target
          const result = await alloy('sendEvent', {
            // decisionScopes is set to an array containing the Adobe Target activity location
            'decisionScopes': [activityLocation],
          });
    
          if (result.propositions?.length > 0) {
            // Find the first proposition for the active activity location
            var proposition = result.propositions?.filter((proposition) => { return proposition.scope === activityLocation; })[0];
    
            // Get the Content Fragment Offer JSON from the Adobe Target response
            const contentFragmentOffer = proposition?.items[0]?.data?.content || { status: 'error', message: 'Personalized content unavailable'};
    
            if (contentFragmentOffer?.data) {
              // Content Fragment Offers represent a single Content Fragment, hydrated by
              // the byPath GraphQL query, we must traverse the JSON object to retrieve the
              // Content Fragment JSON representation
              const byPath = Object.keys(contentFragmentOffer.data)[0];
              const item = contentFragmentOffer.data[byPath]?.item;
    
              if (item) {
                // Set the offer to the React state so it can be rendered
                setOffer(item);
    
                // Record the Content Fragment Offer as displayed for Adobe Target Activity reporting
                // If this request is omitted, the Target Activity's Reports will be blank
                alloy("sendEvent", {
                    xdm: {
                        eventType: "decisioning.propositionDisplay",
                        _experience: {
                            decisioning: {
                                propositions: [proposition]
                            }
                        }
                    }
                });
              }
            }
          }
        };
    
        sendAlloyEvent();
    
      }, [activityLocation, OfferComponent]);
    
      if (!offer) {
        // Adobe Target offer initializing; we render a blank component (which has a fixed height) to prevent a layout shift
        return (<OfferComponent></OfferComponent>);
      } else if (offer.status === 'error') {
        // If Personalized content could not be retrieved either show nothing, or optionally default content.
        console.error(offer.message);
        return (<></>);
      }
    
      console.log('Activity Location', activityLocation);
      console.log('Content Fragment Offer', offer);
    
      // Render the React component with the offer's JSON
      return (<OfferComponent content={offer} />);
    };
    

    使用以下方式调用AdobeTargetActivity React组件:

    code language-jsx
    <AdobeTargetActivity activityLocation={"wknd-adventure-promo"} OfferComponent={AdventurePromo}/>
    
  2. 创建React组件AdventurePromo.js以呈现JSON Adobe Target提供的冒险。

    此React组件采用完全水合的JSON,表示冒险内容片段,并以促销方式显示。 根据导出到Adobe Target的内容片段,显示从Adobe Target内容片段选件提供的JSON服务的React组件可以视需要而有所不同,也非常复杂。

    src/components/AdventurePromo.js

    code language-javascript
    import React from 'react';
    
    import './AdventurePromo.scss';
    
    /**
    * @param {*} content is the fully hydrated JSON data for a WKND Adventure Content Fragment
    * @returns the Adventure Promo component
    */
    export default function AdventurePromo({ content }) {
        if (!content) {
            // If content is still loading, then display an empty promote to prevent layout shift when Target loads the data
            return (<div className="adventure-promo"></div>)
        }
    
        const title = content.title;
        const description = content?.description?.plaintext;
        const image = content.primaryImage?._publishUrl;
    
        return (
            <div className="adventure-promo">
                <div className="adventure-promo-text-wrapper">
                    <h3 className="adventure-promo-eyebrow">Promoted adventure</h3>
                    <h2 className="adventure-promo-title">{title}</h2>
                    <p className="adventure-promo-description">{description}</p>
                </div>
                <div className="adventure-promo-image-wrapper">
                    <img className="adventure-promo-image" src={image} alt={title} />
                </div>
            </div>
        )
    }
    

    src/components/AdventurePromo.scss

    code language-css
    .adventure-promo {
        display: flex;
        margin: 3rem 0;
        height: 400px;
    }
    
    .adventure-promo-text-wrapper {
        background-color: #ffea00;
        color: black;
        flex-grow: 1;
        padding: 3rem 2rem;
        width: 55%;
    }
    
    .adventure-promo-eyebrow {
        font-family: Source Sans Pro,Helvetica Neue,Helvetica,Arial,sans-serif;
        font-weight: 700;
        font-size: 1rem;
        margin: 0;
        text-transform: uppercase;
    }
    
    .adventure-promo-description {
        line-height: 1.75rem;
    }
    
    .adventure-promo-image-wrapper {
        height: 400px;
        width: 45%;
    }
    
    .adventure-promo-image {
        height: 100%;
        object-fit: cover;
        object-position: center center;
        width: 100%;
    }
    

    按如下方式调用此React组件:

    code language-jsx
    <AdventurePromo adventure={adventureJSON}/>
    
  3. 将AdobeTargetActivity组件添加到React应用程序的Home.js冒险列表上方。

    src/components/Home.js

    code language-javascript
    import AdventurePromo from './AdventurePromo';
    import AdobeTargetActivity from './AdobeTargetActivity';
    ...
    export default function Home() {
        ...
        return(
            <div className="Home">
    
              <AdobeTargetActivity activityLocation={"wknd-adventure-promo"} OfferComponent={AdventurePromo}/>
    
              <h2>Current Adventures</h2>
              ...
        )
    }
    
  4. 如果React应用未运行,请使用npm run start重新启动。

    在两种不同的浏览器中打开React应用程序,以便允许A/B测试向每个浏览器提供不同的体验。 如果两个浏览器显示相同的冒险选件,请尝试关闭/重新打开其中一个浏览器,直到显示另一个体验。

    下图显示了wknd-adventure-promo活动基于Adobe Target逻辑显示的两个不同的内容片段选件。

    体验选件

恭喜!

现在,我们已将AEM as a Cloud Service配置为将内容片段导出到Adobe Target,在Adobe Target活动中使用了内容片段选件,并在AEM Headless应用程序中显示该活动,从而个性化了体验。

recommendation-more-help
4859a77c-7971-4ac9-8f5c-4260823c6f69