[入門到吐槽系列] 微信小程式 敏感違規圖片檢測 mediaCheckAsync,客服介面 訊息推送 的各種坑分享!

發表於2022-03-04

前言:

最近需要做個使用者上傳圖片,服務端校驗圖片問題的需求。需要使用小程式訊息推送,非同步接受騰訊的圖片驗證回撥。實在太多坑了。

相信10分鐘看完本文的朋友,可以非常順利避坑。

 

前期準備:

首先需要一個訊息推送幫助類wechat.class.php,在這裡下載:https://github.com/dodgepudding/wechat-php-sdk

也可以來百度網盤下載:
連結: https://pan.baidu.com/s/1D_WcAp7e0lyWj4STXd6spQ 提取碼: te4a 複製這段內容後開啟百度網盤手機App,操作更方便哦
 
 

小程式管理介面配置介面

登入微信小程式後臺mp.weixin.qq.com,去開發管理-開發設定-訊息推送,配置好:

 

 

測試程式碼編寫:

寫一個接收程式碼php,放在上面URL(伺服器地址)對應的伺服器上。

<?php

define('IN_MOD', TRUE);
header("Content-Type: text/html;charset=utf-8");
date_default_timezone_set('PRC');//其中PRC為“中華人民共和國

include_once('wechat.class.php');

$options = array(
    'token'=>'填寫介面配置的 Token(令牌)', 
    'encodingaeskey'=>'填寫介面配置的 EncodingAESKey(訊息加密金鑰)', 
    'appid'=>'填寫小程式的appid', 
    'appsecret'=>'填寫小程式的appsecret',
);

$weObj = new Wechat($options);
$weObj->valid();

return true;
?>

紅色部分是需要替換成自己小程式實際配置。

注意把當前檔案和wechat.class.php檔案放在統一個目錄下,可以被URL伺服器地址訪問。

 

測試訊息推送——巨坑提醒!

開啟微信的客服小程式:

 

 

 

注意小程式左上角,有個叫“客服線上”,設定為客服離線!

 

 

 

這是個超級巨坑,如果設定了客服線上,會發現非常多的訊息,介面都收不到,只能收到event型別的推送。這裡小編被坑了12個小時,無意中才發現。所以要用介面,就必須設定離線。

 

 

訊息推送——訊息轉發給客服

由於我們設定了離線,但是對於無法處理的訊息,還是要給人工處理,所以程式碼需要修改:

<?php

define('IN_MOD', TRUE);
header("Content-Type: text/html;charset=utf-8");
date_default_timezone_set('PRC');//其中PRC為“中華人民共和國

include_once('wechat.class.php');

$options = array(
    'token'=>'填寫介面配置的 Token(令牌)', 
    'encodingaeskey'=>'填寫介面配置的 EncodingAESKey(訊息加密金鑰)', 
    'appid'=>'填寫小程式的appid', 
       'appsecret'=>'填寫小程式的appsecret',
);

$weObj = new Wechat($options);
$weObj->valid();


// RECRIECT TO SERVICE

$msg = array(
    'ToUserName'=>$weObj->getRev()->getRevFrom(),
    'FromUserName'=>$weObj->getRev()->getRevTo(),
    'CreateTime'=>$weObj->getRev()->getRevCtime(),
    'MsgType'=>'transfer_customer_service',
);
$weObj->transfer_customer_service()->reply();
return true;
?>

增加一段程式碼,讓無法處理的訊息,轉發給客服小程式。這樣即使離線也可以收到推送。

 

 

訊息推送——回覆訊息給使用者 巨坑2!

這裡又出現第二個巨坑,就是不能直接return結構體回覆給顧客,必須呼叫服務端介面。程式碼如下:

<?php

define('IN_MOD', TRUE);
header("Content-Type: text/html;charset=utf-8");
date_default_timezone_set('PRC');//其中PRC為“中華人民共和國

include_once('wechat.class.php');

$options = array(
    'token'=>'填寫介面配置的 Token(令牌)', 
    'encodingaeskey'=>'填寫介面配置的 EncodingAESKey(訊息加密金鑰)', 
    'appid'=>'填寫小程式的appid', 
       'appsecret'=>'填寫小程式的appsecret',
);

$weObj = new Wechat($options);
$weObj->valid();

// REPLY TO CUSTOMER

if ($weObj->getRev()->getRevType() == 'text' && $weObj->getRev()->getRevContent()."" == "TEST") {
    $url='https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$weObj->checkAuth();
    $msg = array(
        'touser' => $weObj->getRev()->getRevFrom(),
        'msgtype' => 'text',
        'text' => array(
            'content' => 'HELLOWORLD!'
        )
    );
    $msg = json_encode($msg);
    $ret = $weObj->http_post($url, $msg);
    return 'success';
}

// RECRIECT TO SERVICE

$msg = array(
    'ToUserName'=>$weObj->getRev()->getRevFrom(),
    'FromUserName'=>$weObj->getRev()->getRevTo(),
    'CreateTime'=>$weObj->getRev()->getRevCtime(),
    'MsgType'=>'transfer_customer_service',
);
$weObj->transfer_customer_service()->reply();
return true;
?>

如果收到的使用者訊息,並且內容是TEST的時候,返回HELLOWORLD,效果如下:

 

 

 

 

圖片校驗是否違法請求1——巨坑3!

相關文件在這裡:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/sec-check/security.mediaCheckAsync.html

首先使用java構造個http請求,推送給微信:

        String mediaurl = "http://www.pixysoft.cn/images/pages/moc/dab7b3_81493ed8bd1e4d53bc3a9ce761734675~mv2.png";
        String url = "https://api.weixin.qq.com/wxa/media_check_async?access_token=ACCESS_TOKEN";
        JsonObject params = new JsonObject();
        params.addProperty("version", 2);
        params.addProperty("openid", "o6qII0dUQxFt3Dvs1m6sXv5vZydQ");
        params.addProperty("scene", 1);
        params.addProperty("media_url", mediaurl);
        params.addProperty("media_type", 2);

        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url.replace("ACCESS_TOKEN", WxssJSSDKCache.getAccessToken()));
        httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
        String body = JsonUtils.toJson(params).toString();
        StringEntity entity = new StringEntity(body, "utf-8");
        entity.setContentType(ContentType.APPLICATION_JSON.getMimeType());

        httpPost.setEntity(entity);
        org.apache.http.HttpResponse response1;
        response1 = httpClient.execute(httpPost);
        InputStream inputStream = response1.getEntity().getContent();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[8192];
        int bytesRead = 0;
        while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
            out.write(buffer, 0, bytesRead);
        }

        out.flush();
        out.close();
        System.out.println(new String(out.toByteArray()));
  • 首先要求這個openid的使用者在2小時內登入過小程式。
  • 其次通過介面獲取access_token,這個步驟我們們就省略了,可以看這裡:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/access-token/auth.getAccessToken.html
  • 最後,注意請求體必須宣告"UTF-8"。我看到很多朋友呼叫敏感字檢查的時候,都沒有正確返回遮蔽資訊,就是因為沒有使用utf-8!

呼叫成功,會返回:

{"errcode":0,"errmsg":"ok","trace_id":"62219863-342b4e47-6dedd2b5"}

 

 

圖片校驗是否違法請求2——非同步回撥

修改服務端的php程式碼,新增一個事件監聽:

<?php

define('IN_MOD', TRUE);
header("Content-Type: text/html;charset=utf-8");
date_default_timezone_set('PRC');//其中PRC為“中華人民共和國

include_once('wechat.class.php');

$options = array(
    'token'=>'填寫介面配置的 Token(令牌)', 
    'encodingaeskey'=>'填寫介面配置的 EncodingAESKey(訊息加密金鑰)', 
    'appid'=>'填寫小程式的appid', 
       'appsecret'=>'填寫小程式的appsecret',
);

$weObj = new Wechat($options);
$weObj->valid();

// EVENT HANDLE

if ($weObj->getRev()->getRevType() == 'event') {
    $event = $weObj->getRev()->getRevEvent();
    $event = $event['event'];
    if ($event == 'wxa_media_check') {
        $url = 'https://www.pixysoft.cn:8443/sso/wxss/callback/wxa_media_check'; 
        $t = time();
        $sign = 'wxa_media_check'.$t.$options['appsecret'];
        $sign = md5($sign);
        $postdata = array(
            'req' => json_encode($weObj->getRevData()),
            't' => $t,
            'sign' => $sign,
        );
        return $weObj->http_post($url, $postdata);
    }
}

// REPLY TO CUSTOMER

if ($weObj->getRev()->getRevType() == 'text' && $weObj->getRev()->getRevContent()."" == "TEST") {
    $url='https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$weObj->checkAuth();
    $msg = array(
        'touser' => $weObj->getRev()->getRevFrom(),
        'msgtype' => 'text',
        'text' => array(
            'content' => 'HELLOWORLD!'
        )
    );
    $msg = json_encode($msg);
    $ret = $weObj->http_post($url, $msg);
    return 'success';
}

// RECRIECT TO SERVICE

$msg = array(
    'ToUserName'=>$weObj->getRev()->getRevFrom(),
    'FromUserName'=>$weObj->getRev()->getRevTo(),
    'CreateTime'=>$weObj->getRev()->getRevCtime(),
    'MsgType'=>'transfer_customer_service',
);
$weObj->transfer_customer_service()->reply();
return true;
?>

判斷回撥資料是否event,型別是否wxa_media_check,如果是,則表示圖片檢測結果出來了, 我就把結果打個包,發給服務端程式進一步處理。得到的返回資料是:

 

 

格式化一下:

{
    "ToUserName": "gh_f8935bc8ccb8",
    "FromUserName": "o6qII0bS2NFHsMtZ7XGGPC6JapuA",
    "CreateTime": "1646368869",
    "MsgType": "event",
    "Event": "wxa_media_check",
    "appid": "wx207f784d4c617ec9",
    "trace_id": "62219863-342b4e47-6dedd2b5",
    "version": "2",
    "detail": {
        "strategy": "content_model",
        "errcode": "0",
        "suggest": "pass",
        "label": "100",
        "prob": "90"
    },
    "errcode": "0",
    "errmsg": "ok",
    "result": {
        "suggest": "pass",
        "label": "100"
    }
}

 

到了這裡,整個圖片檢測邏輯就完成了。今天的入門包括了客服介面配置、介面php邏輯編寫、圖片檢測回撥。

 

文所有程式碼在這裡可以下載:

連結: https://pan.baidu.com/s/1pkFfEgFHoHOG0tFiS-P1RA

提取碼: ab9u

也歡迎大家關注我們們公眾號:辰同學技術 微信公眾號,同樣會分享各種技術10分鐘從入門到吐槽:

相關文章