phpでmicrosoft365のメールアカウントからメール送信
初めに
コーポレート系お問合せフォームからのメール送信でSendmailなんて使えないので、
SMTPを利用するんだけど、
Microsoft365とかgogleWorkspaceとかを利用してると、SMTPすら使えなくて、
APIを利用する事になる。
そして、Microsoft365で利用してるメールアドレスからphpを利用して送信する方法を
調べても本当に情報が無くて苦労したので、まとめておく。
phpからMicrosoft365のAPIを利用するには、SDKを利用する
仕組み
microsoft365のメール送信をphpやその他のプログラム言語で行う為には
Graph Apiを利用する必要が有る。
また、
Graph Apiの認証方法でアプリ専用認証を利用する事で、
アカウントにログインせずに、メール送信が利用できる。
ただし、
送信元ユーザー(アドレス)は明示的に指定する必要が有る。
送信元ユーザーのUserIdの取得方法も合わせて書いておく
全体の流れ
バクっと全体の流れをまとめておく
- Microsoft365のEntra管理センターでアプリを作成して【クライアントID】と【テナントID】を取得
- アプリにAPIのMail.send権限を付与
- 【クライアントシークレット】を作成する
- 送信元ユーザーの【UserId】を取得
- phpで処理を書く
Microsoft365のEntra管理センターでアプリを作成
ポータルでアプリを登録する
Microsoft Entra 管理センターに移動して、
[ID] を展開し、[ アプリケーション] を展開して、[ アプリの登録] を選択
アプリの登録画面でアプリを作成する
登録する内容はこんな感じ
① : アプリ名を入力する。日本語でOKだし、自分に解ればOK
とりあえず「サイトメール送信アプリ1」にした
② :この組織ディレクトリに含まれるアカウントにチェック。
③ : リダイレクトURLは空白でOK
④ : 登録をクリック
登録したアプリの画面が表示される。
2つの文字列をメモしておく
- アプリケーション (クライアント) ID
- ディレクトリ (テナント) ID
アプリにAPIのMail.send権限を付与
既存の「User.Read」権限は削除する
「Mail.Send」権限を付与する
これで、
一覧に「Mail.send」が入るが、
状態の列で「〇〇〇に付与されていません」という表示が出る
「〇〇〇に管理者の同意を与えます」をクリックし
出てきたフロートウィンドの中の「はい」をクリックする
クライアントシークレットを作成する
下の画像の感じでシークレットを作成する
説明は自分が解る名前にしとけばいい。
有効期限はカスタムにすると、起動と終了を入力できるようになり、
起動は今日の日付
終了はエラー文に2年後の日付が表示されるのでその日付を指定
画面下の「保存」をクリックする
クライアントシークレットができるので値の方の文字列をメモしておく
これがクライアントシークレットとなるのでメモ
この値は1回しか表示しないので注意
送信者のUserIDを取得
これも管理者のEntraから確認できる
ユーザー→全てのユーザー→一覧から該当のユーザー名をクリックして、ユーザーの詳細を開く
「オブジェクトID」部分がUserIdになるので、メモっておく
phpで処理を書く
あとは、普通にブラウザから利用する為のphpを作成する。
ComposerでSDKをインストール
composer require microsoft/microsoft-graph
完成後フォルダ構成はこんな感じ
root/
├── GraphMail.php
├── composer.json
├── composer.lock
├── index.php
└── vendor/
メール送信クラスの作成「GraphMail.php」
<?php
use Microsoft\Graph\GraphServiceClient;
use Microsoft\Kiota\Authentication\Oauth\ClientCredentialContext;
use Microsoft\Graph\Generated\Users\Item\SendMail\SendMailPostRequestBody;
use Microsoft\Graph\Generated\Models\BodyType;
use Microsoft\Graph\Generated\Models\EmailAddress;
use Microsoft\Graph\Generated\Models\ItemBody;
use Microsoft\Graph\Generated\Models\Message;
use Microsoft\Graph\Generated\Models\Recipient;
class GraphMail
{
private $tokenContext;
private $appClient;
private $userId = '${UserId}';
private $fromEmailAddress ='${送信元メールアドレス}'; //送信元アドレス;
private $clientId = '${クライアントID}';
private $clientSecret = '${クライアントシークレット}';
private $tenantId = '${テナントID}';
public function initializeGraphForAppOnlyAuth()
{
$this->tokenContext = new ClientCredentialContext(
$this->tenantId,
$this->clientId,
$this->clientSecret
);
$this->appClient = new GraphServiceClient(
$this->tokenContext,
['https://graph.microsoft.com/.default']
);
}
public function sendMail($toEmailAddress, $subject, $body): void
{
//送信元
$sender = new EmailAddress();
$sender->setAddress($this->fromEmailAddress);
$fromRecipient = new Recipient();
$fromRecipient->setEmailAddress($sender);
//送信先
$recipients = [];
$recipientEmail = new EmailAddress();
$recipientEmail->setAddress($toEmailAddress);
$toRecipient = new Recipient();
$toRecipient->setEmailAddress($recipientEmail);
$recipients[] = $toRecipient;
//メール本文
$emailBody = new ItemBody();
$emailBody->setContent($body);
$emailBody->setContentType(new BodyType(BodyType::TEXT));
//メール作成
$message = new Message();
$message->setSubject($subject);
$message->setFrom($fromRecipient);
$message->setToRecipients($recipients);
$message->setBody($emailBody);
//メール送信
$requestBody = new SendMailPostRequestBody();
$requestBody->setMessage($message);
$this->appClient->users()->byUserId($this->userId)->sendMail()->post($requestBody)->wait();
}
}
メール送信処理の作成「index.php」
<?php
require 'vendor/autoload.php';
require 'GraphMail.php';
$graphMail = new GraphMail();
//クライアントの作成
$graphMail->initializeGraphForAppOnlyAuth();
try {
//メール送信
$graphMail->sendMail('${送信先メールアドレス}', '${件名}', '${本文}');
} catch (Exception $e) {
print(PHP_EOL . 'Error getting users: ' . $e->getMessage() . PHP_EOL . PHP_EOL);
}
最後に
日本語の情報が無さ過ぎて苦労したので、
誰かの役に立てば嬉しいです。
2024/12/06現在は、これで送信できてる
このへんのAzureとかのAPIは、ガンガン仕様変更されていくので、
半年後ぐらいには約に立たないかもしれないけど
ちょっとは役に立ってくれると嬉しいです。
参考記事
SDKのリポジトリ
SDKの解説ドキュメント
アプリ認証のやり方は「o make requests without a signed-in use」でページ内検索したらある
メール送信
公式のメール送信についてのドキュメント
公式のチュートリアル「Microsoft Graph とアプリ専用認証を使用して PHP アプリを構築する」
Discussion