注册
环信即时通讯云

环信即时通讯云

单聊、群聊、聊天室...
环信开发文档

环信开发文档

Demo体验

Demo体验

场景Demo,开箱即用
RTE开发者社区

RTE开发者社区

汇聚音视频领域技术干货,分享行业资讯
技术讨论区

技术讨论区

技术交流、答疑
资源下载

资源下载

收集了海量宝藏开发资源
iOS Library

iOS Library

不需要辛辛苦苦的去找轮子, 这里都有
Android Library

Android Library

不需要辛辛苦苦的去找轮子, 这里都有

第二届Gopher大会将在京举办,环信小伙伴们等你来!

2015年Go中国在上海举行了第一届Gopher大会,那一次大会参会人员在500人左右,会后大家都觉得这是参加过的最实在,最物超所值,干货最多的大会。这里有去年参会的人员写的一些回顾,大家可以体会当时的情形。 http://thinkandcode.info...
继续阅读 »
2015年Go中国在上海举行了第一届Gopher大会,那一次大会参会人员在500人左右,会后大家都觉得这是参加过的最实在,最物超所值,干货最多的大会。这里有去年参会的人员写的一些回顾,大家可以体会当时的情形。

http://thinkandcode.info/gopherchina2015can-hui-ji-lu/


http://fuxiaohei.me/2015/4/29/gopher-china-2015.html


http://life.leanote.com/post/gopher-china-2015-my-golang-way


说了那么多,回到2016年这一届的大会,因为北京可以说是中国的互联网中心,这里有着大量的Go使用者,而且我去年也答应了很多北京的同学,说明年一定来北京,为了当初的承诺,所以我们来了。北京可以说是一个开大会巨贵的地方,我们年前就一直在寻找会议场所,交通便利又要价格适当,但是北京这样的地方没有,最后我们只能硬着头皮签了一个价格高的不那么离谱的地方,但是必须保证交通便利,吃喝玩乐方便的地方。所以我们选择了亚洲大酒店。目前这个地点我还是比较满意的。

给大家看看我们今年的Logo和给大家准备的T恤


640.webp_.jpg




640.webp_(1)_.jpg


说完这个回到我们最重要的内容安排上,这一次我还是邀请了大量的一线工程师来给大家分享Go的经验,举行的行程大家看下面:


4月16日周六

08:20-8:50 入场报到
08:50-9:00 大会介绍
09:00-09:10 主办方致辞
09:10-10:00 陈辉,蚂蚁金服 Go在数据挖掘的应用
10:05-10:55 刘奇,PingCAP Go在分布式数据库中的应用
11:00-11:50 许式伟,七牛 待定
13:10-14:00 孙宏亮,DaoCloud Go在分布式docker里面的应用
14:05-14:55 Marcel,Google Go如何解决i18n和i13n问题
14:55-15:15 茶歇
15:15-16:05 米嘉,宜信 Go如何构建Web应用
16:10-17:00 邓洪超,CoreOS Go在分布式系统的性能调试和优化
17:05-17:55 沈晟,心动网络 Golang在移动客户端开发中的应用
20:15-22:00 Gopher技术沙龙party, 七牛和DaoCloud联合赞助举办
 
4月17日周日

09:00-09:50 Dave Cheney How to Write high performance application
09:55-10:45 吴小伟,阿里云 Go在CDN系统的应用
10:50-11:40 陶春华,百度 Go在百度bfe的应用
13:00-13:50 毛剑,哔哩哔哩 Go在数据存储上面的应用
13:55-14:45 高步双,小米 Go在小米网运维平台的应用与实践
14:45-15:05 茶歇
15:05-15:55 孙建良,网易 Go在网易广域网上传加速系统中的应用
15:55-16:45 Paul Dix,influxdb 待定


最后欢迎大家踊跃报名,我们这一次安排了800-1000人的场地,相比于去年规模大了一倍,我一直怀着把这个大会做成一个party的心态,所以我们的每一个细节都是希望给嘉宾、赞助商、参会者带来兴奋点。当然这样的一个大会光靠我一个人肯定是搞不定的,要特别感谢七牛的妹子们给我很大的帮助,感谢合作伙伴环信的大力支持,感谢各位好友的鼎力相助,我坚信今年的大会一定还会做成一个让大家难忘的大会。


合作伙伴


640.webp_(2)_.jpg



注册参会请点击“阅读原文”
↓↓↓
阅读原文 收起阅读 »

既然一切不能解决问题的客服都是纸老虎,如何才能做好“新时代客服”?

一切都是为了更有效率地沟通,尤其在机器人介入之后,人的工作变得更复杂了。 “普通话请按 1,For English Press 2……”你耐着性子听完一大堆话,等着那句“转人工服务请按 0”,它出现的时候,你毫不犹豫地按了 0。 这样的场景可能每个...
继续阅读 »


一切都是为了更有效率地沟通,尤其在机器人介入之后,人的工作变得更复杂了。


“普通话请按 1,For English Press 2……”你耐着性子听完一大堆话,等着那句“转人工服务请按 0”,它出现的时候,你毫不犹豫地按了 0。

这样的场景可能每个人都很熟悉,它让人思考消费者寻求客户服务的本质。很多时候,人们并不是想找客服,而是希望解决问题。无论是出于咨询、投诉还是别的需求,和机器纠缠可能效率低下,找人说几句明白话反而来得更方便。但事实上,当一个消费者沉浸在一个互联网产品里(不管是 App 还是网站),Ta 拿起电话沟通的意愿很可能不太高。换句话说,要不是产品里设置的机器人服务无法令人满意,谁都不想去排队听《致爱丽斯》,然后按一个“0”。
 



345ca40eaa53.jpg


2014 年双 11,中国邮政速递物流呼叫中心


随着更多服务的细化(很多需求是被创造出来的,比如追踪快递的进程。你能想象这个服务出现之前,你会主动了解你买的货物到了哪里,以及为什么在某一个地方停留过久吗?),客服这个行当已经不能仅仅用售前、售后之类的名词来区分,准确的说法应该是,如何第一时间满足用户的信息需求,就应该有怎样的客服形式。

我们拿这个问题去问阿里巴巴的客户服务事业部总监汪海,他简略地概括了客服的整个发展过程,可能也是这个行业的发展过程,“我们开通了 PC(客服)系统、帮助中心;再后来,无线时代到了,用户有往无线渠道转移的倾向。只要打开手机淘宝,他就很容易找到客服入口。”“阿里意识到,服务是流量的组成部分,接下来十年,体验是整个电商的重要因素。”

2011 年携程旅游网扩建南通呼叫中心的时候,应该也不会想到客服行业的变化会来得那么快。才四年,8 万平方米 12000 个服务坐席,宏伟壮观的全球最大旅游业服务呼叫中心,到今天,还增加了一个个有“微领队”的微信群。

举个例子,有一批游客购买了去马尔代夫的产品,微领队就发短信给他们让他们加群。在这个群里你就能提问任何信息,既包括携程的产品,也包括目的地玩乐推荐。负责解答问题的微领队、一线员工童琳对《好奇心日报》说,他手里 20 个群左右,旺季(春节)每个群一百多人、平时 30、40 个人。

在携程,这样的微领队的总数不到 100 人。携程旅游事业部 COO 喻晓江表示,电话坐席目前占 7 成,剩下的 2~3 成是其他形式,但现在也慢慢模糊,“(我们正在)试图培养全工种的客服。市场和客服人员也需要教育”。
 



93bbb7dba1d6.jpg


微领队


客服行业,企业的投入成本和产品形式、与消费者沟通的方式都在发生变化。尽管一切宗旨依然指向效率,但如今的客服牵涉更多的品牌意义——这也是“让机器人客服更像个有血有肉的人”的意义,换句话说,无论使用机器,还是真人,企业都竭力让消费者在解决问题的过程中感受到它们的特点,如果说“细节决定成败”,这可能是最有代表性的一点。

我们分解了一下“新时代客服”的若干特点及其背后的原因。你会看到,以上变革正在越来越快地发生。

大部分情况下,机器人可以解决效率问题

智能机器人客服的存在意义就像语音功能之于电话客服一样。它的面貌通常是一个交互式的帮助中心,以防一些找不到 FAQ 的网友耽误客服人员的时间。拥有开发团队的大公司往往会自主研发智能机器人,淘宝有阿里小蜜、京东则称之为 JIMI 智能服务体系,根据赵鹏亿的说法,这套 JIMI 系统花了京东 3 年时间迭代生成,研发团队有 80 人,而 JIMI 的服务能力在高峰时期等同于京东所有人工客服。


赵鹏亿是 2011 年加入京东的。从一线客服人员做起工作了八年,现在是京东全国客服中心成都分中心的总监。“2010 年我们的电话客服接通率是非常困难的,每个月增加 1 倍的人力,但是用户需求每个月增加 10 倍。”在那个网络客服的蛮荒时代,大公司急需全新的手段改善服务的供需失衡,希望用户能够“生活自理”的客服机器人+帮助中心的组合,就是分流的主要手段之一。
 



ab447323395c.jpg


JIMI 客服机器人


以双 11 的极端客服高峰为例,商家自己的客服能力远不足以应付 1 对 30 的顾客,智能机器人的价值在于,只要把店铺的信息填进标准模板,商家就拥有了一个专属的客服机器人。

“机器人”更深的一层含义则和我们熟悉的“互联网+”有关。假设一名乘客用 Uber 叫了辆车,发生了意外情况,取消订单后 APP 仍然给他扣了款。在找不到客服电话的情况下,此时正确的申诉流程是在 APP 的“帮助”里找到“收费有误”并提交,没多久你就能收到退款邮件。Uber 对此的官方解释是:“乘客在 APP 里可以完成大部分申诉、提问的操作,只有最后一步(退款)需要我们的员工来完成。”

公司们把每一种服务场景都细分出来,是对解决问题的进一步模拟。大众点评里,餐馆定位有一个按钮,催单有一个按钮,而很多电商会特别注重优化评价体系,你甚至可以快速找到已经有购买记录的陌生网友提问,而不用重复一遍“加为好友”的过程。

与此同时,人的工作正在变得更复杂

王丽杰在陌陌担任客服主管,她对《好奇心日报》说:“不断学习才能跟得上,请个长假,我根本跟不上一个月两次的版本迭代”。而“微领队”童琳的说法则是,“为游客解答目的地玩乐的难题,价值肯定比一名开发票的在线客服要高一点。”他负责携程的新加坡目的地,那些客人在网上查得到的问题,他都不用解答了,换句话说,他要知道的东西更“偏”,也更多了。

目前中国从事客服的大约有 1000 多万人,社会和企业对这一行的认知在发生变化。“打字速度 60/min 以上”可能只是最基础的要求,京东赵鹏亿说:“客服人员的角色已经从原来的帮你催单、退款、查询延迟原因,逐渐朝服务专家、产品专家去转型。”

当简单的东西年复一年被机器代替,沉淀下来的问题都是更复杂的。“我该穿多大码”、“这个新疆阿克苏苹果真的甜吗”,这些问题现在都抛给了网络客服。这些服务过程也伴随着商机的转化,他们实际上提供的是一种售前导购服务——介绍产品,引导购买,消除网购的不信任感。

苹果店 Genius Bar 的员工,同样会去 Call Center 接一阵子的电话,保证前后台的技术水平同步。之所以人们觉得 AppleCare 的客服体验好,就是因为他们真的很了解产品。基层的客服人员更了解用户需求,迅速接触全端的生产体系,于是当社会招聘无法满足公司人才需求的时候,客服人员就可以为公司输出基层管理人才,比如京东每年招聘几百人的服务之星,就能在一年多后成长为运营体系中的管理层。


2fbc3d2301c8.jpg


除了面对消费者时客服人员开始处理更复杂的问题,因为和产品开发离得更近,客服部门本身也开始发挥作用。在去年 9 月的一次媒体采访中,阿里巴巴首席客户服务官戴珊透露了集团内部 APP 的新功能 “九点电台”——其本质是让庞大的组织机构扁平化——当集团客服发现一个有共性的行为,就可以点一个叫做“拉铃”的按钮,把案例分享到九点电台,这些建议业务部门的同事都能看到,它们如果足够重要,最终可能就会变成一个可优化的点。“我们几千个服务的小二不仅是解决问题,它还能作为内容输送到各个部门去。”汪海说。
 



5006535173d8.jpg


阿里集团内部 APP,九点电台的入口


客服社交化,最重要的特点可能是语言

“京东互助体系”是一个典型的社交化案例,它的本质是借助一些用户的力量解决另一些用户的需求。目前这个测试中的产品主要集中在母婴领域。京东会设立公共讨论的话题(比如关于某款奶粉),培养购物达人。根据赵亿鹏透露的数字,电话客服只能一对一,一个在线人员最多同时处理 6-8 个用户,但一个话题可以影响的用户的平均数字在 3000+左右,“里面有活跃发言的,也有沉默浏览的。单从服务的角度看,它是很有效的。”
 



40d629bef880.jpg


商品下的购买咨询


而客服使用的语言(很多时候是机器人被设定的语言),最大的目的是拉近与客户的距离。微博名为“周小帅私房菜”的大 V 有一百万粉丝,主打菜品就是小龙虾。他在微博的认证居然是“知名搞笑幽默达人”,而不是“卖小龙虾的”。翻翻他的微博,大部分都是他和顾客的聊天记录,多为搞笑的对话和段子,每次回复都会附上一个“恼火”的表情,这就是他营销自己的方式。


21e2b69d21cf.jpg


2016 年 1 月底,某卫浴品牌旗舰店因为接待了 438 名留学生提问而火了。一道美国大学生数学建模竞赛关于浴缸放水的题被学生丢给了卫浴客服,越来越多网友来调戏后,店家的自动回复已经变成了“亲,浴缸常用尺寸有 1.5 米到 1.8 米的,厚度是 2 公分,热传导系数根据学生回答是 0.19 左右,一小时温度下降 5 度左右……询问学生太多,所以回复可能会稍微有点慢。”

个性化的客服语言还是主要出现在社交网络上,一旦面对的用户量级增大,公司则倾向于保守应对。至于这些噱头之所以能成为卖点,归根结底,人们固然贪图网购的方便,可也怀念面对面交流的人情味,而人情味,在互联网上永远是稀缺的。

大数据应该是帮助形成解决方案的支持者

如果你打过顺丰快递或者麦当劳的电话,你肯定已经知道了他们会假装了解你。比如记录你的地址、点单偏好之类。

其实大数据的最佳使用方式是用来记录用户复杂行为。比如京东开发的用户画像系统就可以根据用户的操作记录判断优先级——比如说你已经点了催促订单,之后如果系统再接到注册用号码的电话,首先就判断它可能是一个催单的问题,然后看订单时间判断是否延期,如果正常,则交由在线服务机器人或普通客服,如果已经超时,一名擅长处理疑难杂症的资深客服就会准备好接这个电话。

还有就是平台沉淀下来的用户信用记录。在客服层面,交易平台的信用积累能起到减轻网购风险的作用。阿里巴巴客服事业部总监汪海向我们介绍了这个已经进行了近两年的机制:“当你信用等级够高,只要你发起退货,这个钱就马上能到你账上。”在可以应用于极速退款的场景,信用等级有权力简化客服的流程,先赔付、再处理后续。对商家也一样,当信用好的商家遭到恶意投诉,平台就会要求消费者提供更多的证据。


0ebfc0d2a564.jpg


客服不一定总是希望帮你解决问题

我们打算用一个经典的故事来结束本文。

原《纽约时报》记者乔·塞拉诺在 2006 年曾说:“顾客支持服务在电子消费产业中是个弃儿”。事实也是如此,有一度,公司希望你在买完产品之后就不要去打扰他们,所以用相当节省成本的方式解决问题。一个美国消费者听到印度口音的售后服务接线员打招呼说“先生你好”,也没什么好奇怪的。

不过乔·塞拉诺有另一个洞察。

他的音乐播放器 iPod 坏了,而且他打定主意要修一修。

所以他费尽千辛万苦找到了客服电话,然后得到了“再买一台”的真诚建议。他坚持不懈,最后发现可以填一份表格,把机器寄回去修理——苹果公司为此索价 250 美元,外加税收。


89b4d960f1fa.jpg


换句话说,苹果根本无意维修。乔·塞拉诺引用了投资人安迪·凯斯勒(Andrew Kessler)的话解释了一下,“一个电话每分钟就花去公司 75 美分,一个小时就要花45 美元“,然后他说:“一方面,因为音乐播放器的价格远比电脑的价格来得低,苹果公司有更强烈的动机, 不让人们打电话进来;一台本来有赢利的音乐播放器,因一个长途电话反而变得没有什么利润可言。修理甚至在保修期内的音乐播放器,也没有任何经济意义。苹果公司仅仅只是给您寄来一台新的而已。”

这个故事在一本叫做《绅士与无赖》的书里,探讨的是公司客服成本的秘密。
 
 
本文转载自《好奇心日报》,作者:朱凯麟。您可以点击阅读原文跳转。 收起阅读 »

环信直播课堂第一期 知识点干货分享和项目代码

以下为直播中记录的干货笔记,视频中写的webim集成项目在文章末尾附件下载Q:心跳的支持 A:连接成功的回调里面启动心跳 Q:环信发消息是否需要好友关系呢 A:不需要的 ,知道对方id就可以直接聊天 var options = { ...
继续阅读 »
以下为直播中记录的干货笔记,视频中写的webim集成项目在文章末尾附件下载
Q:心跳的支持
A:连接成功的回调里面启动心跳

Q:环信发消息是否需要好友关系呢
A:不需要的 ,知道对方id就可以直接聊天
var options = {
//to : to,
to:'msgto',
msg : msg,
type : "chat"
};

Q:输入空消息的判断
A: var sendText = function() {
// if (textSending) {
// return;
//}

Q:自动登陆的 实现
A:$(function()
{
login();
}

)

Q:用户token 的登陆
A://根据用户名密码登录系统
conn.open({
apiUrl : Easemob.im.config.apiURL,
user : user,
// pwd : pass,
accessToken : "YWMtV8DgQt97EeWInF-xEd80TgAAAVRl-FixEr0I5NWLkYFefpM919W5-JU1Uvc",
//连接时提供appkey
appKey : Easemob.im.config.appkey
});

Q:多网页的共存
A:var resource_value = Math.floor(Math.random()*1000);
// var resource_value = "webim";

Q:刷新或者退出网页的时候提示
A: $(function() {
$(window).bind('beforeunload', function() {
if (conn) {
conn.close();
if (navigator.userAgent.indexOf("Firefox") > 0)
return ' ';
else
return '';
}
});
});

Q:低版本ie是否支持
A:支持ie789+,在调试的过程中需要本地配置服务

集成移动客服的时候,IM 服务号是干嘛的呢
A:
1:在客服后台绑定一个关联
指定一个im服务号

2:客户端联系客服的时候,写个按钮“联系客服”
调用了发消息的方法,接收对象 to=关联里面的 im服务号
消息发送过去之后 会到客服后台,根据分配策略分配给对应的客服

Q:网站集成环信移动客服
A:在</body>标签前加入这段代码
<script src='//kefu.easemob.com/webim/easemob.js?tenantId=327&hide=false' async='async'></script>

Q:这个按钮进行自定义
A:首先,将已嵌入网站中的JS插件代码中的hide=false修改为hide=true:(确保tenantId为自己的)
<a href="javascript:;" onclick="easemobIM()" tenantId=0000>自定义按钮</a>

Q:自定义联系客服的界面
A:[url]https://github.com/easemob/kefu-webim[/url]
 
直播中写的项目代码下载 ↓ ↓ 收起阅读 »

环信:发送头像和昵称(从消息扩展中获取)

昵称和头像 注意:以下是在官方Demo3.0的基础上修改的。官方Demo下载地址 环信提供了获取头像和昵称的两种方式:方法一 从APP服务器获取昵称和头像 昵称和头像的获取:当收到一条消息(群消息)时,得到发送者的用户ID,然后查找手机本地数据库是否有此...
继续阅读 »
昵称和头像

注意:以下是在官方Demo3.0的基础上修改的。官方Demo下载地址

环信提供了获取头像和昵称的两种方式:
方法一 从APP服务器获取昵称和头像

昵称和头像的获取:当收到一条消息(群消息)时,得到发送者的用户ID,然后查找手机本地数据库是否有此用户ID的昵称和头像,如没有则调用APP服务器接口通过用户ID查询出昵称和头像,然后保存到本地数据库和缓存,下次此用户发来信息即可直接查询缓存或者本地数据库,不需要再次向APP服务器发起请求

昵称和头像的更新:当点击发送者头像时加载用户详情时从APP服务器查询此用户的具体信息然后更新本地数据库和缓存。当用户自己更新昵称或头像时,也可以发送一条透传消息到其他用户和用户所在的群,来更新该用户的昵称和头像。

方法二 从消息扩展中获取昵称和头像

昵称和头像的获取:把用户基本的昵称和头像的URL放到消息的扩展中,通过消息传递给接收方,当收到一条消息时,则能通过消息的扩展得到发送者的昵称和头像URL,然后保存到本地数据库和缓存。当显示昵称和头像时,请从本地或者缓存中读取,不要直接从消息中把赋值拿给界面(否则当用户昵称改变后,同一个人会显示不同的昵称)。

昵称和头像的更新:当扩展消息中的昵称和头像URI与当前本地数据库和缓存中的相应数据不同的时候,需要把新的昵称保存到本地数据库和缓存,并下载新的头像并保存到本地数据库和缓存。


本文主要介绍第二种方法:给消息添加扩展,用于携带昵称和头像信息。先来看下效果:



1163763-27c154f8d8a20e13.gif


效果图


在消息发送时,设置并发送扩展消息

1:因为是在官方Demo里修改的,但对其还不熟悉,咋办呢?

其实,环信是基于XMPP优化而来的,而XMPP消息又是基于XML的。已经知道在XMPP里扩展消息的方式了,这里应该也是类似的。只不过首先要找到发送消息的时机。可是我不知道在哪?这里要善用搜索和断点。下面简要的说下我的思路:在项目里搜索【消息】,找到了EaseChatToolbar.h中的- (void)didSendText:(NSString *)text;方法(别问我为什么是这个方法,不会告诉你我也是查了很久的)。然后在.m中该方法处设置断点,运行程序,输入文字后点击发送按钮。然后看看程序执行的流程是什么。依次向上修改方法,添加头像和昵称信息。如图:



1163763-d32c3f012208e4e4.png


工程截图



2:修改- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
中的调用方法。并设定头像和昵称字典,代码如下:
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if ([text isEqualToString:@"\n"]) {
if ([self.delegate respondsToSelector:@selector(didSendText:)]) {
//注释掉的 -- [self.delegate didSendText:textView.text];
//新增头像和昵称扩展
NSDictionary *ext = @{@"accountName":accountName,@"img":@"http://7xo30v.com1.z0.glb.clouddn.com/animal.png"};
[self.delegate didSendText:textView.text withExt:ext];
//结束
self.inputTextView.text = @"";
[self _willShowInputTextViewToHeight:[self _getTextViewContentH:self.inputTextView]];;
}
return NO;
}
return YES;
}

3:从新运行程序,发送消息,查看日志。在<body>元素里包含了额外添加的昵称和头像信息。如下:
ChatDemoJCV1[17136:720f] SEND: <message type="chat" to="easemob-demo#chatdemoui_zlanchun1@easemob.com" id="151a0fcc287">
<body>{"ext":{"img":"http://7xo30v.com1.z0.glb.clouddn.com/animal.png","accountName":"zlanchun"},"to":"zlanchun1","bodies":[{"type":"txt","msg":"You"}],"from":"zlanchun"}</body></message>

4:在聊天框中显示消息里地头像和昵称。因为是测试,所以在ChatViewController.m直接将消息中的昵称和头像赋值给视图(实际应用中不推荐这么做,正如环信方法二缺点所说的,需要自己缓存,从本地提取信息)
- (UITableViewCell *)messageViewController:(UITableView *)tableView cellForMessageModel:(id<IMessageModel>)model
{
if (model.bodyType == eMessageBodyType_Text ) {
NSString *CellIdentifier = [CustomMessageCell cellIdentifierWithModel:model];
//发送cell
CustomMessageCell *sendCell = (CustomMessageCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (sendCell == nil) {
sendCell = [[CustomMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier model:model];
sendCell.selectionStyle = UITableViewCellSelectionStyleNone;
}
//设定头像和昵称
model.avatarURLPath = model.message.ext[@"img"];
model.nickname = model.message.ext[@"accountName"];
sendCell.model = model;
return sendCell;
}
return nil;
}
最后,这里只是修改了text类型消息的扩展,还有其他几种类型的消息扩展也可以按照这样来处理。
 
本篇集成文章由环信热心开发者提供,作者主页取水 收起阅读 »

用Facebook登录你的APP

项目中有个第三方登录的模块,这也是目前很常见的需求,但国内做Facebook登录的并不多,所以轮到Facebook的时候上网查了下,资料少之又少,通过科学上网的方法访问developer.facebook.com之后发现Facebook登录非常简单明了,这里与...
继续阅读 »
项目中有个第三方登录的模块,这也是目前很常见的需求,但国内做Facebook登录的并不多,所以轮到Facebook的时候上网查了下,资料少之又少,通过科学上网的方法访问developer.facebook.com之后发现Facebook登录非常简单明了,这里与大家分享一下。
 
第一步

首先你要申请一个Facebook APP ID,至于申请方法不是这里要讨论的重点,先过。这个APP ID要放在AndroidManifast.xml文件里。
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/application_id" />
这样就OK了。

第二步

还是在AndroidManifast.xml里,声明下
Activity。<activity android:name="com.facebook.FacebookActivity" android:exported="true" android:label="@string/app_name" android:theme="@android:style/Theme.Translucent.NoTitleBar" />
注意这里有个android:exported="true",不要忘了加,这句的意思是当前Activity是否可以被另一个Application的组件启动:true允许被启动;false不允许被启动。

第三步

写个登录按钮,这地方也有个小小的坑。Facebook有提供一个按钮叫LoginButton的玩意,直接添加到xml文件里即可。下面这段代码就是Facebook提供的。
<com.facebook.login.widget.LoginButton android:id="@+id/login_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="30dp" android:layout_marginBottom="30dp" />
但是这个按钮居然没法修改,设置背景文字之类的都不生效,LoginButton类里也没提供相关的按钮属性修改方法。于是乎最后还是放弃使用LoginButton,自己写个吧。

第四步

导入Facebook的jar。用Android studio的话也很简单了。在build.gradle的dependencies里添加:
compile 'com.facebook.android:facebook-android-sdk:4.6.0'

第五步

万事俱备,我们只要写个activity来调用API测试下就好了。
public class FacebookLoginDemo extends Activity implements View.OnClickListener {
private static String TAG = "FacebookLoginDemo";

private Button mFbLoginBtn;
private CallbackManager callbackManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
FacebookSdk.sdkInitialize(getApplicationContext());
callbackManager = CallbackManager.Factory.create();
LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
@Override
public void onSuccess(LoginResult loginResult) {
Toast.makeText(FacebookLoginDemo.this, "facebook_account_oauth_Success", Toast.LENGTH_SHORT);
Log.e(TAG, "token: " + loginResult.getAccessToken().getToken());
//TODO:got the token,Notify server,and do something
}

@Override
public void onCancel() {
Toast.makeText(FacebookLoginDemo.this, "facebook_account_oauth_Cancel", Toast.LENGTH_SHORT);
}

@Override
public void onError(FacebookException e) {
Toast.makeText(FacebookLoginDemo.this, "facebook_account_oauth_Error", Toast.LENGTH_SHORT);
Log.e(TAG, "e: " + e);
}
});
}

private void initViews() {
mFbLoginBtn = (Button) findViewById(R.id.fbLoginBtn);
mFbLoginBtn.setOnClickListener(this);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}

@Override
protected void onResume() {
super.onResume();
AppEventsLogger.activateApp(this);
}

@Override
protected void onPause() {
super.onPause();
AppEventsLogger.deactivateApp(this);
}

@Override
public void onClick(View v) {
if (v.getId() == R.id.fbLoginBtn) {
AccessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken accessToken = AccessToken.getCurrentAccessToken();
if (accessToken == null || accessToken.isExpired()) {
LoginManager.getInstance().logInWithReadPermissions(this, Arrays.asList("public_profile", "user_friends"));
}
}
}
}

简单分析下代码,点击登录的时候会跳转到FacebookActivity,然后做些权限授权之类的操作,成功后页面finish(),回调到onActivityResult里的callbackManager,onSuccess()里会拿到登录授权信息,一般来说拿到token就好了,再拿着token去告诉自己的服务器,授权登录Facebook成功,然后do something,大功告成。
  收起阅读 »

以前可以在客服系统历史会话中看到访客与客服的所有聊天内容,现在不行了,为什么?

当前版本(客服系统v4.3)是单会话的,即只记录本次会话内容,不会把之前的历史内容给加上。如果展示该访客的全部会话内容,则上下滚动翻阅记录时,会出现和左边列表不对应的问题;另外,当点击某访客以前的某条会话时,不能定位到那条会话相应的聊天记录上,造成客服迷惑。因...
继续阅读 »
当前版本(客服系统v4.3)是单会话的,即只记录本次会话内容,不会把之前的历史内容给加上。如果展示该访客的全部会话内容,则上下滚动翻阅记录时,会出现和左边列表不对应的问题;另外,当点击某访客以前的某条会话时,不能定位到那条会话相应的聊天记录上,造成客服迷惑。因为现在默认定位到该访客的最新一条消息 收起阅读 »

环信关于昵称和图片的问题。android

环信关于昵称和图片的问题。当你去跟技术交流的时候,他们一般会给你这样一个网页,http://www.imgeek.org/article/825307638。让你自忆去看,其它他说的已经很明白了,对于大神来进。但是对于菜鸟的我还是云里雾里,于是脑补各种知识。看...
继续阅读 »
环信关于昵称和图片的问题。当你去跟技术交流的时候,他们一般会给你这样一个网页,http://www.imgeek.org/article/825307638。让你自忆去看,其它他说的已经很明白了,对于大神来进。但是对于菜鸟的我还是云里雾里,于是脑补各种知识。看大神留下的工程。查看我反正说的就是要写一个getUser的具体实现。我就试试看的心里乱写一气,最后成功了。我是修改了easeui中的代码
MainActivity.java,代码如下:

package com.easemob.easeuisimpledemo.ui; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import android.R.integer; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.view.View; import android.widget.Button; import android.widget.TextView; import com.easemob.chat.EMConversation; import com.easemob.easeui.EaseConstant; import com.easemob.easeui.controller.EaseUI; import com.easemob.easeui.domain.EaseUser; import com.easemob.easeui.ui.EaseBaseActivity; import com.easemob.easeui.ui.EaseContactListFragment; import com.easemob.easeui.ui.EaseContactListFragment.EaseContactListItemClickListener; import com.easemob.easeui.ui.EaseConversationListFragment; import com.easemob.easeui.ui.EaseConversationListFragment.EaseConversationListItemClickListener; import com.easemob.easeui.utils.EaseCommonUtils; import com.easemob.easeuisimpledemo.R; public class MainActivity extends EaseBaseActivity{ private TextView unreadLabel; private Button[] mTabs; private EaseConversationListFragment conversationListFragment; private EaseContactListFragment contactListFragment; private SettingsFragment settingFragment; private Fragment[] fragments; private int index; private int currentTabIndex; Map<String, EaseUser> contactsMap = new HashMap<String, EaseUser>(); @Override protected void onCreate(Bundle arg0) { super.onCreate(arg0); setContentView(R.layout.activity_main); unreadLabel = (TextView) findViewById(R.id.unread_msg_number); mTabs = new Button[3]; mTabs[0] = (Button) findViewById(R.id.btn_conversation); mTabs[1] = (Button) findViewById(R.id.btn_address_list); mTabs[2] = (Button) findViewById(R.id.btn_setting); // 把第一个tab设为选中状态 mTabs[0].setSelected(true); conversationListFragment = new EaseConversationListFragment(); contactListFragment = new EaseContactListFragment(); settingFragment = new SettingsFragment(); contactListFragment.setContactsMap(getContacts()); contactsMap=getContacts(); conversationListFragment.setConversationListItemClickListener(new EaseConversationListItemClickListener() { @Override public void onListItemClicked(EMConversation conversation) { startActivity(new Intent(MainActivity.this, ChatActivity.class).putExtra(EaseConstant.EXTRA_USER_ID, conversation.getUserName())); } }); contactListFragment.setContactListItemClickListener(new EaseContactListItemClickListener() { @Override public void onListItemClicked(EaseUser user) { startActivity(new Intent(MainActivity.this, ChatActivity.class).putExtra(EaseConstant.EXTRA_USER_ID, user.getUsername())); } }); fragments = new Fragment[] { conversationListFragment, contactListFragment, settingFragment }; // 添加显示第一个fragment getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, conversationListFragment) .add(R.id.fragment_container, contactListFragment).hide(contactListFragment).show(conversationListFragment) .commit(); EaseUI easeUI = EaseUI.getInstance(); //需要easeui库显示用户头像和昵称设置此provider easeUI.setUserProfileProvider(new EaseUI.EaseUserProfileProvider() { @Override public EaseUser getUser(String username) { if (contactsMap == null) { return null; } Iterator<Map.Entry<String, EaseUser>> iterator = contactsMap.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, EaseUser> entry = iterator.next(); //兼容以前的通讯录里的已有的数据显示,加上此判断,如果是新集成的可以去掉此判断 if (!entry.getKey().equals("item_new_friends") && !entry.getKey().equals("item_groups") && !entry.getKey().equals("item_chatroom") && !entry.getKey().equals("item_robots")) { if (entry.getKey().equals(username)) { //不显示黑名单中的用户 return entry.getValue(); } } } return null; } }); } /** * button点击事件 * * @param view */ public void onTabClicked(View view) { switch (view.getId()) { case R.id.btn_conversation: index = 0; break; case R.id.btn_address_list: index = 1; break; case R.id.btn_setting: index = 2; break; } if (currentTabIndex != index) { FragmentTransaction trx = getSupportFragmentManager().beginTransaction(); trx.hide(fragments[currentTabIndex]); if (!fragments[index].isAdded()) { trx.add(R.id.fragment_container, fragments[index]); } trx.show(fragments[index]).commit(); } mTabs[currentTabIndex].setSelected(false); // 把当前tab设为选中状态 mTabs[index].setSelected(true); currentTabIndex = index; } /** * 临时生成的数据,密码皆为123456,可以登录测试接发消息 * @return */ private Map<String, EaseUser> getContacts(){ Map<String, EaseUser> contacts = new HashMap<String, EaseUser>(); for(int i = 1; i <= 10; i++){ EaseUser user = new EaseUser("easeuitest" + i); contacts.put("easeuitest" + i, user); } EaseUser user = new EaseUser("xu"); user.setNick("xujianxiang"); user.setAvatar("http://happysports.jianxingquyundong.com/image/5,112347a89bf2"); contacts.put("xu", user); user = new EaseUser("shen"); user.setNick("shenxiaojuan"); user.setAvatar("http://happysports.jianxingquyundong.com/image/5,112347a89bf2"); contacts.put("shen", user); return contacts; } }
仅献给跟我一样的菜鸟,看了应该会懂, 收起阅读 »

环信自助式社交大数据平台V1.0 上线!--判断APP的核心用户活动状况和用户在APP中的社交稳定性

亲爱的环信用户: 您好,环信IM大数据平台1.0版本现在已经上线,内容涉及12个指标组共48个指标,希望能在数据展示和分析上,给您的产品带来更大的帮助。 环信IM大数据平台是基于环信IM系统的数据平台。通过分析,整理和挖掘用户之间的IM关系,判断APP的核心...
继续阅读 »
亲爱的环信用户:

您好,环信IM大数据平台1.0版本现在已经上线,内容涉及12个指标组共48个指标,希望能在数据展示和分析上,给您的产品带来更大的帮助。
环信IM大数据平台是基于环信IM系统的数据平台。通过分析,整理和挖掘用户之间的IM关系,判断APP的核心用户活动状况和用户在APP中的社交稳定性,产出对客户有价值的参考结果。
 
———————————————————登       陆————————————————————
◆环信IM用户直接登录
1.官网登录&gt;我的应用&gt;点击“进入我的IM数据平台&gt;&gt;&gt;”


page1.png


2.直接进入d.easemob.com登陆进入(请使用环信即时通讯云账号登陆哟~)

注:本期仅对日IM消息500+用户开放。
——————————————————进入平台—————————————————————
◆接受用户补充协议,进入IM大数据平台


page2.png


在应用概况页,可以对指标组进行操作,即删除某个指标组,单击右上角的删除按钮        即可实现。当您浏览指标组卡片时,鼠标hover到指标名称时,会弹出相应的解释气泡,帮助您去理解这个数据的含义。概况页面最多只能显示5个指标组哟~

———————————————————内       容—————————————————————
◆进入“指标组”,定制选择指标组卡片
滑动开关即可添加该指标组至应用概况页面,次日展示计算结果。



page3.png




page4.png




page5.png




page6.png


IM指标组的作用是通过对用户数据和IM行为分析和挖掘,产生对客户有用的结果。而群组指标组是通过对用户群组数据和行为分析,产生对群组和IM的关系和结果,我们新增了群组的相关数据,希望能帮助您解决各种之前没有预测到的状况。
希望您能在环信IM大数据平台获得直观有效的数据体验,希望我们可以帮助您的APP产品获得更多成功。 收起阅读 »

【已解决】微信和qq中无法使用webim版的环信,在android手机中

有个需求,我们的页面会在微信中传播,微信用户可以,平台有两种用户,商家和个人。我们希望在qq微信中能够很方便的让个人和某个商家进行在线沟通。测了下兼容性,仅在android手机的qq和微信中无法登录和聊天。 经过一晚上对sdk源码的解读和调试解决了问题。 ...
继续阅读 »
有个需求,我们的页面会在微信中传播,微信用户可以,平台有两种用户,商家和个人。我们希望在qq微信中能够很方便的让个人和某个商家进行在线沟通。测了下兼容性,仅在android手机的qq和微信中无法登录和聊天。
经过一晚上对sdk源码的解读和调试解决了问题。
 
---------------------------------上面都是废话
安卓平台的微信和qq的浏览器不支持wss的websocket,只支持ws的websocket。或者可以用Bosh。
修改easemob.im-1.0.7.js让其不要用wss的方式通讯,或者自己去判断如果是android的qq微信就用Bosh方式。
大概在js文件1170行,我改过了可能行数稍有偏差,如下图所示


如果觉得有用,请赞我,谢谢




q.png


  收起阅读 »

团圆,有环信陪伴

天气虽然寒冷,但是春的气息已经渐渐走来。 元宵,作为中国传统节日,按中国民间的传统,在这天上皓月高悬的夜晚,人们要点起彩灯万盏,以示庆贺。出门赏月、燃灯放焰、喜猜灯谜、共吃元宵,合家团聚、同庆佳节,其乐融融。 众里寻它千百度,暮然回首,那人却在灯火...
继续阅读 »
天气虽然寒冷,但是春的气息已经渐渐走来。

元宵,作为中国传统节日,按中国民间的传统,在这天上皓月高悬的夜晚,人们要点起彩灯万盏,以示庆贺。出门赏月、燃灯放焰、喜猜灯谜、共吃元宵,合家团聚、同庆佳节,其乐融融。

众里寻它千百度,暮然回首,那人却在灯火阑珊处。就是描述元宵夜的情境。

值此新春佳节,环信祝大家欢度一个温馨、愉悦、宽松的元宵佳节


未标题-3.jpg


  收起阅读 »

2016创业公开课第一期:初创企业如何快速成长

活动内容   你知道如何注册公司吗? 你知道如何控制企业成本吗? 你知道合伙人及团队该如何选择? 你知道市场该如何打开? 创业不容易,教你怎么避开那些坑? 这里没有大佬给你吹牛,只有众多一线实战专家为你解读在创业路上遇到的问题, 让你具备一个CE...
继续阅读 »
活动内容
 


你知道如何注册公司吗?

你知道如何控制企业成本吗?

你知道合伙人及团队该如何选择?

你知道市场该如何打开?

创业不容易,教你怎么避开那些坑?

这里没有大佬给你吹牛,只有众多一线实战专家为你解读在创业路上遇到的问题,

让你具备一个CEO的基本素质和能力!


活动时间:2016年2月27日 13:30—17:30

活动规模:50人

活动地址:北京市海淀区海淀西大街36号昊海楼7层,北大创业训练营(地铁10号线苏州街A口出 步行10分钟或地铁4号线中关村站E口 步行10分钟)

 
演讲嘉宾:


冰狗网CEO  任冠举
 
分享主题:《初创企业知识产权风险防范》


30552243564112511.jpg


首席知识产权顾问,培训讲师

南京大学生命科学院毕业,硕士;10年以上知识产权从业经验。
曾供职于国家知识产权局专利局,精通专利审理要求及审理流程;其后成立北京易正达知识产权代理有限公司,2015年出任冰狗网CEO;著有《产业专利分析之经典案例》一书。
 
 
51社保 COO 胡万军

分享主题:《初创企业的成本优化及风险防范》


30762243569972758.jpg



     资深企业信息化专家,一直专注于企业运营和流程优化,曾就职于百度和拉手网,担任企业信息化项目负责人,就职于百度公司期间,整体负责百度ERP项目的推进,支持并参与百度财务、人力资源管理、销售、集团预算、财务报表等信息化项目,就职拉手网期间担任公司财务、人力资源管理系统项目经理。
 
 
猿圈 CEO&创始人 郑萌
分享主题:《初创企业如何打造团队》


30922243565782589.jpg




    做为一个资深程序老猿,带了10几年的技术团队,凭借对技术人才和企业的理解,做了一个围绕程序猿招聘的相关项目。在这个巨缺猿类的时代,想让大家辨别真假猿,猿圈就是你的火眼金睛。自主研发Android和iOS云端编译引擎,结合基于大数据的人工智能分析,猿圈是目前是国内唯一一家做程序员代码挑战的平台。
 
百度高级市场主管:贾春雨
分享主题:《初创企业如何做好营销》



30582243568612701.jpg



2010年加入百度,百度金牌营销讲师。拥有丰富的营销经验及互联网推广技巧。目前专注于百度推广研究及营销效果分析


活动流程:
13:30-14:00                签到
14:00-14:45 《初创企业知识产权风险防范》
14:45-15:30 《初创企业的成本优化及风险防范》
15:30-16:15 《初创企业如何打造团队》
16:15-17:00 《初创企业如何做好营销》
17:00-17:10 抽奖
17:10-17:20 互动答疑
17:20-17:30 合影留念

特别感谢
北大创业训练营对本次活动的大力支持! 收起阅读 »

77.4%份额,环信高居SaaS移动端客服市场第一的背后

 从去年开始,SaaS客服领域迅速升温,并成为企业级应用市场里紧随CRM、人力资源、OA协同的第四座金矿。这座金矿旁边也已经占满了猎食者。究竟谁会是SaaS客服行业的最大赢家呢?近日,易观智库发布的一份《中国SaaS客服市场专题研究报告》,针对SaaS客服市场...
继续阅读 »
 从去年开始,SaaS客服领域迅速升温,并成为企业级应用市场里紧随CRM、人力资源、OA协同的第四座金矿。这座金矿旁边也已经占满了猎食者。究竟谁会是SaaS客服行业的最大赢家呢?近日,易观智库发布的一份《中国SaaS客服市场专题研究报告》,针对SaaS客服市场的典型厂商和业务模式进行了分析,并对未来的发展趋势进行了预测

20160219011006425.jpg


报告显示,经过十年发酵的沉淀,SaaS客服市场正从话音呼叫中心、网页端客服向全媒体架构的统一客服平台升级,经过2015年的启动期,2016年SaaS客服行业将进入高速发展期。报告还对当下新兴并逐渐成熟应用的移动端客服市场份额进行了排名,截止到2015年第三季度,环信移动客服在SaaS移动端客服的用户覆盖占比高达77.4%,位居行业第一。

环信占据SaaS移动端客服第一:市场占有率高达77.4%

目前来看,中国SaaS客服市场的成长路径相当清晰。PC时代诞生了最早的传统话音呼叫中心,PC互联网时代诞生了网页在线客服,社交媒体时代诞生了微信、微博等社交媒体客服。进入2015年后,随着移动互联网如电商、O2O生活服务市场的井喷,消费者全面转向移动设备,将移动端客服推到了风口浪尖。这一代客服产品的特点是原生支持移动端APP,并同时支持多种渠道的接入如电话,网页和微信。通过云服务SaaS形式降低用户使用成本,大量运用人工智能技术提高效率。因此,新一代客服正日益成为移动互联网时代的企业的标配。

就此,易观智库出具的SaaS客服报告显示,通过锁定有客服入口的主流APP,统计使用移动端客服功能的APP活跃用户数,以此来计算移动端客服产品的用户覆盖占比。结果显示,截止2015年第三季度,环信移动客服用户覆盖占比达到了77.4%。对于未来SaaS客服的整体表现,易观智库也做了预测,2014年,中国SaaS客服市场规模为380亿元,2015年预计将达到490亿元,年增长率约为22.4%,2017年会增长到680亿元。

SaaS客服主流厂商对比:环信三大优势

目前,市场上盯住SaaS客服蛋糕的主要有三大流派,一是传统话音呼叫中心转型过来的厂商,天润融通是一个代表,经营呼叫中心十余年,依托网络交换机整合不同来源的客服需求,语音客服是其护城河。容联投资的七陌也属此类;二是PC互联网时代兴起的网页端客服,Live800最为典型,但网页端增速明显已经放缓,且有被新兴客服渠道如社交媒体和APP客服分流的态势;三是以环信为代表的移动端云客服。三类厂商偏重不同,但最终都会走向全媒体客服的形态。



20160219011032633.jpg


环信以移动端客服、全媒体客服、智能机器人客服为核心切入点。


有人奇怪,环信成立移动客服的时间并不是最长的,凭什么能一举拿下移动端客服第一的位置呢?实际上有三点理由支撑。

一是环信起家于环信即时通讯云。环信即时通讯云在PaaS市场的份额很高,服务了一大批的一线互联网公司和头部app。环信延伸出客服产品是其PaaS平台SaaS化扩展的过程,继承了一批优势客户资源,更容易得到市场的认可和信赖。

二是未来全媒体客服市场,智能化是一个趋势,但国内客服厂商中,拥有自主知识产权的人工智能、机器问答,语义分析技术实力的并不多,大多数都采取了集成第三方技术的方式。相比,环信一开始就深耕智能问答客服机器人的核心技术,建立核心算法创建应答模型,在实际问答中不断修正、训练和学习,能帮助消费者解答60%-80%的常见问题,提升服务满意度,并减少人工投入。长期看,智能问答机器人是客服产品的标配和核心竞争力,因此环信并没采取集成第三方机器人技术的方式。

三是全媒体客服的四个主要客服渠道,即语音呼叫中心,微信、网页端,移动端APP中的前三个渠道的技术门槛并不高。比如语音呼叫中心技术已经非常成熟了,微信客服只是集成微信提供的接口,而网页端客服基于轮询技术,没有什么技术含量,这也是国内一下子冒出一大批SaaS客服的原因。但随着移动互联网的深入发展,消费者全面转向移动端,移动端APP客服这个接入渠道将成为整个全媒体客服的最至关重要的一环。而IM长连接技术是移动端APP客服的基石,IM长连接技术的实力强弱,能否做到弱网环境下消息必达,能否支持千万级用户同时在线,这些都是企业选购移动端客服产品的重要考量目标。而这些也正是环信等即时通讯云平台起家的厂家的“后院”。这一点在竞争后期会表现出来。

未来SaaS客服的三大趋势:全媒体+移动化+智能化

未来,SaaS客服会呈现三个明显的趋势。首先是客服中心将全面转型为全媒体客服,即呼叫中心+网页在线客服+社交媒体客服+移动端客服的形态,传统呼叫中心将从饱和期进入衰退期,并被移动客服逐步蚕食。同时,智能化的应用广度和深度将加强,竞争壁垒会走高。当然,全媒体会是百舸争流的竞争局面,短兵相接的现象暂时未上演。

其次是移动端客服将扮演越来越重要的角色。消费者全面转向移动终端的大趋势已经毋庸置疑,移动端客服产品的实力,将成为客服软件厂商的竞争焦点。

最后则是客服中心角色的转变,由成本中心向盈利中心升级,开始承担更多的营销、销售的职责。过去是以客服工单为主,沟通关系被动,职能隔离且偏售后,与销售、营销部门无协同关系。但未来客服的业务链条将“并联”营销、销售和售后环节,是互联网时代企业与用户的“第一连接点”,承担客户关系维护、二次销售、营销等职能,成为盈利中心。

虽然环信在移动端客服市场占竞争优势,但着眼未来全媒体、多形态融合的SaaS客服,平台化会催生更丰富的生态,特别是营销、销售等新角色的增强,让客服与前端的营销、CRM系统,以及企业内部的协同办公等模块,产生更多的交叉和整合地带。所以总体看,SaaS客服市场还处于一个初级阶段,企业仅仅是试水期,场景化有待挖掘,平台化还未开始,未来还存在诸多的变数。 收起阅读 »

一乐:当你手抖删了线上数据库..

嘉宾介绍 一乐,aka 梁宇鹏 现任环信首席架构师兼IM技术总监,负责即时通讯云平台的整体研发和管理。曾任新浪微博通讯技术专家,负责微博通讯系统的设计与研发。 2016年1月18日,新年刚过,距离噩梦的圣诞节已经过...
继续阅读 »
嘉宾介绍

image_(1).jpg



一乐,aka 梁宇鹏

现任环信首席架构师兼IM技术总监,负责即时通讯云平台的整体研发和管理。曾任新浪微博通讯技术专家,负责微博通讯系统的设计与研发。




image.jpg


2016年1月18日,新年刚过,距离噩梦的圣诞节已经过去三周。已经好多天没有线上报警,群里一片安静,大家都在享受这份宁静与安逸。唯一不一样的是,有集群的迁移工作要做,相关人员干劲十足,已经连续三天通宵。按照惯例,为了保险起见,线上操作都在夜里进行。

如果说这几天最怀念的时光,也许就是这一天了,因为在第二天,我们的一个线上数据库出了问题。

19日上午10点,陆续有用户抱怨,一个接口的数据丢失,而之前删除的数据又出现了。这时候我们的运维同事贴出一个截图,发现有一个数据同步的进程,从凌晨五点开始运行,把线上数据库覆盖,数据一夜回到了解放前!

好在运气好,在这个覆盖发生之前,有一个备份。

修复工作马上展开,先把主从切断,主库利用备份数据重启,从库用来进行比对,恢复增量数据……(部分内容由于当地政策,未予显示)

然而事情并没有结束。这时候内部出现了一个声音高喊,我们一定要惩罚!惩罚这个人,让他知道服务稳定性的重要!

有没有觉得似曾相识?类似的情况其实经常发生。而很多事情就是这样,好像是日常中的一个插曲,却对团队和公司的发展产生着微妙又长远的影响。

是的,我说的是惩罚。

image_(2).jpg


让我们看看惩罚是做什么的

以儆效尤?如果当事人玩忽职守,故意破坏,也许有一些作用。我这里用了也许,因为真出现这种情况的话,可能不是惩罚就够了的。但如果价值观没有问题,这点却未必有效。因为事故已经可以对当事人造成足够压力,增加罚款并没有什么必要。

解气么?公司变大必然出现分工,而各个团队之间的沟通也会变弱。每出现一个问题,其实都是整个公司的问题,用户需要安抚,市场需要维护。这时候就很容易发出一种声音,你看你总给我们添麻烦。这种指责和随后的处罚除了让发声的人心里痛快,该做的事情并没有减少。

它们并没有创造什么价值,却带来了很多你不想要的东西。

更差的工作表现。因为惩罚带来的畏首畏尾,以及随之而来的挫败感,都会让一个人的工作效率大打折扣。

错误的工作态度。谁都知道疲劳作战效率不高容易出错,既然多做多错,少做少错,为什么要去加班加点赶什么进度呢?多一事肯定不如少一事。

隔阂的团队。出了问题就开始指责,那出问题之前的加班加点为了谁呢?一个彼此间互相信任的团队与一个互相防备的团队,差距也是显而易见。

最重要的是,它让技术团队偏离了对技术的追求,而把目光收回到内部关系上,这自然会放慢前进的步伐,这对创业公司将是致命的。

速度是小公司取胜竞争对手直至打败大公司的关键。

不要惩罚不意味着拒绝进步

我们这么做,是因为我们也相信,促使个人和团队成长的,应该是团队的荣誉感和为之努力的心,而不是对惩罚的恐惧。

但我们也不能停在这个地方。如果连自己的教训都无法总结并长成经验,也注定是悲剧的。所以还是回归本初,看看真正想要的是什么。

我们想要的,不过是避免类似事情的发生。

先看一则旧闻。

2015年10月20日,德意志银行外汇部门的一名初级交易员将一订单中的「净值」错误处理为「总额」,令德意志银行向一家美国的对冲基金客户白白送出了60亿美元。 http://wallstreetcn.com/node/224923

这种输入上的低级错误,金融业里叫胖手指,而避免的最重要的方法就是两人法则,我也更喜欢它第二个名字,四眼原则(four eyes principle)。
https://en.wikipedia.org/wiki/Fat-finger_error

它提醒了我们,在关键业务上需要有人结对。鉴于现在工作的远程状态,我们使用了Tmux的会话共享模式,两个人可以通过相同的会话来共享控制台以及键盘输入。

技术可以做到更多

四眼原则用来做紧急措施是可以的,但毕竟有交互成本。而人在精确性上天生不如机器,因此要确保问题不再发生,还要用一些技术手段才行。

由于命令执行的是一个历史命令,而出错的运维人员进入了一个前人遗留的Tmux会话,或者是按了向上或者是进入时的回车直接执行了CTRL-R留下的命令。于是我们

修改了数据恢复的命令,强制进行二次确认;
对危险命令进行了别名处理;
禁止了Tmux的默认session,使用Tmux的人员强制使用别名。

所以你看,人的问题也可以用技术手段来解决。

技术驱动和技术导向

互联网发展仍是日新月异,挑战无处不在。要想变挑战为机遇,只有创新和技术才有可能。只有重视技术的公司,才能充分发挥技术人员的能动性,也将更容易在技术的竞争中胜出。

我们经常开玩笑,很多公司,做不到技术驱动,因为他的每一步都是领导提出领导拍板,它只能叫领导驱动。而如果一个公司在遇到事情之后就总是想到惩罚,不注意保护和发挥技术人员的能动性,技术导向也只能是一个口号。

说到底不过一句话。一个团队或公司,要变成什么样子,跟她迈出的每一步都有关系。

毕竟罗马不是一天建成的。

image_(3).jpg




image_(4).jpg


  收起阅读 »

环信IM 3.0 Lite发布

各位环信开发者大大新年好呀!春节长假回来的第一周已然过去,不知道各位大大们是否进入了工作状态呢?身边的小伙伴都在抱怨回来第一天看着电脑不知道该干啥呢,大大们是否有同感呢?   长假归来,未做好的仍继续!本次IM 3.0 Lite为各位大大们带来了全新的通信协议...
继续阅读 »
各位环信开发者大大新年好呀!春节长假回来的第一周已然过去,不知道各位大大们是否进入了工作状态呢?身边的小伙伴都在抱怨回来第一天看着电脑不知道该干啥呢,大大们是否有同感呢?
 
长假归来,未做好的仍继续!本次IM 3.0 Lite为各位大大们带来了全新的通信协议、全新的SDK
 


SDK 更新日志
 
1、全新的通信协议:全新的基于消息同步的私有协议,在不稳定网络环境下更稳定更省流量,确保消息投递的可靠、顺序以及实时性,并具有更高的安全性。同时提供了更好的扩展性,将支持更多的对接和设备同步场景。 
2、全新的SDK:全面重构,将核心通信模块做了更好的封装;简化了接口,结构更清晰,集成更容易;提升了登录速度和弱网络环境下的可靠性编辑


 有没有很期待呢,看着就想立马体验下!在这里要提醒各位大大们,Lite不包含实时音视频,如需使用实时音视频请下载Full版本
 


SDK 2.x至3.0升级指南
 
Android点击了解Android升级指南
 
IOS点击了解IOS升级指南


 
文章的最后附上IM 3.0 Lite下载地址,欢迎各位大大们升级体验,在使用过程中有任何优化建议、寻找帮助都可以直接下方评论,我们会及时处理您的每一条留言!
 


IM 3.0 Lite下载地址
 
IM3.0点击下载


收起阅读 »

Android EaseUI 关于设置昵称、头像

关于依赖easeui,设置头像、昵称问题 在调用EaseUI.getInstance().init初始化之后去设置用户信息提供者 //get easeui instance EaseUI easeUI = EaseUI.getInstance(); //需要e...
继续阅读 »
关于依赖easeui,设置头像、昵称问题
在调用EaseUI.getInstance().init初始化之后去设置用户信息提供者
//get easeui instance
EaseUI easeUI = EaseUI.getInstance();
//需要easeui库显示用户头像和昵称设置此provider
easeUI.setUserProfileProvider(new EaseUserProfileProvider() {
 
    @Override
    public EaseUser getUser(String username) {
       return getUserInfo(username);
    }
});

getUserInfo是自己实现的一个方法,在这个方法里去根据传入的username获取本地保存的对应的昵称、头像,设置给EaseUser的对象,并返回。

easeui里显示昵称、头像的时候会去调用EaseUserProfileProvider这个接口去获取EaseUser对象,会去执行在初始化之后设置的getUserInfo方法,如果没有显示昵称、头像,你就要去看getUserInfo里是否拿到昵称、头像设置给EaseUser对象了。

获取昵称、头像显示,我这里给大家两种方案,昵称、头像都保存在自己的服务器。

第一种
可以在登录之后去服务器获取所有好友的昵称、头像,包括自己的,保存在本地,getUserInfo方法里就去根据传入的username去本地获取,设置给EaseUser对象返回。

第二种
可以在getUserInfo方法里去判断本地是否有保存对应的昵称和头像,没有就发送网络请求去服务器获取对应的昵称头像保存到本地,设置给EaseUser对象返回 ,然后发送广播到聊天界面去提示刷新,刷新之后就会执行getUserInfo方法拿到本地的昵称、头像。

头像、昵称更新
用户请求你的服务器修改了昵称、头像,你的服务器去调用rest给这个用户的所有好友,发条透传消息,提示去更新本地保存的昵称、头像
收起阅读 »

关于Android在添加好友时邀请收不到的问题

    在我们集成环信的sdk时,经常会遇到这样一个问题,在我们添加好友时,邀请发出了但是那边却收不到的尴尬情况,针对这样的问题,系统的分析一下,这其中可能的原因:  1. 首先我们要看看好友监听是否在application或MainActivity中注册,要...
继续阅读 »
    在我们集成环信的sdk时,经常会遇到这样一个问题,在我们添加好友时,邀请发出了但是那边却收不到的尴尬情况,针对这样的问题,系统的分析一下,这其中可能的原因:
 1. 首先我们要看看好友监听是否在application或MainActivity中注册,要保证在接收邀请时,监听处于监听状态,也就是没有被消毁和取消注册。
2. 检查监听注册是否正确,在监听的下方是否加了:EMChat.getInstance().setAppInited();
3. 打个断点看看,这个好友邀请的监听onContactInvited(String username,String reason)是否在执行(见Demo中DemoHelper),具体代码如下:
public void onContactInvited(String username, String reason) {
// 接到邀请的消息,如果不处理(同意或拒绝),掉线后,服务器会自动再发过来,所以客户端不需要重复提醒
List<InviteMessage> msgs = inviteMessgeDao.getMessagesList();

for (InviteMessage inviteMessage : msgs) {
if (inviteMessage.getGroupId() == null && inviteMessage.getFrom().equals(username)) {
inviteMessgeDao.deleteMessage(username);
}
}
// 自己封装的javabean
InviteMessage msg = new InviteMessage();
msg.setFrom(username);
msg.setTime(System.currentTimeMillis());
msg.setReason(reason);
Log.d(TAG, username + "请求加你为好友,reason: " + reason);
// 设置相应status
msg.setStatus(InviteMesageStatus.BEINVITEED);
notifyNewIviteMessage(msg);
broadcastManager.sendBroadcast(new Intent(Constant.ACTION_CONTACT_CHANAGED));
}

 
   当然,类似的群组邀请收不到的问题也是类似的,具体排查思路和上面雷同,邀请监听的代码如下:
/**
* 群组变动监听
*/
class MyGroupChangeListener implements EMGroupChangeListener {

@Override
public void onInvitationReceived(String groupId, String groupName, String inviter, String reason) {

boolean hasGroup = false;
for (EMGroup group : EMGroupManager.getInstance().getAllGroups()) {
if (group.getGroupId().equals(groupId)) {
hasGroup = true;
break;
}
}
if (!hasGroup)
return;

// 被邀请
String st3 = appContext.getString(R.string.Invite_you_to_join_a_group_chat);
EMMessage msg = EMMessage.createReceiveMessage(Type.TXT);
msg.setChatType(ChatType.GroupChat);
msg.setFrom(inviter);
msg.setTo(groupId);
msg.setMsgId(UUID.randomUUID().toString());
msg.addBody(new TextMessageBody(inviter + " " +st3));
// 保存邀请消息
EMChatManager.getInstance().saveMessage(msg);
// 提醒新消息
getNotifier().viberateAndPlayTone(msg);
//发送local广播
broadcastManager.sendBroadcast(new Intent(Constant.ACTION_GROUP_CHANAGED));
}

@Override
public void onInvitationAccpted(String groupId, String inviter, String reason) {
}
@Override
public void onInvitationDeclined(String groupId, String invitee, String reason) {
}

@Override
public void onUserRemoved(String groupId, String groupName) {
//TODO 提示用户被T了,demo省略此步骤
broadcastManager.sendBroadcast(new Intent(Constant.ACTION_GROUP_CHANAGED));
}

@Override
public void onGroupDestroy(String groupId, String groupName) {
// 群被解散
//TODO 提示用户群被解散,demo省略
broadcastManager.sendBroadcast(new Intent(Constant.ACTION_GROUP_CHANAGED));
}

@Override
public void onApplicationReceived(String groupId, String groupName, String applyer, String reason) {

// 用户申请加入群聊
InviteMessage msg = new InviteMessage();
msg.setFrom(applyer);
msg.setTime(System.currentTimeMillis());
msg.setGroupId(groupId);
msg.setGroupName(groupName);
msg.setReason(reason);
Log.d(TAG, applyer + " 申请加入群聊:" + groupName);
msg.setStatus(InviteMesageStatus.BEAPPLYED);
notifyNewIviteMessage(msg);
broadcastManager.sendBroadcast(new Intent(Constant.ACTION_GROUP_CHANAGED));
}

@Override
public void onApplicationAccept(String groupId, String groupName, String accepter) {

String st4 = appContext.getString(R.string.Agreed_to_your_group_chat_application);
// 加群申请被同意
EMMessage msg = EMMessage.createReceiveMessage(Type.TXT);
msg.setChatType(ChatType.GroupChat);
msg.setFrom(accepter);
msg.setTo(groupId);
msg.setMsgId(UUID.randomUUID().toString());
msg.addBody(new TextMessageBody(accepter + " " +st4));
// 保存同意消息
EMChatManager.getInstance().saveMessage(msg);
// 提醒新消息
getNotifier().viberateAndPlayTone(msg);
broadcastManager.sendBroadcast(new Intent(Constant.ACTION_GROUP_CHANAGED));
}

@Override
public void onApplicationDeclined(String groupId, String groupName, String decliner, String reason) {
// 加群申请被拒绝,demo未实现
}
}

  收起阅读 »

环信给大家拜年咯!祝大家新春快乐,猴年大吉!

环信祝大家猴年大吉   辞旧迎新,2015年已经随着新年的钟声渐渐远去,但是给中国企业级服务市场所带来的深远影响才刚刚开始。随着中国人口红利的消退、经济走弱带来的各行业毛利下滑以及移动互联网红利的凸显,通过Saas提高企业运营效率,节省成本,成为企业服务加速...
继续阅读 »

640.webp_.jpg


环信祝大家猴年大吉
 


辞旧迎新,2015年已经随着新年的钟声渐渐远去,但是给中国企业级服务市场所带来的深远影响才刚刚开始。随着中国人口红利的消退、经济走弱带来的各行业毛利下滑以及移动互联网红利的凸显,通过Saas提高企业运营效率,节省成本,成为企业服务加速爆发的核心驱动力,SaaS领域将会迎来一个爆发式增长的黄金时期。

2015年是中国企业级服务元年,也是中国SaaS元年。企业服务市场因此成为资本追逐的热点,而其中环信更是明星中的明星公司,一年时间实现四轮融资。环信从连接“人与人”为愿景的即时通讯云产品出发,进而在PaaS平台上生长出了连接“人与商业”的SaaS产品环信移动客服。同时还逐步上线了环信大数据产品、环信反垃圾产品,打造了一个IM蓝图的全产业链布局。环信推动了整个即时通讯云行业从PaaS服务向SaaS服务延展的风潮,引领了整个行业的发展趋势。


  



640.webp_(3)_.jpg

因为有你,环信连接人与人才有价值。

因为有你,环信连接人与商业才有基础。

感谢有你,环信飞速发展,一年四轮融资。

见证有你,环信即时通讯云领军行业,覆盖TOP20领域TOP10客户。

见证有你,环信移动客服占据SaaS移动端客服市场77.4%份额居行业第一。

感谢有你,环信大数据产品,反垃圾服务等如雨后春笋茁壮成长。

感谢有你,感恩有你,感激有你,2016“环信”有“你”更精彩!

环信祝福小伙伴们,新春快乐,猴年大吉!




640.webp_(4)_.jpg


融资情况
环信一年时间内完成了4轮融资。天使轮为经纬中国500万人民币、A轮为SIG 500万美元、A+轮为红杉资本300万美元,B轮融资1250万美元,由红杉资本领投,经纬中国和SIG跟投。是即时通讯云和SaaS客服领域融资最快、资金最充裕的平台。
业绩规模
环信是国内起步最早、规模最大的即时通讯云平台和全媒体智能云客服平台。现已覆盖包括电商、O2O、互联网金融、在线教育、在线旅游、移动医疗、智能硬件、游戏等20大领域的Top10客户,典型用户包括国美在线、58到家、快牙、随手记、猎聘、海尔等。截至2015年底,环信共服务了50833家 App 客户,SDK覆盖手机终端3.19亿,平台日均发送消息2.1亿条。







  收起阅读 »

iOS开发小记:关于环信Demo3.0的使用总结以及昵称和头像问题的研究与解决

来献个丑,关于Demo3.0昵称和头像问题的处理,博主写了一篇详细的文章,希望能帮到大家。 最近公司在开发一款创业项目,可以说是以即时通讯功能为主的,所以用到了第三方的即时通讯SDK----环信。相比于国内的几家即时通讯云服务商,像网易云信、融云什么的,环信...
继续阅读 »
来献个丑,关于Demo3.0昵称和头像问题的处理,博主写了一篇详细的文章,希望能帮到大家。

最近公司在开发一款创业项目,可以说是以即时通讯功能为主的,所以用到了第三方的即时通讯SDK----环信。相比于国内的几家即时通讯云服务商,像网易云信、融云什么的,环信应该算比较早的了吧,可以说IM云服务的老大。

       我们要做的项目类似于微信,有联系人页面、聊天列表与聊天页面、设置页面,刚刚好包括了环信Demo3.0的全部内容,所以理论上应该把Demo直接嵌入工程。由于这个Demo是实现了一些IM的基本UI,但是因为环信的官方文档和视频比较欠缺,维护起来相当麻烦,所以在开发的过程中有好多次决定弃用这个Demo,自己构建UI。但是又考虑到,Demo的代码可以说相当健壮,各种机制都集成的非常好(比如好友申请和删除的回调处理),最终决定还是硬着头皮上,改Demo的UI部分以供自己使用。

        环信的官方文档虽然比较欠缺,但是代码的注释和命名还是很好的,基本上可以一目了然每个变量、每个函数在做什么事情。笔者遇到的最大的问题就是好友头像和用户的显示问题,因为环信的服务器是不存储除了用户名和密码以外的其他任何数据的。解决这个问题的办法,就是将你要保存的其他用户信息保存在应用程序自己的服务器上。先来看一张官方图:


20160204215052121.png


 
 如图所示,你需要构建自己的应用服务器。环信的建议是,包括好友体系都不要用环信来维护,最好是由你APP自己的服务器来维护。但是笔者为了简化开发,并没有这样做,而是使用环信维护的好友体系,把昵称和头像存在自己的服务器上,每次从环信上获得当前用户的好友列表,再根据每个好友的用户名到自己的服务器上去获取。

         需要显示昵称和头像的地方有以下几处:联系人列表、聊天页表、聊天页面、联系人和群的详情页面。环信Demo3.0中有一个叫做ContactListViewController的类正是联系人列表页面,笔者决定从这个类入手。这个类是一个常见的带Tableview的Controller,找到它的下拉刷新和tableview的几个代理方法进行尝试,发现无论如何也不能完美的实现想要的效果。于是开始研究Demo是怎样显示昵称和头像的,经研究发现,环信是使用国外的App数据储存商Parse来实现储存,于是找到Demo中存取Parse部分的代码:


20160204221831667.png



  在ViewDidLoad中,笔者找到了一个叫做UserProfileManager的类(绿色部分),看了看这个类的h和m文件,发现这个类就是管理存取Parse上数据的类,而且全局是一个单例。笔者认真分析了一下这个类的作用,根据它提供给外部使用的方法的名称,发现他的作用主要有以下三个,且是按照以下顺序的:


        1----获取当前用户在Parse服务器上的好友数据(头像、昵称),储存到内存中或者本地沙盒中:loadUserProfileInBackgroundWithBuddy:self.contactsSource saveToLoacal:YES completion:NULL

        2----根据好友的用户名(环信储存的用户名),返回内存或本地沙盒中保存的昵称:  - (NSString*)getNickNameWithUsername:(NSString*)username;


        3---根据好友的用户名(环信储存的用户名),返回内存或本地沙盒中保存的头像Url:- (UserProfileEntity*)getUserProfileByUsername:(NSString*)username;



        其中2和3其实可以合成一个,因为头像的url一般都是用一个用户的唯一标识(数据库表中的主键)来命名,而这个唯一标识刚好可以是环信服务器上所储存的用户名字段

        举个例子,在ViewDidLoad方法中,先调用方法1,获取到昵称和头像,然后在tableview的cellForRowAtIndexPath,也就是给每个cell赋值的那个方法中,先调用方法2和3,再给cell赋值。

20160204223444233.png


如图所示,(绿色部分),根据model.buddy.username属性,获取到环信服务器所保存的用户名,再调用23方法得到昵称和头像url的拼接。

       于是根据这个类,笔者仿照它也写了一个单例,给单例加了一个保存所有好友昵称的NSDictionary属性,这个单例对象在APP全局是唯一的,所以该属性在内存中也是唯一的,每次调用获取它的方法,不用担心是空或者重新生成新对象的问题发生。而且最好将属性设置成nonatomic的,这样可以防止在一次网络请求构建改属性的过程中被访问,导致数据错误。但是笔者还是加上了判断。笔者的这个类叫做NickNameAndHeadImage,也就是上面两幅截图中绿色注释部分紧跟的代码。并且还加入了一些判断,比如,如果昵称为空,则显示环信服务器上保存的用户名。当然,如果你想让更新即时的话,你可以在这个类中实现一些发送和接受透传消息的方法,笔者暂时没有写。

        大家可以全局搜索UserProfileManager的使用地方(比如按昵称搜索,首字母排序,详情等),发现基本上就是用到了笔者所提到那三种操作,所以,可以用自己仿制的这个单例类完美的代替UserProfileManager的功能,这样就可以在不修改环信Demo逻辑的前提下,接入自己的APP服务器,这样便保留了环信Demo的所有优良特性。

       下面将NickName类的代码列出,供大家参考:
#import <Foundation/Foundation.h>

@interface NickNameAndHeadImage : NSObject

+(instancetype) shareInstance;

- (void)loadUserProfileInBackgroundWithBuddy:(NSArray*)buddyList;

- (NSString*)getNicknameByUserName:(NSString*)username;


#import "NickNameAndHeadImage.h"

@interface NickNameAndHeadImage()

@property (strong, nonatomic) NSMutableArray *UserNames;

@property (strong, nonatomic) NSMutableDictionary *NickNames;

@property (nonatomic) BOOL DownloadHasDone;

@property (nonatomic) BOOL LoadFromLocalDickDone;


@end

@implementation NickNameAndHeadImage
{

}
static NickNameAndHeadImage* _instance = nil;

+(instancetype) shareInstance
{
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init] ;
}) ;

return _instance ;
}

- (instancetype)init
{
self = [super init];
if (self) {
_DownloadHasDone = NO;
_LoadFromLocalDickDone = NO;
_UserNames = [NSMutableArray array];
NSMutableDictionary *dic = [[NSUserDefaults standardUserDefaults] objectForKey:dUserDefaults_Dic_NickName];
if (dic == nil || [dic count] == 0) {
_NickNames = [NSMutableDictionary dictionary];
_LoadFromLocalDickDone = YES;
}
else
{
_LoadFromLocalDickDone = YES;
_NickNames = [NSMutableDictionary dictionaryWithDictionary:dic];
}


}
return self;
}


- (void)loadUserProfileInBackgroundWithBuddy:(NSArray*)buddyList
{
_DownloadHasDone = NO;
[_UserNames removeAllObjects];
[_NickNames removeAllObjects];

if (buddyList == nil || [buddyList count] == 0)
{
return;
}
else
{
for (EMBuddy *buddy in buddyList)
{
[_UserNames addObject:buddy.username];
}
}

[self loadUserProfileInBackgroundWithUsernames];
}

- (void)loadUserProfileInBackgroundWithUsernames
{

_DownloadHasDone = NO;

//首先构造Json数组
//1.头
NSMutableString *jsonString = [[NSMutableString alloc] initWithString:@"{\"mobilelist\":["];

for(NSString *mobile in _UserNames){

//2. 遍历数组,取出键值对并按json格式存放
NSString *string;

string = [NSString stringWithFormat:
@"{\"mobile\":\"%@\"},",mobile];

[jsonString appendString:string];

}
// 3. 获取末尾逗号所在位置
NSUInteger location = [jsonString length]-1;

NSRange range = NSMakeRange(location, 1);

// 4. 将末尾逗号换成结束的]}
[jsonString replaceCharactersInRange:range withString:@"]}"];

NSLog(@"请求昵称时要发送的jsonString = %@",jsonString);

NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:dUserDefaults_String_LoginToken];
NSString *url = [NSString stringWithFormat:@"customer/contract?token=%@",token];
NSDictionary *postdic = [NSDictionary dictionaryWithObjectsAndKeys:jsonString,@"mobilelist",nil];
[HttpUtil POST_Path:url params:postdic completed:^(id JSON,NSString *str)
{
_LoadFromLocalDickDone = NO;
NSLog(@"打印JSON数据:%@",str);//打印Json数据
NSString *state = [[JSON objectForKey:@"json"] objectForKey:@"state"];
if ([state isEqualToString:@"1"]) {//获得昵称成功

//打印信息
NSString *msg = [[JSON objectForKey:@"json"] objectForKey:@"msg"];
NSLog(@"获得昵称成功:msg:%@",msg);

NSArray *array = [[[JSON objectForKey:@"json"] objectForKey:@"data"] objectForKey:@"list"];


for (NSDictionary *dic in array) {
[_NickNames setObject: [dic objectForKey:@"name"] forKey: [dic objectForKey:@"mobile"]];
}

NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
[ud setObject:_NickNames forKey:dUserDefaults_Dic_NickName];
[ud synchronize];
_LoadFromLocalDickDone = YES;

_DownloadHasDone = YES;


}
else//获得昵称失败
{
_DownloadHasDone = NO;
//打印信息
NSString *msg = [[JSON objectForKey:@"json"] objectForKey:@"msg"];
NSLog(@"获得昵称失败:msg:%@",msg);
}
}
failed:^(NSError *err){

_DownloadHasDone = NO;
[SVProgressHUD showSuccessWithStatus:@"登录失败"];
NSLog(@"获得昵称失败:%@",err);

}];
}

- (NSString*)getNicknameByUserName:(NSString*)username
{
if(_DownloadHasDone == YES)
{
NSString *string = [_NickNames objectForKey:username];
if (string == nil || [string length] == 0) {
return username;
}
return string;
}

else if(_LoadFromLocalDickDone == YES)
{
NSMutableDictionary *dic = [[NSUserDefaults standardUserDefaults] objectForKey:dUserDefaults_Dic_NickName];
NSString *string = [dic objectForKey:username];
if (string == nil || [string length] == 0) {
return username;
}
return string;
}
return username;
}
附上截图

20160204225153412.png


其中,第一行为没有上传头像而有昵称,第二行为有头像有昵称,第三行为有头像无昵称,则显示用户名。

希望可以和大家多交流,做出更完美的App。 收起阅读 »

IOS V2.2.2 2016-02-02版本更新

流浪的脚步在外闯荡,家是永远的方向。不管你是已经到家,还是在回家的路上或还坚守在公司,环信送上最真挚的祝福,道一声朋友,祝你一路顺风,新春快乐。 环信与你同在,在距离春节最后一周,我们期待已久的ios新版本sdk发布了,这里让我们向还奋斗在一线的工程师们致敬。...
继续阅读 »
流浪的脚步在外闯荡,家是永远的方向。不管你是已经到家,还是在回家的路上或还坚守在公司,环信送上最真挚的祝福,道一声朋友,祝你一路顺风,新春快乐。

环信与你同在,在距离春节最后一周,我们期待已久的ios新版本sdk发布了,这里让我们向还奋斗在一线的工程师们致敬。
 
以下是此次新版本介绍,文章结尾附下载链接

 新功能:


实时通话新增弱网监测、暂停或打开音频视频流等API(相应增加的方法可查看文档)。
实时视频新增录制功能(相应增加的方法可查看文档)。



bug fix:


SDK bug: iphone 6s 实时视频挂断crash。
SDK bug: 优化iphone 6s 实时语音外放噪音。
SDK bug: 使用sdk发送高分辨率图片crush bug。
SDK bug: 附件下载失败,附件下载状态为成功的bug。



SDK细节调整:


提升实时语音音质


 
点击下载体验http://www.easemob.com/downloads 收起阅读 »

支付宝为什么拼了命做社交

悄然何时,身边掀起了一阵“集五福分大奖“的热潮,支付宝规定,参与福卡活动的用户新添加10个支付宝好友,即可获得3张福卡。一时间,大量的社交关系链流入支付宝。 支付宝真的打算做社交了吗? 福卡的玩法将进一步推动用户在支付宝上沉淀自...
继续阅读 »
悄然何时,身边掀起了一阵“集五福分大奖“的热潮,支付宝规定,参与福卡活动的用户新添加10个支付宝好友,即可获得3张福卡。一时间,大量的社交关系链流入支付宝。



20334875_062804601000_2.jpg



支付宝真的打算做社交了吗?


福卡的玩法将进一步推动用户在支付宝上沉淀自己的关系链。以红包为支点,让用户逐步习惯在支付宝内与好友互动。

我们都知道,支付宝重点在于商业,支付只是手段而已,但本身关系链不强大,只有通过各种商业环境来布局自身的触角,通俗点讲,就是在需要使用支付业务时打开支付宝,付款完成,然后就等着被打入手机后台吧~

说到这里,我们就不得不谈下支付宝的对头”微信“了,虽然微信本身是社交,支付只是衍生,但我更愿意把他们看成竞争对手。由于微信社交平台的粘性,我们看到微信从社交化到各个领域的渗透,比如”微信红包“,”网上购物“,“生活缴费”等各种层出不穷的服务(有了用户关系链的场景真的不一样)


那支付宝这次到底是图啥呢?


支付宝其实是在构建金融场景,寻找社交和支付的结合点,借助社交的关系链给支付宝提供服务场景!

我们可以来看下未来的愿景,举个例子,你给家里的父母转每个月的孝敬费,一转过去了可以问下“妈,钱收到了吗,哦,收到了是吧,好的,最近天冷 多保重身体呀” 父母就很开心了,不仅钱收到了,还收到了子女的问候,甚至可以在手机另一边唠叨两句“哎,闺女,过年什么时候回家呀,今年男朋友带回来吗”


为什么很多公司做社交产品没有成功?


场景有了,可是用户间的沟通缺少核心技术。
 
用户已经有非常多的沟通渠道,比如:短信、微信甚至陌陌,经常看到在一些新上架APP里用户的沟通还停留在“请加 我微信***详聊”甚至没有通讯功能,在这个即时通讯连接人与商业的时代,拥有像QQ微信这样的收发文字、图片、语音、实时音视频这样的功能真的很重要。
 


 我们实现即时通讯难吗?


自行研发移动IM,技术门槛高,开发周期长。
 
主要的技术难点包括:
1:协议和IM服务器的选择:
当前常用作IM的协议包括XMPP和MQTT,也有用SIP的,还有自行开发的私有协议。可以使用的开源的IM服务器包括OpenFire, Tigase, Prosody, Mosquitto, ejabberd等。你知道它们各自的优缺点吗,你知道哪个协议,那个IM服务器实现最适合你的需求吗,你知道你一旦选定了一个方案,你分别需要对协议和IM服务器做哪些改动和改进吗?
 
2:不稳定网络环境下(3G,2G,Wifi,无网络,及各种网络环境下的切换)     
    移动终端即时通讯长连接可靠性的维护
    移动终端耗电量优化
    移动终端流量优化
    发送各类富媒体消息的特定处理,如语音文件格式选择,语音压缩算法,语音降噪算法,图片压缩处理,地理位置,名片,文档等
    消息回执处理(ack),防止消息丢失。
    离线消息处理。离线时的实时消息通知(比如通过第三方推送平台)     实时状态同步
    支持千万级同时在线用户的高可靠,高并发的服务器集群架构的搭建和运维
安全
 
 3:移动IM是一个需要长期跟进和维护的技术,并不是产品上线后研发团队就可以解散了。
作为运营者,你做好长期的技术投入的思想准备了吗?比如新的IM功能层出不穷,如匿名社交,阅后即焚,你的产品要不要与时俱进?移动IM相关的各种安全隐患和漏洞,你要不要及时修复?所以你需要问自己一个问题,移动IM技术是你的核心竞争力吗,还是只是支撑你的业务实现的一个工具?


 
实现即时通讯功能那么难,有没有简单的办法轻松拥有?


这里给各位推荐一家即时通讯云服务厂商--环信
 
环信提供基于移动互联网的即时通讯能力,如单聊、群聊、发语音、发图片、发位置、实时音频、实时视频等,让开发者摆脱繁重的移动IM通讯底层开发,24小时即可让App拥有内置IM能力。


 
公司介绍
环信成立于2013年4月,是一家全通讯能力云服务提供商。产品包括全球最大的即时通讯云PaaS平台——环信即时通讯云,以及全球首创的全媒体智能云客服平台——环信移动客服。截至2015年底,环信共服务了50833家 App 客户,SDK覆盖手机终端3.19亿,平台日均发送消息2.1亿条。

 融资情况:
环信一年时间内完成了4轮融资。天使轮为经纬中国500万人民币、A轮为SIG 500万美元、A+轮为红杉资本300万美元,B轮融资1250万美元,由红杉资本领投,经纬中国和SIG跟投。是即时通讯云和SaaS客服领域融资最快、资金最充裕的平台。

 业绩规模:
环信是国内起步最早、规模最大的即时通讯云平台和全媒体智能云客服平台。现已覆盖包括电商、O2O、互联网金融、在线教育、在线旅游、移动医疗、智能硬件、游戏等20大领域的Top10客户,典型用户包括国美在线、58到家、快牙、随手记、猎聘、海尔等。截至2015年底,环信共服务了50833家 App 客户,SDK覆盖手机终端3.19亿,平台日均发送消息2.1亿条。
收起阅读 »

来自环信的新年问候

辞旧迎新,2015年已经随着新年的钟声渐渐远去,但是给中国企业级服务市场所带来的深远影响才刚刚开始。随着中国人口红利的消退、经济走弱带来的各行业毛利下滑以及移动互联网红利的凸显,通过Saas提高企业运营效率,节省成本,成为企业服务加速爆发的核心驱动力,SaaS...
继续阅读 »

head.jpg

辞旧迎新,2015年已经随着新年的钟声渐渐远去,但是给中国企业级服务市场所带来的深远影响才刚刚开始。随着中国人口红利的消退、经济走弱带来的各行业毛利下滑以及移动互联网红利的凸显,通过Saas提高企业运营效率,节省成本,成为企业服务加速爆发的核心驱动力,SaaS领域将会迎来一个爆发式增长的黄金时期。


2015年是中国企业级服务元年,也是中国SaaS元年。企业服务市场因此成为资本追逐的热点,而其中环信更是明星中的明星公司,一年时间实现四轮融资。环信从连接“人与人”为愿景的即时通讯云产品出发,进而在PaaS平台上生长出了连接“人与商业”的SaaS产品环信移动客服。同时还逐步上线了环信大数据产品、环信反垃圾产品,打造了一个IM蓝图的全产业链布局。环信推动了整个即时通讯云行业从PaaS服务向SaaS服务延展的风潮,引领了整个行业的发展趋势。


因为有你,环信连接人与人才有价值。
因为有你,环信连接人与商业才有基础。
感谢有你,环信飞速发展,一年四轮融资。
见证有你,环信即时通讯云领军行业,覆盖TOP20领域TOP10客户。
见证有你,环信移动客服占据SaaS移动端客服市场77.4%份额居行业第一。
感谢有你,环信大数据产品,反垃圾服务等如雨后春笋茁壮成长。
感谢有你,感恩有你,感激有你,2016“环信”有“你”更精彩!
环信祝福小伙伴们,新春快乐,猴年吉祥!​​



融资情况:
环信一年时间内完成了4轮融资。天使轮为经纬中国500万人民币、A轮为SIG 500万美元、A+轮为红杉资本300万美元,B轮融资1250万美元,由红杉资本领投,经纬中国和SIG跟投。是即时通讯云和SaaS客服领域融资最快、资金最充裕的平台。

业绩规模:
环信是国内起步最早、规模最大的即时通讯云平台和全媒体智能云客服平台。现已覆盖包括电商、O2O、互联网金融、在线教育、在线旅游、移动医疗、智能硬件、游戏等20大领域的Top10客户,典型用户包括国美在线、58到家、快牙、随手记、猎聘、海尔等。截至2015年底,环信共服务了50833家 App 客户,SDK覆盖手机终端3.19亿,平台日均发送消息2.1亿条。
  收起阅读 »

凡信2.0beta发布-超仿微信的开源项目 (更新了朋友圈和钱包)

         凡信的第一个版本于2015年4月份发布,之后由于自己工作忙碌的原因,一直没有重大的更新内容。2016年1月份抽空做了一些更新。主要是加入了朋友圈和钱包这两块内容,以及对第一版的一些bug的修复。凡信2.0依然是基于环信IM通信云SDK开发的,...
继续阅读 »
         凡信的第一个版本于2015年4月份发布,之后由于自己工作忙碌的原因,一直没有重大的更新内容。2016年1月份抽空做了一些更新。主要是加入了朋友圈和钱包这两块内容,以及对第一版的一些bug的修复。凡信2.0依然是基于环信IM通信云SDK开发的,当前状态下第三方通信云趋于火热,环信也这一年走过四轮共计几千万美元的融资,开发者用户也呈现几万的增长。这个项目也算是给需要集成IM云的开发者提供一个参考,给刚接触Android开发,对Android整体开发框架还很模糊同学提供一个学习的教材。

       关于此次更新的朋友圈版块,有些地方的处理的我觉得非常有技术分享的价值,项目为了极速开发,整个项目写得有点凌乱粗糙,但是部分功能单独拎出来讨论。会以博客的形式的解析一些功能。

    可关注http://www.imgeek.org/people/huangfangyi 
    作者QQ : 84543217
    技术讨论群:437758366(已有900名小伙伴等着你)


APP运行效果图展示


Screensho.png


 
APK扫码下载体验

liantu.png



二维码下载不了的,直接用链接
http://120.24.211.126/fanxin/download/Fanxin.apk
 
github源码下载 https://github.com/huangfangyi/FanXin2.0_IM



凡信2.0beta的代码更新说明:
 
   
一、朋友圈相关
1.发布动态--文字 图片 位置
2.朋友动态列表
3.点赞
4.评论
5.识别网址
6.好友的所有动态查看
7.我的相册
8.部分功能待完善
二、钱包相关
1.零钱 -虚拟账户
2.充值 选择卡-充值-每张卡初始额度200元
3.提现 提现到卡-需要手动处理才能完成,我就不手动去弄 了,因此提现后无法到你的卡(注:此卡指的是凡信中的虚拟卡)
4.交易记录---转账、充值、提现三类
5.银行卡 后台虚拟了一些卡账号,每张卡有200的额度。添加后可充值。
6.给好友转账--后面会添加提现和在聊天页显示。     
7.支付宝集成(app中常用的功能)-----集成了支付宝的SDK,由于密钥等参数都是比较重要的,已在工程中去掉了。体验这个带参数的功能,可以下载这个包-http://120.24.211.126/fanxin/download/Fanxin.apk,做了一个打赏的功能。
   三、  逻辑变化:
好友关系独立化,弃用了环信的好友关系表,在后端自己管理好友关系,这样做是跟朋友圈的业务相关,因此请务必注册新的账号的测试,

前情回顾:
本项目的IM通信部分是基于第三方通信云——环信的SDK开发的。对于个人开发者或者小企业来说,做IM用第三方的也是一种趋势吧,毕竟自己整一套可供运营使用的IM系统几乎是不切实际的(技术门槛和维护成本)。之前用环信做了几个外包项目,其中有些设计和安排我觉得很赞,所以总结了以前的经验和收获,做了这套全仿微信的APP。总的来说,这里面大的架构还是沿用了环信官方提供的UIdemo,但是里面的很多的细节和大部分页面都是我精心按照微信的逻辑和UI设计进行编写的。功能上目前解决了好友体系、用户资料、单聊、群聊等社交功能,后续还会继续更新类似于更换聊天背景、搜索本地用户、朋友圈、更多聊天表情等功能。。。希望有兴趣的小伙伴能一起更新这个开源项目。      整套代码编写的时间仓促,加上作者水平有限,望理解!
第一版功能说明:
1.注册登录部分:
     1.1重写了EditText的默认的蓝色底线,变成微信的绿色
     1.2 登录和注册按钮对输入框进行监听,并变色
     1.3 密码明文和隐藏
2.主页
     2.1全仿微信底部导航
     2.2 右上角加号按钮可进入 “发起群聊”和“添加朋友“
     2.3 显示未读消息数和未读通知数
3.聊天列表页:
     3.1 群聊头像是群成员头像的组合,有1.2.3.4.5种类型的头像
     3.2 置顶功能。置顶后该会话item置于列表顶端,并像微信一样变底色
     3.3 删除列表功能,删除该条会话记录
4.通讯录页
     4.1 显示好友列表
     4.2 进入还有申请通知
     4.3 进入群聊列表
5.发现页(正在开发朋友圈功能.....)
6.用户详情页
      6.1 资料设置(目前可更改的资料是:头像、昵称、性别)
      6.2 微信号只能设置一次。
      6.3 设置页(通知、声音、震动、退出登录)
7.用户申请通知
      7.1按时间由近及远排序
      7.2 显示申请理由
      7.3 处理状态(已添加、同意)
8.查找添加用户
      8.1 按用户的手机号查找用户
      8.2 搜索的用户的存在显示用户资料
      8.3 若该用户已经是好友,显示”发送消息“按钮
      8.4 若该用户不是好友,显示添加好友,并要求输入申请理由
9.发起群聊
      9.1可以在输入框内按用户昵称搜索好友
      9.2 添加群聊的用户的头像可以动态显示在顶部
10.聊天页面
      可以发送语音文字图片和视频(后续更新更多表情和设置聊天背景)
11聊天设置
       11.1单聊:置顶聊天、免打扰、和清除聊天记录
       11.2 群聊:显示群成员列表、增加群成员、删除群成员(群主可操作)、
                  修改群名称、置顶聊天、屏蔽清除群消息 收起阅读 »

致美洽,造谣抹黑和博同情不能赢得市场,好产品不需要说谎!

1月26日,易观智库发布了《2015中国SaaS客服市场专题研究报告》全方位解读了国内SaaS客服市场现状。易观报告详细诠释了未来客服行业移动端、全媒体、智能化等发展趋势,预测2017年中国SaaS客服市场将达到680亿元人民币。同时公布了2015主要SaaS...
继续阅读 »
1月26日,易观智库发布了《2015中国SaaS客服市场专题研究报告》全方位解读了国内SaaS客服市场现状。易观报告详细诠释了未来客服行业移动端、全媒体、智能化等发展趋势,预测2017年中国SaaS客服市场将达到680亿元人民币。同时公布了2015主要SaaS移动端客服厂商用户覆盖比例,其中环信以77.4%的份额占据SaaS移动端客服市场第一,从而一石惊起千层浪。在报告中份额比较小的美洽通过造谣抹黑环信,付费刷爆微信群和朋友圈,以弱者的姿态博同情误导不明真相群众,我们对此深表遗憾。与之形成鲜明对比的是行业主流SaaS客服厂商均没有借势抹黑环信来抬高自己的产品,我们对此表示由衷的钦佩,因为好产品从不需要说谎。
 
环信呼吁公开、公平、公正测评,规范中国SaaS客服市场
 
中国SaaS客服软件市场将是一个千亿级市场,但目前市场份额的很大部分还是被传统安装型软件和传统的单一语音呼叫中心所占领。中国新一代的SaaS客服厂商的共同战场是SaaS VS 传统安装软件,是移动互联网时代应运而生的创新技术对诞生在PC互联网时代的上一代客服技术的革新,提高整个客服行业的用户体验和工作效率。环信衷心希望可以团结中国新一代的SaaS客服厂商,教育市场,培育市场,一起把中国的SaaS客服市场做大做强。

环信一直秉承着用数据和事实说话,环信郑重承诺,环信公开发布的所有数据包括融资金额、产品数据和客户量等信息均真实可靠,环信愿意为此承担一切法律责任和道德风险。

 环信提倡在一个公开、公平、公正的环境下用第三方的评测标准和透明的用户数据来规范中国SaaS客服市场,大家带上自己的TOP 用户一起来比一比,美洽,敢约么?


640.webp_(12)_.jpg


 
 环信用数据说话,不服来战,美洽敢约么?
 
环信在即时通讯云领域耕耘数年,积累了大量的用户和良好的口碑,成就了环信“连接人与人”的愿景。环信移动客服是在环信即时通讯云PaaS平台上生长出来的SaaS产品,环信移动客服SDK与环信即时通讯云SDK共享核心代码,历经5万余家APP实践验证,2年半迭代开发,承担着环信“连接人与商业”的愿景。环信携其优势移动端技术和客户资源,在SaaS客服的移动端客服领域后发先至,高歌猛进也是理所当然。

企业级服务市场从来都是靠产品技术和市场销售实力取胜,而不是靠造谣、抹黑和博同情,针对美洽质疑报告数据,环信提议美洽带上自己的TOP用户一起来比一比,敢约么?


具体提议如下:(环信已将评测方案开源在github上,其余友商有兴趣参加,环信同样欢迎。)


640.webp_.jpg



 
1,用户:提交各自TOP50移动端app用户名单,需要有明确客服入口,需要检测明确使用了自己的SDK。(针对美洽质疑TOP5/TOP10用户不代表整个厂商市场覆盖,那我们直接加码到TOP50客户,如果对方不足50家客户的可以酌情减少到40家)

2,机构:主持评测机构:第三方公证处。数据来源机构:各大应用商店,App annie、易观千帆、QuestMobile等。

3,评测方法:1、各自Top50 App用户的总累计市场下载量。2、、各自Top50 App用户的总累计日活量。为保证日活数据的透明公正,可采用至少2家研究机构的日活监控数据,如app annie、易观千帆、QuestMobile等。

4,如果你敢接受环信的挑战,请在2月19日前提交申请。SaaS移动端客服市场占有率公开评测方案GitHub开源地址:https://github.com/haozki/servicecloudmarket
 


 市场份额不是大锅饭:主流SaaS客服厂商均认可,为啥单美洽质疑?
 
易观《2015中国SaaS客服市场专题研究报告》发布后获得了广泛传播。其中部分领先厂商比如逸创云、智齿、爱客服等均第一时间解读了,并在各自微信和优势媒体传播了报告里的趋势,引用了报告里的核心市场数据。
 
 

640.webp_(1)_.jpg


 
逸创云客服微信描述易观智库为国内知名数据机构,智齿客服微信描述易观智库为权威的第三方机构,这是为什么呢?


640.webp_(2)_.jpg


 
为啥美洽你口中的“大佬”《2015中国SaaS客服市场专题研究报告》代表厂商天润融通和Live800不质疑,这么多比你优秀的厂商不质疑,为什么只有你质疑?在移动端美洽1.7%的真实市场占有率影响到你投资人信心了是么?市场不是大锅饭,靠的是实力。


640.webp_(3)_.jpg



美洽:恶意中伤,黑稿路人群全覆盖,误导不明真相群众,红包发到手抽筋。
 


640.webp_(4)_.jpg


 
以上为部分大群截图,绑架友商恶意中伤环信,妄图鹤蚌相争渔翁得利,可惜友商都有职业操守。请问程总您是如何得知逸创、Udesk、环信三家的核心市场数据的?还得出结论环信排第四,靠冥想么?
 

640.webp_(5)_.jpg



组团将黑稿发到行业群里供大家讨论本也无可非议,刷爆上百个微信群也没什么,砸红包诱发转发都能理解,美洽COO程总将黑稿发到众多不明真相的普通路人群,比如“北京程氏宗亲群”是单纯为了冲阅读数?还是里面有一股来自东方的神秘力量?


产品和市场落后可以追,最可怕的是固步自封、观念落后

根据官网显示美洽成立于2013年,而环信移动客服2014年12月开始内测,于2015年4月正式上线,环信移动客服是晚于美洽进入市场,但现在市场占有率环信远超美洽,美洽有反思过为什么吗?

2015年某国内最大O2O平台的App内置客服选型,其中某友商爆出两年完全免费的价格,但最后仍旧付费采购了环信移动客服。某友商是否在失败后在产品和技术层面进行了反思:


1,你的移动端客服是否基于IM长连接技术?只有基于IM长连接技术的移动端客服才能保证消息必达、24小时在线,这已经是常识。

2,SaaS云客服要支持互联网上的海量用户,你的移动端客服是否有经过验证的支持千万级用户同时在线咨询的能力?



企业级服务产品的核心竞争点是产品和技术实力,是靠高质量的研发团队的长期和巨量的投入,不是靠价格,更不是靠打嘴仗,发黑稿博取同情,绑架用户。
 

640.webp_(6)_.jpg


 
 易观报告客户服务领域关于移动端和全媒体的趋势已经不需累述,如果SaaS客服“移动端”指标还算是程总口中所谓意淫的“中国特色”指标,那么很遗憾您的观念起码已经落后整个SaaS客服行业了。如果行业厂商一直固步自封,停留在原来的产品和市场圈子自沾自喜,将会被新一轮先进的生产力无情的淘汰,这也是他们为什么市场占有率低的主要原因。当然如果程总能和谈笑风生的 Nielsen 或者其他机构一起在以下美洽提议的三个方面: “付费用户数占比”、“付费金额占市场总额比”和“注册用户占比”做一个中立报告,环信将积极参与并提供数据。


640.webp_(7)_.jpg


 
环信新媒体小编努力工作效率高也有错?行业调研机构发布报告以后,第一时间完成解读借势传播难道不是每个厂商市场部的最起码职责么?由此可以看出美洽的全方面落后,不单只在市场部。

俗话说“离开剂量谈毒性”都是耍流氓,抛开数据谈第一是不是更耍流氓?美洽COO程总说:“反正美洽比环信领先的多了。”亲,原因呢?数据呢?哼,讨厌、恶心、呸,就是比你领先的多…
 

不堪入目的骂街都来了


 

640.webp_(8)_.jpg



造谣和吹牛逼三神兽:“我同学、我朋友、我亲戚”。本来想深度扒扒易观智库的,后来想想还是省省力气吧…其实大家真的很想听。下面这幅图还给您,不谢。


640.webp_(9)_.jpg


 
Udesk:你没看清楚数据,我不怪你


640.webp_(10)_.jpg


 
求Udesk小编手下留情,马上大过年的,就不要打打杀杀啦。重要的事情说三遍:“移动端、移动端、移动端。”这个图里说明的是环信占中国SaaS移动端客服市场比例,而不是整个市场。也许媒体自发转载传播的标题有歧义,你没看清楚数据我不怪你。


写在最后,2015年是中国SaaS元年,行业需要自律,同时也需要新标准。环信衷心希望可以团结中国新一代的SaaS客服厂商,教育市场,培育市场,一起把中国的SaaS客服市场做大做强,市场足够大,大家都可以活下来。 收起阅读 »

【有奖调查】关于表情的使用需求

为了更好地服务环信用户,了解大家对表情的使用需求,环信和萌岛合作发起本次有奖调查,感谢大家支持!如果有需要,可以抓你们的运营或者 PM 来回答哦。    萌岛是一个专注于互联网卡通形象的服务平台,汇聚国内专业卡通形象设计师,大家熟悉的各路表情包设计大...
继续阅读 »
为了更好地服务环信用户,了解大家对表情的使用需求,环信和萌岛合作发起本次有奖调查,感谢大家支持!如果有需要,可以抓你们的运营或者 PM 来回答哦。
 

萌岛.jpg


 
萌岛是一个专注于互联网卡通形象的服务平台,汇聚国内专业卡通形象设计师,大家熟悉的各路表情包设计大神,都在萌岛。萌岛已为国内多个互联网产品提供卡通形象和表情设计服务。


萌岛表情设计稿.png



 1、你是否想要类似天猫和京东狗这样的卡通形象?
 
 2、你是否想要企业专属定制的卡通形象表情包? 
 
3、单个表情制作费用多少钱能够接受?500以内 / 500-1000 / 1000-2500 / 其它价格(可以具体说明)
 
 4、关于表情有任何想法请告诉我们。


 
如果对卡通形象表情感兴趣,还可以关注萌岛的微信服务号了解哦。   



萌岛服务号二维码8.jpg

收起阅读 »

java.lang.NoClassDefFoundError: com.easemob.chat.EMChat

导入jar,在自定义application里oncreat中跑EMChat.getInstance().init(this)这个就报错,估计是导包的问题,就是找不到哪里错了


aaa.png


导入jar,在自定义application里oncreat中跑EMChat.getInstance().init(this)这个就报错,估计是导包的问题,就是找不到哪里错了

Android EaseUI里的百度地图替换为高德地图

鉴于有些客户的项目里要使用高德地图,我就把EaseUI里的百度地图替换为了高德地图,提供给有需要的客户下载使用。 (EaseUI里的类名没有做修改,还是沿用的之前的,想修改的可自行修改) 依赖这个EaseUI之后,需要在项目的清单文件里去配置权限 ...
继续阅读 »
鉴于有些客户的项目里要使用高德地图,我就把EaseUI里的百度地图替换为了高德地图,提供给有需要的客户下载使用。
(EaseUI里的类名没有做修改,还是沿用的之前的,想修改的可自行修改)
依赖这个EaseUI之后,需要在项目的清单文件里去配置权限

QQ截图20160130130317.png


还有高德地图的appkey和定位服务

QQ图片20160128201903.png


我把依赖这个EaseUI写的demo也一并上传了,可以去参考下。
github上的地址:
https://github.com/wangxinjeff/WXEaseUIDemo
我在这里只是简单的实现了高德地图的地位,大家可以根据高德的api自行扩展。 收起阅读 »

ANDROID开发之BUG专讲:入门篇(一)

话说诸葛亮是一个优秀的程序猿,每一个锦囊都是应对不同的case而编写的!但是优秀的程序猿也敌不过更优秀的bug!六出祈山,七进中原,鞠躬尽瘁,死而后已的诸葛亮只因为有一个错误的case-马谡,整个结构就被break了!   BUG真的是一个很讨人厌烦的东西...
继续阅读 »
话说诸葛亮是一个优秀的程序猿,每一个锦囊都是应对不同的case而编写的!但是优秀的程序猿也敌不过更优秀的bug!六出祈山,七进中原,鞠躬尽瘁,死而后已的诸葛亮只因为有一个错误的case-马谡,整个结构就被break了!

 

BUG真的是一个很讨人厌烦的东西,它总是在你以为自己已经战胜它的时候跳出来嘲笑你。如何才能拿下这些烦人的BUG呢?我想要从DEBUG开始。这里给刚刚接触编程的新手们介绍一下Debug的方法,学会了这些方法后反复练习,当你积累了上万的有效代码量以后自然会发现你的水平将大大精进。

 

工具介绍

 

Android Studio:几乎所有的编译器都会带上自己的DEBUG调试器,所以先来讲讲这个。我这里就以Android studio为例,Android studio是谷歌推出的专门同来进行Android开发的软件,由于针对性比eclipse强所以里面集成了很多插件个人觉得比eclipse方便不少。现在多数安卓开发者都在使用这款IDE了。

 

Android Studio自带模拟器:简单讲Android不像C或者C++甚至是单纯的Java编程。它从设计到编写程序到调试,都离不开手机,Android Studio自带一款强大的模拟器,他能在电脑上模拟出一台手机,如果你不考虑程序在真实设备上的兼容性,这款模拟器已经非常棒了,一般程序在开发阶段的需要都能用模拟器来满足。

 

云手机:模拟器也有缺点,它的效率比较低,并且程序在真机上的运行情况,远比模拟器要复杂,所以开发者的程序写好后还需要用真机来调试。我不太不愿意用自己手机调试,所以会用Testbird的云手机,它们会在云端提供好几百款主流手机,你可以直接用Android Studio等IDE,去远程连接这些机器做调试,简直就是为调试Android程序量身定做的,感兴趣的同学可以注册使用,现在免费开放注册

 https://dt.testbird.com/sign_up/?i18n=zh-cn&cl=DNgwzY&invite=gLKeRY

建立一个初始程序

 

首先在建立一个默认的空白工程之后,我们先在工程里面加点儿东西,这样我们才有东西可调。因为这篇文章是写给新手们看的(调试都不会你敢自称老手?),大家都知道Android编程里非常重要的一个概念就是MVC,MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。其中模型(model)大家可以不管,因为这涉及到结构和数据类型,本例还涉及不到。

 

View可以这么概括——你在手机上所看见的都是view或者由view组成的,但这句话反过来是错的,View并不都是可见的。至于controller控制器你可以将其理解为你的控制逻辑。在Android studio默认工程里面本来是有一个TextView和一个信封样的按钮,我们可以对这个默认工程作出如下修改:添加一个Button按键,在用户按下该按键之前那个TextView显示的内容为默认的“Hello world!”。当用户按下按钮以后该TextView变成“->按下的次数”。我把具体步骤贴在这儿:

 

以Design形式打开content_main.xml,拖出一个Button控件,再进入content_main.xml的Text形式,在button里面加入这样一句话:android:onClick="Btn1_Click",然后进入MainActivity.java文件,依次加入下面的语句:

import android.widget.*; // 引入JAVA包



TextView textView;//创建一个TextView对象

Button button; // 创建一个button对象

int count = 0;



在onCreate()方法中添加如下语句:

button = (Button)findViewById(R.id.button);

textView = (TextView)findViewById(R.id.textView);//这两句话将View和controller联系了起来,也就是说你对手机上view的操作有了这两句话才能反映到你的控制逻辑也就是程序中来~

public void Btn1_Click(View view)//按键后要作出反映的函数。
{
     String str = "---->" + count;
     textView.setText(str);
     count++;
}

然后运行程序就可以了,按一下数字就会增加一个。这里先上一张图(我用的是云手机,大家有条件的可以用自己的手机或者模拟器):

 

 

DEBUG的第一步,设置断点

 

现在初始程序就算是完成了,接下来说说调试,Android调试首先你得知道自己在哪儿打断点,它不像C语言那样只有C文件在你想打哪儿打哪儿。Android主要有两种形势的文件,一种是.java文件一种是.xml文件。打断点只能打在.java文件里面,因为.java文件就是控制逻辑。而.xml文件大家可以理解成视图文件或者叫布局文件,程序走逻辑流程是永远不会走到那儿的,就算到了也没有任何的意义。打断点的方式也非常简单,只是在某一行代码前用鼠标左键点一下出现了红圆点就表示打断点成功了。如下图:

 


 

 

打点是使用DEBUG的第一步,那么接下来就只需要点击run->debug”run”就可以了。当你的程序运行到断点所在的位置的时候程序就会自动暂停,如下图:

 

 

 

如果你是通过DEBUG运行程序手机也会有提示,大家可以看看。

然后程序如果运行到断点处你就会看见某行处于被选中的状态,这个时候程序已经暂停了。

 

 

 

这个时候你可以选择继续运行到下一个断点或者自己一步一步的跟踪调试下去:

一步步调试(F8)

 

 

 

直接运行到下一个断点(F9)

 

 

Debug的操作核心就只有这简单的三步:打断点,通过DEBUG运行程序,按自己的需要选择调试方式(调试途中也可以打断点)。

 

今天主要给大家简单的介绍了一下Debug,是基本使用方式,下一节将为大家具体讲解DEBUG的用法和特性。 收起阅读 »

环信移动客服v4.3更新说明

各位开发者大大好呀,寒潮终是过去,年味气息也越来越近了。从上一次发版以来,我们是实实在在感受到了各位小伙伴对环信的热情!为了让大家都能在春节前用上新版本过个好年,我们工程师也是彻底开挂了!如约而至,移动客服V4.3出来了,这次新版本包含了大家期待已久的“机器人...
继续阅读 »
各位开发者大大好呀,寒潮终是过去,年味气息也越来越近了。
从上一次发版以来,我们是实实在在感受到了各位小伙伴对环信的热情!为了让大家都能在春节前用上新版本过个好年,我们工程师也是彻底开挂了!如约而至,移动客服V4.3出来了,这次新版本包含了大家期待已久的“机器人”,“客服自定义消息”“发送文件消息”等热门功能,赶紧来体验下吧!

 1. 新功能    


1.1. 智能机器人客服    
1.2. 企业欢迎语    
1.3. 多级问候语    
1.4. 访客中心    
1.5. 手机版客服工作台(长连接)    
1.6. 会话结束自动发送满意度评价邀请    
1.7. 转接会话需要对方确认    
1.8. 文件发送    
1.9. 自定义消息    
1.10. 客服在线时长统计    
1.11. 客服超时未回复访客端提示    
1.12. 注册验证    
1.13. 消息提示音(客服端)    
1.14. 企业形象展示位(网页访客端)    
1.15. 客服状态切换提示    
1.16. 最大接待人数设置开关    


 
2.优化内容


2.1. 优化数据统计    
2.2. 增加客服最后回复时间    
2.3. 解决客服关闭窗口后30秒内依然分配会话的问题    
2.4. 历史会话消息详情按单会话查询    
2.5. 历史会话可以精确到分钟查询    
2.6. 满意度评价记录和评语查看   
2.7. 访客资料备注区域增大    


  
 
点击下载详细说明↓ 收起阅读 »

群跟聊天室最多能容纳多少人?

群上限是2000人,聊天室是5000人。
群上限是2000人,聊天室是5000人。

类似ChatService这样的服务很容易会被系统或者杀毒软件给kill掉,在安卓sdk中环信是怎么让ChatService不被kill掉的?

在sdk里环信是加了个守护进程,在应用中也可以在应用设置里允许后台运行和保持后台连接。
在sdk里环信是加了个守护进程,在应用中也可以在应用设置里允许后台运行和保持后台连接。

华为手机(小米新版)不自动重连 该怎么处理?

华为(小米新版本)有白名单,不在白名单的应用不准在后台运行 ,需要让用户把应用放到白名单里 ,这个完全是厂家和系统的设置。app绕不过去,我们也增加了小米推送,具体可参考 http://docs.easemob.com/doku.php?id=start:20...
继续阅读 »
华为(小米新版本)有白名单,不在白名单的应用不准在后台运行 ,需要让用户把应用放到白名单里 ,这个完全是厂家和系统的设置。app绕不过去,我们也增加了小米推送,具体可参考 http://docs.easemob.com/doku.php?id=start:200androidcleintintegration:115payloadmsg。 收起阅读 »

如果一个群主解散了一个群,这个群在本地的聊天记录还有吗?

解散群组后本地聊天记录就删除了。
解散群组后本地聊天记录就删除了。

javalangRuntimeException: Appkey is null or empty, Please check AndroidManifestxml,这个错误是什么问题呢?

这是因为没填appkey,需要用户去AndroidManifestxml里面填上appkey。
这是因为没填appkey,需要用户去AndroidManifestxml里面填上appkey。

在IDEA中开发的项目,有的手机会报couldn't find libeasemobserviceso ,请问怎么解决?

检查是否加入了so,没有加入的话请加入so。
检查是否加入了so,没有加入的话请加入so。

Android打包混淆之前实时语音和视频是正常的,混淆之后总是无法建立连接,这个可能是什么原因?

看下官网的相关混淆,音视频相关那些类是不是都keep了,如果还不行的话,请分析下日志看看,无法连接的状况也可能和混淆无关。
看下官网的相关混淆,音视频相关那些类是不是都keep了,如果还不行的话,请分析下日志看看,无法连接的状况也可能和混淆无关。

环信的图片和语音文件是经过加密的么?

上传附件成功后会返回的数据中会有secret,需要根据secret和url从服务器下载附件。
上传附件成功后会返回的数据中会有secret,需要根据secret和url从服务器下载附件。

Demo中用到的友盟部分是什么作用?

做数据统计用的(不需要可以删掉)。从2.2.3以后还会有自动更新。
做数据统计用的(不需要可以删掉)。从2.2.3以后还会有自动更新。

android客户端可以获取群的历史记录吗?

正常来说是看不到进群前面的历史记录。如有需要,可按以下步骤完成。第一步,用户服务端通过环信rest将聊天记录导入用户自己的服务器上;第二步,用户服务器给客户端提供拉取聊天记录的一个接口,手机客户端从用户自己服务器下载到聊天记录后,可以再通过环信的客户端sdk导...
继续阅读 »
正常来说是看不到进群前面的历史记录。如有需要,可按以下步骤完成。第一步,用户服务端通过环信rest将聊天记录导入用户自己的服务器上;第二步,用户服务器给客户端提供拉取聊天记录的一个接口,手机客户端从用户自己服务器下载到聊天记录后,可以再通过环信的客户端sdk导入到手机本地的db中: 调用importmessage存入 收起阅读 »

实时判断好友在不在线能做到吗?

环信与微信类似,弱化了用户在线状态。即使用户不在线环信也会推送消息。
环信与微信类似,弱化了用户在线状态。即使用户不在线环信也会推送消息。

如何设置免打扰这些,如何自定义notification?

从sdk2.1.8开始已经放到demo层控制了,可以参考HXNotifier这个类。
从sdk2.1.8开始已经放到demo层控制了,可以参考HXNotifier这个类。

请问下,环信发送图片那里是断点发送的吗?如果断开了,隔了一段时间,怎么重连?

图片发送不会断点续传,发送不成功超时后会出现一个叹号,点击之后会重新发送。
图片发送不会断点续传,发送不成功超时后会出现一个叹号,点击之后会重新发送。

环信demo通过长按home键,弹出的应用列表里面关掉应用,然后就不能及时收新消息,这种情况算bug吗?

服务被kill掉长链接断了所以收不到消息。
服务被kill掉长链接断了所以收不到消息。

环信的表情可以换成自己的吗?

可以换成自己的,用户自己app里协定好了就可以。比如<:)> 这个字符串代表笑脸的图片,用户在ui上截取了替换就可以了。 对于环信来说,发的就是一个字符串。
可以换成自己的,用户自己app里协定好了就可以。比如<:)> 这个字符串代表笑脸的图片,用户在ui上截取了替换就可以了。 对于环信来说,发的就是一个字符串。

接收不到透传,请问是什么原因?

如果普通消息能收到的话就要看EMChat.getInstance().setAppInited();添加了没。(只用调一次即可,建议放到主activity中)。
如果普通消息能收到的话就要看EMChat.getInstance().setAppInited();添加了没。(只用调一次即可,建议放到主activity中)。

添加好友申请,接收方sdk有打印收到申请,监听收不到,同时打印这句话:received roster presence, but app is not ready,请问是什么原因?

这个是因为没有添加 EMChat.getInstance().setAppInited();
这个是因为没有添加 EMChat.getInstance().setAppInited();

客户端到客户端的消息加密应该调什么API呢?

客户可以先把消息内容按照自己的算法加密之后再通过环信来发送,iOS的回调是EMChatManagerEncryptionDelegate.h;安卓是EncryptProvider,接口说明在http://www.easemob.com/apidoc/andro...
继续阅读 »
客户可以先把消息内容按照自己的算法加密之后再通过环信来发送,iOS的回调是EMChatManagerEncryptionDelegate.h;安卓是EncryptProvider,接口说明在http://www.easemob.com/apidoc/android/chat/ 收起阅读 »

我调用了两次login,结果app打包出来报错。

只建议调用一次login,在登陆时可以添加个是否已经登陆的判断,登录了就不必再次登陆。
只建议调用一次login,在登陆时可以添加个是否已经登陆的判断,登录了就不必再次登陆。

用户客户端收到大量的透传消息和普通消息时,在透传消息的监听里面去创建消息去importmessage,然后会出现消息发送的回调走的onerror,但是对方已经收到了,这个会是什么原因导致的。

在透传监听那块不可以调用importmessage,因为这里面有个notify的提醒会导致一些其他的问题,如果想保存的话可以调用saveMessage这个方法即可。
在透传监听那块不可以调用importmessage,因为这里面有个notify的提醒会导致一些其他的问题,如果想保存的话可以调用saveMessage这个方法即可。