渠道接入

如何接入

原理:在您的页面上点击某个链接跳转到多商户聊天页面。

该链接的地址:https://mchat.udesk.cn/web_client/index.html

后面需要跟一些参数,下面是参数列表

参数名 说明 是否必须
customer_euid 客户euid,由您指定,只能是字母数字下划线
customer_name 客户姓名,由您指定
merchant_euid 我们提供给您的商户euid
tenant_id 我们提供给您的租户id
product_title 咨询对象的标题
product_url 咨询对象的链接
product_image 咨询对象的图片
product_其他 咨询对象的其他信息,“其他”两字可以替换为任意文字
page 如果值为detail,将直接显示聊天界面

通过构造URL接入

在页面上创建一个<a>标签

<a href="https://mchat.udesk.cn/web_client/index.html?customer_euid=xxx&customer_name=xxx&merchant_euid=xxx&tenant_id=xxx&product_title=xxx&product_url=http://xxx.com&product_image=http://xxx.com/xxx.jpg&product_%E4%BB%B7%E6%A0%BC=%EF%BF%A5100&product_%E5%85%B6%E4%BB%96=xxx" target="_blank">联系我们</a>

通过我们提供的js接入

把下面的代码复制到您的</body>之前,参数请按照参数列表的说明替换为正确的值。

<script>
  window.udesk_config = {
    'customer_euid':'xxx',
    'customer_name':'xxx',
    'merchant_euid':'xxx',
    'tenant_id':'xxx',
    'product_title':'xxx',
    'product_url':'http://xxx.com',
    'product_image':'http://xxx.com/xxx.jpg',
    'product_价钱':'¥100',
    'product_其他':'xxx',
    'page':'detail'  //有该参数将直接进入聊天界面
  }

  (function(u, d) {
    var script = d.createElement('script');
    script.setAttribute('type', 'text/javascript');
    script.setAttribute('src', 'https://mchat.udesk.cn/web_client/client-entry.js');
    d.body.appendChild(script);
  })(window, window.document);
</script>

Android SDK接入

1.导入multichat

  Add this in your root build.gradle file (not your module build.gradle file):

    allprojects {
  repositories {
        maven { url "https://jitpack.io" }
    }
   }

2.快速使用

1初始化

出于安全的考虑,建议租户将 key 保存在自己的服务器端,App 端通过租户提供的接口获取经过 SHA1 计算后的加密字符串(sign)和时间戳(timestamp),时间戳精确到秒,然后传给 SDK。密码的有效期为时间戳 +/- 5分钟

SHA1("租户uuid+租户key+时间戳")加密字符粗的格式

// String uuid 租户ID,Udesk后台系统获取

//String timestamp 时间戳,由你们后端返回

//String sign 签名,由你们后端返回

//customer_euid 用户ID是用户的唯一标示,请不要重复,并且只允许使用数字、字母、数字+字母

UdeskSDKManager.getInstance().init(content, uuid, sign, time); UdeskSDKManager.getInstance().setCustomerInfo(customer_euid, customer_name);

备注:签名生成规则:建议由客户的服务端提供接口计算签名并返回对应的参数 | 数据名称 | 说明 | |-----------|-----------------------------------------| | uuid | Udesk后台提供 | | secret | Udesk后台提供 | | timestamp | 获取精确到秒的时间戳 |

sign = SHA1("uuid+secret+timestamp")

2 客户通过某个商品详情页点击咨询按钮直接和客服进行会话

  //进入会话可以设置咨询对象 (可选)
 //设置咨询的商品 如下:
private void createProducts() {
    Products products = new Products();
    Products.ProductBean productBean = new Products.ProductBean();
    productBean.setImage("http://img14.360buyimg.com/n1/s450x450_jfs/t3157/63/1645131029/112074/f4f79169/57d0d44dN8cddf5c5.jpg?v=1483595726320");
    productBean.setTitle("Apple iPhone 7");
    productBean.setUrl("http://item.jd.com/3133829.html?cu=true&amp;utm_source…erm=9457752645_0_11333d2bdbd545f1839f020ae9b27f14");
    List<Products.ProductBean.ExtrasBean> extras = new ArrayList<>();

    Products.ProductBean.ExtrasBean extrasBean = new Products.ProductBean.ExtrasBean();
    extrasBean.setTitle("价格");
    extrasBean.setContent("¥6189.00");

    extras.add(extrasBean);
    productBean.setExtras(extras);
    products.setProduct(productBean);

    UdeskSDKManager.getInstance().setProducts(products);

}

//如果不需要咨询对象显示 UdeskSDKManager.getInstance().setProducts(null);

//通过商户ID,咨询商户 // merchantId 商户ID UdeskSDKManager.getInstance().entryChat(content, merchantId);

//提供了历史对话商户列表,提供ConversationFragment,可根据你们app加入,参见demo。

3.获取历史对话商户列表


 //提供了历史对话商户列表,提供ConversationFragment,可根据你们app加入,参见demo。

4.获取指定的商户的未读消息


  UdeskSDKManager.getInstance().getMerchantUnReadMsg(merchant_euid,merchantUnreadMsgCnt)

5.查询所有商户未读消息


    UdeskSDKManager.getInstance().setItotalCount(new ItotalUnreadMsgCnt() {
                @Override
                public void totalcount(final int count) {

                }
            });
    UdeskSDKManager.getInstance().getUnReadMessages();

6.设置在线状态下收到消息的监听事件


       UdeskSDKManager.getInstance().setMessageArrived(new IMessageArrived() {
                @Override
                public void onNewMessage(final ReceiveMessage receiveMessage) {

                }
            });

7.设置咨询对象的回调


        UdeskSDKManager.getInstance().setCommodityCallBack(new ICommodityCallBack() {
                @Override
                public void callBackProduct(Products products) {


                }
            });

8.设置商品信息

商品信息属性 存放在ProductMessage类中;


public class ProductMessage implements Serializable {


    /**
     * name :  Apple iPhone X (A1903) 64GB 深空灰色 移动联通4G手机
     * url : https://item.jd.com/6748052.html
     * imgUrl : http://img12.360buyimg.com/n1/s450x450_jfs/t10675/253/1344769770/66891/92d54ca4/59df2e7fN86c99a27.jpg
     * params : [{"text":"¥6999.00","color":"#FF0000","fold":false,"break":false,"size":12},{"text":"满1999元另加30元"}]
     */

    /**
     * 商品名称
     */
    private String name;
    /**
     * 商品跳转链接(新页显示),如果值为空,则不能点击
     */
    private String url;
    /**
     * 商品显示图片的url
     */
    private String imgUrl;

    /**
     * 参数列表
     */
    private List<ParamsBean> params;


  public static class ParamsBean {
        /**
         * text : ¥6999.00
         * color : #FF0000
         * fold : false
         * break : false
         * size : 12
         */

        /**
         * 参数文本
         */
        private String text;
        /**
         * 参数颜色值,规定为十六进制值的颜色
         */
        private String color;

        /**
         * 是否粗体
         */
        private boolean fold;
        /**
         * 是否换行
         */
        @SerializedName("break")
        private boolean breakX;
        /**
         * 字体大小
         */
        private int size;



    使用方式 可以参考demo :
    1 直接进入会话界面后 设置传入商品信息 :
     // 直接进入会话界面后 设置传入商品信息
         UdeskSDKManager.getInstance().setProducts(products);


    2 通过导航栏的方式 发送商品消息:
      UdeskConfig.isUseNavigationView = true;
            UdeskSDKManager.getInstance().setNavigationModes(getNavigations());
            UdeskSDKManager.getInstance().setNavigationItemClickCallBack(new INavigationItemClickCallBack() {
                @Override
                public void callBack(Context context, ChatActivityPresenter mPresenter, NavigationMode navigationMode) {
                    if (navigationMode.getId() == 1) {
                        mPresenter.sendProductMessage(createProduct());
                    }
                }
            });

    private List<NavigationMode> getNavigations() {
      List<NavigationMode> modes = new ArrayList<>();
      NavigationMode navigationMode1 = new NavigationMode("发送商品消息发送商", 1);
      modes.add(navigationMode1);
      return modes;
    }

9.离线推送


//App 进入后台时,开启Udesk推送

调用 UdeskSDKManager.getInstance().setCustomerOffline(false);

建议 在application中registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks activityLifecycleCallbacks)来控所有前后台逻辑

10.退出断开xmpp链接


//退出登录时 断开xmpp链接

UdeskSDKManager.getInstance().logout();

11.图片上传压缩配置


     在UdeskConfig类中
    //上传图片是否使用原图 还是缩率图
    public static  boolean isScaleImg = true;

    //缩放图 设置宽高最大值,如果超出则压缩,否则不压缩
    public static  int ScaleMax = 1024;

12.混淆配置

//udesk
-keep class udesk.** {*;}
-keep class cn.udesk.**{*; }

//oss
-keep com.alibaba.sdk.**{*; }
-keep com.google.gson.**{*; }
-keep org.jxmpp.**{*; }
-keep  de.measite.minidns.**{*; }

//eventbus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

//smack
-keep class org.jxmpp.** {*;}
-keep class de.measite.** {*;}
-keep class org.jivesoftware.** {*;}
-keep class org.xmlpull.** {*;}
-dontwarn org.xbill.**
-keep class org.xbill.** {*;}

//retrofit2

# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions



//eventbus
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

//glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
  **[] $VALUES;
  public *;
}

# for DexGuard only
-keepresourcexmlelements manifest/application/meta-data@value=GlideModule

-keep class com.github.chrisbanes.** {*;}

-dontwarn okio.**
-dontwarn com.squareup.okhttp.**
-dontwarn okhttp3.**
-dontwarn javax.annotation.**
-dontwarn com.android.volley.toolbox.**
-dontwarn com.facebook.infer.**


 //其它
-keep class com.tencent.bugly.** {*; }

iOS SDK接入

1.导入SDK

1.1 引入依赖库

1.2 注意事项

<key>NSCameraUsageDescription</key>

<string>App需要访问您的相机</string>

<key>NSMicrophoneUsageDescription</key>

<string>App需要访问您的麦克风</string>

<key>NSPhotoLibraryAddUsageDescription</key>

<string>App需要为您添加图片</string>

<key>NSPhotoLibraryUsageDescription</key>

<string>App需要访问您的相册</string>

2.快速使用

引入 ‘ #import <UdeskMChatSDK/UdeskMChatSDK.h>’

在AppDelegate、或者登陆成功之后里初始化SDK

签名生成规则:
出于安全的考虑,建议租户将 key 保存在自己的服务器端,App 端通过租户提供的接口获取经过 SHA1 计算后的加密字符串(sign)和时间戳(timestamp),时间戳精确到秒,然后传给 SDK。密码的有效期为时间戳 +/- 5分钟 SHA1("租户uuid+租户key+时间戳")加密字符粗的格式
数据名称 说明
uuid Udesk后台提供
secret Udesk后台提供
timestamp 获取精确到秒的时间戳
sign = SHA1("uuid+secret+timestamp")
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

  UMCSystem *system = [UMCSystem new];
  //租户ID,Udesk后台系统获取
  system.UUID = @"a04d138d-98fb-4b9d-b2a7-478b7c0c1ce9";
  //时间戳,由你们后端返回
  system.timestamp = @"timestamp";
  //签名,由你们后端返回
  system.sign = @"sign";

  UMCCustomer *customer = [UMCCustomer new];
  //用户ID是用户的唯一标示,请不要重复,并且只允许使用数字、字母、数字+字母
  customer.euid = @"用户ID";
  customer.name = @"用户姓名";

  [UMCManager initWithSystem:system customer:customer completion:^(NSError *error) {
       NSLog(@"%@",error);
  }];
}

在合适的地方添加商户列表View

UMCMerchantsView *merchats = [[UMCMerchantsView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) sdkConfig:[self getConfig]];
[self.view addSubview:merchats];

- (UMCSDKConfig *)getConfig {

    UMCSDKConfig *config = [UMCSDKConfig sharedConfig];

    UMCSDKStyle *styly = [UMCSDKStyle defaultStyle];
    config.sdkStyle = styly;

    return config;
}

进入聊天页

客户通过某个商品详情页点击咨询按钮直接和客服进行会话
UMCSDKManager *sdkManager = [[UMCSDKManager alloc] initWithMerchantId:@"商户ID"];
sdkManager.sdkConfig = [self getConfig];
[sdkManager pushUdeskInViewController:self completion:nil];

- (UMCSDKConfig *)getConfig {

    UMCSDKConfig *config = [UMCSDKConfig sharedConfig];

#warning 这里写死了单个商品的咨询对象,实际开发中可根据需求自定义
    UMCProduct *product = [[UMCProduct alloc] init];
    product.title = @"iPhone X";
    product.image = @"https://g-search3.alicdn.com/img/bao/uploaded/i4/i3/1917047079/TB1IfFybl_85uJjSZPfXXcp0FXa_!!0-item_pic.jpg_460x460Q90.jpg";
    product.url = @"http://www.apple.com/cn";

    UMCProductExtras *extras = [[UMCProductExtras alloc] init];
    extras.title = @"标题";
    extras.content = @"¥9999";

    product.extras = @[extras];

    config.product = product;

    UMCSDKStyle *styly = [UMCSDKStyle defaultStyle];
    config.sdkStyle = styly;

    return config;
}

3.商品消息

UMCSDKManager *sdkManager = [[UMCSDKManager alloc] initWithMerchantId:@"商户ID"];
sdkManager.sdkConfig = [self getConfig];
[sdkManager pushUdeskInViewController:self completion:nil];

- (UMCSDKConfig *)getConfig {

    UMCSDKConfig *config = [UMCSDKConfig sharedConfig];

    UMCCustomButtonConfig *customButton = [[UMCCustomButtonConfig alloc] initWithTitle:@"自定义按钮" clickBlock:^(UMCCustomButtonConfig *customButton, UMCIMViewController *viewController){

        //点击自定义按钮回调
        //示例里直接在回调里发送了商品消息,开发者可以根据自己需求进行修改
        [viewController sendGoodsMessageWithModel:[self getGoodsModel]];
    }];

    config.showCustomButtons = YES;
    config.customButtons = @[customButton];

    UMCSDKStyle *styly = [UMCSDKStyle defaultStyle];
    config.sdkStyle = styly;

    return config;
}

- (UMCGoodsModel *)getGoodsModel {

    UMCGoodsModel *goodsModel = [[UMCGoodsModel alloc] init];
    goodsModel.goodsId = @"12";
    goodsModel.name = @"Apple iPhone X (A1903) 64GB 深空灰色 移动联通4G手机";
    goodsModel.url = @"https://item.jd.com/6748052.html";
    goodsModel.imgUrl = @"http://img12.360buyimg.com/n1/s450x450_jfs/t10675/253/1344769770/66891/92d54ca4/59df2e7fN86c99a27.jpg";

    UMCGoodsParamModel *paramModel1 = [UMCGoodsParamModel new];
    paramModel1.text = @"¥6999.00";
    paramModel1.color = @"#FF0000";
    paramModel1.fold = @(1);
    paramModel1.udBreak = @(1);
    paramModel1.size = @(14);

    UMCGoodsParamModel *paramModel2 = [UMCGoodsParamModel new];
    paramModel2.text = @"满1999元另加30元";
    paramModel2.color = @"#c2fcc3";
    paramModel2.fold = @(1);
    paramModel2.size = @(12);

    UMCGoodsParamModel *paramModel3 = [UMCGoodsParamModel new];
    paramModel3.text = @"但是我会先提价100";
    paramModel3.color = @"#ffffff";
    paramModel3.fold = @(1);
    paramModel3.size = @(20);

    goodsModel.params = @[paramModel1,paramModel2,paramModel3];

    return goodsModel;
}

4.离线推送

//App 进入后台时,关闭Udesk推送
- (void)applicationDidEnterBackground:(UIApplication *)application {

    __block UIBackgroundTaskIdentifier background_task;
    //注册一个后台任务,告诉系统我们需要向系统借一些事件
    background_task = [application beginBackgroundTaskWithExpirationHandler:^ {

        //不管有没有完成,结束background_task任务
        [application endBackgroundTask: background_task];
        background_task = UIBackgroundTaskInvalid;
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        //根据需求 开启/关闭 通知
        [UMCManager startUdeskMChatPush];
    });
}

//App 进入前台时,开启Udesk推送
- (void)applicationWillEnterForeground:(UIApplication *)application {
  [UMCManager endUdeskMChatPush];
}

5.接口说明

1.接受消息代理
//添加当前类为代理,
[[UMCDelegate shareInstance] addDelegate:self];
//实现接受消息方法
- (void)didReceiveMessage:(UMCMessage *)message {
    NSLog(@"%@",message);
}

//移除代理
[[UMCDelegate shareInstance] removeDelegate:self];
2.未读消息回调
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(msgUnreadCountHasChange:) name:UMC_UNREAD_MSG_HAS_CHANED_NOTIFICATION object:nil];

- (void)msgUnreadCountHasChange:(NSNotification *)notif {
    [UMCManager merchantsUnreadCountWithEuid:nil completion:^(NSInteger unreadCount) {

        UINavigationController *nav = self.tabBarController.viewControllers[1];
        nav.tabBarItem.badgeValue = [NSString stringWithFormat:@"%ld",unreadCount];
        if (unreadCount == 0) {
            nav.tabBarItem.badgeValue = nil;
        }
    }];
}

其他API参考UMCManager.h