1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Node.js × PowerShell で Outlook を操作する

Posted at

はじめに

Outlook でメールを自動送信したり、指定のメールを検索したい。

JavaScript の世界では直接 Outlook を操作するライブラリは限られており、実務では Windows 環境の Outlook アプリを直接操作する方法が正確で確実です。

そこで、PowerShell から COM オブジェクトを使って Outlook を操作するスクリプトを Node.js から呼び出す方法を紹介します。

Powershellラッパークラス実装の基本編は下記をご参照ください:

Outlook のバージョンを取得する

Powershell.ts
public async getVersion(): Promise<string> {
  const script = `
  try {
    $outlook = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Outlook.Application")
  } catch {
    $outlook = New-Object -ComObject Outlook.Application
  }

  try {
    $version = $outlook.Version
    Write-Output $version
  } catch {
    Write-Error "Error: $($_.Exception.Message)"
    exit 1
  }
  `;

  const result = await this.executePowerShell(script);
  return result.stdout.trim();
}
  • 実行環境に Outlook が存在すればバージョン情報を取得
  • Write-Output の結果は stdout として取得

Outlook でメールを送信する

Powershell.ts
public async sendEmail(
  subject: string,
  body: string,
  to: string,
  cc?: string
): Promise<void> {
  let script = `
  try {
    $outlook = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Outlook.Application")
  } catch {
    $outlook = New-Object -ComObject Outlook.Application
  }

  try {
    $mail = $outlook.CreateItem(0)
    $recipient = $mail.Recipients.Add("${to}")
    $recipient.Resolve() | Out-Null

    if ($recipient.Resolved -eq $false) {
      throw "Recipient '${to}' could not be resolved."
    }

    $mail.Subject = "${subject}"
    $mail.Body = "${body}"
    $mail.To = $recipient.Name
  `;

  if (cc) {
    script += `
    $ccRecipient = $mail.Recipients.Add("${cc}")
    $ccRecipient.Resolve() | Out-Null

    if ($ccRecipient.Resolved -eq $false) {
      throw "CC Recipient '${cc}' could not be resolved."
    }
    $mail.CC = $ccRecipient.Name
    `;
  }

  script += `
    $mail.Send()
  } catch {
    Write-Error "Error: $($_.Exception.Message)"
    exit 1
  }
  `;

  const result = await this.executePowerShell(script);
  if (result.exitCode !== 0) {
    throw new Error(`Failed to send email: ${result.stderr}`);
  }
}
  • Recipients.Add()Resolve() の扱いに注意
  • CC は実行時に有効なら追加

指定メールを検索する

Powershell.ts
public async searchForEmail(
  targetSubject: string,
  searchTimeWindowMinutes: number
): Promise<object | null> {
  const script = `
  try {
    $outlook = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Outlook.Application")
  } catch {
    $outlook = New-Object -ComObject Outlook.Application
  }

  try {
    $namespace = $outlook.GetNamespace("MAPI")
    $inbox = $namespace.GetDefaultFolder(6)
    $startTime = (Get-Date).AddMinutes(-${searchTimeWindowMinutes})

    $emails = $inbox.Items | Where-Object {
      $_.Class -eq 43 -and
      $_.Subject -eq "${targetSubject}" -and
      $_.ReceivedTime -gt $startTime
    }

    if ($emails) {
      foreach ($email in $emails) {
        Write-Output "Found email with subject '${targetSubject}'"
        Write-Output $email.SenderName
        Write-Output $email.SenderEmailAddress
        Write-Output $email.Body
      }
    } else {
      Write-Output "No email found with subject '${targetSubject}' within last ${searchTimeWindowMinutes} minutes."
    }
  } catch {
    Write-Error "Error: $($_.Exception.Message)"
    exit 1
  }
  `;

  const result = await this.executePowerShell(script);
  const lines = result.stdout.trim().split("\n");

  if (lines[0]?.includes("Found email")) {
    return {
      senderName: lines[1],
      senderEmailAddress: lines[2],
      body: lines[3],
    };
  }

  return null;
}
  • Subject でフィルター
  • ReceivedTime を使って時間範囲で検索

まとめ

  • Node.js から Outlook を操作するには PowerShell の COM 操作が最も確実
  • 送信や検索は UI なしでバックグラウンドで完結できる
  • Write-Output は stdout に、Write-Error は stderr に出力される点に注意

Excel 編と同様に、実務でよく使う Outlook の自動操作をスクリプト化しておくと、操作ミスやヒューマーエラーを防げます。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?