成功的從企業微信中收到的 Alert 消息的樣子:
Oracle 日志 Alert:

./workweixin_send.php
Usage: workweixin_send.php.php <username> <title> <content>
./workweixin_send.php <這裡填寫企業個人微信ID> hi 這是一條測試的企業微信消息
Windows 指令行使用方法:
php workweixin_send.php <這裡填寫企業個人微信ID> hi 這是一條測試的企業微信消息
測試消息發送成功的樣子:
ZABBIX WEB前端中的配置:
#!/opt/php/bin/php -q
<?php
class Cache
{
/**
* Cache instance
* @var Cache
*/
private static $instance;
protected $conn;
/**
* 獲得一個 cache 緩存執行個體
* @param mixed $params
* @return Cache
*/
public static function getConnect($params = '') : Cache
{
if (! self::$instance instanceof self) {
self::$instance = new self($params);
}
return self::$instance;
}
/**
* 執行個體化一個 cache 執行個體
* @param mixed $params
* @throws \Exception
*/
private function __construct($params)
{
if (! is_array($params)) {
throw new \Exception('Invalid cache params, failed connect to cache server');
}
if (!isset($params['host'])) {
throw new \Exception('Invalid cache host');
}
if (!isset($params['port']) or ($params['port'] < 1 and $params['port'] > 65535)) {
throw new \Exception('Invalid cache port');
}
if (!isset($params['persistent'])) {
$params['persistent'] = false;
}
$params['persistent'] = boolval($params['persistent']);
$this->conn= new \Memcache();
if ($params['persistent']) {
$conn = $this->conn->pconnect($params['host'], $params['port']);
} else {
$conn = $this->conn->connect($params['host'], $params['port']);
}
if ($conn === false) {
throw new \Exception('Failed connect to cache server');
}
}
/**
* 傳回緩存值
* @param string $key
* @param mixed $default
*/
public function get(string $key, $default = null)
{
if (!empty($key)) {
$default = $this->conn->get($key);
}
return $default;
}
/**
* 設定緩存值
* @param string $key
* @param mixed $value
* @param int $ttl
* @param bool $compress
* @return bool
*/
public function set(string $key, $value = null, int $ttl = null, $compress = false)
{
if ($ttl === null) {
$ttl = $this->getTTL();
}
if ($compress) {
return $this->conn->set($key, $value, MEMCACHE_COMPRESSED, $ttl);
} else {
return $this->conn->set($key, $value, 0 , $ttl);
}
}
}
class AccessToken
{
/**
* 企業ID<p>
* 每個企業都擁有唯一的corpid,擷取此資訊可在管理背景“我的企業”-“企業資訊”下檢視“企業ID”
* @var string
*/
protected $corpid;
/**
* secret是企業應用裡面用于保障資料安全的“鑰匙”,每一個應用都有一個獨立的通路密鑰,為了保證資料的安全,secret務必不能洩漏
* @var string
*/
protected $secret;
/**
* 擷取 access token 的 url
* @var string
*/
protected $url;
/**
* 過期時間
* @var string
*/
protected $expire;
/**
* 配置 corpid 和 secret
* @param string $corpid
* @param string $secret
*/
public function __construct(string $corpid, string $secret)
{
$this->corpid = $corpid;
$this->secret = $secret;
}
/**
* 設定擷取 access token 的 url
* @param string $url
*/
public function setUrl(string $url) : AccessToken
{
$this->url = str_replace(['{corpid}', '{secret}'], [$this->corpid, $this->secret], $url);
return $this;
}
/**
* 傳回 access token
* @return string
*/
public function getAccessToken() : string
{
$cache = Cache::getConnect();
$accessToken = $cache->get('work.weixin.access.token');
if (empty($accessToken)) {
$accessToken = $this->getAccessTokenFromServer();
$cache->set('work.weixin.access.token', $accessToken, $this->getExpire() - 60);
}
return $accessToken;
}
/**
* 傳回 access token 的有效時間
* @return int
*/
public function getExpire() : int
{
return $this->expire;
}
/**
* 從企業微信伺服器上擷取 access token
* @return string
*/
final protected function getAccessTokenFromServer() : string
{
$ch = curl_init();
$options = [
CURLOPT_URL => $this->url,
CURLOPT_TIMEOUT => 10,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false
];
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
/*
* 微信接口傳回資料格式:
* {'errcode','errmsg','access_token','expires_in'}
*/
$data = json_decode($response, true);
if (empty($data)) {
throw new \Exception('Failed to access work weixin api');
}
// 判斷是否成功取得access_token
if ($data['errcode'] !== 0) {
throw new \Exception('Failed to get work weixin access token from server. ' . $data['errmsg']);
}
$this->expire = $data['expires_in'];
return $data['access_token'];
}
}
class SendMessage
{
/**
* access token instance
* @var AccessToken
*/
protected $accessToken;
/**
* 發送消息的url
* @var string
*/
protected $url;
/**
* 成員ID清單(指定為@all時則向關注該企業應用的全部成員發送)
* @var array
*/
protected $toUsers = [];
/**
* 部門ID清單(當touser為@all時忽略本參數)
* @var array
*/
protected $toParties = [];
/**
* 标簽ID清單(當touser為@all時忽略本參數)
* @var array
*/
protected $toTags = [];
/**
* 企業應用的id,整型。可在應用的設定頁面檢視
* @var int
*/
protected $agentId;
/**
* 消息内容
* @var string
*/
protected $content;
/**
* 保密資訊(表示是否是保密消息,0表示否,1表示是,預設0)
* @var int
*/
protected $safe = 0;
public function __construct(AccessToken $accessToken)
{
$this->accessToken = $accessToken;
}
/**
* 設定成員ID
* @param array $users
* @return SendMessage
*/
public function setToUsers(array $users) : SendMessage
{
foreach ($users as $k => $user) {
if (is_string($user)) {
$this->toUsers[] = $user;
}
}
return $this;
}
/**
* 設定部門ID
* @param array $parties
* @return SendMessage
*/
public function setToParties(array $parties) : SendMessage
{
foreach ($parties as $k => $party) {
if (is_string($party)) {
$this->toParties[] = $party;
}
}
return $this;
}
/**
* 設定标簽ID
* @param array $tags
* @return SendMessage
*/
public function setToTag(array $tags) : SendMessage
{
foreach ($tags as $k => $tag) {
if (is_string($tag)) {
$this->toTags[] = $tag;
}
}
return $this;
}
/**
* 設定應用ID
* @param int $id
* @return SendMessage
*/
public function setAgentId(int $id) : SendMessage
{
$this->agentId = $id;
return $this;
}
/**
* 設定消息内容(最長不超過2048個位元組)
* @param string $content
* @return SendMessage
*/
public function setContent(string $content) : SendMessage
{
if (!empty($content)) {
$this->content = $content;
}
return $this;
}
public function setUrl(string $url) : SendMessage
{
$this->url = str_replace('{accessToken}', $this->accessToken->getAccessToken(), $url);
return $this;
}
/**
* 調用企業微信 api 發送消息
* @throws \Exception
*/
private function send(string $data)
{
$ch = curl_init();
$options = [
CURLOPT_URL => $this->url,
CURLOPT_HEADER => 0,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $data,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_TIMEOUT => 10,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_SSL_VERIFYHOST => 0
];
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
$data = json_decode($response, true);
if (empty($data)) {
throw new \Exception('Failed to access work weixin api');
}
if ($data['errcode'] !== 0) {
throw new \Exception('Failed to send WeiXin message. ' . $data['errmsg']);
}
}
/**
* 發送文本消息
* @throws \Exception
*/
public function sendTextMessage() {
if (empty($this->toUsers) && empty($this->toParties) && empty($this->toTags)) {
throw new \Exception('Invalid message recevier');
}
if (empty($this->agentId)) {
throw new \Exception('Invalid app agentid');
}
if (empty($this->content)) {
throw new \Exception('Empty message content');
}
$data = json_encode([
'touser' => implode('|', $this->toUsers),
'toparty' => implode('|', $this->toParties),
'totag' => implode('|', $this->toTags),
'msgtype' => 'text',
'agentid' => $this->agentId,
'safe' => $this->safe,
'text' => [
'content' => $this->content
]
], JSON_UNESCAPED_UNICODE);
// 如果第一次發送失敗,嘗試兩次發送
try {
$this->send($data);
} catch (\Exception $e) {
$this->send($data);
}
}
}
// -----------------------------------------------------------------------------------
$cacheParams = [
'host' => '127.0.0.1',
'port' => '11211'
];
// 每個企業都擁有唯一的corpid,擷取此資訊可在管理背景“我的企業”-“企業資訊”下檢視“企業ID”
$corpid = '*************';
//secret是企業應用裡面用于保障資料安全的“鑰匙”,每一個應用都有一個獨立的通路密鑰,為了保證資料的安全,secret務必不能洩漏
$secret = '*************';
// agentid 企業應用的id,整型。可在應用的設定頁面檢視
$agentid = 1;
$fetchAccessTokenUrl= "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpid}&corpsecret={secret}";
$sendMessageUrl = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={accessToken}';
// -----------------------------------------------------------------------------------
if (!isset($argv[1]) || !isset($argv[2]) || !isset($argv[3])) {
echo 'Usage: ' . basename(__FILE__) . '.php <username> <title> <content>';
return;
}
// -----------------------------------------------------------------------------------
try {
Cache::getConnect($cacheParams);
$accessToken = new AccessToken($corpid, $secret);
$accessToken->setUrl($fetchAccessTokenUrl);
$wwx = new SendMessage($accessToken);
$wwx->setAgentId($agentid)
->setUrl($sendMessageUrl)
->setToUsers([$argv[1]])
->setContent(str_replace(' ', '', strip_tags($argv[3])))
->sendTextMessage();
} catch (\Exception $e) {
echo $e->getMessage();
file_put_contents(basename(__FILE__, '.php') . '.log', $e->getMessage());
}