支付宝小程序集成

本文介绍如何将计算巢AI助手服务端集成和客户端集成两种模式以web-view方式集成到支付宝小程序,提供智能对话服务。

业务场景

在支付宝小程序内为用户提供智能客服、业务咨询或知识库查询等功能,以降低人工客服压力。通过将计算巢AI助手嵌入小程序,实现智能对话界面。

准备工作

创建AI助手实例

  1. 登录AppFlow控制台,在左侧导航栏中选择模型服务 > AI助手

  2. 点击创建AI助手,参考创建AI助手文档,完成AI助手的基本信息配置、模型配置等。

绑定自定义域名

AI助手提供可通过公网访问的合规入口地址。支付宝小程序要求web-view加载的业务域名必须完成ICP备案。此步骤先通过配置DNS A记录和 Nginx 完成域名验证,再将 DNS 记录修改为 CNAME 指向 AppFlow 服务。

创建子域名并添加A记录

  1. 创建子域名,参见添加解析记录添加一个A记录

    若域名非阿里云购买,可联系域名管理员创建子域名,或迁移域名解析至阿里云解析DNS后在DNS创建子域名。
  2. 登录云解析DNS-权威域名解析控制台,选择并单击域名。在解析设置页面单击添加记录,进行如下设置,并单击确定

    1. 记录类型:选择A。

    2. 主机记录:填写域名前缀,本节以poptest为例。

    3. 记录值:请填写IPv4地址,通常为您的Nginx服务器公网IPv4地址。

    image

支付宝小程序配置H5域名白名单

  1. 登录支付宝小程序 开放平台控制台 进入对应小程序开发设置详情页面,进入H5域名白名单页签。

    详细操作指引、使用限制及错误码解读可参见配置 H5 域名

    image

  2. 单击添加,在配置弹窗中,单击下载校验文件。image

  3. 获取校验文件并放置在配置域名根目录下,Nginx 的域名根目录可从配置文件中看到。image

  4. 将步骤1的子域名填入域名地址(格式为 https://your-domain-name), 根据页面提示确认验证文件可以正常访问。如果配置正确,则校验通过。补充其他配置信息,点击确定,完成白名单配置。

将子域名CNAMEAppFlow域名

  1. 登录云解析DNS-权威域名解析控制台,选择并单击已经添加的域名。

  2. 选择设置的主机记录,并单击操作列中的修改

    image

  3. 修改记录页面中进行如下设置,并单击确定

    1. 记录类型:选择CNAME。

    2. 主机记录:填写域名前缀,本节以poptest为例。

    3. 记录值:请填写CNAME指向的AppFlow域名,本节以1563457855438522.appflow.aliyunnest.com为例。

      说明

      AppFlow域名为集成Web页面配置部署信息中的访问地址 。

      image

    image

  4. 进入AppFlow-域名管理控制台,添加域名并绑定证书。

    1. 在域名管理页面,单击添加域名

    2. 将域名填写为申请的子域名,本文以poptest.appflow.aliyunnest.com为例。

    3. 设置您的HTTPS证书信息。

      image

      1. 你可使用阿里云提供的证书颁发和管理平台-数字证书管理服务购买并下载证书,详细操作,请参见使用个人测试证书(免费版)为Web站点开启HTTPS访问

        image

      2. 也可联系您的域名管理员获取证书。

    4. 单击提交完成添加。

      image

集成Web页面

集成核心是利用支付宝小程序的<web-view>组件加载AI助手的H5页面,可通过服务端集成或客户端集成。

特性

服务端集成 (推荐)

客户端集成

核心优势

集成简单,用户体验好。

前端独立,无需后端支持。

用户授权

无需重复授权,体验流畅。

可能需要用户重复授权。

信息扩展

可携带丰富的业务属性。

功能受限,不易扩展。

开发维护

  • 前端集成简单

  • 无需在云端维护密钥

  • 前端独立完成

  • 应用信息需要维护到阿里云。

信息是加密存储的,阿里云不会主动泄露您的密钥信息。

主要缺点

页面地址需由服务端改代码生成。

应用信息需要云上维护,用户体验稍差。

服务端集成(推荐)

通过业务服务端调用阿里云API,动态生成具备时效性的会话凭证(Token)。包含凭证的URL下发给小程序前端加载,实现安全访问。

架构与流程

image.jpeg

  1. AI助手设置登录配置为token方式。

  2. 小程序端调用服务端接口,获取web-view页面地址。

  3. 服务端用自己原有的方法获取到当前支付宝用户信息,调用阿里云API GenerateUserSessionToken - 生成登录会话Token,接口返回token,在AI助手页面上拼接上https://xxxxxx?access_session_token=xxxxxxxxxx, 将url返回前端。

  4. 小程序 web-view 的 URL 带上服务端生成的URL访问 H5 页面。

前端实现

可参考以下示例代码:

  • index.axml

    <view class="page">
      <view >  
        <web-view id="web-view-1" src="{{src}}" onMessage="onmessage"></web-view>
      </view>
    </view>
  • index.js

    Page({
      data:{
      },
      async onLoad(){
        this.webviewContext = my.createWebViewContext('web-view-1');
        this.getUrl();
      },
    
      getUrl() {
        // 调用服务端接口获取url
        const url = 调用服务端
        this.setData({
          src: url;
        });
      }
    })

服务端实现

可参考阿里云官方示例代码

image

客户端集成

配置AI助手集成信息

  1. 登录支付宝小程序开放平台,找到对应小程序,单击开发设置 > 查看,查看接口加签方式,获取AI助手需要配置支付宝集成信息包含应用ID、应用私钥、支付宝公钥。

image.png

  1. AppFlow集成页面,点击支付宝小程序,维护支付宝小程序凭据信息,选择要绑定的页面,点击按钮生成web页面,页面地址就是小程序web-viewsrc地址。

image.png

前端实现

支付宝前端需要实现以下几个方法

  1. 获取用户授权码:my.getAuthCodescopes: ['auth_base', 'auth_user']

  2. 如果AI助手需要用户信息:

    1. 上一步scops=auth_user,同时获取用户信息授权:my.getAuthUserInfo

    2. 实现监听方法onmessage,event type=userInfo,授权请求用户信息的message之后,将用户信息POSTAI助手页面,具体参考示例代码:

    • index.axml

      <view class="page">
        <view >  
          <web-view id="web-view-1" src="{{src}}" onMessage="onmessage"></web-view>
        </view>
      </view>
    • index.js

      Page({
        data:{
        },
        async onLoad(){
          this.webviewContext = my.createWebViewContext('web-view-1');
          this.login();
        },
        onmessage(event){
          console.log("接收到web-view消息", event.detail);
          if (event && event.detail && event.detail.type == 'userInfo') {
            this.getUserInfo();
          } 
        },
      
        // 向H5页面传递用户信息
        getUserInfo() {
          console.log("获取用户信息",this.data.userInfo)
          this.webviewContext.postMessage(
            {
              type: 'userInfo',
              data: {
                userName : this.data.userInfo.nickName,
                avatar : this.data.userInfo.avatar,
              }
            }
          )
        },
        login() {
          my.getAuthCode({
            // scopes: "auth_user"
            scopes: 'auth_user', // 或者 ['auth_base', 'auth_user']
            success: (res) => {
              console.log('获取授权码成功', res);
              console.log('授权码:', res.authCode);
              console.log('失败的授权类型:', res.authErrorScopes);
              console.log('成功的授权scope:', res.authSuccessScopes);
              // 设置用户信息
              my.getAuthUserInfo({
                fail: (error) => {
                  console.error('getAuthUserInfo', error);
                },
                success: (userInfo) => {
                  console.log(`userInfo:`, userInfo);
                  this.setData({
                    userInfo: userInfo,
                    src: "https://xxxxx/webhook/home/xxxxxx/index?code=" + res.authCode
                  });
                }
              });
            
            },
            fail: (error) => {
              console.log('获取授权码失败:', error);
            },
            complete: () => {
              console.log('接口调用完成(无论成功或失败)');
            }
          },  )
        }
      })