(同じ利用者による、間の2版が非表示)
198行目: 198行目:
<br>
<br>
  <syntaxhighlight lang="php">
  <syntaxhighlight lang="php">
  $mailbox = new PhpImap\Mailbox(
  <?php
    '{imap.example.com:993/imap/ssl}INBOX',
// Composerで使用されるPHPのパッケージ管理システムに関連する重要な記述
    '<ユーザ名>',
// 必要なクラスファイルを自動的にrequire/includeする
    '<パスワード>'
require 'vendor/autoload.php';
);
   
   
  $emails = $mailbox->searchMailbox('ALL');
  use PhpImap\Mailbox;
use PhpImap\Exceptions\ConnectionException;
use PhpImap\Exceptions\InvalidParameterException;
/*
  * メール処理を行うクラス
  */
class MailProcessor
{
    private $mailbox;
    private $server;
    private $username;
    private $password;
    /**
    * コンストラクタ
    *
    * @param string $server IMAPサーバーアドレス (例: imap.example.com)
    * @param string $username ユーザー名
    * @param string $password パスワード
    */
    public function __construct(string $server, string $username, string $password)
    {
      $this->server = $server;
      $this->username = $username;
      $this->password = $password;
    }
    /**
    * メールボックスへの接続を確立
    *
    * @throws ConnectionException 接続エラー時
    * @return bool 接続成功時にtrue
    */
    public function connect(): bool
    {
      try {
          // IMAPサーバへの接続文字列を構築
          $imapPath = sprintf('{%s:993/imap/ssl}INBOX', $this->server);
          // メールボックスオブジェクトを初期化
          $this->mailbox = new Mailbox($imapPath, $this->username, $this->password,
                                      __DIR__ . '/attachments', // 添付ファイル保存ディレクトリ
                                      'UTF-8'                  // 文字エンコーディング
          );
          // 接続
          $this->mailbox->checkMailbox();
          return true;
      }
      catch (ConnectionException $e) {
          throw new ConnectionException('メールサーバーへの接続に失敗しました: ' . $e->getMessage());
      }
    }
    /**
    * メールを検索して取得
    *
    * @param string $criteria 検索条件 (例: 'ALL', 'UNSEEN', 'FROM "someone@example.com"')
    * @return array 検索結果のメール情報配列
    */
    public function searchMails(string $criteria = 'ALL'): array
    {
      try {
          // メールを検索
          $mailsIds = $this->mailbox->searchMailbox($criteria);
          $results = [];
          foreach ($mailsIds as $mailId) {
            try {
                $email = $this->mailbox->getMail($mailId);
                $results[] = [
                        'id' => $mailId,
                        'subject' => $email->subject,
                        'from' => $email->fromAddress,
                        'date' => $email->date,
                        'body' => $email->textPlain,
                        'hasAttachments' => $email->hasAttachments()
                ];
            }
            catch (\Exception $e) {
                // 個別のメール取得エラーをログに記録し、処理を継続
                error_log("メールID {$mailId} の取得に失敗: " . $e->getMessage());
                continue;
            }
          }
          return $results;
      }
      catch (InvalidParameterException $e) {
          throw new InvalidParameterException('無効な検索条件が指定されました: ' . $e->getMessage());
      }
    }
    /**
    * メールボックスの接続を終了
    */
    public function disconnect(): void
    {
      if ($this->mailbox) $this->mailbox->disconnect();
    }
}
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== APIベースのソリューション ====
<syntaxhighlight lang="php">
===== Google Gmail API =====
// 使用例
try {
    // メールプロセッサのインスタンスを生成
    $processor = new MailProcessor(
        'imap.example.com',
        '<ユーザー名>',
        '<パスワード>'
    );
    // 接続
    $processor->connect();
    // 未読メールを検索
    $unreadMails = $processor->searchMails('UNSEEN');
    // 結果を処理
    foreach ($unreadMails as $mail) {
      echo "Subject: " . $mail['subject'] . "\n";
      echo "From: " . $mail['from'] . "\n";
      echo "Date: " . $mail['date'] . "\n";
    }
}
catch (ConnectionException $e) {
    // 接続エラーの処理
    error_log("接続エラー: " . $e->getMessage());
    exit(1);
}
catch (InvalidParameterException $e) {
    // パラメータエラーの処理
    error_log("パラメータエラー: " . $e->getMessage());
    exit(1);
}
catch (\Exception $e) {
    // その他の予期せぬエラーの処理
    error_log("予期せぬエラー: " . $e->getMessage());
    exit(1);
}
finally {
    // 確実に接続を終了
    if (isset($processor)) {
        $processor->disconnect();
    }
}
</syntaxhighlight>
<br>
 
==== 推奨されるアプローチ ====
新規システムを設計する場合は、以下に示す順序で検討することが推奨される。<br>
# クラウドメールサービスのAPIを使用
#* Gmail API
#* Microsoft Graph API
#* その他のモダンなメールサービスAPI
#: <br>
# メールサービスプロバイダのAPIが使用できない場合
#* SMTP/IMAPの代わりにRESTful APIを提供する中間サービス
#*: 例: Mailgun、SendGrid、Amazon SES等
#: <br>
# IMAPを使わざるを得ない場合
#* php-imap/php-imapを使用
#*: より現代的なライブラリとして保守されているため
<br>
上記の理由から、可能であれば、よりモダンなAPIベースのソリューションを検討することが推奨される。<br>
<br><br>
 
== APIベースのソリューション ==
==== Google Gmail API ====
Composerで必要なライブラリをインストールする。<br>
Composerで必要なライブラリをインストールする。<br>
  composer require google/apiclient
  composer require google/apiclient
<br>
<br>
  <syntaxhighlight lang="php">
  <syntaxhighlight lang="php">
// クライアントの初期化
// クライアントの初期化
  $client = new Google_Client();
  $client = new Google_Client();
  $client->setApplicationName('Your Application Name');
  $client->setApplicationName('Your Application Name');
277行目: 442行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
===== Microsoft Graph API =====
* 検索条件を指定してメッセージを取得する場合
<syntaxhighlight lang="php">
$optParams = [
    'q' => 'from:example@gmail.com',  // 検索クエリ
    'maxResults' => 5
];
// 昨日以降のメール
$optParams = ['q' => 'after:' . date('Y/m/d', strtotime('-1 day'))];
// 未読メール
$optParams = ['q' => 'is:unread'];
// 特定の件名のメール
$optParams = ['q' => 'subject:"Meeting Invitation"'];
// 添付ファイルがあるメール
$optParams = ['q' => 'has:attachment'];
</syntaxhighlight>
<br>
* メッセージの詳細情報の取得例
<syntaxhighlight lang="php">
function getEmailContent($gmail, $messageId)
{
    $message = $gmail->users_messages->get('me', $messageId, ['format' => 'full']);
    $payload = $message->getPayload();
    // メール本文の取得
    $body = '';
    if ($payload->getBody()->getData()) {
      $body = base64url_decode($payload->getBody()->getData());
    }
    else {
      // マルチパートの場合
      $parts = $payload->getParts();
      foreach ($parts as $part) {
          if ($part->getMimeType() === 'text/plain') {
            $body = base64url_decode($part->getBody()->getData());
            break;
          }
      }
    }
    return [
      'id' => $messageId,
      'threadId' => $message->getThreadId(),
      'labelIds' => $message->getLabelIds(),
      'body' => $body,
      // その他必要な情報
    ];
}
// base64url_decode関数の定義
function base64url_decode($data)
{
    return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
</syntaxhighlight>
<br>
<u>※注意</u><br>
<u>メールを取得する場合には、以下に示す事柄に注意すること。</u><br>
* レート制限に注意する。
* 必要な権限(スコープ)が設定されていることを確認する。
* 大量のメールを処理する場合はページネーションを使用する。
<br>
 
==== Microsoft Graph API ====
Composerで必要なライブラリをインストールする。<br>
Composerで必要なライブラリをインストールする。<br>
  composer require microsoft/microsoft-graph
  composer require microsoft/microsoft-graph
329行目: 560行目:
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
<br>
==== 推奨されるアプローチ ====
新規システムを設計する場合は、以下に示す順序で検討することが推奨される。<br>
# クラウドメールサービスのAPIを使用
#* Gmail API
#* Microsoft Graph API
#* その他のモダンなメールサービスAPI
#: <br>
# メールサービスプロバイダのAPIが使用できない場合
#* SMTP/IMAPの代わりにRESTful APIを提供する中間サービス
#*: 例: Mailgun、SendGrid、Amazon SES等
#: <br>
# IMAPを使わざるを得ない場合
#* php-imap/php-imapを使用
#*: より現代的なライブラリとして保守されているため
<br>
上記の理由から、可能であれば、よりモダンなAPIベースのソリューションを検討することが推奨される。<br>
<br><br>
<br><br>