From 09f050888ee5672759b4202fab51de5b984d087e Mon Sep 17 00:00:00 2001 From: ykxiao Date: Wed, 12 Apr 2023 15:05:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 + .travis.yml | 16 +++ README.md | 226 ++++++++++++++++++++++++++++++ composer.json | 40 ++++++ config/ding.php | 31 ++++ phpunit.xml | 24 ++++ src/DingNoticeServiceProvider.php | 44 ++++++ src/DingTalk.php | 121 ++++++++++++++++ src/DingTalkService.php | 168 ++++++++++++++++++++++ src/HttpClient.php | 90 ++++++++++++ src/Messages/ActionCard.php | 50 +++++++ src/Messages/FeedCard.php | 41 ++++++ src/Messages/Link.php | 24 ++++ src/Messages/Markdown.php | 22 +++ src/Messages/Message.php | 37 +++++ src/Messages/Text.php | 17 +++ src/SendClient.php | 15 ++ src/helpers.php | 26 ++++ tests/Feature/ActionTest.php | 62 ++++++++ tests/Feature/FeedTest.php | 62 ++++++++ tests/Feature/LinkTest.php | 48 +++++++ tests/Feature/MarkdownTest.php | 56 ++++++++ tests/Feature/TextTest.php | 52 +++++++ tests/TestCase.php | 65 +++++++++ 24 files changed, 1341 insertions(+) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 README.md create mode 100644 composer.json create mode 100644 config/ding.php create mode 100644 phpunit.xml create mode 100644 src/DingNoticeServiceProvider.php create mode 100644 src/DingTalk.php create mode 100644 src/DingTalkService.php create mode 100644 src/HttpClient.php create mode 100644 src/Messages/ActionCard.php create mode 100644 src/Messages/FeedCard.php create mode 100644 src/Messages/Link.php create mode 100644 src/Messages/Markdown.php create mode 100644 src/Messages/Message.php create mode 100644 src/Messages/Text.php create mode 100644 src/SendClient.php create mode 100644 src/helpers.php create mode 100644 tests/Feature/ActionTest.php create mode 100644 tests/Feature/FeedTest.php create mode 100644 tests/Feature/LinkTest.php create mode 100644 tests/Feature/MarkdownTest.php create mode 100644 tests/Feature/TextTest.php create mode 100644 tests/TestCase.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d4482af --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea +/vendor +.php_cs.cache +composer.lock \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..460f17f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: php + +php: + - 7.0 + - 7.1 + - 7.2 + +dist: trusty +sudo: false + +before_script: + - composer self-update + - composer install --prefer-source --no-interaction + - composer dump-autoload + +script: vendor/bin/phpunit \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..4461f7f --- /dev/null +++ b/README.md @@ -0,0 +1,226 @@ +# 钉钉推送机器人消息发送laravel扩展包 + +[![Latest Stable Version](https://poser.pugx.org/wangju/ding-notice/v/stable)](https://packagist.org/packages/wangju/ding-notice) +[![Total Downloads](https://poser.pugx.org/wangju/ding-notice/downloads)](https://packagist.org/packages/wangju/ding-notice) +[![Latest Unstable Version](https://poser.pugx.org/wangju/ding-notice/v/unstable)](https://packagist.org/packages/wangju/ding-notice) +[![License](https://poser.pugx.org/wangju/ding-notice/license)](https://packagist.org/packages/wangju/ding-notice) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/wowiwj/ding-notice/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/wowiwj/ding-notice/?branch=master) +[![Code Intelligence Status](https://scrutinizer-ci.com/g/wowiwj/ding-notice/badges/code-intelligence.svg?b=master)](https://scrutinizer-ci.com/code-intelligence) +[![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badge/) + + +### 请先阅读 [钉钉官方文档](https://open-doc.dingtalk.com/microapp/serverapi2/qf2nxq) + + +# 介绍 +ding-notie 是一款钉钉机器人消息发送的Laravel扩展,您可以通过此扩展便捷的发送钉钉消息,进行监控和提醒操作 + +# 要求 +- php版本:>=7.0 +- laravel版本: Laravel5.5+ + + +# 安装 + +```php +composer require ykxiao/dm-ding-notice + +``` + +# 在非laravel项目中使用 +```php +$ding = new \DingNotice\DingTalk([ + "default" => [ + 'enabled' => true, + 'token' => "you-push-token", + 'timeout' => 2.0, + 'ssl_verify' => true, + 'secret' => '', + ] +]); + +$ding->text('我就是我, xxx 是不一样的烟火'); +``` + +# 在laravel项目中使用 + +安装成功后执行 +```php +php artisan vendor:publish --provider="DingNotice\DingNoticeServiceProvider" + +``` +会自动将`ding.php`添加到您项目的配置文件当中 + +# 相关配置 + +### 钉钉启用开关 +(可选)默认为开启 +```php +DING_ENABLED=true +``` +### 钉钉的推送token +- (必选)发送钉钉机器人的token,即在您创建机器人之后的access_token +- 钉钉推送链接:https://oapi.dingtalk.com/robot/send?access_token=you-push-token +```php +DING_TOKEN=you-push-token +``` + + +### 多机器人配置 +如果想要添加多个机器人,则在`ding.php`当中添加机器人名字和相关的配置即可 + +```php +return [ + + 'default' => [ + 'enabled' => env('DING_ENABLED',true), + + 'token' => env('DING_TOKEN',''), + + 'timeout' => env('DING_TIME_OUT',2.0), + + 'ssl_verify' => env('DING_SSL_VERIFY',true), + + 'secret' => env('DING_SECRET',true), + ], + + 'other' => [ + 'enabled' => env('OTHER_DING_ENABLED',true), + + 'token' => env('OTHER_DING_TOKEN',''), + + 'timeout' => env('OTHER_DING_TIME_OUT',2.0), + + 'ssl_verify' => env('DING_SSL_VERIFY',true), + + 'secret' => env('OTHER_DING_SECRET',true), + ] + +]; +``` + + +### 钉钉发送的超时时间 +- (可选) 默认为2.0秒 +```php +DING_TIME_OUT= +``` + +### 是否开启SSL验证 + +- (可选)默认为开启,关闭请手动设置 +```php +DING_SSL_VERIFY=false +``` +### 开启钉钉安全配置 + +- (可选)默认为无 +```php +DING_SECRET= +``` + + +# 使用 + +## 发送纯文字消息 +```php +ding('我就是我, xxx 是不一样的烟火') +``` +or +```php +ding()->text('我就是我, xxx 是不一样的烟火') +``` +发送过程@其他人或者所有人 + +```php +ding()->at(["13888888888"],true) + ->text("我就是我,@13888888888 是不一样的烟火") +``` + +## 发送链接类型的消息 + + +```php + +$title = "自定义机器人协议"; +$text = "群机器人是钉钉群的高级扩展功能。群机器人可以将第三方服务的信息聚合到群聊中,实现自动化的信息同步。例如:通过聚合GitHub,GitLab等源码管理服务,实现源码更新同步;通过聚合Trello,JIRA等项目协调服务,实现项目信息同步。不仅如此,群机器人支持Webhook协议的自定义接入,支持更多可能性,例如:你可将运维报警提醒通过自定义机器人聚合到钉钉群。"; +$picUrl = ""; +$messageUrl = "https://open-doc.dingtalk.com/docs/doc.htm?spm=a219a.7629140.0.0.Rqyvqo&treeId=257&articleId=105735&docType=1"; + +ding()->link($title,$text,$messageUrl,$picUrl) +``` + +## 发送markdown类型的消息 + +```php +$title = '杭州天气'; +$markdown = "#### 杭州天气 \n ". + "> 9度,@1825718XXXX 西北风1级,空气良89,相对温度73%\n\n ". + "> ![screenshot](http://i01.lw.aliimg.com/media/lALPBbCc1ZhJGIvNAkzNBLA_1200_588.png)\n". + "> ###### 10点20分发布 [天气](http://www.thinkpage.cn/) "; + +ding()->markdown($title,$markdown); +``` +or + +```php +ding()->at([],true) + ->markdown($title,$markdown) +``` + +## 发送Action类型的消息 + +### 发送single类型的消息 +```php +$title = "乔布斯 20 年前想打造一间苹果咖啡厅,而它正是 Apple Store 的前身"; +$text = "![screenshot](@lADOpwk3K80C0M0FoA) \n". + " #### 乔布斯 20 年前想打造的苹果咖啡厅 \n\n". + " Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划"; + +ding()->actionCard($title,$text,1) + ->single("阅读全文","https://www.dingtalk.com/") + ->send() +``` +### 发送btns类型的消息 + +```php +ding()->actionCard($title,$text,1) + ->addButtons("内容不错","https://www.dingtalk.com/") + ->addButtons("不感兴趣","https://www.dingtalk.com/") + ->send(); +``` + +## 发送Feed类型的消息 + +```php +$messageUrl = "https://mp.weixin.qq.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI"; +$picUrl = "https://www.dingtalk.com"; +ding()->feed() + ->addLinks('时代的火车向前开',$messageUrl,$picUrl) + ->addLinks('时代的火车向前开2',$messageUrl,$picUrl) + ->send(); +``` +## 多机器人消息发送 + +### 发送纯文字消息 +```php +ding('我就是我, xxx 是不一样的烟火','other') +``` +or +```php +ding()->with('other')->text('我就是我, xxx 是不一样的烟火'); +``` + +### 通过其他机器人发送其他类型消息 +```php +ding()->with('other')->markdown($title,$markdown); + +ding()->with('other') + ->feed() + ->addLinks('时代的火车向前开',$messageUrl,$picUrl) + ->addLinks('时代的火车向前开2',$messageUrl,$picUrl) + ->send(); +``` + + + diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..89047ac --- /dev/null +++ b/composer.json @@ -0,0 +1,40 @@ +{ + "name": "ykxiao/dm-ding-notice", + "description": "a dingtalk robot message handle for send message", + "keywords": ["laravel", "ding talk", "ding notice"], + "require": { + "php": ">=7.0", + "guzzlehttp/guzzle": "^6.2|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7", + "mockery/mockery": "^1.2" + }, + "autoload": { + "psr-4": { + "DingNotice\\": "src/" + }, + "files": [ + "src/helpers.php" + ] + }, + "autoload-dev": { + "psr-4": { + "DingNotice\\Tests\\": "tests" + } + }, + "extra": { + "laravel": { + "providers": [ + "DingNotice\\DingNoticeServiceProvider" + ] + } + }, + "license": "MIT", + "authors": [ + { + "name": "ykxiao", + "email": "yk_9001@gmail.com" + } + ] +} diff --git a/config/ding.php b/config/ding.php new file mode 100644 index 0000000..1a433f6 --- /dev/null +++ b/config/ding.php @@ -0,0 +1,31 @@ + [ + // 是否要开启机器人,关闭则不再发送消息 + 'enabled' => env('DING_ENABLED',true), + // 机器人的access_token + 'token' => env('DING_TOKEN',''), + // 钉钉请求的超时时间 + 'timeout' => env('DING_TIME_OUT',2.0), + // 是否开启ss认证 + 'ssl_verify' => env('DING_SSL_VERIFY',true), + // 开启安全配置 + 'secret' => env('DING_SECRET',true), + ], + + 'other' => [ + 'enabled' => env('OTHER_DING_ENABLED',true), + + 'token' => env('OTHER_DING_TOKEN',''), + + 'timeout' => env('OTHER_DING_TIME_OUT',2.0), + + 'ssl_verify' => env('DING_SSL_VERIFY',true), + + 'secret' => env('DING_SECRET',true), + ] +]; diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..59d69e4 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,24 @@ + + + + + ./tests/Unit + + + ./tests/Feature + + + + + ./src + + + \ No newline at end of file diff --git a/src/DingNoticeServiceProvider.php b/src/DingNoticeServiceProvider.php new file mode 100644 index 0000000..073ce5a --- /dev/null +++ b/src/DingNoticeServiceProvider.php @@ -0,0 +1,44 @@ +publishes([ + __DIR__ . '/../config/ding.php' => base_path('config/ding.php'), + ]); + } + + /** + * Register services. + * + * @return void + */ + public function register() + { + $this->registerLaravelBindings(); + } + + + /** + * Register Laravel bindings. + * + * @return void + */ + protected function registerLaravelBindings() + { + $this->app->singleton(DingTalk::class, function ($app) { + return new DingTalk($app['config']['ding']); + }); + } + +} diff --git a/src/DingTalk.php b/src/DingTalk.php new file mode 100644 index 0000000..6072243 --- /dev/null +++ b/src/DingTalk.php @@ -0,0 +1,121 @@ +config = $config; + $this->client = $client; + $this->with(); + } + + /** + * @param string $robot + * @return $this + */ + public function with($robot = 'default'){ + $this->robot = $robot; + $this->dingTalkService = new DingTalkService($this->config[$robot],$this->client); + return $this; + } + + + /** + * @param string $content + * @return mixed + */ + public function text($content = ''){ + return $this->dingTalkService + ->setTextMessage($content) + ->send(); + } + + /** + * @param $title + * @param $text + * @return mixed + */ + public function action($title, $text){ + return $this->dingTalkService + ->setActionCardMessage($title,$text); + } + + /** + * @param array $mobiles + * @param bool $atAll + * @return $this + */ + public function at($mobiles = [], $atAll = false){ + $this->dingTalkService + ->setAt($mobiles,$atAll); + return $this; + } + + /** + * @param $title + * @param $text + * @param $url + * @param string $picUrl + * @return mixed + */ + public function link($title, $text, $url, $picUrl = ''){ + return $this->dingTalkService + ->setLinkMessage($title,$text,$url,$picUrl) + ->send(); + } + + /** + * @param $title + * @param $markdown + * @return mixed + */ + public function markdown($title, $markdown){ + return $this->dingTalkService + ->setMarkdownMessage($title,$markdown) + ->send(); + } + + /** + * @param $title + * @param $markdown + * @param int $hideAvatar + * @param int $btnOrientation + * @return mixed + */ + public function actionCard($title, $markdown, $hideAvatar = 0, $btnOrientation = 0){ + return $this->dingTalkService + ->setActionCardMessage($title,$markdown,$hideAvatar,$btnOrientation); + } + + /** + * @return mixed + */ + public function feed(){ + return $this->dingTalkService + ->setFeedCardMessage(); + } + +} diff --git a/src/DingTalkService.php b/src/DingTalkService.php new file mode 100644 index 0000000..c825bda --- /dev/null +++ b/src/DingTalkService.php @@ -0,0 +1,168 @@ +config = $config; + $this->setTextMessage('null'); + + if ($client != null) { + $this->client = $client; + return; + } + $this->client = $this->createClient($config); + + } + + /** + * @param Message $message + */ + public function setMessage($message) + { + $this->message = $message; + } + + /** + * @return array + */ + public function getMessage() + { + return $this->message->getMessage(); + } + + /** + * @param array $mobiles + * @param bool $atAll + */ + public function setAt($mobiles = [], $atAll = false) + { + $this->mobiles = $mobiles; + $this->atAll = $atAll; + if ($this->message) { + $this->message->sendAt($mobiles, $atAll); + } + } + + /** + * create a guzzle client + * @return HttpClient + * @author wangju 2019-05-17 20:25 + */ + protected function createClient($config) + { + $client = new HttpClient($config); + return $client; + } + + + /** + * @param $content + * @return $this + */ + public function setTextMessage($content) + { + $this->message = new Text($content); + $this->message->sendAt($this->mobiles, $this->atAll); + return $this; + } + + /** + * @param $title + * @param $text + * @param $messageUrl + * @param string $picUrl + * @return $this + */ + public function setLinkMessage($title, $text, $messageUrl, $picUrl = '') + { + $this->message = new Link($title, $text, $messageUrl, $picUrl); + $this->message->sendAt($this->mobiles, $this->atAll); + return $this; + } + + /** + * @param $title + * @param $text + * @return $this + */ + public function setMarkdownMessage($title, $markdown) + { + $this->message = new Markdown($title, $markdown); + $this->message->sendAt($this->mobiles, $this->atAll); + return $this; + } + + + /** + * @param $title + * @param $text + * @param int $hideAvatar + * @param int $btnOrientation + * @return ActionCard|Message + */ + public function setActionCardMessage($title, $markdown, $hideAvatar = 0, $btnOrientation = 0) + { + $this->message = new ActionCard($this, $title, $markdown, $hideAvatar, $btnOrientation); + $this->message->sendAt($this->mobiles, $this->atAll); + return $this->message; + } + + /** + * @return FeedCard|Message + */ + public function setFeedCardMessage() + { + $this->message = new FeedCard($this); + $this->message->sendAt($this->mobiles, $this->atAll); + return $this->message; + } + + /** + * @return bool|array + */ + public function send() + { + if (!$this->config['enabled']) { + return false; + } + return $this->client->send($this->message->getBody()); + } + +} diff --git a/src/HttpClient.php b/src/HttpClient.php new file mode 100644 index 0000000..1176025 --- /dev/null +++ b/src/HttpClient.php @@ -0,0 +1,90 @@ +config = $config; + $this->setAccessToken(); + $this->client = $this->createClient(); + } + + /** + * + */ + public function setAccessToken(){ + $this->accessToken = $this->config['token']; + } + + /** + * create a guzzle client + * @return Client + * @author wangju 2019-05-17 20:25 + */ + protected function createClient() + { + $client = new Client([ + 'timeout' => $this->config['timeout'] ?? 2.0, + ]); + return $client; + } + + /** + * @return string + */ + public function getRobotUrl() + { + $query['access_token'] = $this->accessToken; + if (isset($this->config['secret']) && $secret = $this->config['secret']) { + $timestamp = time() . sprintf('%03d', rand(1, 999)); + $sign = hash_hmac('sha256', $timestamp . "\n" . $secret, $secret, true); + $query['timestamp'] = $timestamp; + $query['sign'] = base64_encode($sign); + } + return $this->hookUrl . "?" . http_build_query($query); + } + + /** + * send message + * @param $url + * @param $params + * @return array + * @author wangju 2019-05-17 20:48 + */ + public function send($params): array + { + $request = $this->client->post($this->getRobotUrl(), [ + 'body' => json_encode($params), + 'headers' => [ + 'Content-Type' => 'application/json', + ], + 'verify' => $this->config['ssl_verify'] ?? true, + ]); + + $result = $request->getBody()->getContents(); + return json_decode($result, true) ?? []; + } +} diff --git a/src/Messages/ActionCard.php b/src/Messages/ActionCard.php new file mode 100644 index 0000000..593d454 --- /dev/null +++ b/src/Messages/ActionCard.php @@ -0,0 +1,50 @@ +service = $service; + $this->setMessage($title,$markdown,$hideAvatar,$btnOrientation); + } + + public function setMessage($title, $markdown, $hideAvatar = 0, $btnOrientation = 0){ + $this->message = [ + 'msgtype' => 'actionCard', + 'actionCard' => [ + 'title' => $title, + 'text' => $markdown, + 'hideAvatar' => $hideAvatar, + 'btnOrientation' => $btnOrientation + ] + ]; + } + + public function single($title,$url){ + $this->message['actionCard']['singleTitle'] = $title; + $this->message['actionCard']['singleURL'] = $url; + $this->service->setMessage($this); + return $this; + } + + public function addButtons($title,$url){ + $this->message['actionCard']['btns'][] = [ + 'title' => $title, + 'actionURL' => $url + ]; + return $this; + } + + public function send(){ + $this->service->setMessage($this); + return $this->service->send(); + } + +} \ No newline at end of file diff --git a/src/Messages/FeedCard.php b/src/Messages/FeedCard.php new file mode 100644 index 0000000..923ee38 --- /dev/null +++ b/src/Messages/FeedCard.php @@ -0,0 +1,41 @@ +service = $service; + $this->setMessage(); + + } + + public function setMessage(){ + $this->message = [ + 'feedCard' => [ + 'links' => [] + ], + 'msgtype' => 'feedCard' + ]; + } + + public function addLinks($title,$messageUrl,$picUrl){ + $this->message['feedCard']['links'][] = [ + 'title' => $title, + 'messageURL' => $messageUrl, + 'picURL' => $picUrl + ]; + return $this; + } + + public function send(){ + $this->service->setMessage($this); + return $this->service->send(); + } + +} \ No newline at end of file diff --git a/src/Messages/Link.php b/src/Messages/Link.php new file mode 100644 index 0000000..d78865b --- /dev/null +++ b/src/Messages/Link.php @@ -0,0 +1,24 @@ +setMessage($title,$text,$messageUrl,$picUrl); + } + + public function setMessage($title,$text,$messageUrl,$picUrl = ''){ + $this->message = [ + 'msgtype' => 'link', + 'link' => [ + 'text' => $text, + 'title' => $title, + 'picUrl' => $picUrl, + 'messageUrl' => $messageUrl + ] + ]; + } +} \ No newline at end of file diff --git a/src/Messages/Markdown.php b/src/Messages/Markdown.php new file mode 100644 index 0000000..2eec4d1 --- /dev/null +++ b/src/Messages/Markdown.php @@ -0,0 +1,22 @@ +setMessage($title,$markdown); + } + + public function setMessage($title,$markdown){ + $this->message = [ + 'msgtype' => 'markdown', + 'markdown' => [ + 'title' => $title, + 'text' => $markdown + ] + ]; + } + +} \ No newline at end of file diff --git a/src/Messages/Message.php b/src/Messages/Message.php new file mode 100644 index 0000000..6ccaeaf --- /dev/null +++ b/src/Messages/Message.php @@ -0,0 +1,37 @@ +message; + } + + protected function makeAt($mobiles = [],$atAll = false){ + return [ + 'at' => [ + 'atMobiles' => $mobiles, + 'isAtAll' => $atAll + ] + ]; + } + + public function sendAt($mobiles = [],$atAll = false){ + $this->at = $this->makeAt($mobiles,$atAll); + return $this; + } + + public function getBody(){ + + if (empty($this->at)){ + $this->sendAt(); + } + return $this->message + $this->at; + } + +} \ No newline at end of file diff --git a/src/Messages/Text.php b/src/Messages/Text.php new file mode 100644 index 0000000..89f8fdf --- /dev/null +++ b/src/Messages/Text.php @@ -0,0 +1,17 @@ +message = [ + 'msgtype' => 'text', + 'text' => [ + 'content' => $content + ] + ]; + } + +} \ No newline at end of file diff --git a/src/SendClient.php b/src/SendClient.php new file mode 100644 index 0000000..f894b63 --- /dev/null +++ b/src/SendClient.php @@ -0,0 +1,15 @@ +with($robot)->text($arguments[0]); + } + + } +} \ No newline at end of file diff --git a/tests/Feature/ActionTest.php b/tests/Feature/ActionTest.php new file mode 100644 index 0000000..16ded69 --- /dev/null +++ b/tests/Feature/ActionTest.php @@ -0,0 +1,62 @@ +setUp(); + } + + /** + * available content to set + * @param $content + * @return bool + * @author wangju 2019-05-17 21:50 + */ + protected function matchContent($content) + { + return $content['title'] && $content['text']; + } + + /** + * A basic test example. + * + * @return void + */ + public function testPushActionSingleMessage() + { + + $result = $this->ding + ->actionCard($this->title,$this->text,1) + ->single("阅读全文","https://www.dingtalk.com/") + ->send(); + $this->assertSame([ + 'errmsg' => 'ok', + 'errcode' => 0 + ],$result); + } + + public function testPushActionBtnsMessageAtAllUser(){ + $result = $result = $this->ding + ->actionCard($this->title,$this->text,1) + ->addButtons("内容不错","https://www.dingtalk.com/") + ->addButtons("不感兴趣","https://www.dingtalk.com/") + ->send(); + $this->assertSame([ + 'errmsg' => 'ok', + 'errcode' => 0 + ],$result); + } +} diff --git a/tests/Feature/FeedTest.php b/tests/Feature/FeedTest.php new file mode 100644 index 0000000..b8ec05b --- /dev/null +++ b/tests/Feature/FeedTest.php @@ -0,0 +1,62 @@ +setUp(); + } + + /** + * available content to set + * @param $content + * @return bool + * @author wangju 2019-05-17 21:50 + */ + protected function matchContent($content) + { + if (empty($content)){ + return false; + } + return array_reduce($content,function ($carry,$item){ + if ($carry === null) return true; + return $carry && $item['title'] && $item['messageURL'] && $item['picURL']; + }); + } + + /** + * A basic test example. + * + * @return void + */ + public function testPushTextMessage() + { + $result =$this->ding->text("我就是我,@{$this->testUser} 是不一样的烟火"); + $this->assertSame([ + 'errmsg' => 'ok', + 'errcode' => 0 + ],$result); + } + + public function testPushTextMessageAtAllUser(){ + $result =$this->ding + ->feed() + ->addLinks('时代的火车向前开',$this->messageUrl,$this->picUrl) + ->addLinks('时代的火车向前开2',$this->messageUrl,$this->picUrl) + ->send(); + + $this->assertSame([ + 'errmsg' => 'ok', + 'errcode' => 0 + ],$result); + } +} diff --git a/tests/Feature/LinkTest.php b/tests/Feature/LinkTest.php new file mode 100644 index 0000000..31d21fb --- /dev/null +++ b/tests/Feature/LinkTest.php @@ -0,0 +1,48 @@ +setUp(); + + } + + /** + * available content to set + * @param $content + * @return bool + * @author wangju 2019-05-17 21:50 + */ + protected function matchContent($content) + { + return $content['text'] && $content['title'] && $content['messageUrl']; + } + + /** + * A basic test example. + * + * @return void + */ + public function testPushLinkMessage() + { + $result = $this->ding->link($this->title,$this->text,$this->messageUrl,$this->picUrl); + $this->assertSame([ + 'errmsg' => 'ok', + 'errcode' => 0 + ],$result); + } + +} diff --git a/tests/Feature/MarkdownTest.php b/tests/Feature/MarkdownTest.php new file mode 100644 index 0000000..95484fa --- /dev/null +++ b/tests/Feature/MarkdownTest.php @@ -0,0 +1,56 @@ + 9度,@1825718XXXX 西北风1级,空气良89,相对温度73%\n\n ". + "> ![screenshot](http://i01.lw.aliimg.com/media/lALPBbCc1ZhJGIvNAkzNBLA_1200_588.png)\n". + "> ###### 10点20分发布 [天气](http://www.thinkpage.cn/) "; + + public function __construct($name = null, array $data = [], $dataName = '') + { + parent::__construct($name, $data, $dataName); + $this->setUp(); + } + + /** + * available content to set + * @param $content + * @return bool + * @author wangju 2019-05-17 21:50 + */ + protected function matchContent($content) + { + return $content['title'] && $content['text']; + } + + /** + * A basic test example. + * + * @return void + */ + public function testPushMarkdownMessage() + { + $result =$this->ding->markdown($this->title,$this->markdown); + $this->assertSame([ + 'errmsg' => 'ok', + 'errcode' => 0 + ],$result); + } + + public function testPushMarkdownMessageAtAllUser(){ + $result =$this->ding + ->at([],true) + ->markdown($this->title,$this->markdown); + $this->assertSame([ + 'errmsg' => 'ok', + 'errcode' => 0 + ],$result); + } +} diff --git a/tests/Feature/TextTest.php b/tests/Feature/TextTest.php new file mode 100644 index 0000000..adb7b16 --- /dev/null +++ b/tests/Feature/TextTest.php @@ -0,0 +1,52 @@ +setUp(); + } + + /** + * available content to set + * @param $content + * @return bool + * @author wangju 2019-05-17 21:50 + */ + protected function matchContent($content) + { + $text = $content['content']; + return !empty($text); + } + + /** + * A basic test example. + * + * @return void + */ + public function testPushTextMessage() + { + $result =$this->ding->text("我就是我,@{$this->testUser} 是不一样的烟火"); + $this->assertSame([ + 'errmsg' => 'ok', + 'errcode' => 0 + ],$result); + } + + public function testPushTextMessageAtAllUser(){ + $result =$this->ding + ->at([],true) + ->text("我就是我,@{$this->testUser} 是不一样的烟火"); + $this->assertSame([ + 'errmsg' => 'ok', + 'errcode' => 0 + ],$result); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..ae27dbe --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,65 @@ +testUser = '18888888888'; + + $robot1['timeout'] = 30.0; + $robot1['enabled'] = true; + $robot1['token'] = $token; + $robot1['secret'] = 'SECcfc6343d91e588d1f83dcf6d725a0208f79607726560ca2be135b437c62523b5'; + $config['default'] = $robot1; + + $this->config = $config; + $this->ding = $this->mockDingClient(); + } + + /** + * mock ding client + * @param null $client + * @return DingTalk + * @author wangju 2019-05-17 20:53 + */ + protected function mockDingClient($client = null) + { + $client = \Mockery::mock(SendClient::class); + $client->shouldReceive('send')->withArgs(function ($arg) { + $messageType = $arg['msgtype']; + + if (!in_array($messageType, ['text', 'actionCard', 'feedCard', 'link', 'markdown'])) { + return false; + } + if (!array_key_exists($messageType, $arg)) { + return false; + } + return $this->matchContent($arg[$messageType]); + })->andReturn([ + 'errmsg' => 'ok', + 'errcode' => 0 + ]); + $ding = new DingTalk($this->config, $client); + return $ding; + } + + protected function matchContent($content) + { + return true; + } + +}