| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878 |
- <?php
- /**
- * The model file of webhook module of ZenTaoPMS.
- *
- * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
- * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
- * @author Gang Liu <liugang@cnezsoft.com>
- * @package webhook
- * @version $Id$
- * @link https://www.zentao.net
- */
- class webhookModel extends model
- {
- /**
- * 获取单个webhook。
- * Get a webhook by id.
- *
- * @param int $id
- * @access public
- * @return object
- */
- public function getByID($id)
- {
- return $this->dao->select('*')->from(TABLE_WEBHOOK)->where('id')->eq($id)->fetch();
- }
- /**
- * 获取某种类型的webhook。
- * Get a webhook by type.
- *
- * @param string $type
- * @param int $id
- * @access public
- * @return object
- */
- public function getByType($type, $id = 0)
- {
- return $this->dao->select('*')->from(TABLE_WEBHOOK)->where('type')->eq($type)
- ->andWhere('deleted')->eq('0')
- ->beginIF($id)->andWhere('id')->eq($id)->fi()
- ->fetch();
- }
- /**
- * 获取已经绑定的用户。
- * Get a webhook by type.
- *
- * @param int $webhookID
- * @param string $webhookType
- * @param string $openID
- * @access public
- * @return object
- */
- public function getBindAccount($webhookID, $webhookType, $openID)
- {
- return $this->dao->select('account')->from(TABLE_OAUTH)
- ->where('providerID')->eq($webhookID)
- ->andWhere('providerType')->eq($webhookType)
- ->andWhere('openID')->eq($openID)
- ->fetch('account');
- }
- /**
- * 获取webhook列表。
- * Get webhook list.
- *
- * @param string $orderBy
- * @param object $pager
- * @access public
- * @return array
- */
- public function getList($orderBy = 'id_desc', $pager = null)
- {
- return $this->dao->select('*,products,executions')->from(TABLE_WEBHOOK)
- ->where('deleted')->eq('0')
- ->orderBy($orderBy)
- ->page($pager)
- ->fetchAll('id', false);
- }
- /**
- * 获取日志列表。
- * Get log list of a webhook.
- *
- * @param int $id
- * @param string $orderBy
- * @param object $pager
- * @access public
- * @return array
- */
- public function getLogList($id, $orderBy = 'date_desc', $pager = null)
- {
- $logs = $this->dao->select('*')->from(TABLE_LOG)
- ->where('objectType')->eq('webhook')
- ->andWhere('objectID')->eq($id)
- ->orderBy($orderBy)
- ->page($pager)
- ->fetchAll('id', false);
- $actions = array();
- foreach($logs as $log) $actions[] = $log->action;
- $this->loadModel('action');
- $actions = $this->dao->select('*')->from(TABLE_ACTION)->where('id')->in($actions)->fetchAll('id');
- $users = $this->loadModel('user')->getPairs('noletter');
- foreach($logs as $log)
- {
- if(!isset($actions[$log->action]))
- {
- $log->action = '';
- continue;
- }
- $action = $actions[$log->action];
- $data = json_decode($log->data);
- $object = $this->dao->select('*')->from($this->config->objectTables[$action->objectType])->where('id')->eq($action->objectID)->fetch();
- $field = zget($this->config->action->objectNameFields, $action->objectType, $action->objectType);
- if(empty($data)) continue;
- if(!is_object($object))
- {
- $object = new stdclass;
- $object->$field = '';
- }
- $log->action = $this->webhookTao->getActionText($data, $action, $object, $users);
- $log->actionURL = $this->getViewLink($action->objectType, $action->objectID);
- $log->module = $action->objectType;
- $log->moduleID = $action->objectID;
- $log->dialog = $action->objectType == 'todo' ? 1 : 0;
- }
- return $logs;
- }
- /**
- * 获取通知信息。
- * Get saved data list.
- *
- * @access public
- * @return array
- */
- public function getDataList()
- {
- $now = helper::now();
- $dataList = $this->dao->select('*')->from(TABLE_NOTIFY)
- ->where('status')->eq('wait')
- ->andWhere('objectType')->eq('webhook')
- ->andWhere('(sendTime IS NULL OR sendTime <= "' . $now . '")')
- ->orderBy('id')
- ->fetchAll('id', false);
- $threeHoursAgo = date('Y-m-d H:i:s', time() - 3 * 3600);
- $dataList += $this->dao->select('*')->from(TABLE_NOTIFY)
- ->where('status')->eq('senting')
- ->andWhere('objectType')->eq('webhook')
- ->andWhere('(sendTime IS NULL OR (sendTime <= "' . $now . '" AND sendTime >= "' . $threeHoursAgo . '"))')
- ->orderBy('id')
- ->fetchAll('id', false);
- return $dataList;
- }
- /**
- * 获取绑定用户。
- * Get bind users.
- *
- * @param int $webhookID
- * @param array|string $users
- * @access public
- * @return array
- */
- public function getBoundUsers($webhookID, $users = array())
- {
- return $this->dao->select('*')->from(TABLE_OAUTH)->where('providerType')->eq('webhook')
- ->andWhere('providerID')->eq($webhookID)
- ->beginIF($users)->andWhere('account')->in($users)->fi()
- ->fetchPairs('account', 'openID');
- }
- /**
- * 创建webhook。
- * Create a webhook.
- *
- * @param object $webhook
- *
- * @access public
- * @return int|false
- */
- public function create($webhook)
- {
- $webhook->createdBy = $this->app->user->account;
- $webhook->createdDate = helper::now();
- $webhook->domain = trim($webhook->domain, '/');
- $webhook->params = $this->post->params ? implode(',', $this->post->params) . ',text' : 'text';
- if($webhook->type == 'dinguser')
- {
- $webhook = $this->webhookTao->getDingdingSecret($webhook);
- }
- elseif($webhook->type == 'wechatuser')
- {
- $webhook = $this->webhookTao->getWeixinSecret($webhook);
- }
- elseif($webhook->type == 'feishuuser')
- {
- $webhook = $this->webhookTao->getFeishuSecret($webhook);
- }
- if(!empty($webhook->url) && !preg_match('/^http(s)?:\/\//', $webhook->url)) dao::$errors['url'] = $this->lang->webhook->error->url;
- if(dao::isError()) return false;
- $this->dao->insert(TABLE_WEBHOOK)->data($webhook, 'agentId,appKey,appSecret,wechatCorpId,wechatCorpSecret,wechatAgentId,feishuAppId,feishuAppSecret')
- ->batchCheck($this->config->webhook->create->requiredFields, 'notempty')
- ->autoCheck()
- ->exec();
- return $this->dao->lastInsertID();
- }
- /**
- * 编辑webhook。
- * Update a webhook.
- *
- * @param int $id
- * @param object $webhook
- * @access public
- * @return bool
- */
- public function update($id, $webhook)
- {
- $webhook->editedBy = $this->app->user->account;
- $webhook->editedDate = helper::now();
- $webhook->domain = trim($webhook->domain, '/');
- $webhook->params = $this->post->params ? implode(',', $this->post->params) : 'text';
- if(strpos($webhook->params, 'text') === false) $webhook->params .= ',text';
- if($webhook->type == 'dinguser')
- {
- $webhook = $this->webhookTao->getDingdingSecret($webhook);
- }
- elseif($webhook->type == 'wechatuser')
- {
- $webhook = $this->webhookTao->getWeixinSecret($webhook);
- }
- elseif($webhook->type == 'feishuuser')
- {
- $webhook = $this->webhookTao->getFeishuSecret($webhook);
- }
- if(!empty($webhook->url) && !preg_match('/^http(s)?:\/\//', $webhook->url)) dao::$errors['url'] = $this->lang->webhook->error->url;
- if(dao::isError()) return false;
- $this->dao->update(TABLE_WEBHOOK)->data($webhook, 'agentId,appKey,appSecret,wechatCorpId,wechatCorpSecret,wechatAgentId,feishuAppId,feishuAppSecret')
- ->batchCheck($this->config->webhook->edit->requiredFields, 'notempty')
- ->autoCheck()
- ->where('id')->eq($id)
- ->exec();
- return !dao::isError();
- }
- /**
- * 绑定钉钉、飞书、企业微信的用户到禅道。
- * Bind users of dingding, feishu, weixin to zentao.
- *
- * @param int $webhookID
- * @access public
- * @return bool
- */
- public function bind($webhookID)
- {
- $userList = $this->post->userid;
- if(!$userList) return false;
- $this->dao->delete()->from(TABLE_OAUTH)
- ->where('providerType')->eq('webhook')
- ->andWhere('providerID')->eq($webhookID)
- ->andWhere('account')->in(array_keys($userList))
- ->exec();
- foreach($userList as $account => $userid)
- {
- if(empty($userid)) continue;
- $oauth = new stdclass();
- $oauth->account = $account;
- $oauth->openID = $userid;
- $oauth->providerType = 'webhook';
- $oauth->providerID = $webhookID;
- $this->dao->insert(TABLE_OAUTH)->data($oauth)->exec();
- }
- return !dao::isError();
- }
- /**
- * 发送数据。
- * Send data.
- *
- * @param string $objectType
- * @param int $objectID
- * @param string $actionType
- * @param int $actionID
- * @param string $actor
- * @access public
- * @return bool
- */
- public function send($objectType, $objectID, $actionType, $actionID, $actor = '')
- {
- static $webhooks = array();
- if(!$webhooks) $webhooks = $this->getList();
- if(!$webhooks) return true;
- /* 如果对象类型是瀑布,动作是提交审计或者审计,那么对象类型就是审批。*/
- if($objectType == 'waterfall' && strpos(',toaudit,audited,', ",{$actionType},") !== false) $objectType = 'review';
- $aitaskObject = null;
- if($objectType == 'aitask' && in_array($actionType, array('finished', 'failed')))
- {
- $aitaskObject = $this->dao->select('*')->from(TABLE_AI_TASK)->where('id')->eq($objectID)->fetch();
- }
- foreach($webhooks as $id => $webhook)
- {
- $postData = $this->buildData($objectType, $objectID, $actionType, $actionID, $webhook);
- if(!$postData) continue;
- $needDelay = false;
- if($aitaskObject && !empty($aitaskObject->noticeTime) && $aitaskObject->noticeTime != '1')
- {
- $needDelay = true;
- }
- if($webhook->sendType == 'async' || $needDelay)
- {
- if($webhook->type == 'dinguser')
- {
- $openIdList = $this->getOpenIdList($webhook->id, $actionID);
- if(empty($openIdList)) continue;
- }
- $this->saveData($id, $actionID, $postData, $actor, $aitaskObject);
- continue;
- }
- $result = $this->fetchHook($webhook, $postData, $actionID);
- if(!empty($result)) $this->saveLog($webhook, $actionID, $postData, (string)$result);
- }
- return !dao::isError();
- }
- /**
- * Build data.
- *
- * @param string $objectType
- * @param int $objectID
- * @param string $actionType
- * @param int $actionID
- * @param object $webhook
- * @access public
- * @return string
- */
- public function buildData($objectType, $objectID, $actionType, $actionID, $webhook)
- {
- /* Validate data. */
- if(!isset($this->lang->action->label)) $this->loadModel('action');
- if(!isset($this->lang->action->label->$actionType)) return false;
- if(empty($this->config->objectTables[$objectType])) return false;
- $action = $this->dao->select('*')->from(TABLE_ACTION)->where('id')->eq($actionID)->fetch();
- if(!$action) return false;
- if($webhook->products)
- {
- $webhookProducts = explode(',', trim($webhook->products, ','));
- $actionProduct = explode(',', trim($action->product, ','));
- $intersect = array_intersect($webhookProducts, $actionProduct);
- if(!$intersect) return false;
- }
- if($webhook->executions && strpos(",$webhook->executions,", ",$action->execution,") === false) return false;
- static $users = array();
- if(empty($users)) $users = $this->loadModel('user')->getList();
- $object = $this->dao->select('*')->from($this->config->objectTables[$objectType])->where('id')->eq($objectID)->fetch();
- if(!$object) return false;
- $host = empty($webhook->domain) ? common::getSysURL() : $webhook->domain;
- $viewLink = $this->getViewLink($objectType == 'kanbancard' ? 'kanban' : $objectType, $objectType == 'kanbancard' ? $object->kanban : $objectID);
- if($objectType == 'aitask' && in_array($actionType, array('finished', 'failed')))
- {
- $text = $this->loadModel('aitask')->getNotificationText($object, $objectID, $actionType, 'markdown', '', $viewLink, $host);
- $title = $text;
- }
- else
- {
- $field = $this->config->action->objectNameFields[$objectType];
- $objectTypeName = ($objectType == 'story' and $object->type == 'requirement') ? $this->lang->action->objectTypes['requirement'] : $this->lang->action->objectTypes[$objectType];
- $title = $this->app->user->realname . $this->lang->action->label->$actionType . $objectTypeName;
- $host = (defined('RUN_MODE') and RUN_MODE == 'api') ? '' : $host;
- $text = $title . ' ' . "[#{$objectID}::{$object->$field}](" . $host . $viewLink . ")";
- }
- $action->text = $text;
- $mobile = '';
- $email = '';
- if(in_array($objectType, $this->config->webhook->needAssignTypes) && !empty($object->assignedTo))
- {
- $assignedTo = $this->loadModel('user')->getById($object->assignedTo);
- if($assignedTo)
- {
- $mobile = $assignedTo->mobile;
- $email = $assignedTo->email;
- }
- }
- return $this->getDataByType($webhook, $action, $title, $text, $mobile, $email, $objectType, $objectID);
- }
- /**
- * 根据webhook类型获取数据。
- * Get data by type.
- *
- * @param object $webhook
- * @param object $action
- * @param string $title
- * @param string $text
- * @param string $mobile
- * @param string $email
- * @param string $objectType
- * @param int $objectID
- * @access public
- * @return string
- */
- public function getDataByType($webhook, $action, $title, $text, $mobile, $email, $objectType, $objectID)
- {
- if($webhook->type == 'dinggroup' or $webhook->type == 'dinguser')
- {
- $data = $this->getDingdingData($title, $text, $webhook->type == 'dinguser' ? '' : $mobile);
- }
- elseif($webhook->type == 'bearychat')
- {
- $data = $this->getBearychatData($text, $mobile, $email, $objectType, $objectID);
- }
- elseif($webhook->type == 'wechatgroup' or $webhook->type == 'wechatuser')
- {
- $data = $this->getWeixinData($text, $mobile);
- }
- elseif($webhook->type == 'feishuuser' or $webhook->type == 'feishugroup')
- {
- $data = $this->getFeishuData($title, $text);
- }
- else
- {
- $data = new stdclass();
- foreach(explode(',', $webhook->params) as $param) $data->$param = $action->$param;
- }
- return json_encode($data);
- }
- /**
- * 获取对象详情链接。
- * Get view link.
- *
- * @param string $objectType
- * @param int $objectID
- * @access public
- * @return string
- */
- public function getViewLink($objectType, $objectID)
- {
- $oldOnlyBody = '';
- $tab = '';
- if(isset($_GET['onlybody']) and $_GET['onlybody'] == 'yes')
- {
- $oldOnlyBody = 'yes';
- unset($_GET['onlybody']);
- }
- if($objectType == 'case') $objectType = 'testcase';
- if($objectType == 'kanbancard')
- {
- $objectType = 'kanban';
- $objectID = $this->dao->select('kanban')->from(TABLE_KANBANCARD)->where('id')->eq($objectID)->fetch('kanban');
- }
- if($objectType == 'meeting')
- {
- $meeting = $this->dao->findById($objectID)->from(TABLE_MEETING)->fetch();
- $tab = $meeting->project ? '#app=project' : '#app=my';
- }
- if($objectType == 'aitask')
- {
- $viewLink = helper::createLink('aitask', 'view', "taskID={$objectID}", 'html') . $tab;
- if($oldOnlyBody) $_GET['onlybody'] = $oldOnlyBody;
- return $viewLink;
- }
- $viewLink = helper::createLink($objectType, 'view', "id=$objectID", 'html') . $tab;
- if($oldOnlyBody) $_GET['onlybody'] = $oldOnlyBody;
- return $viewLink;
- }
- /**
- * 获取发送钉钉的数据。
- * Get hook data for dingding.
- *
- * @param string $title
- * @param string $text
- * @param string $mobile
- * @access public
- * @return object
- */
- public function getDingdingData($title, $text, $mobile)
- {
- if($mobile) $text .= " @{$mobile}";
- $markdown = new stdclass();
- $markdown->title = $title;
- $markdown->text = $text;
- $data = new stdclass();
- $data->msgtype = 'markdown';
- $data->markdown = $markdown;
- if($mobile)
- {
- $at = new stdclass();
- $at->atMobiles = array($mobile);
- $at->isAtAll = false;
- $data->at = $at;
- }
- return $data;
- }
- /**
- * 获取发送bearychat的数据。
- * Get hook data for bearychat.
- *
- * @param string $text
- * @param string $mobile
- * @param string $email
- * @param string $objectType
- * @param int $objectID
- * @access public
- * @return object
- */
- public function getBearychatData($text, $mobile, $email, $objectType, $objectID)
- {
- $data = new stdclass();
- $data->text = $text;
- $data->markdown = 'true';
- if($mobile)
- {
- $data->user = $mobile;
- }
- elseif($email)
- {
- $data->user = $email;
- }
- else
- {
- $data->user = $this->app->user->account;
- }
- if(!empty($_FILES['files']['name'][0]))
- {
- $this->loadModel('file');
- $files = $this->dao->select('*')->from(TABLE_FILE)->where('objectType')->eq($objectType)->andWhere('objectID')->eq($objectID)->orderBy('addedDate_desc,id_desc')->limit(count($_FILES['files']['name']))->fetchAll();
- if($files)
- {
- foreach($files as $file)
- {
- $attachment = array();
- $attachment['title'] = $file->title;
- $attachment['images'][]['url'] = common::getSysURL() . $this->file->webPath . $file->pathname;
- $data->attachments[] = $attachment;
- }
- }
- }
- return $data;
- }
- /**
- * 获取发送微信的数据。
- * Get weixin send data.
- *
- * @param string $text
- * @param string $mobile
- * @access public
- * @return object
- */
- public function getWeixinData($text, $mobile = '')
- {
- $data = new stdclass();
- $data->msgtype = 'markdown';
- $markdown = new stdclass();
- $markdown->content = $text;
- if($mobile)
- {
- $data->msgtype = 'text';
- $markdown->mentioned_mobile_list = array($mobile);
- }
- $data->{$data->msgtype} = $markdown;
- return $data;
- }
- /**
- * 获取发送飞书的数据。
- * Get feishu send data.
- *
- * @param string $title
- * @param string $text
- * @access public
- * @return object
- */
- public function getFeishuData($title, $text)
- {
- $data = new stdclass();
- $data->msg_type = 'interactive';
- $data->card = array();
- $data->card['header'] = array();
- $data->card['elements'] = array();
- $data->card['elements'][] = array('tag' => 'markdown', 'content' => $text);
- $data->card['header']['title'] = array('tag' => 'plain_text', 'content' => (string)$title);
- $data->card['header']['template'] = 'blue';
- return $data;
- }
- /**
- * 获取openID列表。
- * Get openID list.
- *
- * @param int $webhookID
- * @param int $actionID
- * @param string|array $toList
- * @access public
- * @return string
- */
- public function getOpenIdList($webhookID, $actionID, $toList = '')
- {
- if($toList)
- {
- $openIdList = $this->getBoundUsers($webhookID, $toList);
- $openIdList = implode(',', $openIdList);
- return $openIdList;
- }
- if(empty($actionID)) return false;
- $action = $this->dao->select('*')->from(TABLE_ACTION)->where('id')->eq($actionID)->fetch();
- $table = zget($this->config->objectTables, $action->objectType, '');
- if(empty($table)) return false;
- $object = $this->dao->select('*')->from($table)->where('id')->eq($action->objectID)->fetch();
- $toList = $this->loadModel('message')->getToList((object)$object, $action->objectType, $actionID);
- if(!empty($object->mailto)) $toList .= ',' . $object->mailto;
- if(empty($toList)) return false;
- /* Remove duplicate people. */
- if($action->objectType == 'release')
- {
- $toList = array_unique(explode(',', $toList));
- $toList = implode(',', $toList);
- }
- $toList = str_replace(",{$this->app->user->account},", ',', ",$toList,");
- $openIdList = $this->getBoundUsers($webhookID, $toList);
- $openIdList = implode(',', $openIdList);
- return $openIdList;
- }
- /**
- * 请求发送数据的接口。
- * Post hook data.
- *
- * @param object $webhook
- * @param string $sendData
- * @param int $actionID
- * @param string|array $appendUser
- * @access public
- * @return int
- */
- public function fetchHook($webhook, $sendData, $actionID = 0, $appendUser = '')
- {
- if(!extension_loaded('curl')) return print(helper::jsonEncode($this->lang->webhook->error->curl));
- if(in_array($webhook->type, array('dinguser', 'wechatuser', 'feishuuser'))) return $this->sendToUser($webhook, $sendData, $actionID, $appendUser);
- $contentType = "Content-Type: {$webhook->contentType};charset=utf-8";
- if($webhook->type == 'dinggroup' or $webhook->type == 'wechatgroup' or $webhook->type == 'feishugroup') $contentType = "Content-Type: application/json";
- $header[] = $contentType;
- $url = $webhook->url;
- if($webhook->type == 'dinggroup' and $webhook->secret)
- {
- $timestamp = time() * 1000;
- $sign = $timestamp . "\n" . $webhook->secret;
- $sign = urlencode(base64_encode(hash_hmac('sha256', $sign, $webhook->secret, true)));
- $url .= "×tamp={$timestamp}&sign={$sign}";
- }
- if($webhook->type == 'feishugroup' and $webhook->secret)
- {
- $timestamp = time();
- $sign = $timestamp . "\n" . $webhook->secret;
- $sign = base64_encode(hash_hmac('sha256', '', $sign, true));
- $content = json_decode($sendData);
- $content->timestamp = $timestamp;
- $content->sign = $sign;
- $sendData = json_encode($content);
- }
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
- curl_setopt($ch, CURLOPT_TIMEOUT, 30);
- curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
- curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
- curl_setopt($ch, CURLOPT_POSTFIELDS, $sendData);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
- $result = curl_exec($ch);
- $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
- $error = curl_error($ch);
- curl_close($ch);
- if($error) return $error;
- if($result) return $result;
- return $httpCode;
- }
- /**
- * 发送消息到钉钉、飞书、企业微信的用户。
- * Send to dingding, feishu, weixin users.
- *
- * @param object $webhook
- * @param string $sendData
- * @param int $actionID
- * @param string|array $appendUser
- * @access public
- * @return string|false
- */
- public function sendToUser($webhook, $sendData, $actionID, $appendUser)
- {
- if(is_string($webhook->secret)) $webhook->secret = json_decode($webhook->secret);
- $openIdList = $this->getOpenIdList($webhook->id, $actionID, $appendUser);
- if(empty($openIdList)) return false;
- if($webhook->type == 'dinguser')
- {
- $this->app->loadClass('dingapi', true);
- $dingapi = new dingapi($webhook->secret->appKey, $webhook->secret->appSecret, $webhook->secret->agentId);
- $result = $dingapi->send($openIdList, $sendData);
- return json_encode($result);
- }
- elseif($webhook->type == 'wechatuser')
- {
- $this->app->loadClass('wechatapi', true);
- $wechatapi = new wechatapi($webhook->secret->appKey, $webhook->secret->appSecret, $webhook->secret->agentId);
- $result = $wechatapi->send($openIdList, $sendData);
- return json_encode($result);
- }
- elseif($webhook->type == 'feishuuser')
- {
- $this->app->loadClass('feishuapi', true);
- $feishuapi = new feishuapi($webhook->secret->appId, $webhook->secret->appSecret);
- $result = $feishuapi->send($openIdList, $sendData);
- return json_encode($result);
- }
- }
- /**
- * 保存发送的通知。
- * Save datas.
- *
- * @param int $webhookID
- * @param int $actionID
- * @param string $data
- * @param string $actor
- * @access public
- * @return bool
- * @param object $aitaskObject
- */
- public function saveData($webhookID, $actionID, $data, $actor = '', $aitaskObject = null)
- {
- if(empty($actor)) $actor = $this->app->user->account;
- $sendTime = helper::now();
- $object = $aitaskObject;
- if(!$object)
- {
- $action = $this->loadModel('action')->getById($actionID);
- if($action && $action->objectType == 'aitask' && in_array($action->action, array('finished', 'failed')))
- {
- $object = $this->dao->select('*')->from(TABLE_AI_TASK)->where('id')->eq($action->objectID)->fetch();
- }
- }
- if($object && !empty($object->noticeTime) && $object->noticeTime != '1')
- {
- $today = date('Y-m-d');
- $targetTime = $today . ' ' . $object->noticeTime . ':00';
- $targetTimestamp = strtotime($targetTime);
- $nowTimestamp = time();
- $sendTime = $targetTimestamp < $nowTimestamp ? helper::now() : $targetTime;
- }
- $webhookData = new stdclass();
- $webhookData->objectType = 'webhook';
- $webhookData->objectID = $webhookID;
- $webhookData->action = $actionID;
- $webhookData->data = $data;
- $webhookData->status = 'wait';
- $webhookData->createdBy = $actor;
- $webhookData->createdDate = helper::now();
- $webhookData->sendTime = $sendTime;
- $this->dao->insert(TABLE_NOTIFY)->data($webhookData)->exec();
- return !dao::isError();
- }
- /**
- * 保存发送日志。
- * Save log.
- *
- * @param object $webhook
- * @param int $actionID
- * @param string $data
- * @param string|int $result
- * @access public
- * @return bool
- */
- public function saveLog($webhook, $actionID, $data, $result)
- {
- $log = new stdclass();
- $log->objectType = 'webhook';
- $log->objectID = $webhook->id;
- $log->action = $actionID;
- $log->date = helper::now();
- $log->url = $webhook->url;
- $log->contentType = $webhook->contentType;
- $log->data = $data;
- $log->result = (string)$result;
- $this->dao->insert(TABLE_LOG)->data($log)->exec();
- return !dao::isError();
- }
- /**
- * 设置消息发送状态。
- * Set sent status.
- *
- * @param array|int|string $idList
- * @param string $status
- * @param string $time
- * @access public
- * @return void
- */
- public function setSentStatus($idList, $status, $time = '')
- {
- $this->dao->update(TABLE_NOTIFY)
- ->set('status')->eq($status)
- ->beginIF(!empty($time))->set('sendTime')->eq($time)->fi()
- ->where('id')->in($idList)
- ->exec();
- }
- }
|