次のタスクにPHPIMAPを使用しています。
- メールボックスから古い文字を削除します。残念ながら、企業のG Suiteアカウントのコントロールパネルでは、受信後N日後に組織のすべてのメールボックスからメッセージを削除する期間のみを構成できます。ただし、指定されたメールボックス内で、受信後の指定された異なる日数後にのみ、文字を削除する必要があります。
- 文字のフィルタリング、解析、マーキング。当サイトから自動モードで多くの手紙が送られてきますが、その中には受取人に届かないものもあり、それに応じて報告があります。これらのレポートをキャッチし、分解し、電子メールでクライアントを見つけ、マネージャーがクライアントに連絡して電子メールアドレスの関連性を明確にできるように、人間が読める手紙を作成する必要があります。
この記事では、Gmail APIを使用してこれら2つのタスクを解決します(同時に、PHP IMAPが機能するように有効にされたメールボックス設定で、安全でないアプリケーションへのアクセスを無効にします。実際、2021年2月のひどい日に機能を停止します)。Gmailアプリケーションのいわゆるサービスアカウントを使用します。これを適切に構成すると、組織のすべてのメールボックスに接続して、それらのメールボックスで任意のアクションを実行できます。
1. GoogleAPI開発者コンソールでプロジェクトを作成します
このプロジェクトの助けを借りて、GmailとのAPIインタラクションを実行し、その中で同じサービスアカウントを作成します。
プロジェクトを作成するには:
- Google API開発者コンソールに移動し、G Suite管理者としてログインします(または、すべての権限を持つユーザーは誰ですか)
- 「プロジェクトの作成」ボタンを探しています。
私はここで見つけました:
そしてここに:
プロジェクト名を入力して保存します。
プロジェクトの作成
- プロジェクトに移動し、[APIとサービスを有効にする]ボタンをクリックします。
APIとサービスを有効にする
GmailAPIの選択
2.サービスアカウントを作成して構成します
これを行うには、公式マニュアルを使用するか、以下を読み続けてください。
- 追加したGmailAPIに移動し、[資格情報の作成]ボタンをクリックして、[サービスアカウント]を選択します。
サービスアカウントの作成
何かを入力して[作成]をクリックします。
サービスアカウントの詳細
他のすべては空白のままにすることができます:
サービスアカウントのアクセス権
- , . G Suite, « — API».
API
- « »:
«», « » , « OAuth» — :
- https://mail.google.com/ -
- https://www.googleapis.com/auth/gmail.modify -
- https://www.googleapis.com/auth/gmail.readonly -
- https://www.googleapis.com/auth/gmail.metadata -
- « G Suite»:
また、下のフィールドに製品の名前を入力してください。
- 次に、サービスアカウントキーを作成する必要があります。これは、アプリケーションで使用できるはずのファイルです。実際、彼は承認のために使用されます。
これを行うには、プロジェクトの[資格情報]ページから、[サービスアカウントの管理]リンクをたどります。
資格情報
「アクション-キーの作成」を選択し、次のように入力します。JSON:
サービスアカウント管理
その後、キーファイルが生成されてコンピュータにダウンロードされます。このファイルはプロジェクトに配置され、GmailAPIを呼び出すときにアクセスできるようにする必要があります。
これでGmailAPIの構成が完了し、実際には、これまでにIMAPPHP拡張機能によって解決された関数を実装する私のココアコードが少しあります。
3.コードを書く
私が使用した GmailAPIの非常に優れた公式ドキュメント(クリックアンドクリック)があります。しかし、私は詳細なマニュアルを書き始めたので、私は自分のココアコードを添付します。
そこで、まず、composerを使用してGoogleクライアントライブラリ(apiclient)をインストールします:(
composer require google/apiclient
最初は、真の文学の専門家として、PHPクイックスタートに示されているようにバージョン2.0のapiクライアントをインストールしましたが、最初のスタートでは、あらゆる種類のボーニングとアラームがPHP7.4に落ちました。 、したがって、同じことを行うことはお勧めしません)
次に、公式ドキュメントの例に基づいて、サービスアカウントキーファイルを指定することを忘れずに、Gmailを操作するための独自のクラスを作成します。
Gmailを操作するためのクラス
<?php
// Gmail
class GmailAPI
{
private $credentials_file = __DIR__ . '/../Gmail/credentials.json'; //
// ---------------------------------------------------------------------------------------------
/**
* Google_Service_Gmail Authorized Gmail API instance
*
* @param string $strEmail
* @return Google_Service_Gmail Authorized Gmail API instance
* @throws Exception
*/
function getService(string $strEmail){
//
try{
$client = new Google_Client();
$client->setAuthConfig($this->credentials_file);
$client->setApplicationName('My Super Project');
$client->setScopes(Google_Service_Gmail::MAIL_GOOGLE_COM);
$client->setSubject($strEmail);
$service = new Google_Service_Gmail($client);
}catch (Exception $e) {
throw new \Exception(' getService: '.$e->getMessage());
}
return $service;
}
// ---------------------------------------------------------------------------------------------
/**
* ID
*
* @param Google_Service_Gmail $service Authorized Gmail API instance.
* @param string $strEmail
* @param array $arrOptionalParams
* Gmail after: 2020/08/20 in:inbox label:
* q $opt_param
* @return array ID array('arrErrors' => $arrErrors),
* @throws Exception
*/
function listMessageIDs(Google_Service_Gmail $service, string $strEmail, array $arrOptionalParams = array()) {
$arrIDs = array(); // ID
$pageToken = NULL; //
$messages = array(); //
//
$opt_param = array();
// , Gmail q
if (count($arrOptionalParams)) $opt_param['q'] = str_replace('=', ':', http_build_query($arrOptionalParams, null, ' '));
// , ,
do {
try {
if ($pageToken) {
$opt_param['pageToken'] = $pageToken;
}
$messagesResponse = $service->users_messages->listUsersMessages($strEmail, $opt_param);
if ($messagesResponse->getMessages()) {
$messages = array_merge($messages, $messagesResponse->getMessages());
$pageToken = $messagesResponse->getNextPageToken();
}
} catch (Exception $e) {
throw new \Exception(' listMessageIDs: '.$e->getMessage());
}
} while ($pageToken);
// ID
if (count($messages)) {
foreach ($messages as $message) {
$arrIDs[] = $message->getId();
}
}
return $arrIDs;
}
// ---------------------------------------------------------------------------------------------
/**
* ID batchDelete
*
* @param Google_Service_Gmail $service Authorized Gmail API instance.
* @param string $strEmail
* @param array $arrIDs ID listMessageIDs
* @throws Exception
*/
function deleteMessages(Google_Service_Gmail $service, string $strEmail, array $arrIDs){
// 1000 , batchDelete
$arrParts = array_chunk($arrIDs, 999);
if (count($arrParts)){
foreach ($arrParts as $arrPartIDs){
try{
//
$objBatchDeleteMessages = new Google_Service_Gmail_BatchDeleteMessagesRequest();
//
$objBatchDeleteMessages->setIds($arrPartIDs);
//
$service->users_messages->batchDelete($strEmail,$objBatchDeleteMessages);
}catch (Exception $e) {
throw new \Exception(' deleteMessages: '.$e->getMessage());
}
}
}
}
// ---------------------------------------------------------------------------------------------
/**
* get
*
* @param Google_Service_Gmail $service Authorized Gmail API instance.
* @param string $strEmail
* @param string $strMessageID ID
* @param string $strFormat The format to return the message in.
* Acceptable values are:
* "full": Returns the full email message data with body content parsed in the payload field; the raw field is not used. (default)
* "metadata": Returns only email message ID, labels, and email headers.
* "minimal": Returns only email message ID and labels; does not return the email headers, body, or payload.
* "raw": Returns the full email message data with body content in the raw field as a base64url encoded string; the payload field is not used.
* @param array $arrMetadataHeaders When given and format is METADATA, only include headers specified.
* @return object Message
* @throws Exception
*/
function getMessage(Google_Service_Gmail $service, string $strEmail, string $strMessageID, string $strFormat = 'full', array $arrMetadataHeaders = array()){
$arrOptionalParams = array(
'format' => $strFormat // ,
);
// - metadata,
if (($strFormat == 'metadata') and count($arrMetadataHeaders))
$arrOptionalParams['metadataHeaders'] = implode(',',$arrMetadataHeaders);
try{
$objMessage = $service->users_messages->get($strEmail, $strMessageID,$arrOptionalParams);
return $objMessage;
}catch (Exception $e) {
throw new \Exception(' getMessage: '.$e->getMessage());
}
}
// ---------------------------------------------------------------------------------------------
/**
* ,
*
* @param Google_Service_Gmail $service Authorized Gmail API instance.
* @param string $strEmail
* @return object $objLabels - -
* @throws Exception
*/
function listLabels(Google_Service_Gmail $service, string $strEmail){
try{
$objLabels = $service->users_labels->listUsersLabels($strEmail);
return $objLabels;
}catch (Exception $e) {
throw new \Exception(' listLabels: '.$e->getMessage());
}
}
// ---------------------------------------------------------------------------------------------
/**
* ()
*
* @param Google_Service_Gmail $service Authorized Gmail API instance.
* @param string $strEmail
* @param string $strMessageID ID
* @param array $arrAddLabelIds ID ,
* @param array $arrRemoveLabelIds ID ,
* @return object Message -
* @throws Exception
*/
function modifyLabels(Google_Service_Gmail $service, string $strEmail, string $strMessageID, array $arrAddLabelIds = array(), array $arrRemoveLabelIds = array()){
try{
$objPostBody = new Google_Service_Gmail_ModifyMessageRequest();
$objPostBody->setAddLabelIds($arrAddLabelIds);
$objPostBody->setRemoveLabelIds($arrRemoveLabelIds);
$objMessage = $service->users_messages->modify($strEmail,$strMessageID,$objPostBody);
return $objMessage;
}catch (Exception $e) {
throw new \Exception(' modifyLabels: '.$e->getMessage());
}
}
// ---------------------------------------------------------------------------------------------
}
Gmailを操作するときはいつでも、最初に行うことは、GmailAPIクラスのgetService($ strEmail)関数を呼び出すことです。この関数は、$ strEmailメールボックスを操作するための「承認済み」オブジェクトを返します。さらに、このオブジェクトは、必要なアクションを直接実行するために、他の関数にすでに渡されています。GmailAPIクラスの他のすべての関数は、すでに特定のタスクを実行しています。
- listMessageIDs-指定された基準に従ってメッセージを検索し、そのIDを返します(listUsersMessages Gmail API関数に渡される検索文字列は、メールボックスWebインターフェイスの検索文字列と類似している必要があります)。
- deleteMessages-IDが渡されたメッセージを削除します(batchDelete API Gmail関数は1回のパスで1000個以下のメッセージを削除するため、関数に渡されたIDの配列をそれぞれ999文字の複数の配列に分割し、削除を数回実行する必要がありました)、
- getMessage-IDが渡されたメッセージに関するすべての情報を取得します。
- listLabels-メールボックス内のフラグのリストを返します(メールボックスWebインターフェイスで最初に作成され、目的のメッセージに割り当てられたフラグのIDを取得するために使用しました)
- modifyLabels-メッセージにフラグを追加または削除します
次に、さまざまなメールボックスの古い文字を削除するタスクがあります。同時に、メールボックスごとに数日前に受け取った古い手紙を考慮します。このタスクを実行するために、cronによって毎日実行される次のスクリプトを記述します。
古いメールを削除する
<?php
/**
* Gmail
*
*/
require __DIR__ .'/../general/config/config.php'; //
require __DIR__ .'/../vendor/autoload.php'; //
//
$arrMailBoxesForClean = array(
'a@domain.com' => 30,
'b@domain.com' => 30,
'c@domain.com' => 7,
'd@domain.com' => 7,
'e@domain.com' => 7,
'f@domain.com' => 1
);
$arrErrors = array(); //
$objGmailAPI = new GmailAPI(); // GMail
// ,
foreach ($arrMailBoxesForClean as $strEmail => $intDays) {
try{
//
$service = $objGmailAPI->getService($strEmail);
//
$arrParams = array('before' => date('Y/m/d', (time() - 60 * 60 * 24 * $intDays)));
// ,
$arrIDs = $objGmailAPI->listMessageIDs($service,$strEmail,$arrParams);
// ID $arrIDs
if (count($arrIDs)) $objGmailAPI->deleteMessages($service,$strEmail,$arrIDs);
//
unset($service,$arrIDs);
}catch (Exception $e) {
$arrErrors[] = $e->getMessage();
}
}
if (count($arrErrors)){
$strTo = 'my_email@domain.com';
$strSubj = ' ';
$strMessage = ' :'.
'<ul><li>'.implode('</li><li>',$arrErrors).'</li></ul>'.
'<br/>URL: '.filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL);
$objMailSender = new mailSender();
$objMailSender->sendMail($strTo,$strSubj,$strMessage);
}
スクリプトは、指定された各メールボックスに接続し、古い文字を選択して削除します。
自動レポートに基づいて未配信の電子メールに関するマネージャーのレポートを生成するタスクは、次のスクリプトによって解決されます。
メールのフィルタリングとマーキング
<?php
/*
* a@domain.com
* , : : mailer-daemon@googlemail.com
* . , b@domain.com
*
*/
require __DIR__ .'/../general/config/config.php'; //
require __DIR__ .'/../vendor/autoload.php'; //
$strEmail = 'a@domain.com';
$strLabelID = 'Label_2399611988534712153'; // reportProcessed -
//
$arrParams = array(
'from' => 'mailer-daemon@googlemail.com', //
'in' => 'inbox', //
'after' => date('Y/m/d', (time() - 60 * 60 * 24)), //
'has' => 'nouserlabels' //
);
$arrErrors = array(); //
$objGmailAPI = new GmailAPI(); // GMail
$arrClientEmails = array(); // ,
try{
//
$service = $objGmailAPI->getService($strEmail);
// ,
$arrIDs = $objGmailAPI->listMessageIDs($service,$strEmail, $arrParams);
// 'X-Failed-Recipients', ,
if (count($arrIDs)){
foreach ($arrIDs as $strMessageID){
//
$objMessage = $objGmailAPI->getMessage($service,$strEmail,$strMessageID,'metadata',array('X-Failed-Recipients'));
//
$arrHeaders = $objMessage->getPayload()->getHeaders();
//
foreach ($arrHeaders as $objMessagePartHeader){
if ($objMessagePartHeader->getName() == 'X-Failed-Recipients'){
$strClientEmail = mb_strtolower(trim($objMessagePartHeader->getValue()), 'UTF-8');
if (!empty($strClientEmail)) {
if (!in_array($strClientEmail, $arrClientEmails)) $arrClientEmails[] = $strClientEmail;
}
// reportProcessed,
$objGmailAPI->modifyLabels($service,$strEmail,$strMessageID,array($strLabelID));
}
}
}
}
unset($service,$arrIDs,$strMessageID);
}catch (Exception $e) {
$arrErrors[] = $e->getMessage();
}
// , ,
if (count($arrClientEmails)) {
$objClients = new clients();
// email
$arrAllClientsEmails = $objClients->getAllEmails();
foreach ($arrClientEmails as $strClientEmail){
$arrUsages = array();
foreach ($arrAllClientsEmails as $arrRow){
if (strpos($arrRow['email'], $strClientEmail) !== false) {
$arrUsages[] = ' email "<a href="'.MANAGEURL.'?m=admin&sm=clients&edit='.$arrRow['s_users_id'].'">'.$arrRow['name'].'</a>"';
}
if (strpos($arrRow['email2'], $strClientEmail) !== false) {
$arrUsages[] = ' email "<a href="'.MANAGEURL.'?m=admin&sm=clients&edit='.$arrRow['s_users_id'].'">'.$arrRow['name'].'</a>"';
}
if (strpos($arrRow['site_user_settings_contact_email'], $strClientEmail) !== false) {
$arrUsages[] = ' email "<a href="'.MANAGEURL.'?m=admin&sm=clients&edit='.$arrRow['s_users_id'].'">'.$arrRow['name'].'</a>"';
}
}
$intUsagesCnt = count($arrUsages);
if ($intUsagesCnt > 0){
$strMessage = ' <span style="color: #000099;">'.$strClientEmail.'</span><br/>
';
if ($intUsagesCnt == 1){
$strMessage .= ' '.$arrUsages[0].'<br/>';
}else{
$strMessage .= ':<ul>';
foreach ($arrUsages as $strUsage){
$strMessage .= '<li>'.$strUsage.'</li>';
}
$strMessage .= '</ul>';
}
$strMessage .= '<br/>, .<br/><br/>
, ';
if (empty($objMailSender)) $objMailSender = new mailSender();
$objMailSender->sendMail('b@domain.com',' email ',$strMessage);
}
}
}
if (count($arrErrors)){
$strTo = 'my_email@domain.com';
$strSubj = ' ';
$strMessage = ' :'.
'<ul><li>'.implode('</li><li>',$arrErrors).'</li></ul>'.
'<br/>URL: '.filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL);
if (empty($objMailSender)) $objMailSender = new mailSender();
$objMailSender->sendMail($strTo,$strSubj,$strMessage);
}
このスクリプトは、最初のスクリプトと同様に、指定されたメールボックスに接続し、フラグなしで必要な文字を選択し(未配信のメッセージを報告します)、文字の送信を試みた電子メールアドレスを文字内で見つけ、この文字に「処理済み」フラグを付けます。 ..。次に、見つかった電子メールアドレスを使用して操作が実行され、その結果、担当の従業員に人間が読み取れる手紙が作成されます。
ソースはGitHubで入手できます。
この記事で伝えたかったのはそれだけです。読んでくれてありがとう!私のコードがあなたの目に刺さった場合は、スポイラーを巻き上げるか、コメントを書いてください-建設的な批判をうれしく思います。