iOS调起QQ客户端发送消息失败的解决方案

2,485 阅读4分钟

"对方没有开通在线咨询,无法发起临时会话"

今天同事突然发现一个bug,从我们的app跳转到QQ客户端后,无法向客服QQ发送消息,总是提示 "对方没有开通在线咨询,无法发起临时会话"(如下图)。
网页端没有问题,只有从移动端(iOS和安卓)会发送失败。经过再三确认不是QQ权限设置问题的。于是花了些时间研究了一下。

对方没有开通在线咨询,无法发起临时会话

普通QQ和营销QQ

QQ号是有分类的

普通QQ

就是我们平时用的QQ,一般要加好友才能发消息,除非你们有共同的群和讨论组。之前只要不设置权限禁止临时会话,也能用代码调起消息框发消息。现在好像不行了,我测了一下,即使没有设置禁止临时会话,也发不了消息,效果和上图一样,提示"对方没有开通在线咨询,无法发起临时会话"。

营销QQ

是腾讯给企业在线客服用的QQ,类似公众号,有自动回复的功能,不用加好友也能发消息。会话框也有所不同,如下图。

营销QQ界面与普通QQ区别

营销QQ本身是为网站设计的,并没有对移动端做优化。我们找营销QQ的售后要相关文档和资料,啥都没有。因为营销QQ的代码直接在官方网站上给你生成了,所以根本就没有文档!

营销QQ自动生成的代码

营销QQ在PC上启动QQ客户端的过程是这样的,浏览器打开一个地址(这个地址是在你的营销QQ后台生成的),然后浏览器再调起QQ客户端。
虽然腾讯没有公布文档,但移动端也可以像PC一样采用上述方法启动QQ发起会话(下文解决方案中会提到)。

总结

1.网站打开营销QQ是通过营销后台生成的链接(格式http:/ /wpa.b.qq.com/xxxx)打开浏览器,浏览器再打开QQ。
移动端采用的是URLShemes技术(App间通讯),调用的地址是,mqq://im/chat?chat_type=wpa&uin=qq&version=1&src_type=web(这是iOS的,安卓类似)。

2.普通QQ和营销QQ,需要配置不同的参数:chat_type=wpa,普通QQ;chat_type=crm,营销QQ。出现上文中的错误是因为我们参数配置错了,我们的对象QQ实际上是营销QQ,我们传chat_type=wpa,就会发送失败。同理,如果我们的对象QQ是普通QQ我们传chat_type=crm,聊天的界面会出现营销QQ的样式,发消息同样会失败。由此可以推断,QQ客户端实际上是根据chat_type这个字段来显示不同的会话UI和配置不同的发消息参数,这个字段错了,当然会后台校验不通过。

解决方案

下面两个方案安卓也适用。

方案一

下面的链接大家很熟悉吧,网上一搜一大堆,启动QQ加好友\发消息,都是这条链接。
mqq://im/chat?chat_type=wap&uin=QQ号&version=1&src_type=web
注意里面的chat_type参数,chat_type=wpa普通QQ,chat_type=crm营销QQ,请根据你的情况替换即可。

不过为了更好的扩展性,可以让后台或者前端把chat_type传给我们,以后chat_type有更多的值也不怕了。

/**
 加QQ(发消息)

 @param qq QQ号
 @param chatType QQ号类型,wpa普通QQ,nil或crm营销QQ
 @return 成功调起QQ返回nil,失败返回错误信息
 */
+ (NSString *)joinQQ:(NSString *)qq chatType:(NSString *)chatType
{
    if (!qq) {
        return @"参数缺失";
    }
    NSString *chat_type = @"crm";            //默认营销QQ
    if (chatType && chatType.length>0) {
        chat_type = chatType;
    }
    NSString *urlStr = [NSString stringWithFormat:@"mqq://im/chat?chat_type=%@&uin=%@&version=1&src_type=web",chat_type,qq]; //chat_type=wpa普通QQ,chat_type=crm营销QQ
    NSURL *url = [NSURL URLWithString:urlStr];
    BOOL success = [[UIApplication sharedApplication] openURL:url];
    if (success) {
        return nil;
    }
    return @"没安装QQ";
}

方案二

如果你确信对象QQ是营销QQ,还有一种模仿PC端解决此问题的方案:

url = @"http://wpa.b.qq.com/cgi/wpa.php?ln=2&uin=你的营销QQ号码";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];

Safari被调起,Safari中提示是否打开QQ -> 打开QQ发起临时会话
此方案可以成功发送消息。弊端就是多了一步跳转Safari的过程,用户体验不好。
注意,此方案在iOS11上会失败,提示“Safari浏览器打不开该网页,因为网址无效”,iOS12+上没问题。

方案二,跳转Safari打开QQ

iOS11上失败

如果觉得这篇文章对你有帮助,请点个赞吧。如果有疑问可以关注我的公众号我留言。
转载请注明出处,谢谢!