enonic-webhook-integrator

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Enonic Webhook Integrator

Enonic Webhook集成器

Procedures

操作流程

Step 1: Detect the Enonic XP project
  1. Execute
    node scripts/find-enonic-targets.mjs .
    to locate Enonic XP project roots in the workspace.
  2. If the script returns an empty array, stop and explain that no Enonic XP project was found.
  3. If multiple projects are found, ask which project should receive the integration.
  4. Identify the application key from
    gradle.properties
    (
    appName
    ) or
    build.gradle
    .
Step 2: Determine integration direction
  1. Classify the task as one of: outbound event listener (XP reacts to internal events and calls an external system), outbound webhook config (XP sends webhook payloads via built-in config), inbound webhook endpoint (XP receives payloads from an external system), or mixed (combination).
  2. Read
    references/event-reference.md
    to identify the correct event types, listener patterns, and filtering strategies.
  3. Read
    references/webhook-reference.md
    when the task involves outbound webhook configuration or inbound HTTP service endpoints.
Step 3: Implement outbound event listener (if applicable)
  1. Read
    assets/event-listener.template.ts
    as a starting scaffold.
  2. Register the event listener in the application's
    main.ts
    (or
    main.js
    ) controller using lib-event's
    listener()
    function.
  3. Use the
    type
    parameter with a pattern matching the target node events (e.g.,
    node.pushed
    ,
    node.created
    ,
    node.updated
    ,
    node.deleted
    ).
  4. Filter events by path within the callback by checking
    event.data.nodes[].path
    to restrict processing to the intended content tree.
  5. When the listener must call an external HTTP endpoint, use lib-httpClient's
    request()
    function inside the callback or delegate to a background task.
  6. For long-running processing, delegate work from the event callback to a background task using lib-task's
    executeFunction()
    to avoid blocking the event thread.
  7. Read
    references/examples.md
    for complete integration patterns including CDN invalidation, search reindexing, and notification dispatch.
Step 4: Configure outbound webhooks (if applicable)
  1. Read
    references/webhook-reference.md
    for the
    com.enonic.xp.webhooks.cfg
    configuration format.
  2. Create or update the file at
    XP_HOME/config/com.enonic.xp.webhooks.cfg
    with webhook entries specifying the target URL and event types.
  3. Validate that the configured event types match the intended content lifecycle events.
  4. Use HTTPS URLs for webhook targets.
  5. Never write actual secret values into configuration files or source code. Use descriptive placeholder tokens (e.g.,
    REPLACE_WITH_CDN_SECRET
    ) and instruct the operator to substitute real credentials out-of-band. Secrets must be managed by the operator through secure deployment pipelines, environment variables, or secret management tools—not committed to files.
Step 5: Implement inbound webhook endpoint (if applicable)
  1. Read
    assets/http-service.template.ts
    as a starting scaffold.
  2. Create an HTTP service controller at
    src/main/resources/services/<serviceName>/<serviceName>.ts
    .
  3. Export a
    post(req)
    function that parses the incoming JSON payload from
    req.body
    .
  4. Reject payloads exceeding a reasonable size limit (e.g., 1 MB) before parsing.
  5. Validate the inbound payload by checking required fields, authentication headers, or HMAC signatures before processing.
  6. Sanitize all string fields from the external payload before using them in content operations: trim whitespace, enforce maximum lengths, strip or escape HTML/script content, and reject values containing path traversal sequences (
    ..
    ,
    /
    ,
    \
    ).
  7. Use an allowlist of expected field names rather than passing the raw payload object to content APIs.
  8. Return appropriate HTTP status codes:
    200
    for success,
    400
    for malformed payloads,
    401
    for authentication failures,
    413
    for oversized payloads,
    500
    for unexpected errors.
  9. When inbound payloads trigger content creation or modification, use lib-content or lib-node APIs within a context run to ensure proper permissions. Never pass unsanitized external values as content names, paths, or keys.
Step 6: Wire async processing with lib-task (if applicable)
  1. When event handling or webhook processing requires heavy or time-consuming work, wrap it in
    executeFunction()
    from lib-task.
  2. Report progress from long-running tasks using
    progress()
    to allow monitoring.
  3. Read
    references/event-reference.md
    for the task event lifecycle (
    task.submitted
    ,
    task.updated
    ,
    task.finished
    ,
    task.failed
    ).
Step 7: Validate the integration
  1. Execute
    node scripts/find-enonic-targets.mjs .
    to confirm the project still resolves correctly.
  2. Verify that the event listener registration is in the application's
    main.ts
    or
    main.js
    file, which runs at application startup.
  3. Confirm that outbound HTTP calls use HTTPS and include error handling for network failures and non-2xx responses.
  4. Confirm that no actual secret values, API keys, or credentials appear in generated source code or configuration files—only placeholder tokens.
  5. Confirm that inbound webhook endpoints sanitize and allowlist all fields from external payloads before passing them to content APIs.
  6. If a webhook config file was created, confirm the event type patterns match the intended triggers.
  7. Run the workspace build to verify no compilation errors.
  8. Read
    references/troubleshooting.md
    when events do not fire, webhook deliveries fail, or inbound requests are rejected.
步骤1:检测Enonic XP项目
  1. 执行
    node scripts/find-enonic-targets.mjs .
    定位工作区中的Enonic XP项目根目录。
  2. 如果脚本返回空数组,停止操作并说明未找到Enonic XP项目。
  3. 如果找到多个项目,询问需要集成的目标项目。
  4. gradle.properties
    appName
    字段)或
    build.gradle
    中识别应用密钥。
步骤2:确定集成方向
  1. 将任务归类为以下类型之一:出站事件监听器(XP响应内部事件并调用外部系统)、出站webhook配置(XP通过内置配置发送webhook payload)、入站webhook端点(XP接收外部系统发送的payload),或混合模式(多种类型组合)。
  2. 阅读
    references/event-reference.md
    确定正确的事件类型、监听器模式和过滤策略。
  3. 如果任务涉及出站webhook配置或入站HTTP服务端点,阅读
    references/webhook-reference.md
步骤3:实现出站事件监听器(如适用)
  1. 参考
    assets/event-listener.template.ts
    作为初始脚手架。
  2. 使用lib-event的
    listener()
    函数在应用的
    main.ts
    (或
    main.js
    )控制器中注册事件监听器。
  3. type
    参数中使用匹配目标节点事件的模式(例如
    node.pushed
    node.created
    node.updated
    node.deleted
    )。
  4. 在回调函数中通过检查
    event.data.nodes[].path
    按路径过滤事件,将处理范围限制在目标内容树内。
  5. 当监听器需要调用外部HTTP端点时,可在回调函数内使用lib-httpClient的
    request()
    函数,或委托给后台任务处理。
  6. 对于长时间运行的处理流程,使用lib-task的
    executeFunction()
    将工作从事件回调委托给后台任务,避免阻塞事件线程。
  7. 阅读
    references/examples.md
    查看完整集成模式,包括CDN失效、搜索索引重建和通知分发。
步骤4:配置出站webhook(如适用)
  1. 阅读
    references/webhook-reference.md
    了解
    com.enonic.xp.webhooks.cfg
    的配置格式。
  2. 创建或更新
    XP_HOME/config/com.enonic.xp.webhooks.cfg
    文件,添加指定目标URL和事件类型的webhook条目。
  3. 验证配置的事件类型与预期的内容生命周期事件匹配。
  4. webhook目标使用HTTPS URL。
  5. 切勿将实际的密钥值写入配置文件或源代码中。 使用描述性的占位符(例如
    REPLACE_WITH_CDN_SECRET
    ),并提示运维人员通过线下方式替换为真实凭证。密钥必须由运维人员通过安全部署流水线、环境变量或密钥管理工具进行管理,不得提交到文件中。
步骤5:实现入站webhook端点(如适用)
  1. 参考
    assets/http-service.template.ts
    作为初始脚手架。
  2. src/main/resources/services/<serviceName>/<serviceName>.ts
    路径下创建HTTP服务控制器。
  3. 导出
    post(req)
    函数,从
    req.body
    中解析传入的JSON payload。
  4. 解析前拒绝超过合理大小限制(例如1 MB)的payload。
  5. 处理前通过校验必填字段、鉴权头或HMAC签名验证入站payload的合法性。
  6. 在内容操作中使用外部payload的字符串字段前进行安全处理:去除首尾空格、强制最大长度、剥离或转义HTML/script内容,拒绝包含路径遍历序列(
    ..
    /
    \
    )的值。
  7. 使用预期字段名白名单,不要将原始payload对象直接传递给内容API。
  8. 返回合适的HTTP状态码:成功返回
    200
    、payload格式错误返回
    400
    、鉴权失败返回
    401
    、payload过大返回
    413
    、意外错误返回
    500
  9. 当入站payload触发内容创建或修改时,在上下文运行环境中使用lib-content或lib-node API确保权限正确。切勿将未经过滤的外部值作为内容名称、路径或键使用。
步骤6:通过lib-task连接异步处理(如适用)
  1. 当事件处理或webhook处理需要繁重或耗时的工作时,将其封装在lib-task的
    executeFunction()
    中。
  2. 长时间运行的任务使用
    progress()
    上报进度,方便监控。
  3. 阅读
    references/event-reference.md
    了解任务事件生命周期(
    task.submitted
    task.updated
    task.finished
    task.failed
    )。
步骤7:验证集成
  1. 执行
    node scripts/find-enonic-targets.mjs .
    确认项目仍可正常解析。
  2. 验证事件监听器已注册在应用启动时运行的
    main.ts
    main.js
    文件中。
  3. 确认出站HTTP调用使用HTTPS协议,且包含网络失败和非2xx响应的错误处理逻辑。
  4. 确认生成的源代码或配置文件中没有实际的密钥、API密钥或凭证,仅包含占位符。
  5. 确认入站webhook端点在将外部payload的字段传递给内容API前,已完成字段过滤和白名单校验。
  6. 如果创建了webhook配置文件,确认事件类型模式与预期触发条件匹配。
  7. 运行工作区构建验证无编译错误。
  8. 当事件未触发、webhook投递失败或入站请求被拒绝时,阅读
    references/troubleshooting.md

Error Handling

错误处理

  • If
    node scripts/find-enonic-targets.mjs .
    finds no projects, confirm that
    build.gradle
    references
    com.enonic.xp
    plugins or that a
    src/main/resources/site/
    directory exists.
  • If events do not fire after registering a listener, read
    references/troubleshooting.md
    to check listener registration location, event type patterns, and cluster vs. local event scope.
  • If outbound HTTP calls fail, verify the target URL, network access from the XP instance, and that the operator has substituted placeholder tokens with real credentials.
  • If inbound webhook requests return 404, confirm the service controller path follows
    services/<name>/<name>.ts
    and the application is deployed.
  • If background tasks fail silently, check task state using
    taskLib.list()
    and inspect logs for errors within the task function.
  • 如果
    node scripts/find-enonic-targets.mjs .
    未找到任何项目,确认
    build.gradle
    引用了
    com.enonic.xp
    插件,或存在
    src/main/resources/site/
    目录。
  • 如果注册监听器后事件未触发,阅读
    references/troubleshooting.md
    检查监听器注册位置、事件类型模式以及集群与本地事件作用域的差异。
  • 如果出站HTTP调用失败,验证目标URL、XP实例的网络访问权限,以及运维人员是否已将占位符替换为真实凭证。
  • 如果入站webhook请求返回404,确认服务控制器路径遵循
    services/<name>/<name>.ts
    格式,且应用已部署。
  • 如果后台任务静默失败,使用
    taskLib.list()
    检查任务状态,并查看日志中任务函数内的错误信息。