public function __construct()
{
$this->aesKey = base64_decode(config('wechat.app.aes_key') . '=');
$this->iv = substr($this->aesKey, 0, 16);
}
public function decrypt(string $encrypted): string
{
$encrypted = base64_decode($encrypted, true);
$randMsg = openssl_decrypt($encrypted, "aes-256-cbc", $this->aesKey, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING ,$this->iv);
$decrypted = $this->decode($randMsg);
if (strlen($decrypted) < 16) {
Log::info('wechat decrypt error, result is ' . $decrypted);
return '';
}
$content = substr($decrypted, 16, strlen($decrypted));
$len_list = unpack("N", substr($content, 0, 4));
$xml_len = $len_list[1];
$result = substr($content, 4, $xml_len);
$formAppId = substr($content, $xml_len + 4);
if ($formAppId != config('wechat.app.aiadartifact.app_id')) {
Log::info('wechat decrypt error, appid is wrong '. $formAppId);
return '';
}
return $result;
}
private function decode($text)
{
$pad = ord(substr($text, -1));
if ($pad < 1 || $pad > 32) {
$pad = 0;
}
return substr($text, 0, (strlen($text) - $pad));
}
private function getAccessToken(): string
{
$accessToken = Redis::get(RedisKey::WECHAT_ACCESS_TOKEN);
if ($accessToken) {
return $accessToken;
}
$resp = HttpClientFactory::factory()->request(
'GET', WechatCustomMessage::ACCESS_TOKEN_URL,
[
'query' => [
'grant_type' => 'client_credential',
'appid' => $this->appId,
'secret' => $this->appSecret
],
]
);
$body = json_decode($resp->getBody()->getContents(), true);
Log::info('get access token from wechat result:' . json_encode($body));
if (isset($body['errcode'])) {
Log::info('get access token from wechat result error: ' . json_encode($body));
return '';
}
Redis::set(RedisKey::WECHAT_ACCESS_TOKEN, $body['access_token']);
Redis::expire(RedisKey::WECHAT_ACCESS_TOKEN, 2 * 60 * 60);
return $body['access_token'];
}
public function sendMsgToUser(string $receiveUser): void
{
$accessToken = $this->getAccessToken();
$execTime = ExecTime::record();
$resp = HttpClientFactory::factory()->request(
'POST', WechatCustomMessage::SEND_MSG_TO_USER,
[
RequestOptions::QUERY => ['access_token' => $accessToken],
RequestOptions::JSON => [
'msgtype' => 'text',
'touser' => $receiveUser,
'text' => [
'content' => 'hello world'
],
],
]
);
$body = $resp->getBody();
Log::info('send wechat message after result:', [
'headers' => $resp->getHeaders(),
'body' => $body,
'exec_time' => $execTime->end(),
]);
}