22
33namespace Mondago \MSGraph \Mail ;
44
5- use GuzzleHttp \ClientInterface ;
6- use Illuminate \Mail \Transport \Transport as LaravelTransport ;
7- use Illuminate \Support \Str ;
8-
9- class Transport extends LaravelTransport
5+ use Illuminate \Support \Facades \Http ;
6+ use Symfony \Component \Mailer \SentMessage ;
7+ use Symfony \Component \Mailer \Transport \AbstractTransport ;
8+ use Symfony \Component \Mime \Email ;
9+ use Symfony \Component \Mime \MessageConverter ;
10+ use Symfony \Component \Mime \Part \DataPart ;
11+
12+ class Transport extends AbstractTransport
1013{
1114 /**
1215 * Graph api configuration
1316 * @var array
1417 */
15- private $ config ;
16-
17- private $ http ;
18+ private array $ config ;
1819
19- public function __construct (ClientInterface $ client , array $ config )
20+ public function __construct (array $ config )
2021 {
22+ parent ::__construct (null , null );
2123 $ this ->config = $ config ;
22- $ this ->http = $ client ;
2324 }
2425
25- public function send (\Swift_Mime_SimpleMessage $ message , &$ failedRecipients = null )
26+
27+ protected function doSend (SentMessage $ message ): void
2628 {
27- $ this ->beforeSendPerformed ($ message );
2829 $ token = $ this ->getToken ();
29- $ emailMessage = $ this ->getMessage ($ message );
30- $ url = sprintf ('https://graph.microsoft.com/v1.0/users/%s/sendMail ' , urlencode ($ emailMessage ['from ' ]['emailAddress ' ]['address ' ]));
31-
32- try {
33- $ this ->http ->post ($ url , [
34- 'headers ' => [
35- 'Accept ' => 'application/json ' ,
36- 'Authorization ' => sprintf ('Bearer %s ' , $ token ),
37- ],
38- 'json ' => [
39- 'message ' => $ emailMessage ,
40- ],
41- ]);
42-
43- $ this ->sendPerformed ($ message );
44-
45- return $ this ->numberOfRecipients ($ message );
46-
47- } catch (\Exception $ e ) {
48- throw $ e ;
49- }
30+ $ email = MessageConverter::toEmail ($ message ->getOriginalMessage ());
31+ $ url = sprintf ('https://graph.microsoft.com/v1.0/users/%s/sendMail ' , $ email ->getFrom ()[0 ]->getEncodedAddress ());
32+ $ response = Http::withHeaders ([
33+ 'Authorization ' => sprintf ('Bearer %s ' , $ token )
34+ ])->post ($ url , [
35+ "message " => $ this ->getMessage ($ email )
36+ ]);
37+ $ response ->throw ();
5038 }
5139
5240 public function getToken ()
5341 {
5442 $ url = sprintf ('https://login.microsoftonline.com/%s/oauth2/v2.0/token ' , $ this ->config ['tenant ' ]);
55- try {
56- $ response = $ this ->http ->request ('POST ' , $ url , [
57- 'form_params ' => [
58- 'client_id ' => $ this ->config ['client_id ' ],
59- 'client_secret ' => $ this ->config ['client_secret ' ],
60- 'scope ' => 'https://graph.microsoft.com/.default ' ,
61- 'grant_type ' => 'client_credentials '
62- ],
63- ]);
64- $ data = json_decode ($ response ->getBody ()->getContents ());
43+ $ response = Http::asForm ()->post ($ url , [
44+ 'client_id ' => $ this ->config ['client_id ' ],
45+ 'client_secret ' => $ this ->config ['client_secret ' ],
46+ 'scope ' => 'https://graph.microsoft.com/.default ' ,
47+ 'grant_type ' => 'client_credentials '
48+ ]);
49+ $ response ->throw ();
6550
66- return $ data ->access_token ;
67- } catch (\Exception $ e ) {
68- throw $ e ;
69- }
51+ return $ response ['access_token ' ];
7052 }
7153
7254 public function __toString (): string
@@ -75,84 +57,59 @@ public function __toString(): string
7557 }
7658
7759 /*
78- * @link https://docs.microsoft.com/en-us/graph/api/resources/message?view=graph-rest-1.0
60+ * https://docs.microsoft.com/en-us/graph/api/resources/message?view=graph-rest-1.0
7961 */
80- private function getMessage (\ Swift_Mime_SimpleMessage $ email )
62+ private function getMessage (Email $ email )
8163 {
8264 return array_filter ([
83- "from " => $ this ->getRecipientsCollection ($ email ->getFrom ()) [0 ],
84- "sender " => $ this ->getRecipientsCollection ($ email ->getFrom ()) [0 ],
65+ "from " => $ this ->getRecipient ($ email ->getFrom ()[0 ]) ,
66+ "sender " => $ this ->getRecipient ($ email ->getFrom ()[0 ]) ,
8567 "toRecipients " => $ this ->getRecipientsCollection ($ email ->getTo ()),
8668 "ccRecipients " => $ this ->getRecipientsCollection ($ email ->getCc ()),
8769 "bccRecipients " => $ this ->getRecipientsCollection ($ email ->getBcc ()),
8870 "replyTo " => $ this ->getRecipientsCollection ($ email ->getReplyTo ()),
8971 "subject " => $ email ->getSubject (),
9072 "body " => [
91- "contentType " => $ this -> getContentType ( $ email ) ,
92- "content " => $ email ->getBody ()
73+ "contentType " => $ email -> getTextBody () ? ' Text ' : ' HTML ' ,
74+ "content " => $ email ->getTextBody () ?? $ email -> getHtmlBody (),
9375 ],
94- "attachments " => $ this ->getAttachmentsCollection ($ email ->getChildren ())
76+ "attachments " => $ this ->getAttachmentsCollection ($ email ->getAttachments ())
9577 ]);
9678 }
9779
98- private function getRecipientsCollection ($ addresses ): array
80+ private function getRecipientsCollection (array $ addresses ): array
9981 {
100- $ collection = [];
101- if (!$ addresses ) {
102- return [];
103- }
104- if (is_string ($ addresses )) {
105- $ addresses = [
106- $ addresses => null ,
107- ];
108- }
109-
110- foreach ($ addresses as $ email => $ name ) {
111- # https://docs.microsoft.com/en-us/graph/api/resources/recipient?view=graph-rest-1.0
112- $ collection [] = [
113- 'emailAddress ' => [
114- 'name ' => $ name ,
115- 'address ' => $ email ,
116- ],
117- ];
118- }
82+ return array_map ('self::getRecipient ' , $ addresses );
83+ }
11984
120- return $ collection ;
85+ /*
86+ * https://docs.microsoft.com/en-us/graph/api/resources/recipient?view=graph-rest-1.0
87+ */
88+ private function getRecipient ($ address ): array
89+ {
90+ return [
91+ 'emailAddress ' => array_filter ([
92+ 'address ' => $ address ->getAddress (),
93+ 'name ' => $ address ->getName (),
94+ ])
95+ ];
12196 }
12297
12398 private function getAttachmentsCollection ($ attachments )
12499 {
125- $ collection = [];
126-
127- foreach ($ attachments as $ attachment ) {
128- if (!$ attachment instanceof \Swift_Mime_Attachment) {
129- continue ;
130- }
131- // https://docs.microsoft.com/en-us/graph/api/resources/fileattachment?view=graph-rest-1.0
132- $ collection [] = [
133- 'name ' => $ attachment ->getFilename (),
134- 'contentId ' => $ attachment ->getId (),
135- 'contentType ' => $ attachment ->getContentType (),
136- 'contentBytes ' => base64_encode ($ attachment ->getBody ()),
137- 'size ' => strlen ($ attachment ->getBody ()),
138- '@odata.type ' => '#microsoft.graph.fileAttachment ' ,
139- 'isInline ' => $ attachment instanceof \Swift_Mime_EmbeddedFile,
140- ];
141-
142- }
143-
144- return $ collection ;
100+ return array_map ('self::getAttachment ' , $ attachments );
145101 }
146102
147- public function getContentType (\Swift_Mime_SimpleMessage $ email ): string
103+ /*
104+ * https://docs.microsoft.com/en-us/graph/api/resources/fileattachment?view=graph-rest-1.0
105+ */
106+ private function getAttachment (DataPart $ attachment )
148107 {
149- if (Str::contains ($ email ->getBodyContentType (), ['html ' ])) {
150- return 'HTML ' ;
151- } else {
152- if (Str::contains ($ email ->getBodyContentType (), ['text ' , 'plain ' ])) {
153- return 'Text ' ;
154- }
155- }
156- return 'HTML ' ;
108+ return array_filter ([
109+ "@odata.type " => "#microsoft.graph.fileAttachment " ,
110+ "name " => $ attachment ->getName () ?? $ attachment ->getFilename (),
111+ "contentType " => $ attachment ->getContentType (),
112+ "contentBytes " => base64_encode ($ attachment ->getBody ()),
113+ ]);
157114 }
158115}
0 commit comments