loginPKCEGrant, Browser auth - verify inputs

I'm using the following code to try and connect to the API, but I'm getting this error response:
Uncaught Reference Error: state is not defined

function ConnectToApi() {
const client = platformClient.ApiClient.instance;
const redirectUri = "https://apps.mypurecloud.com/api/v2/conversations/callbacks";
// Method1: Let loginPKCEGrant generate the code verifier
client.loginPKCEGrant(clientId, redirectUri, { state: state })
.then((data) => {
console.log(data);
// Do authenticated things
})
.catch((err) => {
// Handle failure response
console.log(err);
});
}

I couldn't find info on the redirectUri, so I figured it was what I used, but since the state isn't being overwritten, I assume that means that my Uri is wrong. Please let me know.

It's probably referring to this:

You have to provide your own value for state, or don't provide that option at all if your app doesn't need to use the state. Examples:

// Example using the current URI fragment for a SPA that uses fragment-based navigation
client.loginPKCEGrant(clientId, redirectUri, { state: window.location.hash })

// Example not using state
client.loginPKCEGrant(clientId, redirectUri)
1 Like

Oh, ok then.
So my Uri is valid, my understanding is correct?

Can we update the loginPKCE info to not that state is optional?

This is not an appropriate redirect URI. Nor is it an appropriate API endpoint. The redirect URI should be your app. When making an API request later on, you need to use one of the API servers: https://developer.genesys.cloud/platform/api/.

So like this?
image

If so, I'm getting this error and I know my client ID is correct.
image

No, that's the URI for the Genesys Cloud web UI. The redirect URI should be the URI of your application. That might be a localhost address if you're developing locally otherwise would be something on the hostname of the server that's hosting your page/application.

1 Like

Also, you'll get that error unless the redirect URI you send is exactly the one you configured on the oauth client. Create an OAuth client - Genesys Cloud Resource Center

1 Like

Thanks Tim,

For my redirect, I tried with both the local 127 and my external facing IP and both are in my OAuth settings

I'm developing locally on a non-hosted web file, an htm and js combo in a folder on my machine, so it makes sense for there to be a problem if I try to redirect to the local address, and my external IP doesn't provide routing.

Does there have to be a redirect? I'd rather just be able to execute without having to redirect.

If you're still getting that error, it's one of those two things. Either the client ID has a typo or the redirect URI you're sending is not an exact match for what's configured on the oauth client.

When developing locally, the page doesn't have to be available externally; you're the only one viewing it.

Yes. This behavior is defined by the OAuth 2.0 specification.

Thanks for verifying.

Do you know of any solutions for local development where the redirect is needed, but there is no 1 to 1 url to redirect to?

Is the redirect just here to match against urls defined by the admin client?

I'm not sure what you mean. You said you're working on a HTML file, so it will have an absolute URI as served by your locally running web server. It would be something like http://localhost:8080/path/to/file.html.

No, it's part of the OAuth flow. See the links I posted previously or the OAuth RFC directly for documentation on that flow.

Hi Tim,

Thanks for your help on this. I realized that my understanding on this must be frustrating when paired with my relentless pursuit. I appreciate your assistance.

I've made a few changes and a little progress.

Here is my code using the JS SDK:

const redirectUri = "http://api.localhost";
ConnectToApi();

function ConnectToApi() {
const client = platformClient.ApiClient.instance;
// Method1: Let loginPKCEGrant generate the code verifier
client.loginPKCEGrant(clientId, redirectUri)
.then((data) => {
console.log("API Connected!",data);
// Do authenticated things
})
.catch((err) => {
// Handle failure response
console.log("Failed. ",err);
});
}

function UserAPI() {
const client = platformClient.ApiClient.instance;
// Create API instance
const usersApi = new platformClient.UsersApi();
// Authenticate
client.loginImplicitGrant(clientId, redirectUri)
.then(() => {
// Make request to GET /api/v2/users/me?expand=presence
return usersApi.getUsersMe({ 'expand': ["presence"] });
})
.then((userMe) => {
// Handle successful result
console.log(Hello, ${userMe.name}!);
})
.catch((err) => {
// Handle failure response
console.log(err);
});
}

Here is my output:

Please help me figure this out.

The error unauthorized client means your org does not currently allow logins from that oauth client. You can read more about this here: Authorize an OAuth client - Genesys Cloud Resource Center.

Hi Tim,

I approved the APP that's tied to the clientID from my OAuth,


, but the error persists

That error means that the client you're using in the OAuth redirect is not authorized in the org you're trying to authenticate with. If you've double checked that info and are absolutely sure you haven't made any mistakes, please open a case with Genesys Cloud Care to investigate.

I was able to get connected, the original issue is resolved, however in testing a callback creation I ran into this issue:

The first time I call the API nothing happens.

The second time 1 call is completed, adding a callback to the queue.

The third time, two callbacks are added.
3

Here is the code I'm using:

function ConnectToApi(pn) {
const client = platformClient.ApiClient.instance;
const conversationsApi = new platformClient.ConversationsApi();
client.setEnvironment("mypurecloud.com");
client.loginImplicitGrant(clientId, redirectUri)
.then((data) => {
//client.setAccessToken = data["accessToken"]; //Not sure what to do with token
console.log("API Connected!");
// Do authenticated things
const callbackData = {
routingData: {
queueId: test_queue
},
scriptId: '',
callbackUserName: 'Test Callee',
callbackNumbers: [
pn
],
data:{
notes: 'Test Notes'
},
callerId: '+16266666666',
callerIdName: 'Tester'
};
// Create callback
return (conversationsApi.postConversationsCallbacks(callbackData)
);
})
.catch((err) => {
// Handle failure response
console.log("Failed. ",err);
});
}

Please let me know if you can spot what's wrong.

When your app does't have a valid auth token, the call to loginImplicitGrant will result in redirecting the user to the auth server to authenticate. Once authentication is complete, it will redirect back to your app's redirect URI.

The multiple traces of "API Connected!" are presumably because you're calling that function multiple times.

Hi Tim,

Thanks for your help on this and though your responses grew terser over time, the information you were able to provide at the beginning helped my look in the right direction.

I'm now able to host a local page where I can trigger api calls.