[AEM Forms]{class="badge positive" title="适用于AEM Forms)。"}

在应用程序中集成关联UI

交互式通信功能在早期采用者计划下可用。 将工作地址中的电子邮件发送至aem-forms-ea@adobe.com以请求访问权限。

本文说明如何将关联UI与您的应用程序集成,从而使面向客户的专业人员(如现场助理和服务代理)能够在Publish实例上实时生成个性化的交互式通信。

先决条件

在将关联UI与您的应用程序集成之前,请确保您已:

NOTE

关联UI的其他SAML配置

为关联UI配置SAML 2.0身份验证时,必须在OSGi配置文件中应用以下特定设置。

SAML身份验证处理程序

SAML身份验证处理程序是一个OSGi工厂配置,它允许为不同的资源树使用多个SAML配置。 这支持多站点AEM部署,并允许您向现有SAML设置添加关联UI资源。

com.adobe.granite.auth.saml.SamlAuthenticationHandler~saml.cfg.json中创建文件ui.config/src/main/content/jcr_root/apps/<project-name>/osgiconfig/config.publish

  {
    "path": ["/libs/fd/associate"],
    "serviceProviderEntityId": "https://publish-p{program-id}-e{env-id}.adobeaemcloud.com",
    "assertionConsumerServiceURL": "https://publish-p{program-id}-e{env-id}.adobeaemcloud.com/libs/fd/associate/saml_login"
    "idpUrl": "https://login.microsoftonline.com/{azure-tenant-id}/saml2",
    "idpCertAlias": "{your-certificate-alias}",
    "idpIdentifier": "https://sts.windows.net/{azure-tenant-id}/",
    "userIDAttribute": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
    "createUser": true,
    "userIntermediatePath": "saml",
    "synchronizeAttributes": [
      "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname=profile/givenName",
      "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname=profile/familyName",
      "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress=profile/email"
      ],
      "addGroupMemberships": true,
      "defaultGroups": ["forms-associates"],
      "defaultRedirectUrl": "/libs/fd/associate/ui.html",
      "idpHttpRedirect": false,
      "service.ranking": 5002
  }
属性
描述
path
必须为关联UI设置为/libs/fd/associate
defaultGroups
设置为forms-associates以自动将用户分配给所需的组
defaultRedirectUrl
将经过身份验证的用户重定向到关联UI
idpHttpRedirect
对于SP启动的流,必须为false
idpCertAlias
必须完全匹配信任存储区中的证书别名(区分大小写)

Sling身份验证程序

Sling Authenticator强制进行身份验证以访问发布上的关联UI资源。

更新org.apache.sling.engine.impl.auth.SlingAuthenticator~saml.cfg.json中的文件ui.config/src/main/content/jcr_root/apps/<project-name>/osgiconfig/config.publish

{
  "sling.auth.requirements": ["+/libs/fd/associate/ui.html"],
  "sling.auth.anonymous": false
}

Dispatcher筛选器

添加以下规则以确保Interactive Communications API和关联UI在发布实例上正确运行。

如果尚未存在,请将以下规则添加到您的dispatcher/src/conf.dispatcher.d/filters/filters.any文件:

  # Allow Interactive Communications APIs and Associate UI
  /XXXX { /type "allow" /method '(GET|OPTIONS)' /url "/adobe/communications" }
  /XXXX { /type "allow" /method '(GET|POST|OPTIONS)' /url "/adobe/communications/*" }
  /XXXX { /type "allow" /method "GET" /url "/content/dam/fd:fonts/*" }
  /XXXX { /type "allow" /method '(GET|OPTIONS)' /url "/libs/fd/associate/*" }
NOTE
XXXX替换为现有filters.any文件中使用的相应数字序列。

在发布实例上调用关联UI

本节将指导您从自己的应用程序中启动关联UI。 按照以下步骤快速入门 — 从现成的示例HTML页面开始,然后为您的环境配置它。

步骤1:开始创建示例HTML页面

要快速测试和了解关联UI集成的工作方式,请使用以下示例HTML页面。 将此代码复制到HTML文件中,并在浏览器中将其打开。

NOTE
此示例HTML需要IC ID和预填充服务。 您可以使用IC ID和示例预填充服务“FdmTestData”对其进行测试。

HTML示例提供了一个简单的表单界面,您可以在其中输入交互式通信详细信息,然后单击以启动关联UI。

<!DOCTYPE html>
<html>
<head>
  <title>Associate UI Integration</title>
  <style>
    body {
      font-family: sans-serif;
      max-width: 600px;
      margin: 50px auto;
      padding: 20px;
    }
    .form-group {
      margin: 20px 0;
    }
    label {
      display: block;
      margin-bottom: 5px;
      font-weight: bold;
    }
    input, textarea {
      width: 100%;
      padding: 8px;
      border: 1px solid #ccc;
      border-radius: 4px;
      box-sizing: border-box;
    }
    textarea {
      height: 80px;
      font-family: monospace;
    }
    button {
      padding: 10px 20px;
      margin: 5px;
      cursor: pointer;
      border-radius: 4px;
    }
    .btn-primary {
      background: #007bff;
      color: white;
      border: none;
    }
    .btn-primary:hover {
      background: #0056b3;
    }
    .error {
      color: red;
      font-size: 12px;
      display: none;
    }
  </style>
</head>
<body>
  <h1>Launch Associate UI</h1>

  <form id="form">
    <div class="form-group">
      <label>IC ID *</label>
      <input type="text" id="icId" placeholder="Enter Interactive Communication ID" required>
    </div>

    <div class="form-group">
      <label>Prefill Service</label>
      <input type="text" id="serviceName" placeholder="e.g., CustomerDataService">
    </div>

    <div class="form-group">
      <label>Service Parameters (JSON)</label>
      <textarea id="serviceParams" placeholder='{"customerId": "12345"}'>{}</textarea>
      <span id="paramsError" class="error">Invalid JSON format</span>
    </div>

    <div class="form-group">
      <label>Options (JSON)</label>
      <textarea id="options" placeholder='{"mode": "edit", "locale": "en_US"}'>{}</textarea>
      <span id="optionsError" class="error">Invalid JSON format</span>
    </div>

    <button type="button" onclick="reset()">Reset</button>
    <button type="button" class="btn-primary" onclick="launch()">Launch Associate UI</button>
  </form>

  <script>
    // Replace with your AEM Publish instance URL
    const AEM_URL = 'https://publish-p{program-id}-e{env-id}.adobeaemcloud.com/libs/fd/associate/ui.html';

    function validateJSON(str, errorId) {
      const err = document.getElementById(errorId);
      try {
        const obj = JSON.parse(str || '{}');
        err.style.display = 'none';
        return obj;
      } catch (e) {
        err.style.display = 'block';
        return null;
      }
    }

    function launch() {
      const icId = document.getElementById('icId').value.trim();
      if (!icId) {
        alert('IC ID is required');
        return;
      }

      const params = validateJSON(document.getElementById('serviceParams').value, 'paramsError');
      const opts = validateJSON(document.getElementById('options').value, 'optionsError');

      if (!params || !opts) {
        alert('Please fix JSON errors before launching');
        return;
      }

      const data = {
        id: icId,
        prefill: {
          serviceName: document.getElementById('serviceName').value.trim(),
          serviceParams: params
        },
        options: opts
      };

      const win = window.open(AEM_URL, '_blank');
      if (!win) {
        alert('Pop-up blocked. Please enable pop-ups for this site.');
        return;
      }

      const handler = (e) => {
        if (e.data && e.data.type === 'READY' && e.data.source === 'APP') {
          win.postMessage({ type: 'INIT', source: 'PORTAL', data }, '*');
          window.removeEventListener('message', handler);
        }
      };

      window.addEventListener('message', handler);

      // Fallback timeout in case READY message is missed
      setTimeout(() => {
        if (win && !win.closed) {
          win.postMessage({ type: 'INIT', source: 'PORTAL', data }, '*');
          window.removeEventListener('message', handler);
        }
      }, 1000);
    }

    function reset() {
      document.getElementById('form').reset();
      document.getElementById('serviceParams').value = '{}';
      document.getElementById('options').value = '{}';
      document.getElementById('paramsError').style.display = 'none';
      document.getElementById('optionsError').style.display = 'none';
    }
  </script>
</body>
</html>

步骤2:配置发布实例URL

在启动关联UI之前,您需要将示例指向AEM Forms Cloud Service发布实例。

在上面的HTML示例中,在<script>部分中找到以下行:

const AEM_URL = 'https://publish-p{program-id}-e{env-id}.adobeaemcloud.com/libs/fd/associate/ui.html';

将占位符值替换为您的实际环境详细信息:

  • {program-id}:您的AEM Cloud Service项目ID
  • {env-id}:您的环境ID

例如,如果您的项目ID为12345,环境ID为67890,则URL将变为:

const AEM_URL = 'https://publish-p12345`-e67890.adobeaemcloud.com/libs/fd/associate/ui.html';
NOTE
为安全起见,交互式通信ID、预填充服务和服务参数等参数不会通过URL进行传递。 相反,这些参数是使用JavaScript的postMessage API安全传递的。

步骤3:了解JavaScript集成功能

示例HTML使用以下JavaScript函数来启动关联UI。 此函数验证IC ID、构造数据有效负载、在新的浏览器窗口中打开关联UI,并使用浏览器的postMessage API发送数据。

function launchAssociateUI(icId, prefillService, prefillParams, options) {
  if (!icId) {
    console.error('IC ID required');
    return;
  }

  const data = {
    id: icId,
    prefill: {
      serviceName: prefillService || '',
      serviceParams: prefillParams || {}
    },
    options: options || {}
  };

  const AEM_URL = 'https://your-aem.adobeaemcloud.com/libs/fd/associate/ui.html';
  const win = window.open(AEM_URL, '_blank');

  if (!win) {
    alert('Please enable pop-ups for this site');
    return;
  }

  const readyHandler = (event) => {
    if (event.data && event.data.type === 'READY' && event.data.source === 'APP') {
      win.postMessage({ type: 'INIT', source: 'PORTAL', data: data }, '*');
      window.removeEventListener('message', readyHandler);
    }
  };

  window.addEventListener('message', readyHandler);

  // Fallback timeout in case READY message is missed
  setTimeout(() => {
    if (win && !win.closed) {
      win.postMessage({ type: 'INIT', source: 'PORTAL', data: data }, '*');
      window.removeEventListener('message', readyHandler);
    }
  }, 1000);
}

该函数接受四个参数:IC ID(必需)、预填充服务名称、预填充服务参数和其他选项。 这些参数将结构化到数据有效负载中,如下所述。

步骤4:了解数据有效载荷结构

有效负载格式:

const data = {
  id: "your-ic-id",              // Required: Interactive Communication ID
  prefill: {                      // Optional: Data to prefill the IC
    serviceName: "YourService",
    serviceParams: { key: "value" }
  },
  options: {}                     // Optional: Additional configuration options
};

有效负载组件:

组件
必需
描述
id
要加载的交互式通信(IC)的标识符
prefill
可选
包含用于数据预填充的服务配置
prefill.serviceName
可选
要调用以预填充数据的表单数据模型服务的名称
prefill.serviceParams
可选
传递到预填充服务的键值对
options
可选
PDF渲染支持的其他属性 — 区域设置、包括Attachments、embedFonts、makeAccessible

数据有效负载示例

最小有效负载(仅限IC ID)

当不需要预填充数据时,使用此项:

{
  "id": "12345",
  "prefill": {
    "serviceName": "",
    "serviceParams": {}
  },
  "options": {}
}

包含预填充数据

使用它动态地向IC填充客户数据:

{
  "id": "12345",
  "prefill": {
    "serviceName": "IC_FDM",
    "serviceParams": {
      "customerId": "101",
      "accountNumber": "ACC-98765"
    }
  },
  "options": {}
}

具有PDF渲染选项

使用此选项可指定其他渲染选项:

{
  "id": "12345",
  "prefill": {
    "serviceName": "IC_FDM",
    "serviceParams": {
      "customerId": "101",
      "accountNumber": "ACC-98765"
    }
  },
  "options": {
      "locale": "en_US",
      "includeAttachments": "true",
      "webOptimized": "false",
      "embedFonts": "false",
      "makeAccessible": "false"
  }
}

步骤5:输入IC ID并启动关联UI

现在,您可以使用示例HTML页面启动关联UI:

  1. 输入IC ID:在​ IC ID ​字段中,输入已发布的交互式通信的标识符。 这是唯一的必填字段。

  2. 配置预填充服务:如果要使用动态数据预填充IC,请在​ 预填充服务 ​字段中输入表单数据模型服务名称。 例如,使用FdmTestData作为示例数据。

    HTML UI示例

  3. 单击“启动关联UI”:单击“启动关联UI”​按钮。 此时将打开一个新浏览器窗口,其中显示与交互式通信预先加载的关联UI 。

输入数据,此时将显示关联UI,如下所示:

关联UI

NOTE
如果该窗口未打开,请检查浏览器是否允许显示此站点的弹出窗口。

疑难解答

已阻止弹出窗口

问题:“关联UI”窗口未打开。

解决方案

  • 在浏览器设置中为域启用弹出窗口
  • 确保从用户操作(例如,按钮单击)中调用window.open()
  • 使用不同的浏览器测试以识别阻止行为

数据未加载

问题:交互式通信打开,但数据未填充。

解决方案

  • 验证IC ID是否正确,以及IC是否已发布
  • 检查浏览器控制台是否显示 JavaScript 错误
  • 确保postMessage结构与规范完全匹配
  • 验证表单数据模型服务是否已正确配置

身份验证错误

问题:打开关联UI时,用户收到身份验证错误。

解决方案

  • 在发布实例上配置SAML 2.0身份验证
  • 验证用户是否属于​ forms-associates ​组
  • 检查会话超时设置

CORS错误

问题:控制台中存在跨源资源共享错误。

解决方案

  • 对于开发:在'*'中使用postMessage作为目标来源
  • 用于生产:指定应用程序的确切起源URL
  • 确保发布实例CORS设置允许您的应用程序域

另请参阅

recommendation-more-help
fbcff2a9-b6fe-4574-b04a-21e75df764ab