GMO サイン: 封筒署名依頼

GMO サイン: 封筒署名依頼

GMO Sign: Send Sign Request

この工程は GMO サイン に登録された封筒用文書ファイルを含む封筒の署名依頼を送付します。

Auto Step icon
Configs for this Auto Step
conf_OAuth2
C1: シークレットキー *
cusId
C2: 顧客ID *#{EL}
accessUrl
C3: アクセス先URL(例 api.gmosign.com) *#{EL}
documentCode
C4: ドキュメントコード が保存されている文字型データ項目 *
envelopeName
C5: 封筒名 が保存されている文字型データ項目 *
documentName
C6: ドキュメント名 が保存されている文字型データ項目 *
signerName
C7: 署名者名 が保存されている文字型データ項目 (複数設定する場合、1件ごとに改行してください) *
signerEmail
C8: 署名者アドレス が保存されている文字型データ項目 (1件ごとに改行してください) *
signingPoint
C9: 署名位置 x座標(左),y座標(下),x座標(右),y座標(上),ページ (パーセント指定、1件ごとに改行してください)#{EL}
envelopeXid
C10: 封筒トランザクションID を保存する文字型データ項目 *
Script (click to open)


/*
JSON例

・アクセストークン生成 AccessToken_Generate_Post
{
  "secret_key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "cus_id": "XXXXXXXXXX"
}

・封筒署名依頼 Envelope_SendRequest_Post
{
  "secret_key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "cus_id": "XXXXXXXXXX",
  "access_token": "(取得したトークン)",
  "envelope_name": "(configから、表示あり)",

"document_list": [
  {
  "document_code": "(文書登録で取得した値)",
  "document_name": "(configから、表示あり)"
  }
],

"partner_signer_list": [
  {
  "order_no": "(configの指定数から)",
  "sign_type": "1",(立会人で固定)
  "name": "(configから、表示あり)",
  "email": "(configから)",
  "is_send_mail": "1",(メールありで固定)

  "document_list": [
    {
    "document_code": "(文書登録で取得した値)",
    "request_type": "1",(署名で固定)

    "signing_points": [
      {
      "signing_point_start_x": "(configから)",
      "signing_point_start_y": "(configから)",
      "signing_point_end_x": "(configから)",
      "signing_point_end_y": "(configから)",
      "page_no": "(configから)"
      }
    ]

    }
  ]

  }
]

}
*/


main();

function main() {

    //// == 工程コンフィグの参照 / Config Retrieving ==
    //シークレットキーはHTTP認証設定のトークン直接指定に入れてもらう
    const key = configs.getObject("conf_OAuth2").getToken();
    const cusId = configs.get("cusId");
    const accessUrl = configs.get("accessUrl") + "";

    const dataId_envelopeXid = configs.get("envelopeXid");

    //// == ワークフローデータの参照 / Data Retrieving ==
    const documentCode = engine.findData(configs.getObject("documentCode")) + "";
    const envelopeName = engine.findData(configs.getObject("envelopeName")) + "";
    const documentName = engine.findData(configs.getObject("documentName")) + "";
    const signerNamesArray = retrieveFilledArray('signerName', 'Signer Name');
    const signerEmailsArray = retrieveFilledArray('signerEmail', 'Signer Email');
    const signingPointsArray = retrieveFilledArray2('signingPoint', 'Signing Point');
    
    // 件数チェック
    if (signerNamesArray === null || signerNamesArray.length === 0) {
        throw `No Signer Name.`;
    }
    if (signerEmailsArray === null || signerEmailsArray.length === 0) {
        throw `No Signer Email.`;
    }
    //サイン位置指定なし(不可視署名を考慮)サイン位置の数はチェックしない

/* 署名者の最大数の情報はなかったのでチェックしない、ちなみに署名順は999までいける
    if (signerNamesArray.length > MAX_SIGNER_NUM) {
        throw `Number of Email Addresses exceeds the limit. The maximum number is ${MAX_SIGNER_NUM}.`;
    }
*/

    // 件数一致チェック
    if (signerNamesArray.length !== signerEmailsArray.length) {
        throw `Number of Signer Emails does not match the number of Signer Names.`;
    }
    //サイン位置指定なし(不可視署名を考慮して)サイン位置の数との一致チェックはしない

    //// == 演算 / Calculating ==

    //アクセストークン取得
    let accessToken = getAccessToken(key, cusId, accessUrl);

    //署名依頼
    let envelopeXid = sendRequest(key, cusId, accessUrl, accessToken, documentCode, envelopeName, documentName, signerNamesArray, signerEmailsArray, signingPointsArray);


    //// == ワークフローデータへの代入 / Data Updating ==
    engine.setDataByNumber( dataId_envelopeXid, envelopeXid );


/* アクセスログがあれば
    if ( dataId_log !== "" ) {
        engine.setDataByNumber( dataId_log, accessLog );
    }
*/

}


/**
  * config から複数行のデータを読み出し、配列を生成する(configで文字型を指定するケース)
  * データ項目が設定されていない場合は null を返す
  * データ項目が設定されていて、中身が空の場合はエラー
  * 空行を含む場合はエラー (最後に空行がひとつだけある場合は無視)
  * @param {String} confName config 名
  * @param {String} label エラー出力に使用するラベル
  * @return {Array<String>} array 空文字列を含まない配列
  */
function retrieveFilledArray(confName, label) {
    const dataDef = configs.getObject(confName);
    if (dataDef === null) { // データ項目が設定されていない
        return null;
    }
    const string = engine.findData(dataDef);
    if (string === null || string === '') { // データ項目の中身が空
        throw `Data item for ${label} is set but its content is empty.`;
    }

    const array = string.split('\n');
    if (array[array.length - 1] === '') { // 最後に空行があれば削除
        array.pop();
    }
    // 空行が残っている場合はエラー
    const i = array.indexOf('');
    if (i !== -1) {
        throw `${label} at line ${i+1} is blank.`;
    }
    return array;
}

/**
  * config から複数行のデータを読み出し、配列を生成する(configで直接入力のケース、空行を含む場合あり)
  * @param {String} confName config 名
  * @param {String} label エラー出力に使用するラベル
  * @return {Array<String>} array 配列
  */
function retrieveFilledArray2(confName, label) {
    const string = configs.get(confName);
    if (string === null || string === '') { // データ項目の中身が空
        return null;
    }

    const array = string.split('\n');
/* (不可視署名を考慮して)サイン位置なしを許容、空行をそのままにする
    if (array[array.length - 1] === '') { // 最後に空行があれば削除
        array.pop();
    }

    // 空行が残っている場合はエラー
    const i = array.indexOf('');
    if (i !== -1) {
        throw `${label} at line ${i+1} is blank.`;
    }
*/
    return array;
}


/**
  * アクセストークン取得
  * @param {String} key  シークレットキー
  * @param {String} cusId  顧客ID
  * @param {String} accessUrl  接続先URL
  * @returns {String} アクセストークン
  */
function getAccessToken(key, cusId, accessUrl) {

    //JSON準備
    let requestObj = {};
    requestObj.secret_key = key;
    requestObj.cus_id = cusId;


    //HTTPリクエスト送付
    const url = "https://" + accessUrl + "/agree-api/v0/api/accesstoken/generate";
    const response = httpClient.begin()
        .body( JSON.stringify(requestObj), "application/json" )
        .post(url);
    const status = response.getStatusCode();
    const responseStr = response.getResponseAsString();
    if (status !== 200) {
        engine.log(responseStr);
        throw `Failed to get access token. status: ${status}`;
    }

    engine.log("responseStr:" + responseStr);//検証用
    const json = JSON.parse(responseStr);
    if ( json['status'] !== "0") {
        throw `Failed to get acess token. status: ${json['status']}. message: ${json['message']}`;
    }
    return json['result']['access_token'];
}


/**
  * 署名依頼
  * @param {String} key  シークレットキー
  * @param {String} cusId  顧客ID
  * @param {String} accessUrl  接続先URL
  * @param {String} accessToken  アクセストークン
  * @param {String} documentCode  文書コード
  * @param {String} envelopeName  封筒名
  * @param {String} documentName  文書名
  * @param {String} signerNamesArray  署名者名
  * @param {String} signerEmailsArray  署名者メールアドレス
  * @param {String} signingPointsArray  署名位置
  * @returns {String} 封筒トランザクションID
  */
function sendRequest(key, cusId, accessUrl, accessToken, documentCode, envelopeName, documentName, signerNamesArray, signerEmailsArray, signingPointsArray) {

    //JSON準備
    let requestObj = {};
    requestObj.secret_key = key;
    requestObj.cus_id = cusId;
    requestObj.access_token = accessToken;
    requestObj.envelope_name = envelopeName;

    let documentListArray = [];
    let documentListObj = {};
    documentListObj.document_code = documentCode;
    documentListObj.document_name = documentName;
    documentListArray[0] = documentListObj;
    requestObj.document_list = documentListArray;

    let partnerSignerListArray = [];

    for (let i = 0; i < signerNamesArray.length; i++) {
        let partnerSignerListObj = {};
        partnerSignerListObj.order_no = i+1;//文字でなく数値で問題なし
        partnerSignerListObj.sign_type = "1";
        partnerSignerListObj.name = signerNamesArray[i];
        partnerSignerListObj.email = signerEmailsArray[i];
        partnerSignerListObj.is_send_mail = "1";

        let pslDocumentListArray = [];
        let pslDocumentListObj = {};
        pslDocumentListObj.document_code = documentCode;
        pslDocumentListObj.request_type = "1";

        //サイン位置指定がある場合のみ
        if (signingPointsArray) {
            let signingPointArray = signingPointsArray[i].split(",");
            //位置指定のパラメータ数が正しいか
            if (signingPointArray.length == 5) {
                let pslSigningPointsListArray = [];
                let pslSigningPointsListObj = {};
                pslSigningPointsListObj.signing_point_start_x = signingPointArray[0];
                pslSigningPointsListObj.signing_point_start_y = signingPointArray[1];
                pslSigningPointsListObj.signing_point_end_x = signingPointArray[2];
                pslSigningPointsListObj.signing_point_end_y = signingPointArray[3];
                pslSigningPointsListObj.page_no = signingPointArray[4];

                pslSigningPointsListArray[0] = pslSigningPointsListObj;
                pslDocumentListObj.signing_points = pslSigningPointsListArray;
            } else {
                throw `Signing Point ${i+1} Num invalid.`;
            }
        }

        pslDocumentListArray[0] = pslDocumentListObj;
        partnerSignerListObj.document_list = pslDocumentListArray;
        partnerSignerListArray[i] = partnerSignerListObj;
    }

    requestObj.partner_signer_list = partnerSignerListArray;

    engine.log("requestObj:" + JSON.stringify(requestObj));//検証用


    //HTTPリクエスト送付
    const url = "https://" + accessUrl + "/agree-api/v0/api/envelope/sendRequest";
    const response = httpClient.begin()
        .body( JSON.stringify(requestObj), "application/json" )
        .post(url);
    const status = response.getStatusCode();
    const responseStr = response.getResponseAsString();
    if (status !== 200) {
        engine.log(responseStr);
        throw `Failed to regist file. status: ${status}`;
    }

    engine.log("responseStr:" + responseStr);//検証用
    const json = JSON.parse(responseStr);
    if ( json['status'] !== "0") {
        throw `Failed to send request. status: ${json['status']}. message: ${json['message']}`;
    }
    return json['result']['envelope_xid'];
}

  
    

Download

warning 自由改変可能な JavaScript (ECMAScript) コードです。いかなる保証もありません。
(アドオン自動工程のインストールは Professional editionでのみ可能です)

Notes

Capture

See Also

上部へスクロール

Questetra Supportをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む