【ServiceNow×DocuSign】DocuSignでのフローの進行状況を取得する

以前ServiceNowからDocuSignへの連携方法を記事にしました。

https://qiita.com/sakuma-iho/items/c0b3ca3c849ac3ec9d31

https://qiita.com/sakuma-iho/items/0c2be28dacf138f56327

上記2つの方法ではServiceNowからDocuSignへ渡った後の進行状況がServiceNowから確認できません。

本記事ではDocuSign上でのフローの進行状況をServiceNowからでも確認できるような設定方法をご紹介します。

## 連携時の動き

連携時の動作概要は以下のとおりです。
① DocuSign上で承認を行う
② DocuSignからエンベロープの更新情報をServiceNowへリアルタイムで送信
③ ServiceNowのレコードに取得結果を反映し、WFのノードを進める

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/ae8f3756-4ef4-de4c-f3bd-993e4be38597.png)

## 使用する機能
今回使用する機能は以下です。
図中の番号順に設定方法を解説します。
<img width="800" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/88aa5e06-30f4-27eb-dd21-342651c03ddb.png">

※1. Scripted REST API
外部システムから受信したリクエストを加工する機能です。
使用方法について書きにまとめているのでぜひご参照ください。

https://qiita.com/sota-suzuki/items/499fa09d8e88761671ae

## 事前準備
使用する機能をご紹介しましたが、その前にServiceNow/DocuSign双方で事前準備を行います。

### 1.　リクエストアイテムとエンベロープのキーを設定
ServiceNowのリクエストアイテムレコードに紐づくDocuSignのエンベロープを特定できるよう、それぞれに共通の値を持たせます。

今回はリクエストアイテムNoをエンベロープの「shinseiNo」という項目にセットしたいと思います。

DocuSignのテンプレートに「shinseiNo」に値をセットするように指定します。
　※エンベロープをPower Formから作成する場合：onSubmit
　　REST APIから作成する場合：リクエストボディ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/8e15efae-6693-37f7-8643-5fe7dc3cc0ab.png)

### 2.　受信者ごとのステータス格納先を作成（ServiceNow）
DocuSignから取得するデータ（Webhook）にはエンベロープの受信者ごとのステータスが含まれています。

そのためServiceNow側にそれら（受信者ごとのステータス）を保持する体制を作ります。

今回はリクエストアイテムに紐づく変数にステータスを保持するようにします。
作成イメージは以下です。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/a360b6fe-757d-d18c-20f4-67770e0fe1ac.png">
DocuSignからステータスを取得する都度、上記の変数の値を更新します。

### 3．エンベロープの更新情報を送信するよう設定（DocuSign）
DocuSignはただエンベロープを作成したり更新したりするだけでは、外部システムにリクエストを送信しません。

事前に設定をすることで特定のタイミングで特定のシステムへリクエストを送信してくれるようになります。

設定方法はエンベロープをPower Formから作成するのか、REST APIから作成するのかで異なります。

### Power Formからエンベロープを作成する場合

DocuSign Connectというサービスを使用します。

https://support.docusign.com/s/document-item?language=ja&rsc_301&bundleId=pik1583277475390&topicId=ctv1583277395112.html&_LANG=jajp

DocuSign Connectを設定するとアカウント（環境）に作成された全てのエンベロープの更新情報をリアルタイムで外部へ送信してくれます。

※PowerFormで作成したエンベロープには「特定のPowerFormで作成したエンベロープだけの更新情報を送信する」という設定ができません。

詳しい設定方法は本記事「➁DocuSign Connect（DocuSign）」で説明します。

### REST APIからエンベロープを作成する場合

REST APIを実行する際にリクエストボディに外部システムへエンベロープの更新情報を送信するよう設定します。

リクエストボディのサンプルを以下に記載します。

下記記事でご紹介したリクエストボディを組み合わせて使用します。

https://qiita.com/sakuma-iho/items/0c2be28dacf138f56327

※REST API関する詳細はAPI Referenceをご参照ください。

https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopes/create/



```json:リクエストボディ.json
{
"eventNotification": {
    "includeHMAC": "true",　※1
    "envelopeEvents": [
       {
        "envelopeEventStatusCode": "Delivered"　※2
      },
      {
        "envelopeEventStatusCode": "Completed"　※2
      }
    ],
    "url": "https://～～～～",　※3
    "eventData": {
      "format": "json",
      "includeData": [　※4
        "recipients"
      ],
      "version": "restv2.1"
    },
    "loggingEnabled": "true"
  },
```
**※1. includeHMAC**
trueにすることでリクエストヘッダーにハッシュ値が含まれます。
受信側システム（ServiceNow）はこのハッシュ値とDocuSignで発行されるキーを使用することでメッセージの信頼性を検証できます。

**※2. envelopeEventStatusCode**
外部システムへ更新情報を送信するタイミングを指定します。
複数のタイミングで送信したい場合は、その数だけ{}も含めて記載します。
サンプルJSONはエンベロープを送信した時と完了した時の2回送信します。

**※3. url**
リクエストの送信先URLを記載します。
今回はScripted REST APIsで作成したURLを指定します。
例) https://インスタンス名.service-now.com/ベースAPIパス

**※4. includeData**
リクエストボディに含めるデータを指定します。
今回は受信者ごとのステータスが欲しいので「recipients」を指定します。

以上で事前準備の完了です。

## ①Scripted REST APIs （ServiceNow）
DocuSignからのリクエストを受け取り、その内容をテーブルに反映する処理を行います。

### Scripted REST APIs（親）
【操作方法】
1．システムWebサービス >>　Scripted REST APIs　をクリックし、新規作成画面を起動する。
2．[名前]と[API ID]に任意の文字列を入力し、[保存]をクリックする。
3．[セキュリティ：デフォルトACL]の選択を解除し、[更新]をクリックする。
4．[リソース：新規]をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/700449cc-cfde-5a2c-cbd4-d3a80151b9c0.png)


### Scripted REST APIs（子）
【操作方法】
1．入力値は以下のとおり。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/01f4d428-e89c-130f-44f4-59e2f991077d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/54188ac0-f6eb-420e-e15b-36395e48121a.png)

[タイプ]に入力するスクリプトのサンプルは以下です。
取得したリクエストから受信者ごとのステータスを抽出するところまでを記載します。

```javascript:Scripted REST API
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
 //HMACを使用してWebhookメッセージの検証
    //bodyの値
    var bodyAll =request.body.data;

    //Headerの値
    var headers =JSON.stringify(request.headers);

    //DocuSignで作成した秘密鍵と、取得したbodyを使用してハッシュ値を作成する
    var mac = new GlideCertificateEncryption;
    var key = 'Docusignで作成する秘密鍵';
    key = GlideStringUtil.base64Encode(key);
    var payload = JSON.stringify(bodyAll);
    var hash = mac.generateMac(key, "HmacSHA256", payload);

    //HMAC署名の確認	
    if(headers.indexOf(hash) !== -1){

        //エンベロープIDを変数にセット
        var envelopeId = JSON.stringify(bodyAll.envelopeId);

        //署名者情報を変数にセット
        var signersStatus = bodyAll.recipients.signers;

        //受信者ごとのステータスと申請番号を取得する
        var statuslist = [];
        var fieldList = [];

        for (var i=0; i< signersStatus.length; i++) {		
		
            //署名者ごとのステータスを連想配列に格納する
            var roleStatus = {};
            roleStatus.name = signersStatus[i].roleName.toString();
            roleStatus.status = signersStatus[i].status.toString();
            statuslist.push(roleStatus);	
		
            //申請番号の取得	
            //DocuSignの入力フィールドに格納されている値を変数にセット
            var tabs = signersStatus[i].tabs.textTabs;	
		
            //各入力項目の値を連想配列に格納する
            for (var a=0; a< tabs.length; a++) {
                var textTabs = {};
                textTabs.tabLabel = tabs[a].tabLabel.toString();
                textTabs.value = tabs[a].value.toString();
                fieldList.push(textTabs);
            }
        }		

        //申請番号の値のみ取得する	
        var getShinseiNo;	
        var fieldLists = fieldList.filter(function(item, index){	
            if (item.tabLabel == 'shinseiNo') {
                getShinseiNo = item.value;
    		}
        }
    }		
			
	//署名者ごとのステータスをセット		
	var statuslists = statuslist.filter(function(item, index){
        if (item.name == '作成者') {	
			getsakuseisyaStatus = item.status;
        			
			}else if(item.name == '確認者'){	
    			kakuninsyaStatus = item.status;
						
			}else if(item.name == '発議者'){	
    			hatssugisyaStatus = item.status;
			
        	}else if(item.name == '決裁者'){	
    			kessaisyaStatus = item.status;
        	}	
    	}
    }
);			
```
以降、要求アイテムテーブルにエンベロープIDと各受信者のステータスをupdateする。


サンプルスクリプトの冒頭で行っている処理については別の記事にて解説しています。

https://qiita.com/sakuma-iho/items/b517cd261aadca85ca23

## ➁DocuSign Connect（DocuSign）
Power Formから作成したエンベロープの更新情報をServiceNowへ送信する設定を行います。

【操作方法】
1．DocuSign eSignatureの[設定]タブで、[インテグレーション] >> [DocuSign Connect] をクリックします。
2．[設定の追加] > [カスタム] をクリックします。
3．各項目を以下のように入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/0894ae04-80a5-acd3-a95d-9028afe06850.png)

## ③CONNECTキー（DocuSign）
REST APIから作成したエンベロープの更新情報をServiceNowへ送信する設定は、事前準備のエンベロープ作成時点で行っています。
DocuSignからのリクエストの信頼性をServiceNow上で検証するためにCONNECTキーの発行を行います。

【操作方法】
1．DocuSign eSignatureの[設定]タブで、[インテグレーション] >> [DocuSign Connect] をクリックします。
2．[CONNECTキー]タブをクリックします。
3．[秘密鍵の追加]をクリックします。
キーはServiceNowでの処理で使用するので控えておいてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/7d582fa3-3bdf-8896-ca63-bfccce995c44.png)

## ④ワークフローエディタ
ワークフローエディタには「条件待ち（Wait for condition）」というアクティビティがあります。
これはレコードが特定の条件を満たすとノードを進める、という機能を持ったアクティビティです。

今回はステータスを格納している変数の値が「complete」となった時、フローを進めるというように設定します。

【操作方法】
①Workflow　>>　ワークフローエディタ　をクリックする。
➁[新規ワークフロー]をクリックする。
③入力値は以下のとおり。
<img width="350" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/52e5deb4-aef1-1127-20c7-8392358ab338.png">
④画面右の[コア]タブから[条件待ち]アクティビティをドラッグする。
⑤入力値は以下のとおり。
<img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600769/d55e7aab-511d-4fb9-852a-1498e2f24578.png">

以上です。

## 終わりに
ServiceNow×DocuSignとして3パターンの連携方法をご紹介しました。
ServiceNowとDocuSignの良いとこどりをした連携で、企業活動のペーパーレス化に貢献できるのではと考え検証したものです。
ご興味のあるかたは是非参考にしてください。