apiSingle.php 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034
  1. <?php
  2. namespace weworkapi\api;
  3. use app\model\Company;
  4. use app\model\WeworksingleContactWay;
  5. use EasyWeChat\Factory;
  6. use EasyWeChat\Kernel\Messages\TextCard;
  7. use think\facade\Config;
  8. use think\facade\Log;
  9. use \WxWorkFinanceSdk;
  10. use \WxworkFinanceSdkException;
  11. class apiSingle {
  12. protected $app = null;
  13. public $error = null;
  14. protected $config = null;
  15. private $errorCode = 1;
  16. private $errorMsg = ['errcode'=> 1, 'errmsg'=> 'error'];
  17. public function __construct($config='')
  18. {
  19. if ($config){
  20. $this->config = $config;
  21. $this->app = Factory::work($config);
  22. }
  23. }
  24. /**
  25. * 获取部门列表
  26. * @return mixed
  27. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  28. */
  29. public function getDepartmentList(){
  30. return $this->app->department->list();
  31. }
  32. /**
  33. * 根据部门ID获取用户列表
  34. * @param int $departmentId 部门ID
  35. * @param bool $fetchChild 是否查询子部门
  36. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  37. */
  38. public function getUserList($departmentId = 1, $fetchChild = false){
  39. $list_result = $this->app->user->getDetailedDepartmentUsers($departmentId, $fetchChild);
  40. $list = $list_result['userlist'];
  41. return $list;
  42. }
  43. /**
  44. * 根据用户ID获取用户详情
  45. */
  46. public function getUserById($userId){
  47. return $this->app->user->get($userId);
  48. }
  49. /**
  50. * 开启外部联系功能的成员
  51. */
  52. public function getExternalContactUser(){
  53. return $this->app->external_contact->getFollowUsers();
  54. // $result['follow_user'];
  55. }
  56. /**
  57. * 根据客户id获取客户详情
  58. * @param $customer_id
  59. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  60. * @throws \GuzzleHttp\Exception\GuzzleException
  61. */
  62. public function getCustomerDetailById($customer_id){
  63. return $this->app->external_contact->get($customer_id);
  64. }
  65. /**
  66. * 根据用户ID批量获取外部联系人详情
  67. * @param string $user_id 内部人员ID
  68. * @param string $cursor 请求分页
  69. * @param int $limit 单次条数
  70. */
  71. public function getCustomerDetailByUser($user_id = [], $cursor = '', $limit = 100, $list = []){
  72. $result = $this->app->external_contact->batchGetByUser($user_id, $cursor, $limit);
  73. $list = array_merge($list, $result['external_contact_list']);
  74. if ($result['next_cursor']) {
  75. return $this->getCustomerDetailByUser($user_id, $result['next_cursor'], $limit, $list);
  76. }
  77. return $list;
  78. }
  79. /**
  80. * 根据用户ID获取外部联系人列表
  81. * @param string $user_id
  82. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  83. * @throws \GuzzleHttp\Exception\GuzzleException
  84. */
  85. public function getCustomerListByUser($user_id = ''){
  86. $result = $this->app->external_contact->list($user_id);
  87. if ($result['errcode'] == 0) {
  88. return $result;
  89. } else {
  90. Log::record($result['errmsg'])->save();
  91. return $this->errorMsg;
  92. }
  93. // $result['external_userid'];
  94. }
  95. /**
  96. * 拉取会话记录
  97. * @param int $start_seq
  98. * @return bool
  99. */
  100. public function getTalkRecord($start_seq = 0, $config = []){
  101. try {
  102. //$config = Config::get('app.wework_talk_record');
  103. $obj = new \WxworkFinanceSdk($config['corp_id'], $config['secret'], [
  104. "proxy_password" => "world",
  105. "timeout" => -2,
  106. ]);
  107. // 私钥地址
  108. $privateKey = file_get_contents($config['private_key']);
  109. $chats = json_decode($obj->getChatData($start_seq, 1000), true);
  110. $msg_data = []; //消息数组
  111. $file_data = []; // 文件数组
  112. $recall_data = []; // 撤回消息数据
  113. foreach ($chats['chatdata'] as $val) {
  114. // 单条消息数组
  115. unset($once_msg);
  116. $once_msg = [];
  117. //单条存储文件信息
  118. unset($once_file);
  119. $once_file = [];
  120. $once_file['is_local'] = 1; // 1文件在本地 0 文件在OSS
  121. $once_file['local_delete'] = 1; // 1文件在本地未删除
  122. $decryptRandKey = null;
  123. openssl_private_decrypt(base64_decode($val['encrypt_random_key']), $decryptRandKey, $privateKey, OPENSSL_PKCS1_PADDING);
  124. $str = $obj->decryptData($decryptRandKey, $val['encrypt_chat_msg']);
  125. $msg = json_decode($str, true);
  126. // 切换企业单独处理
  127. if ($msg['action'] == 'switch') {
  128. $once_msg['company_id'] = $config['company_id'];
  129. $once_msg['msgid'] = $msg['msgid'];
  130. $once_msg['action'] = 'switch';
  131. $once_msg['msgfrom'] = $msg['user'];
  132. $once_msg['msgtime'] = strtotime(get_microtime_format($msg['time']));
  133. $once_msg['msgtype'] = 'switch';
  134. $once_msg['content'] = '切换企业';
  135. $once_msg['json_content'] = $str;
  136. $msg_data[] = $once_msg;
  137. continue;
  138. }
  139. $once_msg = $msg;
  140. $once_msg['company_id'] = $config['company_id'];
  141. $once_msg['msgfrom'] = !empty($msg['from']) ? $msg['from'] : '';
  142. $once_msg['tolist'] = !empty($msg['tolist']) ? json_encode($msg['tolist']) : '';
  143. $once_msg['json_content'] = $str;
  144. if (!empty($msg['msgtype'])) {
  145. switch ($msg['msgtype']) {
  146. case 'text':
  147. // 文本
  148. $once_msg['content'] = $msg['text']['content'];
  149. break;
  150. case 'image':
  151. // 图片
  152. $path = 'weworksingle_file/'.$config['company_id'].'/' . date('Ymd') . '/';
  153. $dir_path = public_path() . $path;
  154. if (!mkdirs($dir_path)) {
  155. Log::record('----------image error---------')->save();
  156. Log::record('创建' . $dir_path . '失败')->save();
  157. Log::record('----------image error---------')->save();
  158. break;
  159. }
  160. $file_name = make_file_name($dir_path, 'jpg');
  161. try {
  162. $obj->downloadMedia($msg['image']['sdkfileid'], $dir_path . $file_name);
  163. } catch (\WxworkFinanceSdkException $e) {
  164. Log::record('----------image error---------')->save();
  165. Log::record($e->getMessage())->save();
  166. Log::record('----------image error---------')->save();
  167. break;
  168. }
  169. $once_msg['content'] = $file_name;
  170. $once_file['msgid'] = $msg['msgid'];
  171. $once_file['path'] = $path . $file_name;
  172. $once_file['filename'] = $file_name;
  173. $once_file['sdkfileid'] = $msg['image']['sdkfileid'];
  174. $once_file['filesize'] = $msg['image']['filesize'];
  175. $once_file['md5sum'] = $msg['image']['md5sum'];
  176. $once_file['cretetime'] = time();
  177. $file_data[] = $once_file;
  178. break;
  179. case 'revoke':
  180. // 撤回消息
  181. $recall_data[] = $msg['revoke']['pre_msgid'];
  182. break;
  183. case 'agree':
  184. // 同意会话聊天内容
  185. break;
  186. case 'voice':
  187. // 语音消息
  188. $path = 'weworksingle_file/'.$config['company_id'].'/' . date('Ymd') . '/';
  189. $dir_path = public_path() . $path;
  190. if (!mkdirs($dir_path)) {
  191. Log::record('----------voice error---------')->save();
  192. Log::record('创建' . $dir_path . '失败')->save();
  193. Log::record('----------voice error---------')->save();
  194. break;
  195. }
  196. $amr = make_file_name($dir_path, 'amr');
  197. $mp3 = make_file_name($dir_path, 'mp3');
  198. try {
  199. $obj->downloadMedia($msg['voice']['sdkfileid'], $dir_path . $amr);
  200. } catch (\WxworkFinanceSdkException $e) {
  201. Log::record('----------voice download error---------')->save();
  202. Log::record($e->getMessage())->save();
  203. Log::record('----------voice download error---------')->save();
  204. break;
  205. }
  206. // amr2mp3
  207. $amr_path = $dir_path . $amr;
  208. $mp3_path = $dir_path . $mp3;
  209. if (file_exists($amr_path)) {
  210. try {
  211. $command = "/usr/local/bin/ffmpeg -i $amr_path $mp3_path";
  212. exec($command, $error);
  213. Log::record('----------arm2mp3 $error---------')->save();
  214. Log::record($error)->save();
  215. Log::record('----------arm2mp3 $error---------')->save();
  216. } catch (\WxworkFinanceSdkException $e) {
  217. Log::record('----------arm2mp3 error---------')->save();
  218. Log::record($e->getMessage())->save();
  219. Log::record('----------arm2mp3 error---------')->save();
  220. }
  221. }
  222. $once_msg['content'] = $mp3;
  223. $once_file['other_file'] = $amr;
  224. $once_file['other_path'] = $path . $amr;
  225. $once_file['msgid'] = $msg['msgid'];
  226. $once_file['path'] = $path . $mp3;
  227. $once_file['filename'] = $mp3;
  228. $once_file['sdkfileid'] = $msg['voice']['sdkfileid'];
  229. $once_file['filesize'] = $msg['voice']['voice_size'];
  230. $once_file['md5sum'] = $msg['voice']['md5sum'];
  231. $once_file['cretetime'] = time();
  232. $file_data[] = $once_file;
  233. break;
  234. case 'video':
  235. // 视频消息
  236. $path = 'weworksingle_file/'.$config['company_id'].'/' . date('Ymd') . '/';
  237. $dir_path = public_path() . $path;
  238. if (!mkdirs($dir_path)) {
  239. Log::record('----------video error---------')->save();
  240. Log::record('创建' . $dir_path . '失败')->save();
  241. Log::record('----------video error---------')->save();
  242. break;
  243. }
  244. $file_name = make_file_name($dir_path, 'mp4');
  245. try {
  246. $obj->downloadMedia($msg['video']['sdkfileid'], $dir_path . $file_name);
  247. } catch (\WxworkFinanceSdkException $e) {
  248. Log::record('----------video error---------')->save();
  249. Log::record($e->getMessage())->save();
  250. Log::record('----------video error---------')->save();
  251. break;
  252. }
  253. $once_msg['content'] = $file_name;
  254. $once_file['msgid'] = $msg['msgid'];
  255. $once_file['path'] = $path . $file_name;
  256. $once_file['filename'] = $file_name;
  257. $once_file['sdkfileid'] = $msg['video']['sdkfileid'];
  258. $once_file['filesize'] = $msg['video']['filesize'];
  259. $once_file['md5sum'] = $msg['video']['md5sum'];
  260. $once_file['cretetime'] = time();
  261. $file_data[] = $once_file;
  262. break;
  263. case 'card':
  264. // 名片消息
  265. break;
  266. case 'location':
  267. // 位置消息
  268. break;
  269. case 'emotion':
  270. // 表情消息
  271. $path = 'weworksingle_file/'.$config['company_id'].'/' . date('Ymd') . '/';
  272. $dir_path = public_path() . $path;
  273. if (!mkdirs($dir_path)) {
  274. Log::record('----------emotion error---------')->save();
  275. Log::record('创建' . $dir_path . '失败')->save();
  276. Log::record('----------emotion error---------')->save();
  277. break;
  278. }
  279. $fileext = $msg['emotion']['type'] == 1 ? 'gif' : 'png';
  280. $file_name = make_file_name($dir_path, $fileext);
  281. try {
  282. $obj->downloadMedia($msg['emotion']['sdkfileid'], $dir_path . $file_name);
  283. } catch (\WxworkFinanceSdkException $e) {
  284. Log::record('----------emotion error---------')->save();
  285. Log::record($e->getMessage())->save();
  286. Log::record('----------emotion error---------')->save();
  287. break;
  288. }
  289. $once_msg['content'] = $file_name;
  290. $once_file['msgid'] = $msg['msgid'];
  291. $once_file['path'] = $path . $file_name;
  292. $once_file['filename'] = $file_name;
  293. $once_file['sdkfileid'] = $msg['emotion']['sdkfileid'];
  294. $once_file['filesize'] = $msg['emotion']['imagesize'];
  295. $once_file['md5sum'] = $msg['emotion']['md5sum'];
  296. $once_file['cretetime'] = time();
  297. $file_data[] = $once_file;
  298. break;
  299. case 'file':
  300. // 文件消息
  301. $path = 'weworksingle_file/'.$config['company_id'].'/' . date('Ymd') . '/';
  302. $dir_path = public_path() . $path;
  303. if (!mkdirs($dir_path)) {
  304. Log::record('----------file error---------')->save();
  305. Log::record('创建' . $dir_path . '失败')->save();
  306. Log::record('----------file error---------')->save();
  307. break;
  308. }
  309. $file_name = make_file_name($dir_path, $msg['file']['fileext']);
  310. try {
  311. $obj->downloadMedia($msg['file']['sdkfileid'], $dir_path . $file_name);
  312. } catch (\WxworkFinanceSdkException $e) {
  313. Log::record('----------file error---------')->save();
  314. Log::record($e->getMessage())->save();
  315. Log::record('----------file error---------')->save();
  316. break;
  317. }
  318. $once_msg['content'] = $msg['file']['filename'];
  319. $once_file['msgid'] = $msg['msgid'];
  320. $once_file['path'] = $path . $file_name;
  321. $once_file['filename'] = $msg['file']['filename'];
  322. $once_file['sdkfileid'] = $msg['file']['sdkfileid'];
  323. $once_file['filesize'] = $msg['file']['filesize'];
  324. $once_file['md5sum'] = $msg['file']['md5sum'];
  325. $once_file['cretetime'] = time();
  326. $file_data[] = $once_file;
  327. break;
  328. case 'link':
  329. // 链接消息
  330. break;
  331. case 'weapp':
  332. // 小程序消息
  333. break;
  334. case 'chatrecord':
  335. // 会话记录消息
  336. break;
  337. case 'todo':
  338. // 待办消息
  339. break;
  340. case 'vote':
  341. // 投票消息
  342. break;
  343. case 'collect':
  344. // 填表消息
  345. break;
  346. case 'redpacket':
  347. // 红包消息
  348. break;
  349. case 'meeting':
  350. // 会议邀请消息
  351. break;
  352. case 'docmsg':
  353. // 在线文档消息
  354. break;
  355. case 'markdown':
  356. // 系统消息
  357. break;
  358. case 'news':
  359. // 图文消息
  360. break;
  361. case 'calendar':
  362. // 日程消息
  363. break;
  364. case 'mixed':
  365. // 混合消息
  366. $item = $msg['mixed']['item'];
  367. $once_msg['content'] = json_encode($item);
  368. foreach ($item as $k => $v){
  369. switch ($v['type']){
  370. case 'image':
  371. // 图片
  372. $path = 'weworksingle_file/'.$config['company_id'].'/' . date('Ymd') . '/';
  373. $dir_path = public_path() . $path;
  374. if (!mkdirs($dir_path)) {
  375. Log::record('----------img error---------')->save();
  376. Log::record('创建' . $dir_path . '失败')->save();
  377. Log::record('----------img error---------')->save();
  378. break;
  379. }
  380. $file_name = make_file_name($dir_path, 'jpg');
  381. try {
  382. $obj->downloadMedia($msg['image']['sdkfileid'], $dir_path . $file_name);
  383. } catch (\WxworkFinanceSdkException $e) {
  384. Log::record('----------img error---------')->save();
  385. Log::record($e->getMessage())->save();
  386. Log::record('----------img error---------')->save();
  387. break;
  388. }
  389. $once_msg['content'] = $path . $file_name;
  390. $once_file['msgid'] = $msg['msgid'];
  391. $once_file['path'] = $path . $file_name;
  392. $once_file['filename'] = $file_name;
  393. $once_file['sdkfileid'] = $msg['image']['sdkfileid'];
  394. $once_file['filesize'] = $msg['image']['filesize'];
  395. $once_file['md5sum'] = $msg['image']['md5sum'];
  396. $once_file['cretetime'] = time();
  397. $file_data[] = $once_file;
  398. break;
  399. case 'voice':
  400. // 语音消息
  401. $path = 'weworksingle_file/'.$config['company_id'].'/' . date('Ymd') . '/';
  402. $dir_path = public_path() . $path;
  403. if (!mkdirs($dir_path)) {
  404. Log::record('----------voice error---------')->save();
  405. Log::record('创建' . $dir_path . '失败')->save();
  406. Log::record('----------voice error---------')->save();
  407. break;
  408. }
  409. $file_name = make_file_name($dir_path, 'mp3');
  410. try {
  411. $obj->downloadMedia($msg['voice']['sdkfileid'], $dir_path . $file_name);
  412. } catch (\WxworkFinanceSdkException $e) {
  413. Log::record('----------voice error---------')->save();
  414. Log::record($e->getMessage())->save();
  415. Log::record('----------voice error---------')->save();
  416. break;
  417. }
  418. $once_msg['content'] = $path . $file_name;
  419. $once_file['msgid'] = $msg['msgid'];
  420. $once_file['path'] = $path . $file_name;
  421. $once_file['filename'] = $file_name;
  422. $once_file['sdkfileid'] = $msg['voice']['sdkfileid'];
  423. $once_file['filesize'] = $msg['voice']['voice_size'];
  424. $once_file['md5sum'] = $msg['voice']['md5sum'];
  425. $once_file['cretetime'] = time();
  426. $file_data[] = $once_file;
  427. break;
  428. case 'video':
  429. // 视频消息
  430. $path = 'weworksingle_file/'.$config['company_id'].'/' . date('Ymd') . '/';
  431. $dir_path = public_path() . $path;
  432. if (!mkdirs($dir_path)) {
  433. Log::record('----------video error---------')->save();
  434. Log::record('创建' . $dir_path . '失败')->save();
  435. Log::record('----------video error---------')->save();
  436. break;
  437. }
  438. $file_name = make_file_name($dir_path, 'mp4');
  439. try {
  440. $obj->downloadMedia($msg['video']['sdkfileid'], $dir_path . $file_name);
  441. } catch (\WxworkFinanceSdkException $e) {
  442. Log::record('----------video error---------')->save();
  443. Log::record($e->getMessage())->save();
  444. Log::record('----------video error---------')->save();
  445. break;
  446. }
  447. $once_msg['content'] = $path . $file_name;
  448. $once_file['msgid'] = $msg['msgid'];
  449. $once_file['path'] = $path . $file_name;
  450. $once_file['filename'] = $file_name;
  451. $once_file['sdkfileid'] = $msg['video']['sdkfileid'];
  452. $once_file['filesize'] = $msg['video']['filesize'];
  453. $once_file['md5sum'] = $msg['video']['md5sum'];
  454. $once_file['cretetime'] = time();
  455. $file_data[] = $once_file;
  456. break;
  457. case 'file':
  458. // 文件消息
  459. $path = 'weworksingle_file/'.$config['company_id'].'/' . date('Ymd') . '/';
  460. $dir_path = public_path() . $path;
  461. if (!mkdirs($dir_path)) {
  462. Log::record('----------file error---------')->save();
  463. Log::record('创建' . $dir_path . '失败')->save();
  464. Log::record('----------file error---------')->save();
  465. break;
  466. }
  467. $file_name = make_file_name($dir_path, $msg['file']['fileext']);
  468. try {
  469. $obj->downloadMedia($msg['file']['sdkfileid'], $dir_path . $file_name);
  470. } catch (\WxworkFinanceSdkException $e) {
  471. Log::record('----------file error---------')->save();
  472. Log::record($e->getMessage())->save();
  473. Log::record('----------file error---------')->save();
  474. break;
  475. }
  476. $once_msg['content'] = $msg['file']['filename'];
  477. $once_file['msgid'] = $msg['msgid'];
  478. $once_file['path'] = $path . $file_name;
  479. $once_file['filename'] = $msg['file']['filename'];
  480. $once_file['sdkfileid'] = $msg['file']['sdkfileid'];
  481. $once_file['filesize'] = $msg['file']['filesize'];
  482. $once_file['md5sum'] = $msg['file']['md5sum'];
  483. $once_file['cretetime'] = time();
  484. $file_data[] = $once_file;
  485. break;
  486. default:
  487. break;
  488. }
  489. }
  490. break;
  491. case 'meeting_voice_call':
  492. // 音频存档消息
  493. $path = 'weworksingle_file/'.$config['company_id'].'/' . date('Ymd') . '/';
  494. $dir_path = public_path() . $path;
  495. if (!mkdirs($dir_path)) {
  496. Log::record('----------meeting_voice_call error---------')->save();
  497. Log::record('创建' . $dir_path . '失败')->save();
  498. Log::record('----------meeting_voice_call error---------')->save();
  499. break;
  500. }
  501. $file_name = make_file_name($dir_path, 'mp3');
  502. try {
  503. $obj->downloadMedia($msg['meeting_voice_call']['sdkfileid'], $dir_path . $file_name);
  504. } catch (\WxworkFinanceSdkException $e) {
  505. Log::record('----------meeting_voice_call error---------')->save();
  506. Log::record($e->getMessage())->save();
  507. Log::record('----------meeting_voice_call error---------')->save();
  508. break;
  509. }
  510. $once_file['msgid'] = $msg['msgid'];
  511. $once_file['path'] = $path . $file_name;
  512. $once_file['filename'] = $file_name;
  513. $once_file['sdkfileid'] = $msg['meeting_voice_call']['sdkfileid'];
  514. $once_file['filesize'] = 0;
  515. $once_file['md5sum'] = '';
  516. $once_file['cretetime'] = time();
  517. $file_data[] = $once_file;
  518. break;
  519. case 'voip_doc_share':
  520. // 音频共享文档消息
  521. break;
  522. case 'external_redpacket':
  523. // 互通红包消息
  524. break;
  525. case 'sphfeed':
  526. // 视频号消息
  527. break;
  528. case 'voiptext':
  529. // 音视频通话
  530. break;
  531. case 'qydiskfile':
  532. // 微盘文件
  533. $once_msg['content'] = $msg['info']['filename'];
  534. break;
  535. default:
  536. break;
  537. }
  538. $msg_data[] = $once_msg;
  539. }
  540. }
  541. $return_data['record'] = $msg_data;
  542. $return_data['file'] = $file_data;
  543. $return_data['recall'] = $recall_data;
  544. //最后一条消息的seq
  545. if (!empty($msg_data)) {
  546. $end_chats = end($chats['chatdata']);
  547. $return_data['seq'] = $end_chats['seq'];
  548. } else {
  549. $return_data['seq'] = '';
  550. }
  551. return $return_data;
  552. } catch (\WxworkFinanceSdkException $e) {
  553. Log::record('----------WxworkFinanceSdkException error---------')->save();
  554. Log::record($e->getMessage())->save();
  555. Log::record('----------WxworkFinanceSdkException error---------')->save();
  556. $this->error = $e->getMessage();
  557. return false;
  558. }
  559. }
  560. /**
  561. * 获取开启会话存储功能的用户列表
  562. */
  563. public function getPermitUsers(){
  564. return $this->app->msg_audit->getPermitUsers();
  565. // $result['ids'];
  566. }
  567. /**
  568. * 根据用户ID获取用户群列表
  569. */
  570. public function getGroupChatsByUser($userId = [], $cursor = ''){
  571. $params['status_filter'] = 0; // 客户群跟进状态过滤。0 - 所有列表(即不过滤)1 - 离职待继承2 - 离职继承中3 - 离职继承完成
  572. $params['owner_filter']['userid_list'] = $userId;
  573. $params['cursor'] = $cursor;
  574. $params['limit'] = 1000;
  575. $result = $this->app->external_contact->getGroupChats($params);
  576. return $result;
  577. }
  578. /**
  579. * 获取客户群列表
  580. * @param int $status 客户群跟进状态过滤。 0 - 所有列表(即不过滤) 1 - 离职待继承 2 - 离职继承中 3 - 离职继承完成
  581. * @param array $owner 群主过滤。
  582. * @param int $cursor 用于分页查询的游标,字符串类型,由上一次调用返回,首次调用不填
  583. * @param int $limit 分页,预期请求的数据量,取值范围 1 ~ 1000
  584. */
  585. public function getGroupChats($cursor = '', $limit = 100, $status = 0, $owner = []){
  586. $params = [
  587. "status_filter" => $status,
  588. "owner_filter" => [
  589. "userid_list" => $owner,
  590. ],
  591. "cursor" => $cursor,
  592. "limit" => $limit
  593. ];
  594. return $this->app->external_contact->getGroupChats($params);
  595. }
  596. /**
  597. * 获取所有客户群列表
  598. * @param int $status
  599. * @param array $owner
  600. */
  601. public function getAllGroupChats($cursor = '', $limit = 100, $status = 0, $owner = [], $list = []){
  602. $result = $this->getGroupChats($cursor, $limit, $status, $owner);
  603. if ($result['errcode'] == 0) {
  604. $list = array_merge($list, $result['group_chat_list']);
  605. if (!empty($result['next_cursor'])){
  606. return $this->getAllGroupChats($result['next_cursor'], $limit, $status, $owner, $list);
  607. }
  608. } else {
  609. Log::record($result['errmsg'])->save();
  610. }
  611. return $list;
  612. }
  613. /**
  614. * 获取群详情
  615. * @param string $chatId
  616. */
  617. public function getGroupChat($chatId = ''){
  618. $result = $this->app->external_contact->getGroupChat($chatId);
  619. if ($result['errcode'] == 0) {
  620. return $result;
  621. } else {
  622. Log::record($result['errmsg'])->save();
  623. return $this->errorMsg;
  624. }
  625. }
  626. /**
  627. * 给企业成员发送消息
  628. * @param string $content
  629. * @param string $touser
  630. */
  631. public function sendMessageToUser($content = '', $touser = ''){
  632. $result = $this->app->messenger->message($content)->toUser($touser)->send();
  633. if ($result['errcode'] == 0) {
  634. return true;
  635. } else {
  636. Log::record($result)->save();
  637. return false;
  638. }
  639. }
  640. /**
  641. * 企业群发消息
  642. */
  643. public function sendExternalMessage($content = []){
  644. $result = $this->app->external_contact_message->submit($content);
  645. if ($result['errcode'] == 0) {
  646. return $result;
  647. } else {
  648. Log::record($content)->save();
  649. Log::record($result['errmsg'])->save();
  650. return false;
  651. }
  652. }
  653. /**
  654. * 根据群发消息id获取群发详情
  655. * @param $msgId
  656. */
  657. public function getExternalMessage($msgId){
  658. $result = $this->app->external_contact_message->get($msgId);
  659. return $result;
  660. }
  661. /**
  662. * 根据群发消息id及群发人员获取群发执行结果
  663. */
  664. public function getExternalMessageSendResult($msgid, $userid, $limit = 500, $cursor = '', $list = []){
  665. $result = $this->app->external_contact_message->getGroupmsgSendResult($msgid, $userid, $limit, $cursor);
  666. if ($result['errcode'] == 0){
  667. $list = array_merge($list, $result['send_list']);
  668. if (!empty($result['next_cursor'])){
  669. $list = $this->getExternalMessageSendResult($msgid, $userid, $limit, $result['next_cursor'], $list);
  670. }
  671. }
  672. return $list;
  673. }
  674. /**
  675. * 根据群发id获取群发任务详情
  676. * @param $msgid
  677. * @param $limit
  678. * @param $cursor
  679. */
  680. public function getExternalMessageTask($msgid, $limit = 500, $cursor = ''){
  681. $result = $this->app->external_contact_message->getGroupmsgTask($msgid);
  682. return $result;
  683. }
  684. /**
  685. * 获取企业已配置的【联系我】方式列表
  686. * @param string $cursor
  687. * @param int $limit
  688. * @param string $startTime
  689. * @param string $ednTime
  690. * @return array|bool|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
  691. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  692. * @throws \GuzzleHttp\Exception\GuzzleException
  693. */
  694. public function getContactWayList($cursor = '', $limit = 100, $startTime = '', $ednTime = ''){
  695. $result = $this->app->contact_way->list($cursor, $limit, $startTime, $ednTime);
  696. if ($result['errcode'] == 0) {
  697. return $result;
  698. } else {
  699. Log::record($result['errmsg'])->save();
  700. return false;
  701. }
  702. }
  703. /**
  704. * 根据配置ID获取联系我配置详情
  705. * @param string $configId
  706. * @return bool|mixed
  707. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  708. * @throws \GuzzleHttp\Exception\GuzzleException
  709. */
  710. public function getContactWay($configId = ''){
  711. $result = $this->app->contact_way->get($configId);
  712. if ($result['errcode'] == 0) {
  713. return $result['contact_way'];
  714. } else {
  715. Log::record($result['errmsg'])->save();
  716. return false;
  717. }
  718. }
  719. /**
  720. * 设置【联系我】方式
  721. * @param int $type 联系方式类型,1-单人,2-多人
  722. * @param int $scene 场景,1-在小程序中联系,2-通过二维码联系
  723. * @param array $config 配置项
  724. * @return bool
  725. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  726. * @throws \GuzzleHttp\Exception\GuzzleException
  727. */
  728. public function addContactWay($type = 1, $scene = 2, $config = []){
  729. if (empty($config)) {
  730. return false;
  731. } else {
  732. $result = $this->app->contact_way->create($type, $scene, $config);
  733. Log::record($result)->save();
  734. if ($result['errcode'] == 0) {
  735. $data['company_id'] = Company::where('root_id', '=', request()->token['root_org'])->value('id');
  736. $data['type'] = $type;
  737. $data['scene'] = $scene;
  738. $data['style'] = !empty($config['style']) ? $config['style'] : '';
  739. $data['remark'] = !empty($config['remark']) ? $config['remark'] : '';
  740. $data['skip_verify'] = !empty($config['skip_verify']) ? $config['skip_verify'] : '';
  741. $data['state'] = !empty($config['state']) ? $config['state'] : '';
  742. $data['user'] = !empty($config['user']) ? $config['user'] : '';
  743. $data['party'] = !empty($config['party']) ? $config['party'] : '';
  744. $data['is_temp'] = !empty($config['is_temp']) ? $config['is_temp'] : '';
  745. $data['expires_in'] = !empty($config['expires_in']) ? $config['expires_in'] : '';
  746. $data['chat_expires_in'] = !empty($config['chat_expires_in']) ? $config['chat_expires_in'] : '';
  747. $data['unionid'] = !empty($config['unionid']) ? $config['unionid'] : '';
  748. $data['conclusions'] = !empty($config['conclusions']) ? $config['conclusions'] : '';
  749. $data['config_id'] = $result['config_id'];
  750. WeworksingleContactWay::create($data);
  751. return true;
  752. } else {
  753. Log::record($result['errmsg'])->save();
  754. return false;
  755. }
  756. }
  757. }
  758. /**
  759. * 调整【联系我】方式
  760. * @param string $configId 配置ID
  761. * @param array $config 配置项
  762. * @return bool
  763. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  764. * @throws \GuzzleHttp\Exception\GuzzleException
  765. */
  766. public function editContactWay($configId = '', $config = []){
  767. $result = $this->app->contact_way->update($configId, $config);
  768. if ($result['errcode'] == 0) {
  769. $data['style'] = !empty($config['style']) ? $config['style'] : '';
  770. $data['remark'] = !empty($config['remark']) ? $config['remark'] : '';
  771. $data['skip_verify'] = !empty($config['skip_verify']) ? $config['skip_verify'] : '';
  772. $data['state'] = !empty($config['state']) ? $config['state'] : '';
  773. $data['user'] = !empty($config['user']) ? $config['user'] : '';
  774. $data['party'] = !empty($config['party']) ? $config['party'] : '';
  775. $data['expires_in'] = !empty($config['expires_in']) ? $config['expires_in'] : '';
  776. $data['chat_expires_in'] = !empty($config['chat_expires_in']) ? $config['chat_expires_in'] : '';
  777. $data['unionid'] = !empty($config['unionid']) ? $config['unionid'] : '';
  778. $data['conclusions'] = !empty($config['conclusions']) ? $config['conclusions'] : '';
  779. WeworksingleContactWay::where('config_id', '=', $configId)->save($data);
  780. return true;
  781. } else {
  782. Log::record($result['errmsg'])->save();
  783. return false;
  784. }
  785. }
  786. /**
  787. * 删除【联系我】方式
  788. * @param string $configId
  789. * @return bool
  790. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  791. * @throws \GuzzleHttp\Exception\GuzzleException
  792. */
  793. public function deleteContactWay($configId = ''){
  794. $result = $this->app->contact_way->delete($configId);
  795. if ($result['errcode'] == 0) {
  796. return true;
  797. } else {
  798. Log::record($result['errmsg'])->save();
  799. return false;
  800. }
  801. }
  802. /**
  803. * 上传图片临时素材
  804. */
  805. public function uploadMediaImage($path){
  806. $result = $this->app->media->uploadImage($path);
  807. if ($result['errcode'] == 0) {
  808. return $result;
  809. } else {
  810. Log::record($result['errmsg'])->save();
  811. return $this->errorMsg;
  812. }
  813. }
  814. /**
  815. * 上传声音临时素材
  816. */
  817. public function uploadMediaVoice($path){
  818. $result = $this->app->media->uploadVoice($path);
  819. if ($result['errcode'] == 0) {
  820. return $result;
  821. } else {
  822. Log::record($result['errmsg'])->save();
  823. return $this->errorMsg;
  824. }
  825. }
  826. /**
  827. * 上传视频临时素材
  828. */
  829. public function uploadMediaVideo($path){
  830. $result = $this->app->media->uploadVideo($path);
  831. if ($result['errcode'] == 0) {
  832. return $result;
  833. } else {
  834. Log::record($result['errmsg'])->save();
  835. return $this->errorMsg;
  836. }
  837. }
  838. /**
  839. * 上传普通文件临时素材
  840. */
  841. public function uploadMediaFile($path){
  842. $result = $this->app->media->uploadFile($path);
  843. if ($result['errcode'] == 0) {
  844. return $result;
  845. } else {
  846. Log::record($result['errmsg'])->save();
  847. return $this->errorMsg;
  848. }
  849. }
  850. /**
  851. * 获取临时素材
  852. */
  853. public function getMediaById($mediaId){
  854. $result = $this->app->media->get($mediaId);
  855. return $result;
  856. }
  857. /**
  858. * 获取accessToken
  859. * @return array|string
  860. * @throws \EasyWeChat\Kernel\Exceptions\HttpException
  861. * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
  862. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  863. * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
  864. * @throws \Psr\SimpleCache\InvalidArgumentException
  865. */
  866. public function getToken(){
  867. $config = $this->config;
  868. if ($config) {
  869. $app = Factory::officialAccount($config);
  870. $accessToken = $app->access_token;
  871. $token = $accessToken->getToken(); // token 数组 token['access_token'] 字符串
  872. return $token;
  873. } else {
  874. return '';
  875. }
  876. }
  877. /**
  878. * 上传永久素材
  879. * @param $path
  880. */
  881. public function uploadMaterialImage($path){
  882. $result = $this->app->media->uploadImg($path);
  883. if ($result['errcode'] == 0) {
  884. return $result;
  885. } else {
  886. Log::record($result['errmsg'])->save();
  887. return $this->errorMsg;
  888. }
  889. }
  890. /**
  891. * 客户联系
  892. * 员工行为数据
  893. * return ["errcode": 0, "errmsg": "ok", "behavior_data": []]
  894. * @param $userIds 查询用户id
  895. * @param $from 开始时间
  896. * @param $to 结束时间
  897. * @param $partyid 部门ID列表
  898. * 支持的最大查询跨度为30天;用户最多可获取最近180天内的数据;
  899. */
  900. public function getUserBehaviorData($userIds = [], $from = '', $to = '', $partyid=[]){
  901. $result = $this->app->external_contact_statistics->userBehavior($userIds, $from, $to, $partyid);
  902. if ($result['errcode'] == 0) {
  903. return $result['behavior_data'];
  904. } else {
  905. Log::record($result['errmsg'])->save();
  906. return $this->errorMsg;
  907. }
  908. }
  909. /**
  910. * 获取「群聊数据统计」数据
  911. * 获取指定日期的统计数据。注意,企业微信仅存储180天的数据。
  912. * @param array $param
  913. * @param array $list
  914. * @return array|mixed
  915. * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
  916. * @throws \GuzzleHttp\Exception\GuzzleException
  917. */
  918. public function getGroupChatStatistic($param = [], $list = []){
  919. $param['limit'] = 1000;
  920. $result = $this->app->external_contact_statistics->groupChatStatistic($param);
  921. Log::record($param)->save();
  922. Log::record($result)->save();
  923. if ($result['errcode'] == 0){
  924. $list = array_merge($list, $result['items']);
  925. if (!empty($result['total']) && !empty($result['next_offset']) && $result['total'] != $result['next_offset']){
  926. $param['offset'] = $result['next_offset'];
  927. $list = $this->getGroupChatStatistic($param, $list);
  928. }
  929. }
  930. return $list;
  931. }
  932. }