forcedotcom / postman-salesforce-apis

Salesforce API Postman Collection
Creative Commons Zero v1.0 Universal
1.06k stars 638 forks source link

Template Environment doesn't match the SFMC pre-request script #64

Closed tuck1s closed 1 year ago

tuck1s commented 1 year ago

The SFMC pre-request script expects variables named

The "Salesforce APIs Template Environment" does not have placeholders for these, instead it uses clientId, clientSecret etc.

The token refresh logic in the pre-request script also has a bug. dne_tokenRefreshTime is set whether or not the token request succeeded, so the subsequent requests don't bother trying for a token.

Suggested update:

/* Begin Usage Tracking */
pm.sendRequest('www.google-analytics.com/collect?v=1&tid=UA-114173005-2&cid=1&t=pageview&dh=mcexperts.ninja&dp=/projects/postman/collection/run&dt=PostmanEnhancedCollectionRun');
/* End Usage Tracking */

/* Begin Token Refresh Logic */
const context = pm.environment.name ? pm.environment : pm.collectionVariables;

const tokenRefreshTime = context.get("dne_tokenRefreshTime") || 0;
console.log("token refresh time: " + tokenRefreshTime);

const tokenAge = Math.round((((Date.now() - tokenRefreshTime) % 86400000) % 3600000) / 60000);
if (tokenRefreshTime != 0 && tokenAge < 18) {
    console.log("token valid");
} else {
    console.log("refreshing token...");
    const authRequest = {
        url: 'https://' + context.get("et_subdomain") + '.auth.marketingcloudapis.com/v2/token',
        method: 'POST',
        header: 'Content-Type:application/json',
        body: JSON.stringify({
            "grant_type": "client_credentials",
            "client_id": context.get("et_clientId"),
            "client_secret": context.get("et_clientSecret"),
            "account_id": context.get("et_mid")
        })
    };

    pm.sendRequest(authRequest, (err, res) => {
        console.log(err ? err : res.json());
        if (err === null) {
            const responseJson = res.json();
            if (responseJson.error) {
                console.log('No token today');
            } else {
                context.set('dne_etAccessToken', responseJson.access_token);
                context.set("dne_tokenRefreshTime", Date.now());
                console.log("Success: token refresh");
            }
        } else {
            console.error("Failed: token refresh");
        }
    });
}
/* End Token Refresh Logic */
pozil commented 1 year ago

Hi @tuck1s, this is a bug for the Commerce Cloud collection repository, not the Platform collection (this repository). I'll ping the collection's owner.

tuck1s commented 1 year ago

Thanks! Will close this issue now. FWIW I found Redis (with its automatic capability to give any stored values a time-to-live) is a nice way to handle expiry, in actual code (not Postman).