GMO Sign: Send Sign Request

GMO Sign: Send Sign Request

GMO サイン: 封筒署名依頼

This item sends an envelope signature request to GMO Sign.

Auto Step icon
Configs for this Auto Step
conf_OAuth2
C1: Secret Key *
cusId
C2: Customer id *#{EL}
accessUrl
C3: Access url *#{EL}
documentCode
C4: Document code *
envelopeName
C5: Emvelope name *
documentName
C6: Document name *
signerName
C7: Signer namet (Write one per line) *
signerEmail
C8: Signer email addresst (Write one per line) *
signingPoint
C9: Signing point left,bottom,right,top,page(Write one per line)#{EL}
envelopeXid
C10: Envelope transaction 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 === '') { // データ項目の中身が空
        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;
}


/**
  * アクセストークン取得
  * @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[i]) {
//if (signingPointsArray[i].indexOf(",") > -1) {
        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 Freely modifiable JavaScript (ECMAScript) code. No warranty of any kind.
(Installing Addon Auto-Steps are available only on the Professional edition.)

Notes

  • GMO Sign is a service provided by GMO GlobalSign Holdings, Inc.
  • To use GMO Sign for electronic signatures, you need to use a combination of [GMO Sign: Register Envelope Document], [GMO Sign: Send Sign Request] and [GMO Sign: Retrieve Envelope Status].
  • For “Secret Key”, “Customer ID”, and “Access URL”, please specify the values ​​provided by GMO GlobalSign Holdings, Inc. For “Secret Key”, please specify “Token Fixed Value” in the HTTP Authorization Settings.

Capture

See Also

Scroll to Top

Discover more from Questetra Support

Subscribe now to keep reading and get access to the full archive.

Continue reading