コネクターを自作してBizRoboの機能を拡張する手順

## はじめに

BizRobo!では v11.1 以降 `カスタム アクション` というステップがロボットに追加され、`コネクター` と呼ばれる外部プログラムをロボットの部品として実行できるようになりました。

`カスタム ステップ` と `コネクター`は同じなの？違うの？という「？」が頭をよぎりますが、`Lock`と`Key` の関係というか、`弓`と`矢`の関係というか、一つの機能を別の角度からとらえた用語かなと思います。

コネクターはインターフェイスが公開されているので誰でも作成することができます。

有志が作成したコネクターは Robot-Hub で公開されており、ユーザー登録をすればだれでもサンプルロボットやコネクターをダウンロードして使うことも、自分が作ったコネクターを登録・公開することも可能です。[^1]

[^1]: OPEN社が作成したコネクターはMyBizRobo!内で検索することもできますが、ファイルのダウンロードについてはRobot-Hubで管理されており、両方のアカウント登録が必要です。

https://robot-hub.bizrobo.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/b919f014-f900-2b4e-991a-425ba9a8b5d4.png)

とはいえ、公開されているインターフェイス情報[^5]だけでは実際に作成するには情報が不十分（試行錯誤が必要）だと思い、参考情報の追加としてブログ用に作ってみました。

[^5]: e-Leraning 内のレッスンや [Kofax RPAのオンラインドキュメント](https://docshield.tungstenautomation.com/RPA/ja_JA/11.4.0-vcsft2fhaw/help/rpa_help/help_main/designstudio/c_das_customactionstep.html)にて確認できます。

有用性、実用性よりも、雰囲気の共有や手順の確認を重視したサンプルです。ソースコードも共有するので、皆さんカスタマイズして使ってみてください。

:::note
本記事は、BizRobo! v11.4.0.2 の利用を前提に解説します。
:::

## BizRobo! のコネクターとは

正確な説明は公式ドキュメントや e-Learning の中で語られているので省略しますが、一方で語られていない部分について記述しておこうと思います。

### コネクターは何では `ない` のか？

コネクターは、公開されているインターフェイスを通じてロボットと連携できる仕組みですが、**SDK が提供されているわけではなく**、ロボットの機能をコネクター内に組み込むことはできません。

一方で、`Management Console`（以降、`MC`） が公開しているAPIをコネクター内に組み込むことで、BizRobo!の機能を一部取り込むことも可能です。

わかりにくいですね。矛盾しているように聞こえるかもしれません。

要は、良くも悪くも「疎」な関係であり、BizRobo!のバージョンに縛られることなく色んなバージョンで利用可能な反面、ロボットの `既存機能で解決できなかった問題を直接代替するものではない` ということで、冷静に容量・用法を見定めて取り組むべきものだと思います。

## コネクターをつくろう

それでは、実際にコネクターを作りましょう。

今回はPDFファイルをプリンターに送信して印刷する `pdf-printer` コネクターを作成します。

### 機能の仕様

* PDFファイルのパスを引数として渡すとそのデータをデフォルトプリンターに送信します。
* 単純にPDFデータをプリンターで印刷することに全振りしています。
    * ドキュメントを印刷する時には下に示すように「ページ範囲」や「部数」の他、「カラー/白黒」など指定することも求められますが、今回は全て割愛。 

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/598c7df1-1a3e-779f-f6e6-78608be02108.png)

### コネクターのファイル構成

今回は `SumatraPDF-3.5.2-64.exe` の機能を使ってPDFを印刷するバッチ処理をコネクターとしてラッピングします。

コネクターにはその基本情報を記載する `manifest.json` の他、PDFファイルを操作するための `SumatraPDF-3.5.2-64.exe`、そしてコネクター処理の中心となる `PrintPDF.bat`を同梱します。

```shell
📁 pdf-printer
 ├─ 📄 manifest.json # コネクターの基本情報
 ├─ 📄 PrintPDF.bat  # コネクターの処理
 └─ 🚀 SumatraPDF-3.5.2-64.exe # コネクターが使用するファイル
```
### コネクターの実行コード

:::note
コネクターの作り方や `manifest.json` の書き方などは e-leraning で既に述べられているのでここでは割愛します。
:::

コネクターの処理プログラムはどのプログラミング言語でも記載できますが、今回は Windowsのバッチファイルを選びました。その場合、`type` の値は `shell` とします。

処理は同期実行とし、プリンターへ命令を実行出来たら `OK`、それ以外の場合には `NG` とその理由を返却するために `response` を設定しています。

コネクターの処理として `commandline` からバッチファイルを指定していますが、引数は1つだけ。`parameters` に設定されたファイルパスをプログラムに渡します。

```json:manifest.json
{
  "actions": [
    {
      "name": "印刷",
      "type": "shell",
      "parameters": [
        {
          "name": "ファイルパス",
          "type": "string"
        }
      ],
      "response": [
        {
          "name": "result",
          "type": "string"
        }
      ],
      "commandline": [
        "PrintPDF.bat %1"
      ]
    }
  ],
  "name": "PDF印刷"
}
```

バッチの処理は非常にシンプルです。渡されたファイルパスから `拡張子` をチェックして、PDFだったらそのまま `デフォルト設定`で印刷します。それ以外にエラーが発生した場合にはNGとします。

```batch:PrintPDF.bat
@ECHO OFF
SETLOCAL

REM ファイルパスの引数が指定されているか確認
IF "%~1"=="" (
    ECHO {"result":"NG: ファイルパスが指定されていません"}
    EXIT /B 1
)

REM 半角スペースを含むファイルパスに対応するためにパラメータを全てファイル名として割り当て
SET "FilePath=%*"

REM ファイルが存在するか確認
IF NOT EXIST "%FilePath%" (
    ECHO {"result":"NG: ファイルが存在しません"}
    EXIT /B 1
)

REM SumatraPDF.exeのパスを設定（適切なパスに変更してください）
SET "SumatraPath=SumatraPDF-3.5.2-64.exe"

REM SumatraPDF.exeが存在するか確認
IF NOT EXIST "%SumatraPath%" (
    ECHO {"result":"NG: SumatraPDF.exeが見つかりません。パスを確認してください"}
    EXIT /B 1
)

REM 拡張子を小文字で取得
FOR %%F IN ("%FilePath%") DO SET "Extension=%%~xF"
SET "Extension=%Extension:~1%"
SET "Extension=%Extension:~0,3%"

REM 小文字に変換（大文字小文字を無視するため /I オプションを使用）
REM 拡張子に応じて印刷処理を行う
IF /I "%Extension%"=="pdf" (
    REM PDFファイルをSumatraPDFで印刷
    "%SumatraPath%" -print-to-default "%FilePath%" >NUL 2>&1
    IF ERRORLEVEL 1 (
        ECHO {"result":"NG: 印刷に失敗しました"}
        EXIT /B 1
    ) ELSE (
        ECHO {"result":"OK"}
        EXIT /B 0
    )
) ELSE (
    ECHO {"result":"NG: このファイルタイプの印刷はサポートされていません"}
    EXIT /B 1
)
```

## コネクターの仕上げ

必要なファイルとコードがそろったら仕上げに移ります。

`manifest.json`、`PrintPDF.bat`、`SumatraPDF-3.5.2-64.exe` の3ファイルを選択してZIP圧縮してください。[^2]

[^2]: 3つのファイルが含まれるフォルダを圧縮するのではなく、直接ファイルを選択して圧縮してください。ZIP圧縮後のフォルダ階層がずれてしまうとコネクター実行時にエラーとなります。

圧縮後、ファイル名を `pdf-printer` に変更するとともに、拡張子を `zip` から `connector` に変更すれば完成です。

:thumbsup:

## Design Studioで動かしてみる。

記事に書いたコネクターのコードと、サンプルロボットは GitHub に登録してあります。

https://github.com/kiban-unyo/pdf-printer

具体的には後述の動画の通り。ロボットを有効化したら `pdf-printer` コネクターを設定した `カスタム アクション` ステップの直前まで移動します。

:::note warn
`カスタム アクション` ステップの前に配置された「保存完了待ち」ステップには今回注意が必要です。PDF出力（ダウンロード）を待機するために挿入しているアクションでありダウンロードに時間がかかる場合の同期に有効[^3]ですが、デバッグモードで実行する時には注意を要します。
既にダウンロードが終了した（デバッグモードの）状態でこのステップに入ってしまうと、ダウンロード中の処理がないため延々と「待ち」状態が続いてしまいます。
:::

[^3]: 容量の大きいファイルのダウンロード時にこのステップを入れない場合、ダウンロードが完了する前にロボットを抜けてしまい、ダウンロード自体が途中で（ロボットの完了とともに）終了してしまうため、エラーは出ていないのにファイルがダウンロードされていない。ということが起こり得ます。

この状態ではまだプリンターにデータが送信されていませんが、`カスタム アクション` ステップを経過した直後、プリンターにデータが送信されファイルが印刷されます。

![Animation2562.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/56d9f8da-108f-59f2-21e8-3b1289c84e9b.gif)


## コネクターをロボサーバーで実行するための準備

サーバーでコネクターを動作させるには、事前に以下の設定が必要です。

- `RoboServer 設定` アプリの `セキュリティ` でコネクターの使用を許可していること

    ![roboserver-settings-enable-connector.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3090491/d4306baa-3889-a0a2-62a0-f14f1325d728.png)

- 今回はWindows標準のバッチを使ってコネクターのため不要ですが、例えば `Python` を使ったコネクターをサーバーで動かす際には、サーバーにも同じバージョンの `Python` をインストールしておく必要があります。[^4]

[^4]: Pythonは単なる一例で、C# で作成されたコネクターを動かす場合には、.NETが、Javaで作成されたコネクターを動かす場合にはJDKをサーバーにインストールしておく必要があります。

設定を実施した後は、ロボサーバーを再起動しましょう。

## まとめ

次は、AIと連携させた便利コネクターを作ってみたいですね。