1212
1313use GuzzleHttp \ClientInterface ;
1414use Illuminate \Mail \Transport \Transport ;
15+ use Illuminate \Support \Arr ;
16+ use Psr \Http \Message \ResponseInterface ;
1517use Swift_Mime_SimpleMessage ;
1618
1719/**
18- * Class Transport.
19- *
20- * @author overtrue <i@overtrue.me>
20+ * Class DirectMailTransport
2121 */
2222class DirectMailTransport extends Transport
2323{
2424 /**
25- * Guzzle client instance.
26- *
2725 * @var \GuzzleHttp\ClientInterface
2826 */
2927 protected $ client ;
@@ -33,6 +31,11 @@ class DirectMailTransport extends Transport
3331 */
3432 protected $ key ;
3533
34+ /**
35+ * @var string
36+ */
37+ protected $ secret ;
38+
3639 /**
3740 * @var array
3841 */
@@ -41,18 +44,36 @@ class DirectMailTransport extends Transport
4144 /**
4245 * @var string
4346 */
44- protected $ url = 'https://dm.aliyuncs.com/?Action=SingleSendMail ' ;
47+ protected $ regions = [
48+ 'cn-hangzhou ' => [
49+ 'id ' => 'cn-hangzhou ' ,
50+ 'url ' => 'https://dm.aliyuncs.com ' ,
51+ 'version ' => '2015-11-23 ' ,
52+ ],
53+ 'ap-southeast-1 ' => [
54+ 'id ' => 'ap-southeast-1 ' ,
55+ 'url ' => 'https://dm.ap-southeast-1.aliyuncs.com ' ,
56+ 'version ' => '2017-06-22 ' ,
57+ ],
58+ 'ap-southeast-2 ' => [
59+ 'id ' => 'ap-southeast-2 ' ,
60+ 'url ' => 'https://dm.ap-southeast-2.aliyuncs.com ' ,
61+ 'version ' => '2017-06-22 ' ,
62+ ],
63+ ];
4564
4665 /**
47- * Create a new SparkPost transport instance .
66+ * DirectMailTransport constructor .
4867 *
4968 * @param \GuzzleHttp\ClientInterface $client
5069 * @param string $key
70+ * @param string $secret
5171 * @param array $options
5272 */
53- public function __construct (ClientInterface $ client , $ key , $ options = [])
73+ public function __construct (ClientInterface $ client , string $ key , string $ secret , array $ options = [])
5474 {
5575 $ this ->key = $ key ;
76+ $ this ->secret = $ secret ;
5677 $ this ->client = $ client ;
5778 $ this ->options = $ options ;
5879 }
@@ -72,47 +93,47 @@ public function send(Swift_Mime_SimpleMessage $message, &$failedRecipients = nul
7293 {
7394 $ this ->beforeSendPerformed ($ message );
7495
75- $ to = $ this ->getTo ($ message );
76-
7796 $ message ->setBcc ([]);
7897
79- $ this ->client ->post ($ this ->url , $ this ->payload ($ message , $ to ));
98+ $ regionId = Arr::get ($ this ->options , 'region_id ' , 'cn-hangzhou ' );
99+ $ region = $ this ->regions [$ regionId ];
100+
101+ $ this ->client ->post ($ region ['url ' ], ['form_params ' => $ this ->payload ($ message , $ region )]);
80102
81103 $ this ->sendPerformed ($ message );
82104
83105 return $ this ->numberOfRecipients ($ message );
84106 }
85107
86108 /**
87- * Get the HTTP payload for sending the Mailgun message.
109+ * Get the HTTP payload for sending the message.
88110 *
89111 * @param \Swift_Mime_SimpleMessage $message
90- * @param string $to
112+ * @param array $region
91113 *
92114 * @return array
93115 */
94- protected function payload (Swift_Mime_SimpleMessage $ message , $ to )
116+ protected function payload (Swift_Mime_SimpleMessage $ message , array $ region )
95117 {
96- $ parameters = [
97- 'form_params ' => [
98- 'AccountName ' => $ message ->getFrom (),
99- 'ReplyToAddress ' => true ,
100- 'AddressType ' => array_get ($ this ->options , 'address_type ' , 1 ),
101- 'ToAddress ' => $ this ->getTo (),
102- 'FromAlias ' => array_get ($ this ->options , 'from_alias ' ),
103- 'Subject ' => $ message ->getSubject (),
104- 'HtmlBody ' => $ message ->getBody (),
105- 'ClickTrace ' => array_get ($ this ->options , 'click_trace ' , 0 ),
106- 'Format ' => 'json ' ,
107- 'Version ' => array_get ($ this ->options , 'version ' , '2015-11-23 ' ),
108- 'AccessKeyId ' => $ this ->getKey (),
109- 'Timestamp ' => date ('Y-m-d\TH:i:s\Z ' ),
110- 'SignatureMethod ' => 'HMAC-SHA1 ' ,
111- 'SignatureVersion ' => '1.0 ' ,
112- 'SignatureNonce ' => \uniqid (),
113- 'RegionId ' => \array_get ($ this ->options , 'region_id ' ),
114- ],
115- ];
118+ $ parameters = array_filter ([
119+ 'AccountName ' => Arr::get ($ this ->options , 'from_address ' , \config ('mail.from.address ' , key ($ message ->getFrom ()))),
120+ 'ReplyToAddress ' => 'true ' ,
121+ 'AddressType ' => Arr::get ($ this ->options , 'address_type ' , 1 ),
122+ 'ToAddress ' => $ this ->getTo ($ message ),
123+ 'FromAlias ' => Arr::get ($ this ->options , 'from_alias ' ),
124+ 'Subject ' => $ message ->getSubject (),
125+ 'HtmlBody ' => $ message ->getBody (),
126+ 'ClickTrace ' => Arr::get ($ this ->options , 'click_trace ' , 0 ),
127+ 'Format ' => 'json ' ,
128+ 'Action ' => 'SingleSendMail ' ,
129+ 'Version ' => $ region ['version ' ],
130+ 'AccessKeyId ' => $ this ->getKey (),
131+ 'Timestamp ' => now ()->toIso8601ZuluString (),
132+ 'SignatureMethod ' => 'HMAC-SHA1 ' ,
133+ 'SignatureVersion ' => '1.0 ' ,
134+ 'SignatureNonce ' => \uniqid (),
135+ 'RegionId ' => $ region ['id ' ],
136+ ]);
116137
117138 $ parameters ['Signature ' ] = $ this ->makeSignature ($ parameters );
118139
@@ -128,9 +149,15 @@ protected function makeSignature(array $parameters)
128149 {
129150 \ksort ($ parameters );
130151
131- $ signString = rawurlencode ('POST&/& ' . http_build_query ($ parameters , null , '& ' , PHP_QUERY_RFC3986 ));
152+ $ encoded = [];
153+
154+ foreach ($ parameters as $ key => $ value ) {
155+ $ encoded [] = \sprintf ('%s=%s ' , rawurlencode ($ key ), rawurlencode ($ value ));
156+ }
132157
133- return base64_encode (hash_hmac ('sha1 ' , $ signString , $ this ->getKey (), true ));
158+ $ signString = 'POST&%2F& ' .rawurlencode (\join ('& ' , $ encoded ));
159+
160+ return base64_encode (hash_hmac ('sha1 ' , $ signString , $ this ->getSecret ().'& ' , true ));
134161 }
135162
136163 /**
@@ -148,13 +175,11 @@ protected function getTo(Swift_Mime_SimpleMessage $message)
148175 }
149176
150177 /**
151- * Get the transmission ID from the response.
152- *
153- * @param \GuzzleHttp\Psr7\Response $response
178+ * @param \Psr\Http\Message\ResponseInterface $response
154179 *
155- * @return string
180+ * @return mixed
156181 */
157- protected function getTransmissionId ($ response )
182+ protected function getTransmissionId (ResponseInterface $ response )
158183 {
159184 return object_get (
160185 json_decode ($ response ->getBody ()->getContents ()),
@@ -163,8 +188,6 @@ protected function getTransmissionId($response)
163188 }
164189
165190 /**
166- * Get all of the contacts for the message.
167- *
168191 * @param \Swift_Mime_SimpleMessage $message
169192 *
170193 * @return array
@@ -179,8 +202,6 @@ protected function allContacts(Swift_Mime_SimpleMessage $message)
179202 }
180203
181204 /**
182- * Get the API key being used by the transport.
183- *
184205 * @return string
185206 */
186207 public function getKey ()
@@ -189,14 +210,30 @@ public function getKey()
189210 }
190211
191212 /**
192- * Set the API key being used by the transport.
193- *
213+ * @return string
214+ */
215+ public function getSecret ()
216+ {
217+ return $ this ->secret ;
218+ }
219+
220+ /**
194221 * @param string $key
195222 *
196223 * @return string
197224 */
198- public function setKey ($ key )
225+ public function setKey (string $ key )
199226 {
200227 return $ this ->key = $ key ;
201228 }
229+
230+ /**
231+ * @param string $secret
232+ *
233+ * @return string
234+ */
235+ public function setSecret (string $ secret )
236+ {
237+ return $ this ->secret = $ secret ;
238+ }
202239}
0 commit comments