互客鱼 返回主站

WordPress 和 WooCommerce

WooCommerce 深层链接

当 WooCommerce 在 WordPress 站点上激活时,hukeyu 插件解锁了一个深度集成,远远超出标准内容同步: 登录购物者上下文、lookup_order 工具、 优惠券发射和应用、潜在客户推送,以及 abandoned_cart 触发器。

如果 WooCommerce 未加载,这些端点都不会触发 — 插件将每个 WC 依赖的钩子推迟到 woocommerce_loaded 操作, 因此字母顺序的插件加载顺序无关紧要。

WooCommerce 加载顺序竞争

许多 v2.0.0 之前的 WordPress 集成有一个微妙的 bug: 它们在 plugins_loaded 优先级 10 调用 class_exists('WooCommerce'),并在检查返回 false 时静默禁用 WC 功能。 在集成插件按字母顺序在 woocommerce/ 之前加载的站点上 (例如 hukeyu < woocommerce), WooCommerce 主类在优先级 10 时尚未注册 → false → 集成损坏且没有错误消息。

hukeyu v2.0.0 使用两层防护:

if (function_exists('did_action') && did_action('woocommerce_loaded') > 0) {
    $this->bootWoo();   // WC 已加载 — 立即连接。
} else {
    add_action('woocommerce_loaded', [$this, 'bootWoo'], 10);
}

woocommerce_loaded 在 WC 主类完全注册后触发, 因此在 bootWoo() 运行时,每个 class_exists('WooCommerce') 检查都能确定性地通过。

登录购物者上下文

当 WooCommerce 客户登录并访问加载小部件的页面时, 插件将短期签名的 data-shopper-token 附加到小部件脚本标签上。 小部件将其转发到 /api/v1/widget/init;互客鱼验证它并将 wp_user_id + email_hash 声明烘焙到聊天会话的小部件 JWT 中。

Token 中编码的内容:

  • wp_user_id — WordPress 用户 ID(整数,在 token 中作为字符串发送)。
  • email_hash — 小写电子邮件的 SHA-256。绝不是原始电子邮件。
  • source — 字面量 "wordpress"
  • exp — unix 时间戳,约 24 小时后过期,因此同一个 token 在正常浏览会话期间有效。

Token 使用工作区的 shopper_signing_secret 签名 (每个 token 的明文,由插件在第一次握手时捕获)。 错误的签名会被静默丢弃 — 访客仍然匿名聊天,不会出现错误。

lookup_order 工具

EcommercePreset 的 order_status 能力映射到一个真正的工具。 当访客询问订单、运输、退货或退款时,LLM 可能会调用 lookup_order(limit, order_number?)。该工具:

  1. 读取对话中存储的购物者声明(在 /widget/init 设置)。
  2. 解析智能体的 woocommerce_products Source 的 site_url
  3. 从任何活动的工作区 API token 中提取 shopper_signing_secret
  4. 将 HMAC 签名的主体 POST 到 {site_url}/wp-json/hukeyu/v1/orders/lookup,硬超时 5 秒。
  5. 将订单负载原样返回给 LLM 供其总结。

拒绝路径(不触发回调):

  • 对话中没有购物者声明 → not_signed_in。LLM 要求访客登录。
  • 没有 woocommerce_products source → no_wordpress_source
  • 没有带有 signing secret 的活动 API token → no_signing_secret

插件的 OrderLookupController 最多返回 10 个订单(默认 5 个), 每个订单包含 id、number、status、total、currency、items 数组、 跟踪 URL(尽力通过 AfterShip、ST tracking、通用 _tracking_url meta), 以及客户的订单查看 URL。

如果访客询问特定订单,则过滤到 order_number — 插件在客户 ID 查询后过滤结果集,因此您永远不会暴露其他客户的数据。

潜在客户推送

当聊天智能体捕获潜在客户(访客留下电子邮件或提交潜在客户表单)时, 互客鱼将联系人镜像回 WordPress 站点:

触发器发生什么
LeadCapturedEvent PushLeadToWordPress 排队监听器触发。它解析智能体的 WordPress 或 WooCommerce source,使用工作区的 shopper signing secret 签名 HMAC 主体,并 POST 到 /wp-json/hukeyu/v1/leads
WP 接收调用 如果 WooCommerce 激活,插件通过 wc_create_new_customer 创建 WC 客户。否则创建 WP subscriberhukeyu_lead_id + hukeyu_conversation_id 进入用户 meta,因此店主可以将 WP 用户与互客鱼转录相关联。

在电子邮件上幂等:同一地址的第二次推送会更新现有用户的 first_namebilling_phonehukeyu_lead_idhukeyu_conversation_id meta, 而不是创建重复用户。传输失败被记录并吞没 — 监听器永远不会阻塞访客的聊天回合。

优惠券发射和应用

电子商务智能体可以在聊天回复中发出 <coupon/> 块, 当访客的意图与活动的 WC 优惠券行匹配时。完整的数据流:

  1. 插件的 CouponSyncer 在每次产品同步后运行,枚举发布状态的 shop_coupon 帖子,过滤过期/超限的,并将快照 POST 到 /api/v1/wp/coupons/sync
  2. 互客鱼将列表持久化在 source 的 config['coupons'] 数组上(最多 50 个)。
  3. PromptBuilder 在为电子商务智能体组装系统提示词时读取它们。LLM 获得完整的代码列表和明确的指令,永远不要发明代码。
  4. 当 LLM 决定优惠券对访客有帮助时,它会发出 XML 标记:<coupon code="WELCOME10" label="10% off your first order" discount="10%"/>
  5. InlineBlockParser 提取标记后流并发出类型为 coupon_cardblock SSE 事件。
  6. 小部件的 blocks.tsx 渲染器实现一个带有 Copy 按钮(将代码写入剪贴板)和 Apply 按钮的卡片。
  7. Apply 按钮 POST 到互客鱼上的 /api/v1/widget/coupon/apply
  8. 互客鱼使用工作区的 shopper signing secret 对主体进行 HMAC 签名,并将其转发到 WP 站点上的 /wp-json/hukeyu/v1/cart/coupon
  9. 由于 REST 请求通常没有加载的 WC()->cart,插件将代码暂存在 15 分钟的 transient 中:hukeyu_pending_coupon_{conversation_id}
  10. 在访客的下一个页面加载时,插件的 woocommerce_load_cart_from_session 钩子通过 hukeyu_conv_id cookie(由小部件在初始化时设置)读取 transient 并调用 WC()->cart->apply_coupon($code)
  11. 成功应用后删除 transient;过期的 transient 在 15 分钟后自动清理。

最终结果:访客在聊天中点击 Apply, 走到购物车页面,看到折扣行已经应用 — 无需复制粘贴,不会错过代码。

弃购重新互动

BehaviorRule.kind = "abandoned_cart" 允许您 重新互动购物车闲置的访客。

将购物车状态镜像到 localStorage

当 WooCommerce 激活时,插件在每个前端页面上排队 cart-state.js。 它将每个 WC jQuery 购物车事件镜像到 localStorage.hukeyu_cart_state

{
  "items": 2,           // 运行计数
  "timestamp": 1715472000000  // 上次变更以来的毫秒数
}

监听:

  • added_to_cart jQuery 事件 → 增加计数,刷新时间戳。
  • removed_from_cart jQuery 事件 → 减少;如果 <= 0 则清除。
  • DOM click.add_to_cart_button / .single_add_to_cart_button 上作为无 jQuery 回退。
  • URL 路径名包含 /checkout/order-received/order-pay/thank-you → 完全清除购物车状态。

存储失败(私有浏览、配额耗尽)是静默无操作 — 触发器只是不会为该访客触发。

配置触发器

在智能体的 Behavior triggers 管理员页面上, 添加一个类型为 abandoned_cart 的新规则:

{
  "kind": "abandoned_cart",
  "conditions": { "idle_minutes": 5 },
  "action": {
    "kind": "open_with_message",
    "message": "Still thinking it over? Happy to help you decide — want a hand?"
  }
}

小部件的 TriggerEngine 每 30 秒轮询 localStorage 条目 (并在挂载时立即轮询一次)。当它发现比规则的 idle_minutes 阈值更旧的非空购物车时,它会触发规则的操作 — 通常是主动互动气泡。

仍然适用 5 分钟的全局触发器冷却时间,因此访客不会在每个页面转换时被伏击。

页面上下文负载(用于 Woo 产品)

When the visitor is on a single-product page (is_product()), the plugin enriches the data-page-context JSON with a woo object:

{
  "source": "wordpress",
  "page_url": "https://shop.example/product/blue-tee",
  "post_id": 142,
  "post_type": "product",
  "permalink": "…",
  "categories": ["tees", "summer"],
  "tags": [],
  "woo": {
    "id": 142,
    "sku": "T-BLU-M",
    "name": "Blue tee",
    "permalink": "https://shop.example/product/blue-tee",
    "price": "29.00",
    "regular_price": "39.00",
    "sale_price": "29.00",
    "currency": "USD",
    "stock_status": "instock",
    "on_sale": true
  }
}

小部件将其折叠到检索信封中,因此智能体优先处理访客当前所在页面的内容 (块分数上的当前页面提升 +0.15)。

支持哪些 WooCommerce 版本?

插件的 WooCommerce 依赖项都在稳定的公共类上:

  • WC_Coupon — WC 2.0 起公开。
  • WC_Product — WC 2.0 起公开。
  • WC_Order — WC 2.0 起公开。
  • WC_Customer + wc_create_new_customer — WC 2.5 起公开。
  • wc_get_products — WC 2.7 起公开。
  • wc_get_orders — WC 2.7 起公开。

有效最低版本:WooCommerce 3.0+。 插件在 8.x 和 9.x 上积极测试。 HPOS(高性能订单存储)受支持,因为插件使用公共的 wc_get_orders() + WC_Order API, 而不是直接读取订单帖子。