Skip to content

Commit

Permalink
* 快速便捷的开发消息通知
Browse files Browse the repository at this point in the history
* 支持钉钉、飞书、企业微信以及自定义通知渠道
* 支持文本、markdown以及自定义消息模板
  • Loading branch information
G-YDG committed May 25, 2024
1 parent 0653f05 commit ef6a3a9
Show file tree
Hide file tree
Showing 19 changed files with 865 additions and 2 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.idea/
.git/
runtime/
vendor/
.env
.DS_Store
*.lock
*.cache
.bashrc
80 changes: 80 additions & 0 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

return (new PhpCsFixer\Config())
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true,
'@Symfony' => true,
'@DoctrineAnnotation' => true,
'@PhpCsFixer' => true,
'array_syntax' => [
'syntax' => 'short'
],
'list_syntax' => [
'syntax' => 'short'
],
'concat_space' => [
'spacing' => 'one'
],
'blank_line_before_statement' => [
'statements' => [
'declare',
],
],
'general_phpdoc_annotation_remove' => [
'annotations' => [
'author'
],
],
'ordered_imports' => [
'imports_order' => [
'class', 'function', 'const',
],
'sort_algorithm' => 'alpha',
],
'single_line_comment_style' => [
'comment_types' => [
],
],
'yoda_style' => [
'always_move_variable' => false,
'equal' => false,
'identical' => false,
],
'phpdoc_align' => [
'align' => 'left',
],
'multiline_whitespace_before_semicolons' => [
'strategy' => 'no_multi_line',
],
'constant_case' => [
'case' => 'lower',
],
'global_namespace_import' => [
'import_classes' => true,
'import_constants' => true,
'import_functions' => null,
],
'class_attributes_separation' => true,
'combine_consecutive_unsets' => true,
'declare_strict_types' => true,
'linebreak_after_opening_tag' => true,
'lowercase_static_reference' => true,
'no_useless_else' => true,
'no_unused_imports' => true,
'not_operator_with_successor_space' => true,
'not_operator_with_space' => false,
'ordered_class_elements' => true,
'php_unit_strict' => false,
'phpdoc_separation' => false,
'single_quote' => true,
'standardize_not_equals' => true,
'multiline_comment_opening_closing' => true,
])
->setFinder(
PhpCsFixer\Finder::create()
->exclude('runtime')
->exclude('vendor')
->in(__DIR__)
)
->setUsingCache(false);
36 changes: 34 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,34 @@
# message-notify
easy to send message notify
# 消息通知组件

## 介绍

* 快速便捷的开发消息通知
* 支持钉钉、飞书、企业微信以及自定义通知渠道
* 支持文本、markdown以及自定义消息模板

## 安装

```bash
$ composer require ydg/message-notify
```

## 使用

```php
<?php

use Ydg\MessageNotice\Channel\DingTalkChannel;
use Ydg\MessageNotice\MessageNotify;
use Ydg\MessageNotice\Template\Text;

MessageNotify::make()
->setChannel(DingTalkChannel::class, 'https://oapi.dingtalk.com/robot/send?access_token=xxx')
->setTitle('标题')
->setText('通知测试')
->setTemplate(Text::class)
->send();
```

## 协议

MIT 许可证(MIT)。有关更多信息,请参见[协议文件](LICENSE)
20 changes: 20 additions & 0 deletions bootstrap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

use Dotenv\Dotenv;
use Dotenv\Repository\Adapter;
use Dotenv\Repository\RepositoryBuilder;

! defined('BASE_PATH') && define('BASE_PATH', __DIR__);

require_once BASE_PATH . '/vendor/autoload.php';

if (file_exists(BASE_PATH . '/.env')) {
$repository = RepositoryBuilder::createWithNoAdapters()
->addAdapter(Adapter\PutenvAdapter::class)
->immutable()
->make();

Dotenv::create($repository, [BASE_PATH])->load();
}
40 changes: 40 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "ydg/message-notify",
"description": "message notify sdk",
"license": "MIT",
"keywords": [
"php",
"sdk",
"message",
"message-notify",
"message-notify-sdk"
],
"require": {
"php": "^7.0|^8.0",
"guzzlehttp/guzzle": "^7.4",
"ext-json": "*"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.12",
"phpunit/phpunit": "^9.5",
"vlucas/phpdotenv": "^5.0"
},
"autoload": {
"psr-4": {
"Ydg\\MessageNotice\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"YdgTest\\MessageNotice\\": "tests/"
}
},
"config": {
"optimize-autoloader": true,
"sort-packages": true
},
"scripts": {
"test": "phpunit",
"cs-fix": "php-cs-fixer fix ."
}
}
21 changes: 21 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="./bootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
</coverage>
<testsuites>
<testsuite name="Tests">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
</phpunit>
49 changes: 49 additions & 0 deletions src/Channel/AbstractChannel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace Ydg\MessageNotice\Channel;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\RequestOptions;
use Ydg\MessageNotice\Template\AbstractTemplate;

abstract class AbstractChannel
{
protected $config;

public function __construct($config)
{
$this->config = is_array($config) ? $config : ['url' => $config];
}

abstract public function send(AbstractTemplate $template): bool;

public function getConfig(): array
{
return $this->config;
}

public function setConfig($config)
{
$this->config = $config;
}

protected function doSendRequest(AbstractTemplate $template)
{
$client = $this->getClient();

$option = [
RequestOptions::HEADERS => [],
RequestOptions::JSON => $template->getBody(),
];
$request = $client->post($this->getUrl(), $option);
return json_decode($request->getBody()->getContents(), true);
}

public function getClient(): ClientInterface
{
return new Client();
}
}
12 changes: 12 additions & 0 deletions src/Channel/ChannelInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Ydg\MessageNotice\Channel;

interface ChannelInterface
{
/**
* 发送请求
* @return mixed
*/
public function send(): bool;
}
24 changes: 24 additions & 0 deletions src/Channel/DingTalkChannel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Ydg\MessageNotice\Channel;

use Ydg\MessageNotice\Exception\MessageNotificationException;
use Ydg\MessageNotice\Template\AbstractTemplate;

class DingTalkChannel extends AbstractChannel
{
public function send(AbstractTemplate $template): bool
{
$template->setBody($template->getDingTalkBody());
$result = $this->doSendRequest($template);
if ($result['errcode'] !== 0) {
throw new MessageNotificationException($result['errmsg']);
}
return true;
}

protected function getUrl(): string
{
return $this->getConfig()['url'] ?? '';
}
}
26 changes: 26 additions & 0 deletions src/Channel/FeiShuChannel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Ydg\MessageNotice\Channel;

use Ydg\MessageNotice\Exception\MessageNotificationException;
use Ydg\MessageNotice\Template\AbstractTemplate;

class FeiShuChannel extends AbstractChannel
{
public function send(AbstractTemplate $template): bool
{
$template->setBody($template->getFeiShuBody());
$result = $this->doSendRequest($template);
if (! isset($result['StatusCode']) || $result['StatusCode'] !== 0) {
throw new MessageNotificationException($result['msg']);
}
return true;
}

protected function getUrl(): string
{
return $this->getConfig()['url'] ?? '';
}
}
24 changes: 24 additions & 0 deletions src/Channel/WorkWechatChannel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Ydg\MessageNotice\Channel;

use Ydg\MessageNotice\Exception\MessageNotificationException;
use Ydg\MessageNotice\Template\AbstractTemplate;

class WorkWechatChannel extends AbstractChannel
{
public function send(AbstractTemplate $template): bool
{
$template->setBody($template->getWorkWechatBody());
$result = $this->doSendRequest($template);
if ($result['errcode'] !== 0) {
throw new MessageNotificationException($result['errmsg']);
}
return true;
}

protected function getUrl(): string
{
return $this->getConfig()['url'] ?? '';
}
}
Loading

0 comments on commit ef6a3a9

Please sign in to comment.