UiPath Friends 東京 Orchestrator ハンズオン勉強会 パート2 資料


こんにちは！UiPath Friendsコミュニティ運営メンバの @masatomix です。この記事は 2020/5/15(金)に開催予定の、[UiPath Friends 東京 Orchestrator ハンズオン勉強会 - パート2 ★完全オンラインで開催★](https://uipath-friends.doorkeeper.jp/events/104805) 向けの資料です。

[前回](https://qiita.com/masatomix/items/096de223e05511a1166c) のコンテンツを理解済みの方を対象にしています。 


さて今回は、下記のハンズオンを行います。

- UiPath Orchestrator の機能概要(今回ご紹介分)
- Orchestratorの **アセットの機能**を使ってみよう
- Orchestratorで **カスタムアクティビティを配布**してみよう
- Orchestratorの **キューの機能**を使ってみよう


> 2020/05/18追記
> オンライン ハンズオン時の動画が、Youtubeにアップされました
> https://youtu.be/0pAn1XmHCwY
> 合わせてご覧いただくとよいかもしれません


## 対象の方

- 会社で UiPath Orchestrator(以下OC)を導入するみたいなんだけど、ヒトに構築をお願いするにも**ひととおりはさわっておかなくちゃなー**、って方。
- UiPathはソコソコ使ってるけど、StudioやRobotを **Orchestratorとともに使うのってどうやるのかな？？** って方
- 前回のコンテンツを理解済みの方
- UiPath Love な方

などなどです。

## 前提事項

- 今回は完全にオンライン開催なので、ご自身のWindowsPCをご準備ください。
- 管理者権限のユーザでログインできるようにしてください。
- **あらかじめ UiPath Studio Community 版をインストール**しておいてください。
- 本資料は UiPath Studio Community 2020.4.0 で疎通確認していますが、近しいバージョンであれば問題ないと思います。
- ご自身が**操作可能なUiPath Orchestratorをご準備いただき、UiPath StudioをそのOCに接続**しておいてください。
    - [前回](https://qiita.com/masatomix/items/096de223e05511a1166c)のハンズオンで、Community版(2020/05現在は Community Cloud って呼ぶのかな)を準備するハンズオンがあります。
    - 実施すると Community Cloud 版の Orchestratorに接続済みのUiPath Studio環境を構築できます。
- UiPath Studio Enterprise 版をお使いの場合は、対応するEnterprise版のOCをご準備ください(一応UiPath Studio Enterprise版は 2019.10.3で疎通確認してあります)。
- ハンズオン環境としてZoomをご用意ください(運営側で当日のZoomリンクを用意するため、参加者のアカウント登録は不要です)。



## 1.UiPath Orchestrator の機能概要(今回ご紹介分)

### アセットの機能

アセットは**異なるワークフロー間で共通でもちたい情報を、OCに接続されたロボットたちで共有する機構**です。

![000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/cb5d0635-58f0-ad1c-faf1-8d0bf7e2d175.png)

よくあるケースだと「**どのワークフローも同じファイルパスを指定したい**」とかですね。そのような情報をOCで一元管理することができます。


OC上の設定画面
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/21312f6b-337d-f376-f6d3-e1a9c376c5e2.png)


その共有したい情報は、ロボット上で稼働するワークフローからは「**アセットを取得(Get Asset)**」アクティビティおよび「**資格情報を取得(Get Credential)**」アクティビティで取得できます。
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/f66401a3-6c69-acda-893f-191e6f2c1e48.png)


アセットの情報は**全ロボットで共通の値とすることもできるし、ロボットごとに異なる値とする**こともできます。「外部システムへのログインアカウント」などは、ロボットごとに別々にしたいときもありますよね。

例:「TextPerRobot」というアセット名に対して、ロボット(下記はSQLServerとWINDOWS_URというロボ)ごとの値を設定している
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/f60f87bf-13b4-df6d-e2f9-290179e9cf0d.png)

アセットは「文字列」「True/False」「Integer」の型の他に **「ユーザ名/パスワード(Credential型)」** 型が使用可能です。Credential型で管理するパスワードは **一度設定すると表示不可能になります** ので、他人にみられたくない値などに適しています。
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/afdbf315-af5b-9553-d043-739e71cc8fec.png)

>蛇足:
>これらのデータの保存先ですが、Credential以外はOrchestratorのDB上にそのまま保存されますが、Credentialは「AES256」で暗号化されて保存されるようです。もしくはCredentialについては **Azure のKey Vault などの外部サービスに保存**することも可能です。


アセットのご紹介は以上です。あとでハンズオンで一緒に使ってみましょう。


### カスタムアクティビティの配布

UiPathを使い込んでいくと、**複数のワークフローで共通の処理を「ライブラリ」として作成** することもあると思いますが、作成したライブラリ(nupkg)は**ワークフローを動かすほかのPCにも配布**をしなくてはいけません。その配布の方法をご紹介します。

>あちなみに、UiPath Studio上でアクティビティからペタペタ貼っていくやつを「(カスタム)アクティビティ」と呼び、そのカスタムアクティビティを作るためのプロジェクトや、配布物であるnupkgを「ライブラリ」と呼ぶことにします。


さて、Orchestratorがない場合も含めると、配布の方法は主に3つあります。

1. UiPath StudioからライブラリをPublishしてnupkgファイルを作成したのち、**ファイルサーバ経由などでnupkgを各PCへ配布**する。
1. UiPath Studioからネットワーク上にある**NuGetサーバにPublish**する。(NuGetサーバはネット上だと https://www.nuget.org/ とか、もしかしたら社内ネットワークにもあるかもしれない。)
1. OCに接続しているUiPath Studioから、**Orchestratorへ直接Publish**する。

3の構成図
![cu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/34f9b2b7-57bf-df01-da0c-3c0a8f5f681a.png)

1のファイルサーバ経由は **nupkgファイルを手動で配布**する必要があり、また**バージョン管理なども含めると何かとメンドクサイ**です。
2のネット上の NuGetサーバへの配布は、社内用ライブラリをPublishする先としては、**セキュリティ的にもイマイチ**です。

3は、**OCに接続されたUiPath Studioから直接OCへPublish**でき、また **(OCに接続された)Studio/Robot たちはそのライブラリを自動で受け取る**ことができます。同時に**OC上でバージョン管理**もしてくれるので、とても便利です。

StudioからPublishしている図
![3-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/251dd2e7-d25f-6ee1-fb2d-bcd4b6d271f2.png)

他のStudioから、パッケージ管理で参照できている図
![3-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/2c18eda6-97a0-9ff0-9c52-ba56052f9763.png)


カスタムアクティビティの配布についての概要は以上です。あとでハンズオンで一緒にやってみましょう。


### キューの機能

キュー(Queue)とは **「無制限に項目を保持できる収納機能です。」** とのこと([公式より](https://docs.uipath.com/orchestrator/lang-ja/docs/about-queues-and-transactions))。処理したいデータをOC上のキューに投入することで、**ワークフロー間でデータをやりとりする機構**です。

![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/49364d44-0b73-9835-26c4-cd0a160e3643.png)

キューをつかうことで **「データ投入」と「データ取得・処理」のワークフローを分け**たり、**複数ロボットによる処理の並列化** を行うことができます。たとえば5万件のデータを処理する際に、10台のロボットがそれらのデータを並列で処理する、などができるわけですね。


下記は、OCのキューへ投入されたデータの一覧です。(あるキューに、113件データが入っています)
![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/08576a48-d1d9-49c1-de5c-e1ac6b0a5378.png)


キューから**データを取り出す場合は「トランザクション アイテムを取得」アクティビティ**で。
![009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/5d6ac852-1e2b-748d-3be7-789782cda2ca.png)

一般的に処理を並列化するときは、**データの重複登録**や**複数ロボットによる処理の重複**に注意が必要ですが「キューへのデータ投入時に、同じデータを重複して投入しない」仕組みや「キューからのデータ取得時に、複数のワークフローが同じデータを取得しない」ような仕組みが用意されています。


まずは、**キューへのデータ投入時に、同じデータを重複して投入しない機構「一意の参照」**ですね。各データにキー項目をセットすることで、データが一意であるかをチェックしてくれます(後述)
![010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/295f0f46-8d6c-6f6a-0855-f9b80be11c1a.png)

もうひとつは、**同じデータを処理しないための「トランザクション アイテムを取得」アクティビティ** です。このアクティビティを使うと**他人が処理中でないデータをキューからひとつ、取り出す**ことができます。
![009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/5d6ac852-1e2b-748d-3be7-789782cda2ca.png)


#### 蛇足、というかもう少し細かい話

「トランザクション アイテムを取得」アクティビティで取り出したデータを処理し終わったら、ワークフローは責任を持ってデータに対してステータス「成功/失敗(アプリ例外)/失敗(ビジネス例外)」をセットしなければなりません。
それぞれのステータスの意味は以下のとおり。処理結果に応じて適切なステータスを設定するようにしてください。

- **成功**: 正常に終了
- **失敗(アプリ例外)**: ときどき発生するエラーなどいわゆるシステム例外で、再ラン(再実行)したらふつうに正常終了するかも？という失敗
- **失敗(ビジネス例外)**: 入力チェックでエラーなどいわゆる業務例外で、再ランしてもダメな失敗

失敗(アプリ例外)としたデータはキュー上は「リトライ」という状態になり、**新たに同じデータがキューに投入され**ます。なので、別のトランザクション(同じワークフローかもしれません)が再度、そのデータの処理を試みてくれます。そのリトライは、成功するか、キュー定義で**規定したリトライ回数だけ**繰り返されます。

このトランザクション機構(とステータス管理機構)により

- いろんなロボが並列で稼働しても、同じデータを重複して処理するのを防げる
- 復旧可能な失敗については自動で(規定回数)再ランされる

などを実現しています。**ワークフローはキューのデータを順次取り出して一つ一つ処理**する、って書いておけば OK。**「あるエラーは繰り返し(リトライ)を行う」などのロジックの記述は不要**で、ワークフローがとてもシンプルになります。

さらには RE Framework を用いると、順次取り出す処理やステータスをセットする処理も全部やってくれるので、キューを使うときはRE Frameworkを積極的に使っていきたいですね。

キュー機能についてのご紹介は以上です。あとでハンズオンで一緒にやってみましょう。



機能概要のご説明は以上です。


## ハンズオン環境の確認

前提にも書きましたが、以下ハンズオンを行うにあたって

- 操作できる UiPath Orchestrator (Community Cloud版でも、オンプレでも)をご用意ください。
- そのOCへ接続済みの、UiPath Studioをご用意ください。
    - 繰り返しとなりますが、前回の記事を実施することで「OC接続済みのUiPath Studio と OC」を準備することができます。
    - うまくいっていれば、タスクトレイのアイコンが青もしくは緑になっていると思います。


Community版 Studio の場合
![c0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/6af51556-ffce-c591-fa97-54d8ec6b3556.png)

Enterprise版 Studio の場合
![0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/711812fb-ece4-2051-0aa5-a9fe158a2809.png)


Community Cloud版のOCの場合、カスタムアクティビティの配布には一点設定が必要です。WEBからOCへログインしたのち、右上の赤丸アイコン >> 設定 をクリック して、、
![D0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/62cae0c9-7248-7c34-dc68-b890ef268c72.png)


デプロイメント を選択し、ライブラリ項目のフィードを「テナント」、デプロイメントを「内部」、セキュリティを「安全なデプロイメント」にしてください。最後に「保存」をクリックして、設定を反映させましょう。
![D0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/7633b60a-10ec-6d60-4bf4-9b6e8f071f0d.png)



## 2. Orchestratorの アセットの機能を使ってみよう

さて、アセットを使ってみるハンズオンです。Studio上のワークフローからアセットの情報を取得してみます。流れは以下の通り。

- OCのアセット設定画面で、アセットを登録していきます。
- Studioのプロジェクトを作成します(Gitから取得します)
- Studioから実行して、その情報を取得してみます。
    - テキストやCredential(ID/Pass)
    - ロボットごとに異なる値

### OCのアセット設定画面で、アセットを登録していきます。

OCへログインし、左メニューの「アセット」をクリック
![2-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/2c5d816d-37dc-39c0-b0aa-ab3173a28dc5.png)

右肩のプラスボタンをクリック
![2-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/3aa2714e-041b-647f-316d-81a26ac0d4aa.png)

下記の通り入力して「作成」をクリックします。

- アセット名:「outputPath」
- 型:「Text」
- グローバル値:
    - Text:「c:\temp\output」

![2-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/2cca2555-8d98-e40b-5674-0499c755672a.png)

``outputPath``というアセット名に対して、テキストの値「``c:\temp\output``」が設定できました。

![2-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/d2e93f40-1379-b66a-79be-eec7fc62159b.png)


同様に Credential 型のアセットも作成してみます。同じく右肩のプラスボタンをクリック後、

- アセット名:「Credential001」
- 型:「Credential」
- グローバル値:
    - ユーザ名:「u000」
    - パスワード:「任意」

と情報を入れてみます。

![2-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/38bbee3c-f827-6f88-004b-d85f978bea8c.png)

こちらのアセットには、ロボットごとの値も設定してみましょう。下の「プラスボタン」をクリックして
![2-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/2847c926-7e7f-232e-0e24-a0ee51727082.png)

「ロボット」プルダウンから、自身が操作しているPCのロボットを選び、
![2-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/e3089c40-5ec0-ff95-ea6e-6f679848b0ce.png)

ユーザ名、パスワードを、先ほどと違う値を入れて「追加」をクリックします。
![2-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/146378f1-e5c6-89b1-9e4f-6dfff11fe479.png)

追加されたようですね。最後に「作成」をクリックすればOKです。
![2-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/fb995bca-80dd-ea5f-4da3-38e437935b2f.png)

ロボットごとに異なる情報と、上記に一致しないロボットたちに適用されるグローバル値を持ったアセットが作成できました。
![2-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/ee19f7d2-03f4-c007-3167-9d9adc94a9fd.png)

### Studioのプロジェクトを作成します(Gitから取得します)

Orchestrator上でアセットが作成できたので、つぎはその値を取得するワークフローを作成します。といっても今回は **GitHub にソースコードをアップロード済み**なので、そこから取得してみます。GitHubから取得といっても手順どおりやるだけです。簡単です。
![2-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/eb211553-ffa6-bebf-9371-e4765c245b27.png)


UiPath Studioを起動して「チーム」をクリック
![2-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/bb6f856d-4db8-c1d3-e0e0-a30bcad1e574.png)

「リポジトリを複製」 をクリック
![2-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/f6288fa1-02f9-5daa-949f-3a67e5fcadfe.png)

リポジトリURLに **https://github.com/masatomix/UiPath-OC-Hands-on2.git** と入れて「開く」をクリックします。
![2-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/3035e72a-c7ce-9447-c3c4-050c131d5273.png)

プロジェクトをGitHubからダウンロードすることができました。ダウンロードしたプロジェクトにはサンプルがすでに作成済みです。
``asset/Sample001.xaml``を開いてみてください。
![2-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/1f4dd5ad-b28c-394d-dda9-c0aaf8afd48d.png)

「アセットを取得」アクティビティがすでに配置されていて、OC画面上で設定したアセット名「``"outputPath"``」などが指定されていると思います。
![2-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/922a7df8-13ee-33af-ea15-7f60e83d2301.png)

サンプルは、取得した情報をメモ帳に出力しています。

サンプルのもう少し下をみてみてみると「資格情報を取得」アクティビティが配置され、こちらも先ほどのアセット名「``Credential001``」が指定されています。
![2-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/18e07fff-41f0-3438-d1d4-37bf0578b569.png)


### Studioから実行して、その情報を取得してみます。

さて、ワークフローを実行してみます。上部リボンメニューの「ファイルを実行」をクリックしてワークフローを実行してみます。(実行を選ぶと``Main.xaml``が動いちゃうのでご注意)

![2-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/33b018f5-2d0c-702d-a046-a8f67ec5f918.png)

メモ帳が開いて、OC画面でセットした値が取れていればOKです。
![2-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/316b4c3a-0634-bfed-24d3-57e76029b20d.png)

Credentialの方はロボットごとの値がとれていることなども確認してみてください。
またCredentialのパスワードは、コーディングで


```visualbasic
New System.Net.NetworkCredential(String .Empty, pass).Password
```

とするか、「SecureString で文字を入力」アクティビティを用いればOKです(サンプルには両方のせてあります)。


## 3. Orchestratorで カスタムアクティビティを配布してみよう

つぎはカスタムアクティビティの配布をやってみましょう。簡単なライブラリを作ってPublishして、別のプロジェクトからそのライブラリを使用してみます。流れは以下の通り。

- UiPath Studioのライブラリプロジェクトを作成します
- StudioからPublishして、OC画面上で確認します
- Studioの別のプロジェクトから、作成したライブラリを取得して、利用してみます

### UiPath Studioのライブラリプロジェクトを作成します

**アセットを取得してみて、該当するアセットが存在しなかったら指定したデフォルト値を入れる**という「``MyGetAsset``」アクティビティを作成してみます。

- 入力 :
    - assetName: アセット名
    - defaultValue: 該当するアセットがなかったときのデフォルト値
- 出力: アセットの値

完成図
![3-041.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/54b99d05-8a2c-b010-89e0-e76395fea193.png)


新規で作成していきましょう。
Studioを起動して「ライブラリ」をクリック
![3-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/96ed5d56-562e-32cf-19fa-ec12317d0c75.png)


以下のように入力して「作成」をクリックします。

- 名前:「UiPath-OC-Hands-on2_library」
- 場所:「任意(デフォルトでOK)」

![3-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/43de9ec2-fa58-5bf8-20bd-5a5df1c8c6f6.png)


プロジェクトが作成できました。
![3-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/21db2eac-3623-9761-7933-8a42864f5ab4.png)


空っぽの「``NewActivity.xaml``」すでにありますが、そのままアクティビティ名となるので、``F2``で「``MyGetAsset.xaml``」に変更しておきます。
![3-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/fa2ecf16-e967-b96f-f384-0859096b399b.png)




``MyGetAsset.xaml`` を開いてから、アクティビティの検索ボックスで「try」と入れて「トライキャッチ」アクティビティを検索。``MyGetAsset.xaml`` へドラッグアンドドロップします。
![3-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/d4590275-8b98-a363-c22d-6bf880d283c0.png)



つづいてアクティビティの検索ボックスで「asset」と入れて「アセットを取得」アクティビティを検索。``MyGetAsset.xaml`` へドラッグアンドドロップします。
![3-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/c571580b-898e-330f-b2ed-4173c97f1ba9.png)


「アセットを取得」アクティビティをクリックしてプロパティを設定していきます。「アセット名」のテキストボックスで ``Ctrl + k`` と入力して「変数を設定」状態(?)にして、``assetName``と入力してEnter。変数の定義と値の設定が同時にできたと思います。
![3-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/191bf0f7-cfdd-cb6c-b92f-764f087800f5.png)


つぎに出力の「値」のテキストボックスで``Ctrl + k`` と入力して「変数を設定」状態にして ``result``と入力してEnter。

下記の通り、変数の定義と、アクティビティへの値のセットができました。
![3-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/19c057c3-265b-7937-4137-9d6c2511d208.png)


さて、アセットの取得に失敗したときの処理を記述するため、トライキャッチアクティビティ内の「新しいcatchの追加」をクリック
![3-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/b57aa8f0-f0e7-386d-7ea6-e2939abd3f80.png)


「System.Exception」を選択して、Enter
![3-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/8a227ff5-60a0-1273-6d48-263c2c9a9ad1.png)


``System.Exception`` が発生したときの処理を記述できるようになりました。
![3-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/b98d3495-7a0b-8047-74d3-36bc8dcb5810.png)


アクティビティの検索ボックスで「assign」と入れて「代入」アクティビティを検索。``MyGetAsset.xaml`` の Exceptionの場所にドラッグアンドドロップします。
![3-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/ee5a6ca8-4e37-1d2c-7e91-00cf2a3127d2.png)


エラーが発生したときは戻り値となる ``result`` をユーザが指定した値にしたいので、代入アクティビティで書き換えます。の左辺は``result``、右辺は ``Ctrl + k`` で``defaultValue``としておきます。
![3-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/30687c16-2448-6cb1-10c3-d0654f3a1035.png)


いままで定義してきた変数 ``assetName,defaultValue,result`` は本来はアクティビティに入出力するための「引数」でなければいけないので、一括でに変更します。すべての変数を``Ctrl + a`` で選択して「右クリック >> 引数に変換」します
![3-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/76571dd8-56ed-5de3-957f-0b83e8b8d616.png)

すべての変数が、このxamlの引数に変更されました。


``result``だけは結果を受け取る「出力の引数」にしたいので「方向」を「出力」に変更します。
![3-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/c83d9683-001c-e17a-acd8-99569ed5e9ab.png)


おつかれさまです。長かったですが、完成しました！

#### つまづいたら、こちらから取得してください

いちおう完成品はGitにアップしてありますので、お時間のない方はこちらからどうぞ。

Studioを起動して チーム>> リポジトリを複製 をクリックして、https://github.com/masatomix/UiPath-OC-Hands-on2_library.git と入れて「開く」をクリックします。

![3-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/678946e0-bb25-8dd9-ccc3-a4a37d849d9a.png)

完成品が取得できたと思います。


### StudioからPublishして、OC画面上で確認します

さて右上の「パブリッシュ」をクリックします。
![3-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/85791ffe-7169-f3f8-ff83-36628505a07c.png)

パッケージ名はデフォルトのまま、次へ
![3-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/251dd2e7-d25f-6ee1-fb2d-bcd4b6d271f2.png)

パブリッシュ先もデフォルトのまま「パブリッシュ」をクリック
![3-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/7a6715b7-4f5a-72a7-ad12-3520b34a66df.png)

完了したようです。
![3-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/6483374d-541c-aad9-05bc-af8630a34f97.png)


WEB画面でも確認してみましょう。OCへログインして、左メニューの パッケージ >> ライブラリ を選択すると、下記のようにPublishしたライブラリが確認できると思います。
![3-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/0c191478-cdc8-0e9a-8c82-e973b841ebaa.png)


### Studioの別のプロジェクトから、作成したライブラリを取得して利用してみます

Publishしたライブラリを、ほかのライブラリと同様に使えるか確認してみます。

さきほどアセットのときに作成したプロジェクト「``UiPath-OC-Hands-on2``」を使い回します。
よくわからなくなっちゃったら、とりあえずStudioのホーム画面を表示し(リボンのホームをクリックするか、Studioを終了してから再度開くか、など)履歴から「UiPath-OC-Hands-on2」を開きましょう。
![3-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/9d1eb0a2-c276-e9a4-4e7a-a89a0e97a351.png)

パブリッシュしたライブラリを使用するために、リボンメニューの「パッケージを管理」をクリックします。
![3-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/f41607e5-d58b-38be-24dd-e1471d983b71.png)


パッケージ管理画面が表示されるので「Orchestrator テナント」を選択してみると、作成したライブラリが表示されましたね。
![3-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/2c18eda6-97a0-9ff0-9c52-ba56052f9763.png)


そのままインストール >> 保存で、自分のプロジェクトに自作のライブラリをインストールすることができました。
![3-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/9fcacab9-7ee5-3e40-f780-2ae81a8d158d.png)


アクティビティをみてみましょう。先ほど作成したカスタムアクティビティ「``MyGetAsset``」が表示されるとおもいます。
![3-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/dd202ad1-61ec-14e6-f5ae-5d51825cd9b2.png)


#### 時間があれば、アクティビティを使ってみましょう

アセットで使った``Sample001.xaml`` の最後に下記のようにドラッグアンドドロップします。
![3-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/c5e15025-a60e-1d59-3e99-1833057b62e6.png)

ライブラリの作成時に

- 入力として「``assetName,defaultValue``」
- カスタムアクティビティから結果をもらうための出力として「``result``」

を定義しましたが、プロパティ部にそれが表示されています。先ほどのアセットのときと同様

- assetName: 「"outputPath"」 ← まずは通常通り動くことの確認。OCで定義したアセット名をセット
- defaultValue : 「任意のデフォルト値」
- result: 「result」 (``Ctrl + k`` で ``result`` 変数を定義してセット)

として ``result``変数をログ出力してみました。

![3-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/7de87c17-96c5-8969-6804-2e481ca3f6ef.png)


先ほどのアセットの値が取得できています。

つぎにアセット名をあえて存在しないもの、たとえば「``"outputPath1"``」とかにして実行してみると

![3-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/e07fa440-a1d9-6925-a5fe-bc3ba2ddc263.png)

``defaultValue``プロパティの値が出力されました。カスタムライブラリが動いてそうですね。。


カスタムライブラリの配布のハンズオンは以上です。


## 4. Orchestratorの キューの機能を使ってみよう

OCのキュー機能を使ってみます。キューにデータを投入するワークフローと、それらを処理するワークフローを作成してみます。流れは以下の通り。

- OC画面上で、キューを定義します。
- Studioでデータ投入用のプロジェクトを作成します(Gitから取得します)
- Studioから、データを投入するワークフローを実行します → OC画面で確認
- Studioでデータ取得用のプロジェクトを作成します(Gitから取得します)
- Studioから、データを取得するワークフローを実行します → OC画面で確認


データ投入用のプロジェクトは「メールサーバからメールを受信して、その情報をキューに投入」します。
データ取得用のプロジェクトは「キューから値を取り出して、表示」する(だけ)です。

メールサーバはこちらで準備してあるものを使います。下記の通り数件、受信箱にメールが届いている状態にしてあります。
![4-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/d86fb76c-1821-6e4b-d0f3-7ebc1f1bd804.png)


### OC画面上で、キューを定義します。

OCへログインし、左メニューの「キュー」をクリック(「監視」ではなく「オートメーション」がわのキューです)
![4-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/3bbb74ce-a26c-72f0-62c0-15f4047f3d2c.png)


右肩のプラスボタンをクリック
![4-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/77a346c3-34c3-6ab8-a687-a47ccf0d06c2.png)


下記の通り入力して「追加」をクリックします。

- 名前:「mailQueue」
- 一意の参照:「はい」
- 自動リトライ:「はい」
- 最大リトライ回数: 「1」

![4-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/1c4eead2-85e0-1e6e-dd75-6ccd720d67a6.png)

Queueの定義が作成できました。
![4-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/0e0d1eba-54b3-d151-f617-75c3ff77ef72.png)

「一意の参照」は**キューへのデータ投入時に、同じデータを重複して投入しない機構**でしたね。
「自動リトライ」と「最大リトライ回数」は、蛇足でちょっと書いた **アプリ例外発生時に再実行をさせるか** どうかで、一回だけ再実行するという設定です。今回のハンズオンでは、機能の確認は省略します。。


### Studioでデータ投入用のプロジェクトを作成します(Gitから取得します)

コードをGitHubから取得します。リポジトリURLだけが異なるので、サクサクいきましょう。

Studioを起動して「チーム」をクリック
![2-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/bb6f856d-4db8-c1d3-e0e0-a30bcad1e574.png)

「リポジトリを複製」 をクリック
![2-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/f6288fa1-02f9-5daa-949f-3a67e5fcadfe.png)


リポジトリURLに **https://github.com/masatomix/UiPath-OC-Hands-on2_PutQueue.git** と入れて「開く」をクリックします。
![4-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/2493e604-d916-b688-89a7-74305b0a422c.png)

プロジェクトをダウンロードすることができました。プロジェクトは**簡略化のため Attended Frameworkを使っています**。
メインの処理を記述する ``Process.xaml`` にサンプルを記述済みなので、開いてみてください。
![4-051.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/ee5245ab-1305-9daf-1eff-135cba77d825.png)


メールサーバからメールをとってくる処理が書いてあります。メールサーバの情報などはすでにコードに記載済みなので、なにもしなくても動くはずです。

> 2020/05/17追記:
> メールサーバはハンズオン用にこちらで用意したのですが、そろそろこのメールサーバは使えないようにしてしまいます。なので他のメールサーバ(Gmailですが)
> に変更する手順を記事にしましたので、こちらを見ながら適宜設定を行ってください。
> [UiPath のメールアクティビティ用に Gmail を設定する](https://qiita.com/masatomix/items/2f201a8b71971a6b35fa) 
>
> お手間をかけますがよろしくお願いします
> 
> 2020/08/25追記:
> 今現在、メールサーバはハンズオンPart3向けに再び公開していますが、メールボックスがPart3向けになっているため、
> 結果の件数や処理結果が異なると思います。
> いちおう、認識おきください。
>
> お手間をかけますがよろしくお願いします
> 
> 2021/03/09追記:
> 再度、非公開にしました。
> お手間をかけますがよろしくお願いします
>
> 追記 以上


- メールを複数件受信したのち
- 繰り返し処理で「キューアイテムを追加」アクティビティで、キューにメールデータを投入しています。

例外処理もありますが説明は割愛します。。
![4-052.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/ed0cbb0d-6ed7-7e3d-f945-95229ae0f15c.png)

「キューアイテムを追加」アクティビティのプロパティは以下の感じです。
![4-053.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/74b4bf99-528c-1ccd-3aff-8307fa3d5ae3.png)

- キュー名:
    - ``in_Config("xxxx")``と変数になっていますが、設定ファイル(``Data/Config.xlsx``)に記載されていて、結果的に先ほどOC上で作成した「``mailQueue``」となります。
- 参照: 
    - 「一意の参照」で用いるプロパティです。**キューのデータを一意に定めるための値を指定する必要があり** 今回はメール1通をキューのデータとして投入するので、メールの「Message-Id」を指定しました。
    - 「一意の参照」を有効にしている場合は、**この参照が同じであるデータを投入すると、OC側で「重複してるよ」っていうエラーを返す**ようになります。

**メールって不定期に届くので、定期的にごそっと受信してとりあえず投入しておけば、前回投入済みのデータはOCが勝手にはじいてくれる** わけですね。とっても便利です。


さて、プロパティの「アイテム情報」をクリックすると、下記のように**キューに投入する実際のデータを記述/確認** できます。``message``変数は繰り返しの各要素(``MailMessage``型) なので、ようするにメールデータです。そこからアドレスやメールの件名、本文などを取り出して、セットしています。
![4-054.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/e2d0d781-4c16-9a0e-72c2-0b2ba0f60c79.png)


### Studioから、データを投入するワークフローを実行します → OC画面で確認

では、キューへのデータ投入ワークフローを実行してみましょう。
上部リボンメニューの「実行」をクリックしてください。``Main.xaml`` が実行されると思います。(「ファイルを実行」を選ぶとたぶん ``Process.xaml``が実行されちゃうのでご注意)
![4-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/6c8a467e-6ba1-4fd9-29bc-6e68115a5086.png)

なんだか、実行されているようです。
![4-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/10c8284f-3b28-2525-4a15-dfd800813beb.png)

時間があるかたは、もう一度ワークフローを実行してみてください。**同じデータを投入することになるため、こんどは重複エラーではじかれる**のがわかると思います。
![4-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/325b3ffa-e194-de5b-3a2d-497551534f66.png)


さて、OC画面を開いてキューに投入されたデータをみてみましょう。下記の画面で残り件数が「6件」になってるのがわかります。また右の点々ボタンから「トランザクションを表示」を選ぶと
![4-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/66307d84-4174-622a-d857-23cce778d5b6.png)

下記の通り、投入したデータが一覧されます。さらに一つを選んで「詳細を表示」してみます
![4-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/e9e66e27-be02-dcdc-6f66-9aa703424179.png)


下記の通り、詳細を確認することができます。「固有データ」には、さきほどStudioで「アイテム情報」にて確認した項目名のデータたちが格納されているのがわかると思います。
![4-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/7f125919-7bb4-dd4e-3690-bf9b2c368759.png)


結果的に、各メールメッセージから、下記のような6件のデータがキューに投入されたということですね。
![excel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/bac9bc02-2b04-2223-fe85-0b0a098a2922.png)



キューへのデータ投入ハンズオンは、以上です。


### Studioでデータ取得用のプロジェクトを作成します(Gitから取得します)

つづいてキューからデータを取得してみます。Studioを起動して「チーム」をクリック
![2-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/bb6f856d-4db8-c1d3-e0e0-a30bcad1e574.png)

「リポジトリを複製」 をクリック
![2-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/f6288fa1-02f9-5daa-949f-3a67e5fcadfe.png)


リポジトリURLに **https://github.com/masatomix/UiPath-OC-Hands-on2_GetQueue.git** と入れて「開く」をクリックします。
![4-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/9f5557d9-8708-e784-3049-98cc819e1ac8.png)

プロジェクトをダウンロードすることができました。プロジェクトは簡略化のため RE Frameworkを使っています。
RE Framework は、

- キューから一つデータを取り出して
- ``Process.xaml`` を呼び出す
- ``Process.xaml`` の実行結果(正常終了か、何例外かなど) によって、トランザクションのステータスを適切に設定する

を、**キューにデータがあるだけ勝手に繰り返してくれるフレームワーク**です。
繰り返し処理や、リトライ処理をコーディングする必要がなくて便利なので、今回はコレを使います。
RE Frameworkは全体を理解するのは多少難しいかもしれませんが、上記を理解できていればとりあえず使うことはできると思います。

さてメインの処理を記述する ``Process.xaml`` にはサンプルを記述済みなので、開いてみてください。
![4-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/72771911-dd32-8896-6cbc-0ca055eac73b.png)

サンプルは、フレームワークがキューから取得しておいてくれたデータを取り出して、画面に表示するだけの単純なものです。

> ちょっと詳細。
> この  ``Process.xaml`` が
> - 正常終了した → フレームワークはトランザクションステータスを「成功」とする
> - ``BusinessRuleException``をスローした → フレームワークはトランザクションステータスを「失敗(ビジネス例外)」とする
> - それ以外の例外をスローした → フレームワークはトランザクションステータスを「失敗(アプリ例外)」とする
>
> にします。キューの定義によっては「失敗(アプリ例外)」 となったデータはキューに再投入され、リトライをしてくれます。

参考:

- [ちなみにRE Framework はザックリこんな感じ](https://qiita.com/masatomix/items/35812af3aa97d42de9b4#%E3%81%A1%E3%81%AA%E3%81%BF%E3%81%ABre-framework-%E3%81%AF%E3%82%B6%E3%83%83%E3%82%AF%E3%83%AA%E3%81%93%E3%82%93%E3%81%AA%E6%84%9F%E3%81%98)
- [Orchestrator API のサンプルコード](https://github.com/masatomix/uipath-orchestrator-api-node/tree/develop/src/samples/queueOperation)


### Studioから、データを取得するワークフローを実行します → OC画面で確認

さてデータを取得するワークフローを実行してみます。
上部リボンメニューの「実行」をクリックしてください。``Main.xaml`` が実行されると思います。(「ファイルを実行」を選ぶとたぶん ``Process.xaml``が実行されちゃうのでご注意)
![4-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/9e11b83a-76cc-29b1-1d60-c5c198f382f8.png)

キューにある分、繰り返し処理が実行されてますね！
![4-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/357a14c6-e660-07b8-4c0a-26d3468e16c9.png)

さて再度OC画面を開いて、キューに投入されたデータをみてみましょう。先と同様に「トランザクションを表示」を選ぶと、投入したデータたちのステータスが「成功」になっていますね。
![4-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73777/cb415a75-08df-ffa6-95c4-eb7517c74fed.png)


ハンズオンでは割愛しますが、理解のために``Process.xaml`` でわざと ``BusinessRuleException`` をスローさせたり、それ以外の例外をスローさせたりして、キューがどのような状態になるかを確認してみてください。

キューに関するハンズオンは以上になります。


## まとめ

- Orchestratorのアセット機能を使い方を学びました。
- Orchestratorをつかった、カスタムアクティビティの配布のやり方を学びました。
- Orchestratorのキューの機能を学びました。
    - キューへのデータ投入時、同一のデータを投入しない仕組みがあることを学びました。
    - キューからのデータ取得プロジェクトには、RE Frameworkを用いました。
    - RE Frameworkを使うと繰り返し処理を書かなくても、フレームワークがキューからデータをとってきてくれることがわかりました。
    - トランザクションのステータスを扱うことによって、処理の再ランなどが可能ですが、本ハンズオンでは割愛しました。
    - またRE Frameworkをつかうとステータス管理も自動化されるのですが、そのあたりも本ハンズオンでは割愛しました。


Orchestratorを導入することで利用可能になる機能についてご紹介とハンズオンを行いましたが、いかがでしたでしょうか？
キューの再ランやRE Framework 周りをもう少しやりたかった気もしますが、次回以降のハンズオンにしてみようかと思います。

また Orchestrator は、ほとんどのOC画面での操作をRESTのAPIで行うことが可能になっています。じつはそのAPIを便利に使うための[JavaScriptのライブラリ](https://www.npmjs.com/package/uipath-orchestrator-api-node)を開発しているのですが、機会があればそちらもご紹介したいと思います。



## 謝辞

今回の件でご協力いただいた UiPath Friendsの運営メンバーの方、またもちろん参加してくださった方々に感謝いたします。
ハンズオンをオンラインで開催する初の試みでしたが、いかがだったでしょうか。
2020/05のこの状況下でオンラインによる開催となりましたが、もしかしたら東京から離れた方なども参加できてメリットもあったかもしれません。

今後もいろいろなやり方で、UiPath 界隈を盛り上げていこうと思いますのでよろしくお願いします！

以上、おつかれさまでしたー。。。


## 関連リンク

- サンプルコード
    - [アセットを取得するサンプルプロジェクト](https://github.com/masatomix/UiPath-OC-Hands-on2)
    - [カスタムアクティビティを作成するサンプルプロジェクト](https://github.com/masatomix/UiPath-OC-Hands-on2_library)
    - [キューにデータを投入するサンプルプロジェクト](https://github.com/masatomix/UiPath-OC-Hands-on2_PutQueue)
    - [キューからデータを取得するサンプルプロジェクト](https://github.com/masatomix/UiPath-OC-Hands-on2_GetQueue)
- RE Frameworkとキュー操作を理解するための参考
    - [ちなみにRE Framework はザックリこんな感じ](https://qiita.com/masatomix/items/35812af3aa97d42de9b4#%E3%81%A1%E3%81%AA%E3%81%BF%E3%81%ABre-framework-%E3%81%AF%E3%82%B6%E3%83%83%E3%82%AF%E3%83%AA%E3%81%93%E3%82%93%E3%81%AA%E6%84%9F%E3%81%98)
    - [Orchestrator API のサンプルコード](https://github.com/masatomix/uipath-orchestrator-api-node/tree/develop/src/samples/queueOperation)
- [ワークフローで使用するパスワードの暗号化方法](https://www.uipath.com/ja/resources/knowledge-base/%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%81%A7%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%81%AE%E6%9A%97%E5%8F%B7%E5%8C%96%E6%96%B9%E6%B3%95) アセットの参考に
- [UiPath Orchestrator Community Edition へのサインアップからHelloWorldまで。(UiPath Friends 東京 Orchestratorハンズオン勉強会向け資料)](https://qiita.com/masatomix/items/096de223e05511a1166c) 前回記事
- [uipath-orchestrator-api-node](https://www.npmjs.com/package/uipath-orchestrator-api-node) まとめでご紹介した、Orchestrator API のJavaScript Wrapper