嘿,我来帮您!
53.1℃
  • 微信提供的API
  • 技术文章
  • 2204

  • 2017-12-31 22:53:48

  • 原作者: 青岛江山信息技术有限公司

空间

微信提供的api,对于针对用户openid发消息的话,没有向所有关注者群发消息的接口,但提供了向单一用户和多用户发文本消息的接口,我们可以基于此开发向所有用户群发消息的接口。
补充:后面我发现其实可以有更好的实现方案,详看 ‘有更好的方案吗?‘。

文中遇到部分的接口请查看上一文:

微信开发之获取用户详细列表


1、 给单一用户发文本消息

微信开发文档入口:

客服接口-发消息

我的代码接口:

/**
 * 向一个粉丝发送消息
 */
public function sendMsgToOne($openid, $content)
{
    $access_token = $this->getAccessToken();
    if (!$access_token) {
        return false;
    }

    $url ="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$access_token}";
    $post_arr = [
                    'touser' => $openid,
                    'msgtype' => 'text',
                    'text' => ['content'=>$content]
                ];
    $post_str = json_encode($post_arr, JSON_UNESCAPED_UNICODE);
    $return = httpRequest($url, 'POST', $post_str);
    $wxdata = json_decode($return, true);
    if (isset($wxdata['errcode']) && $wxdata['errcode'] != 0) {
        $this->setError('微信错误码:'.$wxdata['errcode'].',错误信息:'.$wxdata['errmsg']);
        return false;
    }

    return true;
}


2、 给多个用户发文本消息

微信开发文档入口:

根据OpenID列表群发【订阅号不可用,服务号认证后可用】

我的代码接口:

/**
 * 指定一部分人群发消息
 * @param array $openids
 * @param string $content
 * @return boolean
 */
public function sendMsgToMass($openids, $content)
{
    $access_token = $this->getAccessToken();
    if (!$access_token) {
        return false;
    }

    $url ="https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token={$access_token}";
    $post_arr = [
                    'touser' => $openids,
                    'msgtype' => 'text',
                    'text' => ['content'=>$content]
                ];
    $post_str = json_encode($post_arr, JSON_UNESCAPED_UNICODE);
    $return = httpRequest($url, 'POST', $post_str);
    $wxdata = json_decode($return, true);
    if (isset($wxdata['errcode']) && $wxdata['errcode'] != 0) {
        $this->setError('微信错误码:'.$wxdata['errcode'].',错误信息:'.$wxdata['errmsg']);
        return false;
    }

    return true;
}


3、 给所有用户发文本消息

利用上面的两个接口,实现一个统一的接口,如下:
下面接口入参$openids支持数组和字符串,字符串支持多个openid用,连接,具体请看代码吧。

/**
 * 发送消息,自动识别id数
 * @param string or array $openids
 * @param string $content
 * @return boolean
 */
public function sendMsg($openids, $content)
{
    if (empty(openids)) {
        return true;
    }
    if (is_string($openids)) {
        $openids = explode(',', $openids);
    }

    if (count($openids) > 1) {
        $result = $this->sendMsgToMass($openids, $content);
    } else {
        $result = $this->sendMsgToOne($openids[0], $content);
    }

    if ($result === false) {
        return false;
    }

    return true;
}

下面实现向所有用户群发消息, 使用的时候请判断接口返回是否为false,若是,可用getError()获取详细错误信息,具体可参考上一文 微信开发之获取用户详细列表

/**
 * 给所有粉丝发消息
 * @param string $content
 * @return boolean
 */
public function sendMsgToAll($content)
{
    $next_openid = '';
    do {
        $id_list = $this->getFanIdList($next_openid);
        if ($id_list === false) {
            return false;
        }

        $result = $this->sendMsg($id_list['data']['openid'], $content);
        if ($result === false) {
            return false;
        }

        $next_openid = $id_list['next_openid'];
    } while($id_list['count']);

    return true;
}


4、 有更好的方案吗?

微信开发文档入口:

根据标签进行群发【订阅号与服务号认证后均可用】

我一直以为微信没有提供直接向所有用户群发的接口,其实是有的!
在上面的微信文档中,我发现,这个接口竟然被归类在根据标签进行群发里面。不过不需要用标签这个概念,里面有个关键的变量是is_to_all,把它置为 true 即可。
这样子可以节省上一接口中的相关api的调用次数,更能提高web响应的性能!

我的代码接口:

/**
 * 给所有粉丝发消息
 * @param string $content
 * @return boolean
 */
public function sendMsgToAll($content)
{
    $access_token = $this->getAccessToken();
    if (!$access_token) {
        return false;
    }

    $url ="https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token={$access_token}"; 
    $post_arr = [
                    'filter' => ['is_to_all'=>true, 'tag_id'=>0],
                    'msgtype' => 'text',
                    'text' => ['content'=>$content]
                ];
    $post_str = json_encode($post_arr, JSON_UNESCAPED_UNICODE);
    $return = httpRequest($url, 'POST', $post_str);
    $wxdata = json_decode($return, true);
    if ($this->checkError($wxdata, $url)) {
         return false;
    }

    return true;
}


5、 遇到的问题

在向单一用户发消息的时候,遇到报45015错误的接收报文:

{
    "errcode":45015,
    "errmsg":"response out of time limit or subscription is canceled hint: [***]"
}

原因是当用户微信不活跃时间超过48小时,不会将信息推送到用户微信公众号。

: 上面说法来源于腾讯官方,评论区园友实际测试也是,谢谢这位朋友指出。
为了验证这个说法的正确性,我试着先向公众号发个信息,果然公众号可以向单一用户推送消息了。


小结

简单利用微信向单一用户和多用户的发消息接口,实现向所有用户群发消息,但利用标签接口群发效率回更好哦。其他的语音、图文等消息发送也是类似的。


主要参考文档

微信开发文档:https://mp.weixin.qq.com/wiki

微观空间

视觉上最易被忽视的元素空间。如果你是初学者,可能试图填满每一个空的空间。更有经验的设计师会鼓励你使用更多的空白。从用户的角度来看,很少有人会抱怨它有太多的空白。 缺少空间感会造成视觉干扰。相同的内容、元素的垂直位置。注意通过相同定位的元素创建的空间,创建的视觉层次、对比度和秩序感。涉及到图形设计这是至关重要的。通过内容可以易于阅读和扫描。

宏观空间

视觉上最易被忽视的元素空间。如果你是初学者,可能试图填满每一个空的空间。更有经验的设计师会鼓励你使用更多的空白。从用户的角度来看,很少有人会抱怨它有太多的空白。 缺少空间感会造成视觉干扰。相同的内容、元素的垂直位置。注意通过相同定位的元素创建的空间,创建的视觉层次、对比度和秩序感。涉及到图形设计这是至关重要的。通过内容可以易于阅读和扫描。