Rest Message From scripted rest API

eyal abu hamad
Mega Sage

I have a rest message with OAuth token of third party vendor
when I try with the test button in the rest message it works fine
but when I try with the scripted rest api I got this
"errorCode":"AUTHORIZATION_INVALID_TOKEN","message":"The access token provided is expired, revoked or malformed."}

this is my script

(function process(request, response) {
  var J = new global.JSON();

  // --- get IDs from your payload (adapt as needed) ---
  var raw = (request.body && request.body.dataString) || "";
  var p = {};
  try { p = raw ? J.decode(raw) : {}; } catch(e){}
  var accountId  = (p.accountId  || p.data && p.data.accountId  || "").trim();
  var envelopeId = (p.envelopeId || p.data && p.data.envelopeId || "").trim();

  if (!accountId || !envelopeId) {
    gs.error("[DS] Missing accountId/envelopeId. accountId=" + accountId + " envelopeId=" + envelopeId);
    response.setStatus(400); return;
  }

  // ---- use your REST Message + Method ----
  var r = new sn_ws.RESTMessageV2('Docusign Auth', 'Get Envelope');

  // 🔒 1) FORCE the OAuth profile BY SYS_ID (no ambiguity across scopes)
  //    How to get it: open your OAuth Entity Profile record → right-click header → Copy sys_id
  var OAUTH_PROFILE_SYS_ID = 'bc873919875cb25040f210273cbb3582';
  r.setAuthenticationProfileId('oauth2', OAUTH_PROFILE_SYS_ID);

  // 2) Vars must match your method's variable names exactly
  r.setStringParameter('accountid',  accountId);
  r.setStringParameter('envelopeid', envelopeId);

  // 3) Helpful logs
  gs.info("[DS] Endpoint -> " + r.getEndpoint());

  var resp = r.execute();
  var code = resp.getStatusCode();
  var body = (resp.getBody() || "") + "";
  var errm = resp.getErrorMessage();

  gs.info("[DS] HTTP " + code + (errm ? (" | err=" + errm) : ""));
  gs.info("[DS] Body preview: " + body.substr(0, 1500));

  // 🔁 Fallback: if 401, manually fetch token from that SAME profile and retry once
  if (code === 401) {
    gs.info("[DS] 401 -> retry with manual Bearer from OAuth profile");
    var oauth = new sn_auth.GlideOAuthClient();
    var tok   = oauth.getTokenByProfileId(OAUTH_PROFILE_SYS_ID);
    var access = tok && tok.getAccessToken();
    if (!access) { gs.error("[DS] Could not fetch access token. Re-authorize profile (Get OAuth Token)."); response.setStatus(500); return; }

    var r2 = new sn_ws.RESTMessageV2('Docusign Auth', 'Get Envelope');
    r2.setStringParameter('accountid',  accountId);
    r2.setStringParameter('envelopeid', envelopeId);
    r2.setRequestHeader('Authorization', 'Bearer ' + access);

    gs.info("[DS] Endpoint (retry) -> " + r2.getEndpoint());
    var resp2 = r2.execute();
    gs.info("[DS] HTTP (retry) " + resp2.getStatusCode() + " | " + (resp2.getErrorMessage() || ""));
    gs.info("[DS] Body preview (retry): " + (resp2.getBody() || "").substr(0,1500));
  }

  response.setStatus(200);
})(request, response);
6 REPLIES 6

I created oAuth profile

eyalabuhamad_0-1759147341316.png

and linked it with the rest message

eyalabuhamad_1-1759147418452.png

 

@eyal abu hamad 

then simply use REST Message and don't give any OAuth profile etc as REST Message already has linked OAuth profile

try this once

(function process(request, response) {
    var J = new global.JSON();

    // --- get IDs from your payload (adapt as needed) ---
    var raw = (request.body && request.body.dataString) || "";
    var p = {};
    try {
        p = raw ? J.decode(raw) : {};
    } catch (e) {}
    var accountId = (p.accountId || p.data && p.data.accountId || "").trim();
    var envelopeId = (p.envelopeId || p.data && p.data.envelopeId || "").trim();

    if (!accountId || !envelopeId) {
        gs.error("[DS] Missing accountId/envelopeId. accountId=" + accountId + " envelopeId=" + envelopeId);
        response.setStatus(400);
        return;
    }

    // ---- use your REST Message + Method ----
    var r = new sn_ws.RESTMessageV2('Docusign Auth', 'Get Envelope');

    // 🔒 1) FORCE the OAuth profile BY SYS_ID (no ambiguity across scopes)
    //    How to get it: open your OAuth Entity Profile record → right-click header → Copy sys_id
    var OAUTH_PROFILE_SYS_ID = 'bc873919875cb25040f210273cbb3582';

    // 2) Vars must match your method's variable names exactly
    r.setStringParameter('accountid', accountId);
    r.setStringParameter('envelopeid', envelopeId);

    // 3) Helpful logs
    gs.info("[DS] Endpoint -> " + r.getEndpoint());

    var resp = r.execute();
    var code = resp.getStatusCode();
    var body = (resp.getBody() || "") + "";
    var errm = resp.getErrorMessage();

    gs.info("[DS] HTTP " + code + (errm ? (" | err=" + errm) : ""));
    gs.info("[DS] Body preview: " + body.substr(0, 1500));

    // 🔁 Fallback: if 401, manually fetch token from that SAME profile and retry once
    if (code === 401) {
        gs.info("[DS] 401 -> retry with manual Bearer from OAuth profile");
        var oauth = new sn_auth.GlideOAuthClient();
        var tok = oauth.getTokenByProfileId(OAUTH_PROFILE_SYS_ID);
        var access = tok && tok.getAccessToken();
        if (!access) {
            gs.error("[DS] Could not fetch access token. Re-authorize profile (Get OAuth Token).");
            response.setStatus(500);
            return;
        }

        var r2 = new sn_ws.RESTMessageV2('Docusign Auth', 'Get Envelope');
        r2.setStringParameter('accountid', accountId);
        r2.setStringParameter('envelopeid', envelopeId);
        r2.setRequestHeader('Authorization', 'Bearer ' + access);

        gs.info("[DS] Endpoint (retry) -> " + r2.getEndpoint());
        var resp2 = r2.execute();
        gs.info("[DS] HTTP (retry) " + resp2.getStatusCode() + " | " + (resp2.getErrorMessage() || ""));
        gs.info("[DS] Body preview (retry): " + (resp2.getBody() || "").substr(0, 1500));
    }

    response.setStatus(200);
})(request, response);

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader