Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
easy-sms
提交
b606a7c2
E
easy-sms
项目概览
OpenDocCN
/
easy-sms
通知
3
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
easy-sms
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b606a7c2
编写于
12月 04, 2018
作者:
M
milkmeowo
提交者:
安正超
12月 04, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
增加华为云支持 (#148)
* 增加华为云 SMS 支持 * 文档更新支持华为云 SMS * fix styleCI
上级
2a7e47f0
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
354 addition
and
0 deletion
+354
-0
README.md
README.md
+42
-0
src/Gateways/HuaweiGateway.php
src/Gateways/HuaweiGateway.php
+143
-0
tests/Gateways/HuaweiGatewayTest.php
tests/Gateways/HuaweiGatewayTest.php
+169
-0
未找到文件。
README.md
浏览文件 @
b606a7c2
...
...
@@ -520,6 +520,48 @@ $easySms->send(13188888888, $message);
],
```
### [华为云 SMS](https://www.huaweicloud.com/product/msgsms.html)
短信内容使用
`template`
+
`data`
```
php
'huawei'
=>
[
'endpoint'
=>
''
,
// APP接入地址
'app_key'
=>
''
,
// APP KEY
'app_secret'
=>
''
,
// APP SECRET
'from'
=>
[
'default'
=>
'1069012345'
,
// 默认使用签名通道号
'custom'
=>
'csms12345'
,
// 其他签名通道号 可以在 data 中定义 from 来指定
'abc'
=>
'csms67890'
,
// 其他签名通道号
...
],
'callback'
=>
''
// 短信状态回调地址
],
```
使用默认签名通道
`default`
```
php
$easySms
->
send
(
13188888888
,
[
'template'
=>
'SMS_001'
,
'data'
=>
[
6379
],
]);
```
使用指定签名通道
```
php
$easySms
->
send
(
13188888888
,
[
'template'
=>
'SMS_001'
,
'data'
=>
[
6379
,
'from'
=>
'custom'
// 对应 config 中的 from 数组中 custom
],
]);
```
## License
MIT
src/Gateways/HuaweiGateway.php
0 → 100644
浏览文件 @
b606a7c2
<?php
/*
* This file is part of the overtrue/easy-sms.
*
* (c) overtrue <i@overtrue.me>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace
Overtrue\EasySms\Gateways
;
use
GuzzleHttp\Exception\RequestException
;
use
Overtrue\EasySms\Contracts\MessageInterface
;
use
Overtrue\EasySms\Contracts\PhoneNumberInterface
;
use
Overtrue\EasySms\Exceptions\GatewayErrorException
;
use
Overtrue\EasySms\Exceptions\InvalidArgumentException
;
use
Overtrue\EasySms\Support\Config
;
use
Overtrue\EasySms\Traits\HasHttpRequest
;
class
HuaweiGateway
extends
Gateway
{
use
HasHttpRequest
;
const
ENDPOINT_HOST
=
'https://api.rtc.huaweicloud.com:10443'
;
const
ENDPOINT_URI
=
'/sms/batchSendSms/v1'
;
const
SUCCESS_CODE
=
'000000'
;
/**
* 发送信息.
*
* @param PhoneNumberInterface $to
* @param MessageInterface $message
* @param Config $config
*
* @return array
*
* @throws GatewayErrorException
* @throws InvalidArgumentException
*/
public
function
send
(
PhoneNumberInterface
$to
,
MessageInterface
$message
,
Config
$config
)
{
$appKey
=
$config
->
get
(
'app_key'
);
$appSecret
=
$config
->
get
(
'app_secret'
);
$channels
=
$config
->
get
(
'from'
);
$statusCallback
=
$config
->
get
(
'callback'
,
''
);
$endpoint
=
$this
->
getEndpoint
(
$config
);
$headers
=
$this
->
getHeaders
(
$appKey
,
$appSecret
);
$templateId
=
$message
->
getTemplate
(
$this
);
$messageData
=
$message
->
getData
(
$this
);
// 短信签名通道号码
$from
=
'default'
;
if
(
isset
(
$messageData
[
'from'
]))
{
$from
=
$messageData
[
'from'
];
unset
(
$messageData
[
'from'
]);
}
$channel
=
isset
(
$channels
[
$from
])
?
$channels
[
$from
]
:
''
;
if
(
empty
(
$channel
))
{
throw
new
InvalidArgumentException
(
"From Channel [
{
$from
}
] Not Exist"
);
}
$params
=
[
'from'
=>
$channel
,
'to'
=>
$to
->
getUniversalNumber
(),
'templateId'
=>
$templateId
,
'templateParas'
=>
json_encode
(
$messageData
),
'statusCallback'
=>
$statusCallback
,
];
try
{
$result
=
$this
->
request
(
'post'
,
$endpoint
,
[
'headers'
=>
$headers
,
'form_params'
=>
$params
,
//为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题
'verify'
=>
false
,
]);
}
catch
(
RequestException
$e
)
{
$result
=
$this
->
unwrapResponse
(
$e
->
getResponse
());
}
if
(
self
::
SUCCESS_CODE
!=
$result
[
'code'
])
{
throw
new
GatewayErrorException
(
$result
[
'description'
],
ltrim
(
$result
[
'code'
],
'E'
),
$result
);
}
return
$result
;
}
/**
* 构造 Endpoint.
*
* @param Config $config
*
* @return string
*/
protected
function
getEndpoint
(
Config
$config
)
{
$endpoint
=
rtrim
(
$config
->
get
(
'endpoint'
,
self
::
ENDPOINT_HOST
),
'/'
);
return
$endpoint
.
self
::
ENDPOINT_URI
;
}
/**
* 获取请求 Headers 参数.
*
* @param string $appKey
* @param string $appSecret
*
* @return array
*/
protected
function
getHeaders
(
$appKey
,
$appSecret
)
{
return
[
'Content-Type'
=>
'application/x-www-form-urlencoded'
,
'Authorization'
=>
'WSSE realm="SDP",profile="UsernameToken",type="Appkey"'
,
'X-WSSE'
=>
$this
->
buildWsseHeader
(
$appKey
,
$appSecret
),
];
}
/**
* 构造X-WSSE参数值
*
* @param string $appKey
* @param string $appSecret
*
* @return string
*/
protected
function
buildWsseHeader
(
$appKey
,
$appSecret
)
{
$now
=
date
(
'Y-m-d\TH:i:s\Z'
);
$nonce
=
uniqid
();
$passwordDigest
=
base64_encode
(
hash
(
'sha256'
,
(
$nonce
.
$now
.
$appSecret
)));
return
sprintf
(
'UsernameToken Username="%s",PasswordDigest="%s",Nonce="%s",Created="%s"'
,
$appKey
,
$passwordDigest
,
$nonce
,
$now
);
}
}
tests/Gateways/HuaweiGatewayTest.php
0 → 100644
浏览文件 @
b606a7c2
<?php
/*
* This file is part of the overtrue/easy-sms.
*
* (c) overtrue <i@overtrue.me>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace
Overtrue\EasySms\Tests\Gateways
;
use
Overtrue\EasySms\Exceptions\GatewayErrorException
;
use
Overtrue\EasySms\Gateways\HuaweiGateway
;
use
Overtrue\EasySms\Message
;
use
Overtrue\EasySms\PhoneNumber
;
use
Overtrue\EasySms\Support\Config
;
use
Overtrue\EasySms\Tests\TestCase
;
class
HuaweiGatewayTest
extends
TestCase
{
/**
* 测试 发送华为短信
*/
public
function
testSend
()
{
$config
=
[
'endpoint'
=>
'mock-endpoint'
,
'app_key'
=>
'mock-app-key'
,
'app_secret'
=>
'mock-app-secret'
,
'from'
=>
[
'default'
=>
'mock-default-from'
,
],
'callback'
=>
'mock-callback'
,
];
$expectedParams
=
[
'from'
=>
'mock-default-from'
,
'to'
=>
'13800138000'
,
'templateId'
=>
'mock-tpl-id'
,
'templateParas'
=>
'["mock-data-1","mock-data-2"]'
,
'statusCallback'
=>
'mock-callback'
,
];
$gateway
=
\
Mockery
::
mock
(
HuaweiGateway
::
class
.
'[request]'
,
[
$config
])
->
shouldAllowMockingProtectedMethods
();
$gateway
->
shouldReceive
(
'request'
)
->
with
(
'post'
,
\
Mockery
::
on
(
function
(
$endpoint
)
use
(
$config
)
{
return
$config
[
'endpoint'
]
.
'/sms/batchSendSms/v1'
===
$endpoint
;
}),
\
Mockery
::
on
(
function
(
$params
)
use
(
$expectedParams
)
{
ksort
(
$params
[
'form_params'
]);
ksort
(
$expectedParams
);
return
$params
[
'form_params'
]
==
$expectedParams
;
})
)
->
andReturn
(
[
'code'
=>
HuaweiGateway
::
SUCCESS_CODE
,
'description'
=>
'Success'
,
'result'
=>
'mock-result'
],
[
'code'
=>
'E200037'
,
'description'
=>
'The SMS fails to be sent. For details, see status'
]
)
->
twice
();
$message
=
new
Message
([
'template'
=>
'mock-tpl-id'
,
'data'
=>
[
'mock-data-1'
,
'mock-data-2'
],
]);
$config
=
new
Config
(
$config
);
$phoneNum
=
new
PhoneNumber
(
13800138000
);
$expectedSuccessResult
=
[
'code'
=>
HuaweiGateway
::
SUCCESS_CODE
,
'description'
=>
'Success'
,
'result'
=>
'mock-result'
];
$this
->
assertSame
(
$expectedSuccessResult
,
$gateway
->
send
(
$phoneNum
,
$message
,
$config
));
$this
->
expectException
(
GatewayErrorException
::
class
);
$this
->
expectExceptionCode
(
200037
);
$this
->
expectExceptionMessage
(
'The SMS fails to be sent. For details, see status'
);
$gateway
->
send
(
$phoneNum
,
$message
,
$config
);
}
/**
* 测试 自定义签名通道.
*/
public
function
testMultiFrom
()
{
$config
=
[
'endpoint'
=>
'mock-endpoint'
,
'app_key'
=>
'mock-app-key'
,
'app_secret'
=>
'mock-app-secret'
,
'from'
=>
[
'default'
=>
'mock-default-from'
,
'custom'
=>
'mock-custom-from'
,
// 配置自定义签名通道
],
'callback'
=>
'mock-callback'
,
];
$expectedParams
=
[
'from'
=>
'mock-custom-from'
,
'to'
=>
'13800138000'
,
'templateId'
=>
'mock-tpl-id'
,
'templateParas'
=>
'["mock-data-1","mock-data-2"]'
,
'statusCallback'
=>
'mock-callback'
,
];
$gateway
=
\
Mockery
::
mock
(
HuaweiGateway
::
class
.
'[request]'
,
[
$config
])
->
shouldAllowMockingProtectedMethods
();
$gateway
->
shouldReceive
(
'request'
)
->
with
(
'post'
,
\
Mockery
::
on
(
function
(
$endpoint
)
use
(
$config
)
{
return
$config
[
'endpoint'
]
.
'/sms/batchSendSms/v1'
===
$endpoint
;
}),
\
Mockery
::
on
(
function
(
$params
)
use
(
$expectedParams
)
{
ksort
(
$params
[
'form_params'
]);
ksort
(
$expectedParams
);
return
$params
[
'form_params'
]
==
$expectedParams
;
})
)
->
andReturn
(
[
'code'
=>
HuaweiGateway
::
SUCCESS_CODE
,
'description'
=>
'Success'
,
'result'
=>
'mock-result'
],
[
'code'
=>
'E200037'
,
'description'
=>
'The SMS fails to be sent. For details, see status'
]
)
->
twice
();
$message
=
new
Message
([
'template'
=>
'mock-tpl-id'
,
'data'
=>
[
'mock-data-1'
,
'mock-data-2'
,
'from'
=>
'custom'
,
// 设置自定义签名通道
],
]);
$config
=
new
Config
(
$config
);
$phoneNum
=
new
PhoneNumber
(
13800138000
);
$expectedSuccessResult
=
[
'code'
=>
HuaweiGateway
::
SUCCESS_CODE
,
'description'
=>
'Success'
,
'result'
=>
'mock-result'
];
$this
->
assertSame
(
$expectedSuccessResult
,
$gateway
->
send
(
$phoneNum
,
$message
,
$config
));
$this
->
expectException
(
GatewayErrorException
::
class
);
$this
->
expectExceptionCode
(
200037
);
$this
->
expectExceptionMessage
(
'The SMS fails to be sent. For details, see status'
);
$gateway
->
send
(
$phoneNum
,
$message
,
$config
);
}
/**
* 测试 endpoint.
*
* @throws \ReflectionException
*/
public
function
testGetEndpoint
()
{
$method
=
new
\
ReflectionMethod
(
HuaweiGateway
::
class
,
'getEndpoint'
);
$method
->
setAccessible
(
true
);
$gateway
=
\
Mockery
::
mock
(
HuaweiGateway
::
class
.
'[request]'
,
[[]])
->
shouldAllowMockingProtectedMethods
();
$defaultEndpoint
=
'https://api.rtc.huaweicloud.com:10443/sms/batchSendSms/v1'
;
$this
->
assertSame
(
$defaultEndpoint
,
$method
->
invoke
(
$gateway
,
new
Config
()));
$config
=
new
Config
([
'endpoint'
=>
'mock-endpoint'
,
]);
$endpoint
=
'mock-endpoint/sms/batchSendSms/v1'
;
$this
->
assertSame
(
$endpoint
,
$method
->
invoke
(
$gateway
,
$config
));
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录