在浏览某个云课堂的时候,发现了一个直播提醒的功能。在点击开启提醒后,发现它走了如下流程:

  1. 点击开启提醒,弹出一个公众号二维码
  2. 微信扫描二维码,进入小程序客服(app流程)
  3. 点击发送右小角的小程序卡片(app流程)
  4. 服务器返回公众号二维码图片(app流程)
  5. 点击图片识别二维码,关注公众号

云课堂的PC端的开启提醒很简单,只需要扫描二维码即可,但是在 app 开启提醒就稍微复杂了点。
虽然不容易,但经过一番折腾后,终于走通了整个直播提醒的功能。 现分享给需要的朋友。

以下是 app 直播提醒功能:

生成待带参数的二维码

据我所知,目前关注公众号有两种方式:

  1. 扫描或识别公众号后台生成的二维码
  2. 扫描或识别带参数的二维码

这两种都属于关注事件,但第二种在用户关注公众号后,会将带场景值的扫描事件推送给开发者。我们利用这个场景值,可带额外的参数传递给应用服务器,开发者可根据这些参数来判断用户是否已开启提醒。
所以,我们用生成带参数的二维码来完成扫码关注。

生成带参数的二维码地址

下面我们来创建临时二维码:

  1. 获取 access token
$client = new \GuzzleHttp\Client(['verify' => false]);
$header['content-type'] = 'application/json; charset=UTF-8';

$param = [
    'appid' => 'appId',             // 公众号的 appid
    'secret' => 'appSecret',        // 公众号的 secret 
    'grant_type' => 'client_credential'
];

$url = 'https://api.weixin.qq.com/cgi-bin/token?' . http_build_query($param);
$result = file_get_contents($url);
$result = \GuzzleHttp\json_decode($result, true);

if (isset($result['errcode']) && $result['errcode'] <> 0) {
    throw new WeChatException('获取 access_token 失败', 500);
}

$accessToken = $result['access_token'];

2.根据 access_token 获取 ticket

// app传递的数据
$data = [
    'live_id' => 10,    // 直播 ID
    'user_id' => 5      // 用户 ID,未登录可传递 0
];

// post 数据格式
$tmp = [
    'expire_seconds' => 5 * 60,
    'action_name' => 'QR_STR_SCENE',
    'action_info' => [
        'scene' => [
            'scene_str' => http_build_query($data)
        ]
    ]
];
$url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=' . $accessToken;
$json = \GuzzleHttp\json_encode($data, 256);
$ticket = $this->post($url, $json, ['headers' => $headers])['ticket';

3.根据 ticket 生成二维码图片

拿到 ticket 后,访问下面的链接,打开的是一个公众号二维码图片。云课堂的 PC 端即是用这种方式

$qCodeUrl = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=urlencode('.$ticket.')';

唤起小程序

app 中,当点击 开启提醒 时,因为要跳转到小程序客服,所以我们需要将公众号与小程序进行关联。

关联步骤:登录公众号 -> 小程序 -> 管理小程序 -> 添加
关联完成后,就可以在 app 中唤起小程序了。

这个步骤需要 app 开发者和前端开发者协同开发
app 跳转到小程序时,同样要传递直播 ID用户 ID

小程序推送客服消息

客服消息地址

类似公众号推送消息,小程序同样也可以推送该消息。
当用户想微信服务器发送小程序卡片时,
判断 当msgtype 的值为 miniprogrampage 时,发送回复消息

1.获取 Access toten
小程序获取 access token 和公众号获取 access token 基本相同,不同的是 appidsecret分别要换成小程序的 appidsecret

$client = new \GuzzleHttp\Client(['verify' => false]);
$header['content-type'] = 'application/json; charset=UTF-8';

$param = [
    'appid' => 'appId',             // 小程序的 appid
    'secret' => 'appSecret',        // 小程序的 secret 
    'grant_type' => 'client_credential'
];

$url = 'https://api.weixin.qq.com/cgi-bin/token?' . http_build_query($param);
$result = file_get_contents($url);
$result = \GuzzleHttp\json_decode($result, true);

if (isset($result['errcode']) && $result['errcode'] <> 0) {
    throw new WeChatException('获取 access_token 失败', 500);
}

$accessToken = $result['access_token'];
  1. 发送图文消息

我们在第二步中已经生成了公众号二维码,可以直接拿来用

$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" . $accessToken;

$tmp = [
    'touser' => 'OPENID',          // 用户发送卡片时会有个 FromUserName 字段,即 openid
    'msgtype' => "link",
    'link' => [
        'title' => '直播提醒',
        "description" => "点击识别二维码",
        'url' => $qrCodeUrl,            // 带参数的二维码地址
        'thumb_url' => '小程序跳转地址'
    ]
];

$client = new \GuzzleHttp\Client(['verify' => false]);
$header['content-type'] = 'application/json; charset=UTF-8';

$response = $client->request('POST', $url, [
    'headers' => $header,
    'body' => \GuzzleHttp\json_encode($data, 256),
]);

return \GuzzleHttp\json_decode((string)$response->getBody(), true);

图文消息识别二维码

由于推送二维码图片时,需要Media_id,比较麻烦,所以在小程序中,我将公众号二维码地址做成了图文消息发送给用户,
用户点击图文消息后,会显示二维码,用户识别二维码后,即可关注公众号

保存提醒信息

关注公众号,要做个提示消息,告诉用户已经 开启提醒成功
刚好生成带参数的二维码可以帮助我们。

扫描带参数二维码事件有两种情况:

  1. 用户未关注时,进行关注后事件消息:
<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[FromUser]]></FromUserName>
  <CreateTime>123456789</CreateTime>
  <MsgType><![CDATA[event]]></MsgType>
  <Event><![CDATA[subscribe]]></Event>
  <EventKey><![CDATA[qrscene_123123]]></EventKey>
  <Ticket><![CDATA[TICKET]]></Ticket>
</xml>
  1. 用户已关注时的事件消息:
<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[FromUser]]></FromUserName>
  <CreateTime>123456789</CreateTime>
  <MsgType><![CDATA[event]]></MsgType>
  <Event><![CDATA[SCAN]]></Event>
  <EventKey><![CDATA[SCENE_VALUE]]></EventKey>
  <Ticket><![CDATA[TICKET]]></Ticket>
</xml> 

第一种情况,我们可以根据 EventKey 来判断是否是扫描带参数的二维码;
第二种情况,我们可以根据 Event 来判断是否是扫描带参数的二维码;

所以,当出现以上两种情况时,我们就可以判定,用户开启了直播提醒。记录用户的 openid, 以便给用户推送提醒消息

申请模板消息

以上既是 app 开启直播提醒的流程。
需要注意的点:

  1. 公众号必须是服务号
  2. 公众号必须关联小程序
  3. app 唤起小程序时必须传递参数

大步点点
191 声望14 粉丝

There are only two things you need to be a great programmer: curiosity and kindness. Everything else you can learn over time. Everything.