Qiitaで投稿した記事をプリザンターに登録してみた！

# Qiitaで投稿した記事をプリザンターに登録してみた！

## はじめに

アドベントカレンダーということでQiitaとPleasanterを連携？させたバッチ処理の記事を投稿いたします。  
以前投稿した記事のリメイクとなりますが、ご容赦ください・・・  
本記事は[以前の記事](https://qiita.com/teppei12345/items/5a12e70c028d610e0741)の続きとなります。以前はPowerShellを使って「手動」でQiitaで投稿した記事をプリザンターのテーブル上に作成するスクリプトを実行しました。本記事では、「自動」で「定期的」にQiitaで投稿した記事をプリザンターのテーブル上に作成するスクリプトを実行します。  

## 前段

まず、PowerShellで作成したスクリプトを自動定期実行させると聞いたら大体の人は「タスクスケジューラ」を思い浮かべると思います。今回の記事では「タスクスケジューラ」を使ってPowerShellで作成したスクリプトを自動定期実行させる方法を記載します。個人的にはとても感動した内容でした。一人の力で調査し実現したものなのでとくに感動しています。  

## 処理の流れ

前回の記事でご紹介した処理の流れに「メール送信API」を使った処理も追加しました。  

```TEXT
1. 変数定義
2. ログファイルを作成する処理
→こちらの処理でログファイルを「$createLogDirectoryPath」で指定したディレクトリ配下に「yyyyMMddHHmmss(年月日時分秒)」形式で作成します。
3. 過去のログファイルを削除する処理
→こちらの処理で「$deletLogFilePeriod」で指定した日よりも前のログファイルを削除します。
4. レコードを全て削除する処理
→こちらの処理で「$apiKey」「$baseUri」「$recordId」を使い、特定テーブルの全レコードを削除します。
5. Qiitaの記事を取得する処理
→こちらの処理で「Qiita APIから記事を取得する処理」から記事の情報を取得し、「レコードを新規作成する処理」で特定テーブルにレコード単位(1レコード=1記事)で情報を登録します。
6. 処理が完了したことをメール通知する処理
→こちらの処理で処理が完了したことと確認する旨通知されます。
```

## スクリプト

今回のスクリプトはタスクスケジューラやコマンドで実行した際に、前回記事のスクリプトでは実行できなかったため、構造を変えました。前回の記事では、それぞれの処理がメソッドとなっていましたが、今回は直に処理を記載しています。  

```PowerShell
<#
変数定義箇所
ユーザは変更する必要がある
#>

<#
Qiitaの記事操作に関する変数定義
#>
# Qiita APIのエンドポイントURLの指定
$qiitaApiUrl = "https://qiita.com/api/v2/items"
# アクセストークン
$accessToken = "XXXX"
# 取得したいユーザー名を指定
$userName = "XXXX"
# 取得したい件数を指定
$maxPage = 100

<#
API処理に関する変数定義
#>
# APIキー
$apiKey = 'XXXX'
# 一括処理URLとレコード作成URLのドメインまでの指定(スキーマ+ドメイン「http://localhost」のように指定)
$baseUri = 'https://pleasanter.net'
# Qiita記事を登録するサイトのサイトIDを指定
$qiitaSiteId = 'XXXX'
# メール送信APIを実行する際のダミーレコードIDを指定
$sendMailRecordId = 'XXXX'
# APIバージョンを指定
$apiVersion = 1.1
# 宛先メールアドレスを指定
$toMailAddress = 'XXX@XX.X'
# 通知メールの件名を指定
$mailTitle = 'XXXX'
# 通知メールの本文を指定
$mailBody = "XXXX"
# ContentTypeを指定
$contentType = 'application/json'

<#
ログファイルの操作に関する変数定義
#>
# ログファイルを削除する期間を定義(日にち単位)
# 例) 18日 17:00に実行し、かつ「4」を指定した場合、14日の16:59以前のファイルが削除されます。
$deletLogFilePeriod = 31
# ログファイルの格納ディレクトリのPathを定義
$createLogDirectoryPath = 'XXXX'
# 現在日時を取得
$nowDate = Get-Date -Format "yyyyMMddHHmmss"
# ログファイルの格納場所を定義
$createLogFilePath = $createLogDirectoryPath + '\' + $nowDate + '.log'


<#
プログラム箇所
ユーザは操作する必要なし
#>


# 指定のフォルダが存在する場合の処理
if (Test-Path $createLogDirectoryPath) {
    # 同名のログファイルが存在しない場合の処理
    if ( - !(Test-Path $createLogFilePath)) {
        # 空のログファイルを新規作成
        Out-File $createLogFilePath
        # ログファイルが作成されたことをログファイルに出力
        $comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【INFO】ログファイルが作成されました。作成ファイル：' + $createLogFilePath
        Add-Content -Path $createLogFilePath -Value $comment
        # スクリプトを実行する事をログファイルに出力
        $comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【DEBUG】スクリプトの実行開始'
        Add-Content -Path $createLogFilePath -Value $comment
    }
    # 同名のログファイルが存在する場合の処理
    else {
        # ログファイルに追記する場合のログ開始位置がわかるようにログファイルに出力
        $comment = '------------------------------------'
        Add-Content -Path $createLogFilePath -Value $comment
        # スクリプトを実行する事をログファイルに出力
        $comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【DEBUG】スクリプトの実行開始'
        Add-Content -Path $createLogFilePath -Value $comment
    }
}
# 指定のフォルダが存在しない場合の処理
else {
    # 指定のフォルダが存在しない旨、コンソールに出力
    $comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 指定のフォルダが存在しません。指定のフォルダ：' + $createLogDirectoryPath
    write-host $comment
    # 処理を中断する
    exit
}


# 「過去のログファイルを削除する処理」が開始したことをログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【DEBUG】「過去のログファイルを削除する処理」の開始'
Add-Content -Path $createLogFilePath -Value $comment
# 削除対象のログファイルをログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【INFO】削除対象ファイル：今日から' + $deletLogFilePeriod + '日以前のファイル'
Add-Content -Path $createLogFilePath -Value $comment
# 過去のログファイルを削除
Get-ChildItem $createLogDirectoryPath -Recurse | Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-$deletLogFilePeriod) } | Remove-Item -Force
# 過去のログファイルの削除処理を終了した旨ログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【DEBUG】ファイルの削除処理終了'
Add-Content -Path $createLogFilePath -Value $comment


# 「レコードを全て削除する処理」が開始したことをログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【DEBUG】「レコードを全て削除する処理」の開始'
Add-Content -Path $createLogFilePath -Value $comment
# リクエスト情報を設定
$deleteRecordJsonData = @{
    'ApiVersion' = $apiVersion
    'ApiKey'     = $apiKey
    'All'        = 'TRUE'
}
# JSON形式に変換
$deleteRecordConvertBody = $deleteRecordJsonData | ConvertTo-Json
# 一括処理URLの指定
$deleteRecordPath = $baseUri + '/fs/api/items/' + $qiitaSiteId + '/bulkdelete'
# 一括処理URLをログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【INFO】一括処理URL：' + $deleteRecordPath
Add-Content -Path $createLogFilePath -Value $comment
# Webページからのレスポンスを取得
$deleteRecordResponseData = Invoke-RestMethod -Uri $deleteRecordPath -ContentType $contentType -Method POST -Body $deleteRecordConvertBody
# Webページからのレスポンスをログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【INFO】レスポンス内容：' + $deleteRecordResponseData
Add-Content -Path $createLogFilePath -Value $comment


# 「Qiitaの記事を取得する処理」が開始したことをログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【DEBUG】「Qiitaの記事を取得する処理」の開始'
Add-Content -Path $createLogFilePath -Value $comment
# 全件のQiita記事を取得して表示
$page = 1
# Qiitaの記事内容を取得する反復処理が開始したことをログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【DEBUG】Qiitaの記事内容を取得する反復処理が開始しました。'
Add-Content -Path $createLogFilePath -Value $comment
# Qiitaの記事内容(Webページからのレスポンス)を設定
# Queryを発行する
$query = '?per_page=' + $maxPage + '&page=' + $page + '&query=user:' + $userName
# Queryをログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【INFO】Query：' + $query
Add-Content -Path $createLogFilePath -Value $comment
# URLを設定する
$url = $qiitaApiUrl + $query
# URLをログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【INFO】URL：' + $url
Add-Content -Path $createLogFilePath -Value $comment
# Qiita APIへのリクエスト用ヘッダーを作成
$headers = @{
    'Authorization' = 'Bearer ' + $accessToken
}
# Webページからのレスポンスを取得
$response = Invoke-RestMethod -Uri $url -Headers $headers -Method Get

# Qiitaの記事情報が存在した場合の処理
if ($response) {
    # Qiitaの記事情報を読み込む反復処理が開始したことをログファイルに出力
    $comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【DEBUG】Qiitaの記事情報を読み込む反復処理が開始しました。'
    Add-Content -Path $createLogFilePath -Value $comment
    # カウンタを指定
    $count = 1
    # Qiitaの記事情報を1件ずつ読み込む
    foreach ($article in $response) {
        # 「タイトル」を設定
        $title = $article.title
        # 「内容」を設定(マークダウン形式になるように設定)
        $body = '[md]' + $article.body
        # 「分類B」を設定
        $classB = $article.url
        # 区切りをログファイルに出力
        $comment = '-----------------------------------------------------------------------------'
        Add-Content -Path $createLogFilePath -Value $comment
        # 「レコードを新規作成する処理」が開始したことをログファイルに出力
        $comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【DEBUG】' + $count + '件目の「レコードを新規作成する処理」の開始'
        Add-Content -Path $createLogFilePath -Value $comment
        # リクエスト情報を設定
        $createRecordJsonData = @{
            "ApiVersion" = $apiVersion
            "ApiKey"     = $apiKey
            "Title"      = $title
            "Body"       = $body
            "ClassHash"  = @{
                "ClassB" = $classB
            }
        }
        # JSON形式に変換
        $createRecordConvertBody = $createRecordJsonData | ConvertTo-Json
        # プリザンターで表示時に文字化けしないようにUTF-8にエンコーディング
        $createRecordEncodedConvertBody = [System.Text.Encoding]::UTF8.GetBytes($createRecordConvertBody)
        # レコード作成URLの指定
        $createRecordPath = $baseUri + '/fs/api/items/' + $qiitaSiteId + '/create'
        # レコード作成URLをログファイルに出力
        $comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【INFO】レコード作成URL：' + $createRecordPath
        Add-Content -Path $createLogFilePath -Value $comment
        # Webページからのレスポンスを取得
        $createRecordResponseData = Invoke-RestMethod -Uri $createRecordPath -ContentType $contentType -Method POST -Body $createRecordEncodedConvertBody
        # レコード作成APIのレスポンスをログファイルに出力
        $comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【INFO】レスポンス内容' + $createRecordResponseData
        Add-Content -Path $createLogFilePath -Value $comment

        # カウンタをインクリメント
        $count++
    }
    # 区切りをログファイルに出力
    $comment = '-----------------------------------------------------------------------------'
    Add-Content -Path $createLogFilePath -Value $comment
    # Qiitaの記事情報を読み込む反復処理が終了したことをログファイルに出力
    $comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【DEBUG】Qiitaの記事情報を読み込む反復処理が終了しました。'
    Add-Content -Path $createLogFilePath -Value $comment
}

# 処理が完了したことをメール通知するとログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【DEBUG】メール通知処理が開始しました。'
Add-Content -Path $createLogFilePath -Value $comment
$sendMailJsonData = @{
        "ApiVersion" = $apiVersion
        "ApiKey" = $apiKey
        "To" = $toMailAddress
        "Title" = $mailTitle
        "Body" = $mailBody
}
# JSON形式に変換
$sendMailConvertBody = $sendMailJsonData | ConvertTo-Json
# メールの本文で文字化けしないようにUTF-8にエンコーディング
$sendMailEncodedConvertBody = [System.Text.Encoding]::UTF8.GetBytes($sendMailConvertBody)
# レコード作成URLの指定
$sendMailPath = $baseUri + '/fs/api/items/' + $sendMailRecordId + '/OutgoingMails/Send'
# メール通知URLをログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【INFO】メール通知URL：' + $sendMailPath
Add-Content -Path $createLogFilePath -Value $comment
# Webページからのレスポンスを取得
$sendMailResponseData = Invoke-RestMethod -Uri $sendMailPath -ContentType $contentType -Method POST -Body $sendMailEncodedConvertBody
# レコード作成APIのレスポンスをログファイルに出力
$comment = '[' + $(Get-Date -Uformat %Y%m%d_%H:%M:%S) + '] 【INFO】レスポンス内容' + $sendMailResponseData
Add-Content -Path $createLogFilePath -Value $comment
```

## ログファイルの内容

```TEXT
[20230802_15:36:27] 【INFO】ログファイルが作成されました。作成ファイル：C:\XXXX\yyyyMMddHHmmss.log
[20230802_15:36:27] 【DEBUG】スクリプトの実行開始
[20230802_15:36:27] 【DEBUG】「過去のログファイルを削除する処理」の開始
[20230802_15:36:27] 【INFO】削除対象ファイル：今日から31日以前のファイル
[20230802_15:36:27] 【DEBUG】ファイルの削除処理終了
[20230802_15:36:27] 【DEBUG】「レコードを全て削除する処理」の開始
[20230802_15:36:27] 【INFO】一括処理URL：https://pleasanter.net/fs/api/items/XXXX/bulkdelete
[20230802_15:36:28] 【INFO】レスポンス内容：@{Id=X; StatusCode=200; LimitPerDate=1000000; LimitRemaining=X; Message=Qiita記事: 50 件 一括削除しました。}
[20230802_15:36:28] 【DEBUG】「Qiitaの記事を取得する処理」の開始
[20230802_15:36:28] 【DEBUG】Qiitaの記事内容を取得する反復処理が開始しました。
[20230802_15:36:28] 【INFO】Query：?per_page=100&page=1&query=user:XXXX
[20230802_15:36:28] 【INFO】URL：https://qiita.com/api/v2/items?per_page=100&page=1&query=user:XXXX
[20230802_15:36:29] 【DEBUG】Qiitaの記事情報を読み込む反復処理が開始しました。
-----------------------------------------------------------------------------
[20230802_15:36:29] 【DEBUG】1件目の「レコードを新規作成する処理」の開始
[20230802_15:36:29] 【INFO】レコード作成URL：https://pleasanter.net/fs/api/items/XXXX/create
[20230802_15:36:29] 【INFO】レスポンス内容@{Id=XXXX; StatusCode=200; LimitPerDate=1000000; LimitRemaining=XXXX; Message=" Qiitaで投稿した記事をプリザンターのテーブル上に作成する " を作成しました。}
-----------------------------------------------------------------------------
[20230802_15:36:29] 【DEBUG】2件目の「レコードを新規作成する処理」の開始
[20230802_15:36:29] 【INFO】レコード作成URL：https://pleasanter.net/fs/api/items/XXXX/create
[20230802_15:36:29] 【INFO】レスポンス内容@{Id=XXXX; StatusCode=200; LimitPerDate=1000000; LimitRemaining=XXXX; Message=" プリザンターのパフォーマンスが悪いと思った時の調査方法 " を作成しました。}
-----------------------------------------------------------------------------
・
・
・
-----------------------------------------------------------------------------
[20230802_15:36:37] 【DEBUG】49件目の「レコードを新規作成する処理」の開始
[20230802_15:36:37] 【INFO】レコード作成URL：https://pleasanter.net/fs/api/items/XXXX/create
[20230802_15:36:38] 【INFO】レスポンス内容@{Id=XXXX; StatusCode=200; LimitPerDate=1000000; LimitRemaining=XXXX; Message=" プリザンターAPIを用いてCSVファイルの自動取込をする " を作成しました。}
-----------------------------------------------------------------------------
[20230802_15:36:38] 【DEBUG】50件目の「レコードを新規作成する処理」の開始
[20230802_15:36:38] 【INFO】レコード作成URL：https://pleasanter.net/fs/api/items/XXXX/create
[20230802_15:36:38] 【INFO】レスポンス内容@{Id=XXXX; StatusCode=200; LimitPerDate=1000000; LimitRemaining=XXXX; Message=" プリザンターAPIを用いて全レコードの添付ファイルをローカルに一括ダウンロードする方法 " を作成しました。}
-----------------------------------------------------------------------------
[20230802_15:36:38] 【DEBUG】Qiitaの記事情報を読み込む反復処理が終了しました。
[20230802_15:36:38] 【DEBUG】メール通知処理が開始しました。
[20230802_15:36:38] 【INFO】メール通知URL：https://pleasanter.net/fs/api/items/XXXX/OutgoingMails/Send
[20230802_15:36:38] 【INFO】レスポンス内容@{Id=XXXX; StatusCode=200; LimitPerDate=1000000; LimitRemaining=XXXX; Message=メールを送信しました。}
```

ログファイルの内容はこのようになっています。エラーチェックは実施していません。

## タスクスケジューラでの設定

ここからが本題です。ここからは正解かどうかはさておき、正常にバッチ処理として動作しているため、こちらの内容を記載いたします。こちらの設定では極力デフォルトの設定で実行できる方法となります。こちらの設定を参考に適宜変更してください。  
また、本設定によって何らか不具合が発生しても責任は負いかねますので、ご了承お願いいたします。  

### 全般タブ

セキュリティ オプション：  
ユーザーがログオンしているときのみ実行する：オン  
こちらの設定は特段変えていません。  

### トリガータブ

こちらは処理を実行するタイミングを選択してください。また、詳細設定の「有効(B)」のチェックはオンにしてください。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659914/6d5f8c25-8322-72b9-5b95-b8f2450fa8b6.png)  

### 操作タブ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659914/c1c65092-d57b-5a60-fc02-2e3f378e7862.png)  
設定値は下記のとおりです。

```TEXT
プログラム/スクリプト(P)：powershell
引数の追加(オプション)(A)：-ExecutionPolicy Bypass ps1ファイルを特定するための絶対PATH
```

それぞれのコマンドについては他WEBサイト等でも紹介があるため、そちらをご参照してください。  

### 条件タブ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659914/01f64246-45fc-9b5b-8bf0-176154aefde7.png)  
こちらはそれぞれの利用条件などに応じてチェックのオン・オフを切り替えてください。  

### 設定タブ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659914/7b3d1c29-40d3-775b-533a-5b320249624a.png)  
こちらもそれぞれの利用条件などに応じてチェックのオン・オフを切り替えてください。

## さいごに

今回の記事ではプログラムというよりもタスクスケジューラの設定内容についてご紹介しました。調査方法が悪かったのかもしれませんが、タスクスケジューラの設定に関する記事はいろいろあるのですが、なかなか私の環境にあった設定内容を見つけることができなかったため、私自身の備忘録も含めて本記事に記載いたします。本記事の内容が誰かの役に立てば幸いです。