# OAuth Refresh Token Job

We recommend customers using outbound OAuth use this scheduled job script to ensure outbound OAuth connections remain alive, as explained in [this KB Article](https://support.servicenow.com/kb?id=kb_article_view\&sysparm_article=KB0823628) from ServiceNow.

Without this job, the refresh token will eventually expire which means ServiceNow will no longer be able to retrieve an access token. This in turn will cause outbound requests to fail.&#x20;

If your OAuth service is including refresh tokens with each access token request, this job may not be required.

This script has been reformatted from the KB Article for ease of use.

```javascript
function refreshAccessToken(requestorId, oauthProfileId, token) {
    if (!(token && requestorId && oauthProfileId)) return;

    var tokenRequest = new sn_auth.GlideOAuthClientRequest();
    tokenRequest.setGrantType("refresh_token");
    tokenRequest.setRefreshToken(token.getRefreshToken());
    tokenRequest.setParameter('oauth_requestor_context','sys_rest_message');
    tokenRequest.setParameter('oauth_requestor', requestorId);
    tokenRequest.setParameter('oauth_provider_profile',oauthProfileId);

    var oAuthClient = new  sn_auth.GlideOAuthClient();
    var tokenResponse = oAuthClient.requestTokenByRequest(null,tokenRequest);
    var error = tokenResponse.getErrorMessage();
    if (error) gs.warn("Error:" + tokenResponse.getErrorMessage());
}

function isExpired(expiresIn, withinSeconds) {
    if (expiresIn > withinSeconds) return false;
    return true;
}


function getToken(requestorId, oauthProfileId) {
    if (!requestorId || !oauthProfileId) return null;
    var client = new sn_auth.GlideOAuthClient();
    return client.getToken(requestorId, oauthProfileId);
}

function checkAndRefreshAccessToken(grRestMessage) {
    if (grRestMessage.getValue("authentication_type") != "oauth2") return false;
    var accountMsg = grRestMessage.getValue("name");
    if (!accountMsg)
        accountMsg = grRestMessage.getUniqueValue();
    accountMsg = "Account=\"" + accountMsg + "\"";

    var token = getToken(grRestMessage.getUniqueValue(), grRestMessage.getValue('oauth2_profile'));
    var accessToken = token.getAccessToken();

    if (accessToken) {
        if (!isExpired(token.getExpiresIn(), 300)) return;
    }

    if (!token.getRefreshToken()) {
        gs.error("No OAuth refresh token for Rest Message. Manual reauthorization required. " + accountMsg);
        return;
    }

    if (isExpired(token.getRefreshTokenExpiresIn(), 0)) {
        gs.error("OAuth refresh token for Rest Message is expired. Manual reauthorization required. " + accountMsg);
        return;
    }

    gs.info("Refreshing oauth access token for Rest Message account. " + accountMsg);
    refreshAccessToken(grRestMessage.getUniqueValue(), grRestMessage.getValue('oauth2_profile'), token);
}

var grAccount = new GlideRecord("sys_rest_message");
grAccount.addQuery("authentication_type", "oauth2");
grAccount.addNotNullQuery("oauth2_profile");
grAccount.query();

while (grAccount.next()) {
    checkAndRefreshAccessToken(grAccount);
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sharelogic.com/unifi/4.3/configure/how-to-guides/how-to-setup-an-oauth-connection/oauth-refresh-token-job.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
