PADで指定期間内のSlackメッセージを1日分ずつEvernoteにバックアップ

EvernoteのSlack連携機能の一つである「Slackメッセージの保存（ `/clip` ）」を指定期間分、一日分ずつ実行する作業をPower Automate Desktopで自動化してみました。今後もSlackのフリープランと付き合っていく、今後のメッセージ履歴はEvernoteに毎日送ることにする、でもその前に過去分の履歴〇年分を一日分ずつ送っておかないとなのは辛いな…という私みたいな人のお役に立ちましたら。

# 背景

Slackのフリープランでは、2022年9月以降、履歴が直近90日分しか表示できなくなるようです。

> **ワークスペースにある90日が経過したメッセージやファイルのデータはどうなりますか？**
> 2022年9月1日より、過去90日間のメッセージ、ファイル、クリップにはすべてアクセスできますが、90日が経過したものは非表示になります。有料プランへアップグレードすれば、いつでもワークスペースのメッセージとファイルの全履歴にアクセスできるようになります。
> （[フリープランの変更に関するよくある質問 | プロプランの料金改定とフリープランの最新情報 | Slack](https://slack.com/intl/ja-jp/help/articles/7050776459923#h_01G7QZ8REYPNN7K59AVFDSNK7V)）

すでに[Qiitaに様々な対応策が上がっています](https://qiita.com/search?sort&q=slack%2090%E6%97%A5)が、個人的には過去分のメッセージを[EvernoteのSlack連携機能](https://help.evernote.com/hc/ja/articles/115013171368-Evernote-for-Slack-%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9)で、一日分を1ページとしてSlackメッセージをEvernoteに保存したいと思いました。これであれば、今後もSlackのフリープランを使い続けながら、日々のメッセージは同じ形でEvernoteに残していけます。Evernoteの連携機能には、Slackから `/find` コマンドでEvernoteを検索というのもあるので、検索もその場でできそうです。

一日分のメッセージの保存は `/clip yyyy-MM-dd` でできます。とはいえ過去数年（私の場合は3年、1,000日ぐらい）分をひたすら実行していくのはちょっと苦行です。またAPIからチャンネルに `/clip yyyy-MM-dd` を流して自動化ということを過去に考えましたが、これだと単にそのままのメッセージが投稿されるだけで、コマンドとして実行されなかった覚えがあります。そこでブラウザの自動操作で、実際に `/clip yyyy-MM-dd` を入力、実行させる形で、指定期間分を連続で自動実行させたいと考えました。

# フローの作成

フローを作成します。

* Power Automate Desktopで「フローの追加」をします。名前はなんでも構いません。
* Mainフローに左ペインから「変数の設定」をドラッグ＆ドロップし、変数名 `AutomationTitle` にフローの名前をセットします。これは実行中のメッセージダイアログのタイトルなどに表示されます。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/7984090f-b79e-100c-1ad8-399a9261f6f6.png)
* 以下のコードをコピーします。

```Robin
FUNCTION ClipSlackToEvernote GLOBAL
    Display.ShowMessageDialog.ShowMessage Title: AutomationTitle Message: $'''対象Chromeウィンドウを最前面にしてください''' Icon: Display.Icon.None Buttons: Display.Buttons.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: True ButtonPressed=> ButtonPressed
    IF ButtonPressed <> $'''OK''' THEN
        EXIT FUNCTION
    END
    WebAutomation.LaunchChrome.AttachToForegroundChrome BrowserInstance=> BrowserInstance
    Display.SelectDateDialog.SelectDateRange Title: AutomationTitle Message: $'''clip対象期間を指定してください''' DateDialogFormat: Display.DateDialogFormat.DateOnly IsTopMost: False SelectedDate=> ClipDateFrom SecondSelectedDate=> ClipDateTo ButtonPressed=> ButtonPressed
    IF ButtonPressed <> $'''OK''' THEN
        EXIT FUNCTION
    END
    SET ClipDate TO ClipDateFrom
    LOOP WHILE (ClipDate) <= (ClipDateTo)
        Text.ConvertDateTimeToText.FromCustomDateTime DateTime: ClipDate CustomFormat: $'''yyyy-MM-dd''' Result=> ClipDateString
        Display.ShowMessageDialog.ShowMessageWithTimeout Title: AutomationTitle Message: $'''/clip %ClipDateString%''' Icon: Display.Icon.None Buttons: Display.Buttons.OKCancel DefaultButton: Display.DefaultButton.Button1 IsTopMost: True Timeout: 2 ButtonPressed=> ButtonPressed
        IF ButtonPressed <> $'''OK''' THEN
            EXIT FUNCTION
        END
        WebAutomation.PopulateTextField.PopulateTextField BrowserInstance: BrowserInstance Control: appmask['Slack Chanel']['Paragraph'] Text: $'''/clip %ClipDateString%''' Mode: WebAutomation.PopulateTextMode.Replace EmulateTyping: True UnfocusAfterPopulate: False WaitForPageToLoadTimeout: 60
        WebAutomation.PressButton.PressButton BrowserInstance: BrowserInstance Control: appmask['Slack Chanel']['Button \'今すぐ送信する\''] WaitForPageToLoadTimeout: 60
        DateTime.Add DateTime: ClipDate TimeToAdd: 1 TimeUnit: DateTime.TimeUnit.Days ResultedDate=> ClipDate
    END
END FUNCTION
```

* `Main` タブを右クリックし、「貼り付け」をします。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/02ab7acb-bac8-2973-603a-b336d5f1cb69.png)
* `ClipSlackToEvernote` というサブフローができます。エラー（「UI要素が見つかりません）が2件出ると思います。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/777c9402-c9ea-40fe-450a-71fe7f363c70.png)

UI要素のエラーを修正していきます。

* エラーになっている17行目をダブルクリックします。「Webページ内のテキストフィールドに入力する」ダイアログが開くので、「UI要素」のプルダウンメニューを開き、「UI要素の追加」をクリックします。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/e83b563e-8b29-f15b-39df-f047fb4b1a94.png)
* UI要素ピッカーというダイアログが表示されます。これはそのままにしておいて、ChromeブラウザでSlackを開きます。下部のメッセージ入力欄にマウスポインタを合わせ、「Paragraph」という赤い枠が出たら `Ctrl`+左クリックします。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/6cf87ec8-dafe-609e-54ba-4e90516dd479.png)
* 「Webページ内のテキストフィールドに入力する」ダイアログに戻るので、「保存」をクリックして閉じます。
* 同様に、18行目の「Webページのボタンを押します」でも「UI要素の追加」を行います。Slack画面でメッセージ入力欄になにか入力して送信ボタンが緑色になったら、同様にマウスポインタを合わせ、「Button」という赤い枠が出たら `Ctrl`+左クリックでUI要素として指定し、保存します。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/927208ab-af9c-34ea-2500-841586d66bfa.png)
* 右側の「UI要素」ボタンを押してUI要素ペインを開き、「Paragraph」をダブルクリックします。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/76e80768-5190-cc1c-4acf-147dac758e32.png)
* UI要素のセレクターの編集ダイアログが表示されます。右上の「テキストエディター」を選択して表示を切り替え、セレクターの内容を `div[Class*="ql-editor"] > p` に書き換え、「保存」をクリックします。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/fcaf2279-694e-b10f-dc14-15d34d63e734.png)
* 同様に「Button '今すぐ送信する'」のセレクターの内容を `span[Class*="c-wysiwyg_container__send_button--with_options"] > button` に変更します。

Mainフローの最後の修正をして、保存終了します。

* 「Main」タブをクリックしてMainフローに戻ります。
* 左ペインの「フローコントロール」内の「サブフローの実行」をドラッグ＆ドロップします。「サブフローの実行」ダイアログが表示されるので、実行対象として作成した「ClipSlackToEvernote」を選択し、「保存」をクリックします。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/1c0d4942-2c7e-e12a-7e33-d5cb4f109128.png)
* 「保存」ボタンをクリックしてフローを保存します。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/e648cc28-7340-671e-5106-d15b9080a572.png)
* フローエディタ（編集画面）を閉じます。

# 実行

* ChromeでSlackのバックアップしたいチャンネルを開きます。
* フロー一覧から、作成したフローの三角形の「実行」ボタンをクリックします。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/544cb4f0-a584-53f9-0912-dd98f50b6de3.png)
* 「対象Chromeウィンドウを最前面にしてください」メッセージボックスが表示されます。Slackを開いたChromeを最前面にしてから、メッセージボックスの「OK」をクリックします。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/b9a4e5ad-b246-48a7-1a9b-5d1b5c65ff08.png)
* 「Clip対象期間を指定してください」メッセージボックスが表示されます。開始年月日、終了年月日を指定し、「OK」をクリックします。<br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/f705f658-9686-20e8-9639-fff652b14b82.png)
* 「/clip 年-月-日」メッセージボックスが表示されます。2秒たつと自動的に消え、この `/clip` コマンドがSlackに投稿（実行）されます。なおこのメッセージボックスでキャンセルを選択すると、処理を途中で終了できます。 <br/>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/c8e0a93d-4723-ef75-b84f-7258e563da79.png)
* 処理を途中終了しなければ、上記の動作を繰り返して指定した終了年月日分まで連続的に `/clip` コマンドが投稿（実行）されていきます。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/9f367d3c-e10b-da2f-c757-b901be102a9d.png)

# 終わりに

3年前は諦めたSlack→Evernoteバックアップの簡素化（半自動化）ですが、今回はブラウザオートメーションの開発が容易なPower Automate Desktopのおかげで、実現できました。これを使うと、2秒間隔で1日分の `/clip` コマンドを実行するので、単純計算だと1分で1か月分のバックアップができることになり、9月1日までに過去分を全部バックアップできるのではと思います。それ以降も月に一回、本フローで前月分をバックアップといった形で、わりと省力的にSlackフリープラン運用を続けられそうです。

前述のとおり、すでにDiscordに過去メッセージを移行するとか、SlackクローンのMattermostを構築するとか[様々な対応策が上がっています](https://qiita.com/search?sort&q=slack%2090%E6%97%A5)が、本案はSlackをフリープランのまま使い続けつつ過去メッセージはEvernoteで保持、閲覧可能にするという、環境や利用方法の変化をできるだけ小さく抑える選択肢を提供できるかと思います。いずれの方法にせよ、皆様のSlackフリープラン内容変更対応も、無事に済みますように。