开发者文档 开发者文档
帮助中心 (opens new window)
帮助中心 (opens new window)
  • 渠道接入

    • Web 链接接入说明
    • Web-JS 接入说明
    • Android SDK
    • Android SDK V6
    • iOS SDK
    • iOS SDK V6
    • 微信小程序
    • 微信公众号
    • 企业微信
    • 微博私信
    • Flutter、DCloud、APICloud
    • 微信客服
    • CRM 对接方案
    • 在线客服 API
    • 在线统计 API
    • 在线机器人 API
    • 知识库 API
    • 电商平台 API
    • 客服组件SDK

    • 消息推送
    • 在线消息转发 API
    • 知识库V6 API
    • 在线机器人统计 API
    • 企业主动发送离线消息API
    • 规则引擎API
    • 大模型机器人API
    • 文本类产品 API
    • 渠道接入
    智齿科技
    2024-12-05
    目录

    CRM 对接方案

    # 功能概述

    配置 CRM 对接功能后,在用户进线时,客服系统会调用企业接口查询用户信息并存储至CRM,查询到的客户信息,将作为客户分组、路由策略的条件。 该功能价值如下:

    • 完善客户信息:对于三方渠道,不支持接口传参,可通过 CRM 对接功能,在客户进线时,调用企业业务系统 API 查询客户信息,如 WhatsApp 渠道,可根据客户手机号码查询调用企业 API 查询更多客户信息
    • 提升安全性:桌面网站和移动网站支持链接传入用户信息,但该方案安全性较低,升级 CRM 对接功能后,通过服务端查询用户信息,安全性更高

    # 对接流程说明

    该功能需要企业开发人员提供查询客户信息的接口,供客服系统调用以查询客户信息,详细流程如下:

    • 企业根据客服系统接口规范,提供查询客户信息 API
    • 在线客服-对接设置-对接客户信息,添加对接方案,配置生效的渠道、加密秘钥和查询客户信息 API
    • 用户进线时,读取渠道配置的 CRM 对接方案,根据 CRM 对接方案中配置的接口,通过手机号、Email 和 partnerid 查询客户信息,并将查询结果同步至客服系统 CRM

    # CRM 对接接口规范

    # ● 接口说明

    智齿在调用企业接口时,会对请求内容做AES加密,企业在响应时,也需要对返回数据加密。

    接口类型:回调型接口

    接口作用:通过「查询用户信息接口地址」+ 「partnerid/手机号/邮箱」查询用户信息,将查询到的用户信息,录入 CRM。

    请求方式:POST

    请求接口合法验证:

    1、请求企业接口时 header 中会传时间戳(取服务器时间 timestamp)、sign(签名) 2、sign 生成规则 MD5(companyId + timestamp + secretKey + parameter),parameter(AES 加密后的请求参数) 3、企业根据 header 中传的参数验证请求是否合法

    时间戳转换参考工具:

     http://tool.chinaz.com/Tools/unixtime.aspx
    
    1

    parameter 加密示例:

    例如,查询条件 email = "55612609866@163.com"; partnerid = "partnerId"; tel = "55612609866"; secretKey="secretKey" 。

    parameter = AESUtils.dcodes("{"email":"55612609866@163.com","partnerid":"partnerId","tel":"55612609866"}",secretKey) 为 1D6061B2D3E630351669C2A7FA96681E7D2F340484225A0EEF7D0065FF8D1FA4F42FDBCF8841CFA8F92C44026739C74D0A95AABEA0553274A0E393B891DAACD8EEF0A18B45A61F1807FF8EADD9D76132。

    sign 签名生成示例:

    例如,companyId = "1"; timestamp="1569397773"; secretKey="secretKey";parameter="1D6061B2D3E630351669C2A7FA96681E7D2F340484225A0EEF7D0065FF8D1FA4F42FDBCF8841CFA8F92C44026739C74D0A95AABEA0553274A0E393B891DAACD8EEF0A18B45A61F1807FF8EADD9D76132"。

    sign = Md5("11569397773secretKey1D6061B2D3E630351669C2A7FA96681E7D2F340484225A0EEF7D0065FF8D1FA4F42FDBCF8841CFA8F92C44026739C74D0A95AABEA0553274A0E393B891DAACD8EEF0A18B45A61F1807FF8EADD9D76132") 为 868b2fe841ca486e7344b0c15aac1e76。

    参数说明:

    参数 类型 必填 描述
    parameter String AES加密后的请求参数

    请求示例:

    「用户信息接口地址」需要客户配置,例如 https://xxxxxxx.xxxxxx.com/sobot/geUserInfo

    POST https://xxxxxxx.xxxxxx.com/sobot/geUserInfo HTTP/1.1
    Content-Type: application/json
    timestamp: 1569397773
    sign: 868b2fe841ca486e7344b0c15aac1e76
    
    {
        "parameter": "1D6061B2D3E630351669C2A7FA96681E7D2F340484225A0EEF7D0065FF8D1FA4F42FDBCF8841CFA8F92C44026739C74D0A95AABEA0553274A0E393B891DAACD8EEF0A18B45A61F1807FF8EADD9D76132"  // AES加密后的请求参数
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    返回参数加密:

    1、企业收到请求后,先校验 sign,再对 parameter 进行解密。 2、企业使用与智齿客服系统约定好的 secretKey(如secretKey)对收到的 parameter 字段进行解密,得到原始请求数据。

    parameter 解密示例:

    例如,接收到的 parameter = "1D6061B2D3E630351669C2A7FA96681E7D2F340484225A0EEF7D0065FF8D1FA4F42FDBCF8841CFA8F92C44026739C74D0A95AABEA0553274A0E393B891DAACD8EEF0A18B45A61F1807FF8EADD9D76132"。

    解密示例: AESUtils.ecodes("1D6061B2D3E630351669C2A7FA96681E7D2F340484225A0EEF7D0065FF8D1FA4F42FDBCF8841CFA8F92C44026739C74D0A95AABEA0553274A0E393B891DAACD8EEF0A18B45A61F1807FF8EADD9D76132",secretKey)

    解密结果:

    {"email":"55612609866@163.com","partnerid":"partnerId","tel":"55612609866"}

    data 加密示例:

    例如,查询出的客户信息为 {"uname":"su0012","realname":"su0012","email":"55612609866@163.com","tel":"55612609866","remark":"Regular customer, interested in premium services.","customer_fields":"{\"4a069df0fd4d49298041240bf15e47c8\":\"123\"}","is_vip":"1","vip_level":"","user_label":"0fd208364e3a4c67954027680002a89e"}

    data = AESUtils.dcodes("{"uname":"su0012","realname":"su0012","email":"55612609866@163.com","tel":"55612609866","remark":"Regular customer, interested in premium services.","customer_fields":"{\"4a069df0fd4d49298041240bf15e47c8\":\"123\"}","is_vip":"1","vip_level":"","user_label":"0fd208364e3a4c67954027680002a89e"}",secretKey)

    加密结果: 8DD8EF1E018180C11E287594A1751B095B44EC2029160C96D58305BD536A9DCBB09591D1D708B22E39A041FE06C149C0A7E10381B67770BF97872B9C125847050A9EAE9990323AFFDCD06DC5EC5736FF007545D07099B761DD66BF6268E91EB5BF67907EE9509D24BA3F95E6F7BAE77D575E762612E58D866B00DFA3587B113F73593866A4026EB88A78996FF71A894705024F4DD743D794129CFBA7A14BE410F1C7D87A80F9CFAFF877A53115E1D35C4D8C14A19EA66C52ABD7240B3CA28B301808802FF21B2F072E006F0408C807BF94CFA2109515746DF9697B6597228A7E0B3E7C6907D3EFBBF79F14040FD2450EE9122B813AD0B47BA2DFC0DA406956FB90361A8073E19832AF1C49E6F9CA37F863376417D472CE6AC02D2CAA34BCA3B4DDCF3DEF3C61922AC6DEE6F107F42F44

    返回示例:

    {
        "data":"8DD8EF1E018180C11E287594A1751B095B44EC2029160C96D58305BD536A9DCBB09591D1D708B22E39A041FE06C149C0A7E10381B67770BF97872B9C125847050A9EAE9990323AFFDCD06DC5EC5736FF007545D07099B761DD66BF6268E91EB5BF67907EE9509D24BA3F95E6F7BAE77D575E762612E58D866B00DFA3587B113F73593866A4026EB88A78996FF71A894705024F4DD743D794129CFBA7A14BE410F1C7D87A80F9CFAFF877A53115E1D35C4D8C14A19EA66C52ABD7240B3CA28B301808802FF21B2F072E006F0408C807BF94CFA2109515746DF9697B6597228A7E0B3E7C6907D3EFBBF79F14040FD2450EE9122B813AD0B47BA2DFC0DA406956FB90361A8073E19832AF1C49E6F9CA37F863376417D472CE6AC02D2CAA34BCA3B4DDCF3DEF3C61922AC6DEE6F107F42F44"
    }
    
    1
    2
    3

    没有查询到客户信息时返回示例:

    {
        "data":""
    }
    
    1
    2
    3
    # ● 用户身份和资料字段
    参数 类型 必填 描述
    uname String 否 昵称
    realname String 否 真实姓名
    email String 否 邮箱账号
    tel String 否 手机或电话
    remark String 否 备注
    customer_fields String 否 自定义字段(后台控制)
    is_vip Number 否 是否为VIP客户 0: 普通客户,1: VIP客户 默认普通客户
    vip_level String 否 VIP等级对应的id(id值通过上方'查询客户固定字段信息'接口获得),若传入为普通客户字段则即使传入了VIP等级字段也无效
    user_label String 否 客户标签对应的id(id值通过上方'查询客户固定字段信息'接口获得)
    # ● AES对称加解密工具类
    /**
     * AES对称加密和解密
     */
    public class AESUtils {
    
        private static final Logger log = LoggerFactory.getLogger(AESUtils.class);
    
        /**
         * <p>Discription:[加密]</p>
         * @param content 明文 用JSON.toJSONString(Map<String, String> map)转换的json字符串
         * @param key 加解密规则 访客系统提供key
         * @return String 密文
         */
        public static String ecodes(String content, String key) {
            if (content == null || content.length() < 1) {
                return null;
            }
            try {
                KeyGenerator kgen = KeyGenerator.getInstance("AES");
                SecureRandom random=SecureRandom.getInstance("SHA1PRNG");
                random.setSeed(key.getBytes());
                kgen.init(128, random);
                SecretKey secretKey = kgen.generateKey();
                byte[] enCodeFormat = secretKey.getEncoded();
                SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
                Cipher cipher = Cipher.getInstance("AES");
                byte[] byteContent = content.getBytes("utf-8");
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
                byte[] byteRresult = cipher.doFinal(byteContent);
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < byteRresult.length; i++) {
                    String hex = Integer.toHexString(byteRresult[i] & 0xFF);
                    if (hex.length() == 1) {
                        hex = '0' + hex;
                    }
                    sb.append(hex.toUpperCase());
                }
                return sb.toString();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * <p>Discription:[解密]</p>
         * @param content 密文
         * @param key 加解密规则
         * @return String 明文
         */
        public static String dcodes(String content, String key) {
            if (content == null || content.length() < 1) {
                return null;
            }
            if (content.trim().length() < 19) {
                return content;
            }
            byte[] byteRresult = new byte[content.length() / 2];
            for (int i = 0; i < content.length() / 2; i++) {
                int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16);
                int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2), 16);
                byteRresult[i] = (byte) (high * 16 + low);
            }
            try {
                KeyGenerator kgen = KeyGenerator.getInstance("AES");
                SecureRandom random=SecureRandom.getInstance("SHA1PRNG");
                random.setSeed(key.getBytes());
                kgen.init(128, random);
                SecretKey secretKey = kgen.generateKey();
                byte[] enCodeFormat = secretKey.getEncoded();
                SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
                Cipher cipher = Cipher.getInstance("AES");
                cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
                byte[] result = cipher.doFinal(byteRresult);
                return new String(result);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    上次更新: 2024/12/10 16:38:52

    ← 微信客服 在线客服 API→

    最近更新
    01
    运营支持 API
    03-03
    02
    大模型机器人API
    09-09
    03
    LINE API
    06-25
    更多文章>
    Theme by Vdoing
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式