追記情報
- googleが信頼性の低いアプリの使用を禁止したため、2段階認証によるメールの送信ができなくなった。
-
yahoo.co.jp
のアカウントをつかってのメール送信もかなり制限されている。 - OAuth認証をつかったmail apiは
Azure
,Microsoft
,Yahoo.com
などの大手もある。 - 正直
SendGrid
のほうが使いやすい。
SendGrid
は個人利用ができなくなった。
審査も厳しくなり、途中でバンされたという報告が多数ある。 - 独自ドメインの利用は Google Workspace(月額 680 円/ユーザー)で可能。
- oauth認証のメールで送信し、差出人メールを
同じメールアカウント
で送ることで送信ドメイン認証もオールPASSになる。
参考サイト
ほぼ下の手順通り 2024/6/19
少し変更がある。
大きな変更はテストユーザーでは不可になったのでユーザーにアカウント追加する必要がある。
必要なもの
- GCPのプロジェクトを作成して、gmail apiを有効にする
- refresh token
refresh tokenの取得
- ドキュメントで公開されている quickstart.phpで取得 する方法
- PHPMailerに付属している
get_auth_token.php
を使って取得する方法
🙅get_oauth_token.php
にURLからアクセスするため 簡易サーバーの起動 は駄目
なので、Xampp
やlamp
などの開発環境が必要
🙅 // php -S 127.0.0.1:80 簡易サーバーではリレフレシュトークンが取得できない。
クライアントIDとクライアントシークレットの取得のための手続き
gmail_api
はアプリ名
cd gmail_api
googleのリダイレクトURLの登録にPHPMailerのget_auth_token.php
を使用するため
composer require phpmailer/phpmailer
get_oauth_token.php にアクセス
http://localhost/gmail_api/vendor/phpmailer/phpmailer/get_oauth_token.php
このURLがリダイレクトURLになる。
add User
でuser名は アカウントのgmailアドレス
http://localhost/vendor/phpmailer/phpmailer/get_oauth_token.php
を登録
PHPMailerでのリフレッシュトークンの取得
get_oauth_token.php にアクセス
http://localhost/gmail_api/vendor/phpmailer/phpmailer/get_oauth_token.php
入力してcontinue
2つくらいcontinue
をおしてたら下記のサイトがでてくるのでチェックをいれてcontinue
refresh token: ここがリフレッシュトークン
1度しか発行されないので注意
メールの送信
リフレッシュトークンを gmail apiになげてアクセストークンを取得することでメールが送れる。
アクセストークンの有効期限は1時間くらい。
refresh tokenの期限切れ
Gmail APIのリフレッシュトークンは通常、期限切れにならない。
一度発行されたら期限が切れるまで再発行(再取得)されない。
以下のいくつかの特別な状況で期限切れになる可能性がある。
- Gmail アカウントの所有者がアプリのアクセスを取り消した場合
- リフレッシュトークンが6ヶ月間使用されていない場合
XOAUTH2 用のパッケージ(league/oauth2-google)をインストール
composer require league/oauth2-google
テストコード
webdesignleavesから丸パクリ 注意事項も 必読
$google_email
,$clientId
,$clientSecret
,$refreshToken
は変更
<?php
// https://www.webdesignleaves.com/pr/php/php_phpmailer.php から丸パクリ
// HPMailer のクラスをグローバル名前空間(global namespace)にインポート
// スクリプトの先頭で宣言する必要があります
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\OAuth; // ### 追加 ###
// Alias the League Google OAuth2 provider class
use League\OAuth2\Client\Provider\Google;// ### 追加 ###
// Composer のオートローダーの読み込み(ファイルの位置によりパスを適宜変更)
require 'vendor/autoload.php';
//mbstring の日本語設定
mb_language("japanese");
mb_internal_encoding("UTF-8");
// インスタンスを生成(引数に true を指定して例外 Exception を有効に)
$mail = new PHPMailer(true);
//日本語用設定
$mail->CharSet = "iso-2022-jp";
$mail->Encoding = "7bit";
try {
//サーバの設定
$mail->SMTPDebug = SMTP::DEBUG_SERVER; // デバグの出力を有効に(テスト環境での検証用)
$mail->isSMTP(); // SMTP を使用
$mail->Host = 'smtp.gmail.com'; // ★★★ Gmail SMTP サーバーを指定
$mail->SMTPAuth = true; // SMTP authentication を有効に
$mail->AuthType = 'XOAUTH2';// ### 追加 ### AuthType を XOAUTH2 に指定
//$mail->Username = 'xxxxxx@gmail.com'; // ### 不要 ###
//$mail->Password = 'xxxxxx'; // ### 不要 ###
// ★★★ 暗号化を有効に PHPMailer::ENCRYPTION_STARTTLS を使う場合はポートを 587 に
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = 465; //ポートの指定
// ### OAUTH2 の設定 ###
//Gmail メールアドレス
$google_email = 'ここ変更@gmail.com';
//クライアント ID
$clientId = 'ここ変更';
//クライアントシークレット
$clientSecret = 'ここ変更';
//トークン(Refresh Token)
$refreshToken = 'ここ変更';
//OAuth2 プロバイダのインスタンスの生成
$provider = new Google(
[
'clientId' => $clientId,
'clientSecret' => $clientSecret,
]
);
//OAuth プロバイダのインスタンスを PHPMailer へ渡す
$mail->setOAuth(
new OAuth(
[
'provider' => $provider,
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'refreshToken' => $refreshToken,
'userName' => $google_email,
]
)
);
// ### OAUTH2 の設定 ここまで ###
//受信者設定
//差出人アドレス(Gmail のアドレス), 差出人名
$mail->setFrom($google_email, mb_encode_mimeheader('差出人名')); // ### 変更 ###
// 送信先アドレス, 受信者名(受信者名はオプション)
$mail->addAddress('ここ変更', mb_encode_mimeheader("受信者名"));
// 追加の受信者(受信者名は省略可能)
// $mail->addAddress('xxxxxx@xxxxxx.com');
//返信用アドレス(差出人以外に必要であれば)
$mail->addReplyTo('info@example.com', mb_encode_mimeheader("お問い合わせ"));
//Cc 受信者の指定
// $mail->addCC('xxxxxx@xxxxxx.com');
//コンテンツ設定
$mail->isHTML(true); // HTML形式を指定
//メール表題(タイトル)
$mail->Subject = mb_encode_mimeheader('日本語メールタイトル');
//本文(HTML用)
$mail->Body = mb_convert_encoding('HTML メッセージ <b>BOLD</b>',"JIS","UTF-8");
//テキスト表示の本文
$mail->AltBody = mb_convert_encoding('テキストメッセージ',"JIS","UTF-8");
$mail->send(); //送信
echo 'Message has been sent';
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
gmail apiでメールを取得
composer require google/apiclient:^2.0
composer require vlucas/phpdotenv
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Google\Client;
use Google\Service\Gmail;
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
$clientId = $_ENV['CLIENT_ID'];
$clientSecret = $_ENV['CLIENT_SECRET'];
$filePath = __DIR__ . '/gmail_refresh_token.txt';
if (is_readable($filePath)) {
$refreshToken = file_get_contents($filePath);
} else {
echo "ファイルが見つからないか、読み取りできません。";
}
$client = new Client();
$client->setClientId($clientId);
$client->setClientSecret($clientSecret);
$client->refreshToken($refreshToken);
$client->setScopes(['https://mail.google.com/']);
// Gmail サービスを作成
$service = new Gmail($client);
// 受信箱メッセージを取得
$optParams = [];
$optParams['maxResults'] = 5; // 例えば、最初の5件のメッセージだけを取得
$optParams['labelIds'] = 'INBOX'; // 受信箱のメッセージのみ
$messagesResponse = $service->users_messages->listUsersMessages('me', $optParams);
foreach ($messagesResponse->getMessages() as $message) {
$messageId = $message->getId();
$message_contents = $service->users_messages->get('me', $messageId, ['format' => 'full']);
$body_parts = $message_contents->getPayload()->getParts();
echo get_body($body_parts);
}
function get_body($parts) {
$body = '';
foreach ($parts as $part) {
//$part['mimeType'] === 'text/plain'とかある
if ($part['mimeType'] === 'text/html' && $part['body'] && $part['body']['data']) {
$rawData = $part['body']['data'];
$sanitizedData = strtr($rawData, '-_', '+/');
$decodedMessage = base64_decode($sanitizedData);
$body .= $decodedMessage;
} elseif (!empty($part['parts'])) {
$body .= get_body($part['parts']);
}
}
return $body;
}