【Pleasanter】Outlookの.msgファイルをPowerShellで自動登録する

Outlookで保存した.msgを特定フォルダへ投入し、PowerShellで件名・本文を読み取ってプリザンターの記録テーブルへ登録します。Redmine向けの記事とは独立したプリザンターAPI版です。

前提

Windows 11、Windows PowerShell 5.1、Classic Outlook(COM対応)、プリザンターのAPIキー、作成権限のある記録テーブルを使用します。New OutlookではOutlook COMを利用できません。以下は検証用実装例であり、運用環境での登録動作は未確認です。

登録先の項目

プリザンター項目 用途
Title メール件名
DescriptionA 送信者・本文
ClassA 種別(障害・問い合わせ)

対象テーブルで説明Aと分類Aを有効化してください。

APIの登録形式

プリザンター公式のレコード作成APIは POST /api/items/{サイトID}/create です。

{
  "ApiVersion": 1.1,
  "ApiKey": "YOUR_API_KEY",
  "Title": "【障害】ログインできない",
  "ClassHash": {"ClassA": "障害"},
  "DescriptionHash": {"DescriptionA": "メール本文"}
}

フォルダ構成

C:\MsgPleasanter\
  config.json
  import.ps1
  inbox\
  done\

config.json

{
  "BaseUrl": "https://pleasanter.example.com",
  "SiteId": 12345,
  "Inbox": "C:\\MsgPleasanter\\inbox",
  "Done": "C:\\MsgPleasanter\\done"
}

APIキーはファイルに平文保存せず、Windowsのユーザー環境変数 PLEASANTER_API_KEY に登録します。

[Environment]::SetEnvironmentVariable('PLEASANTER_API_KEY', 'YOUR_API_KEY', 'User')

新しいPowerShellを起動してから実行してください。

import.ps1(全文)

$ErrorActionPreference = 'Stop'
$config = Get-Content "$PSScriptRoot\config.json" -Raw -Encoding UTF8 | ConvertFrom-Json
$key = [Environment]::GetEnvironmentVariable('PLEASANTER_API_KEY', 'User')
if (!$key) { throw 'APIキーが設定されていません。' }
if (!$config.BaseUrl.StartsWith('https://')) { throw 'HTTPSのURLを設定してください。' }
New-Item -ItemType Directory -Force -Path $config.Inbox, $config.Done | Out-Null

while ($true) {
  Get-ChildItem -LiteralPath $config.Inbox -Filter '*.msg' -File | ForEach-Object {
    $path = $_.FullName
    $app = $null
    $mail = $null
    try {
      # コピー途中のファイルは次回処理
      $size = $_.Length
      Start-Sleep -Milliseconds 500
      if ((Get-Item -LiteralPath $path).Length -ne $size) { return }
      $app = New-Object -ComObject Outlook.Application
      $mail = $app.Session.OpenSharedItem($path)
      $title = [string]$mail.Subject
      $kind = if ($title -match '【障害】') { '障害' } else { '問い合わせ' }
      $desc = "差出人: $($mail.SenderEmailAddress)`n`n$($mail.Body)"
      $payload = @{
        ApiVersion = 1.1
        ApiKey = $key
        Title = $title
        ClassHash = @{ ClassA = $kind }
        DescriptionHash = @{ DescriptionA = $desc }
      } | ConvertTo-Json -Depth 10
      $url = "$($config.BaseUrl.TrimEnd('/'))/api/items/$($config.SiteId)/create"
      $response = Invoke-RestMethod -Uri $url -Method Post -ContentType 'application/json; charset=utf-8' -Body ([Text.Encoding]::UTF8.GetBytes($payload))
      if ([int]$response.StatusCode -ne 200) { throw "APIエラー: $($response.Message)" }
      $name = [guid]::NewGuid().ToString('N') + '_' + $_.Name
      Move-Item -LiteralPath $path -Destination (Join-Path $config.Done $name)
      Write-Host "登録成功 ID=$($response.Id)"
    }
    catch { Write-Warning "$path : $($_.Exception.Message)" }
    finally {
      if ($mail) { [void][Runtime.InteropServices.Marshal]::ReleaseComObject($mail) }
      if ($app) { [void][Runtime.InteropServices.Marshal]::ReleaseComObject($app) }
    }
  }
  Start-Sleep -Seconds 3
}

PowerShellで powershell.exe -NoProfile -File C:\MsgPleasanter\import.ps1 を実行します。約3秒ごとにフォルダを調べ、成功したファイルだけdoneへ移動します。タスクスケジューラで「ログオン時」に起動することもできます。Outlook COMのため、対話ユーザーでの実行を推奨します。

運用時の注意点

この最小実装では、API登録成功後にファイルの移動が失敗した場合、再試行で重複登録する可能性があります。本番運用時はMessage-IDなどの重複確認用項目と処理ログを追加してください。メール本文には個人情報が含まれ得るため、必要なアクセス制御を行います。

参考資料

Previous Post Next Post