Search code examples
dialogflow-esactions-on-googlegoogle-assistant-sdk

google assistant account linking faliure


I am trying to implement account linking in google actions. I've chosen Google and OAuth with Implicit linking type. In the Authorization URL I am validating the request and redirecting to google's oauth handler. Here is the sample code,

@Post('/google/actions/authorize')
public async authorizeGoogle(
    @Req() request: Request,
    @Res() response: Response,
    @Body() authorizeRequest: DAuthorizeRequest,
) {
    // tempToken is stored in cookie after login.
    const tempToken = request.cookies['temp-token'];
    if (!tempToken) {
      throw new UnauthorizedException();
    }

    let token: DTemporaryToken;

    try {
      token = await this.jwtService.verifyAsync<DTemporaryToken>(tempToken);
    } catch (err) {
      throw new UnauthorizedException();
    }

    // validate request parameters are as it should be.
    const valid = this.authService.validateGoogleOauthRequest(
      token,
      authorizeRequest,
    );

    if (!valid) {
      throw new UnauthorizedException();
    }

    const user: User = await this.userService.findById(token.user_id);
    const accessToken = await this.authService.generateAccessTokenForGoogle(
      user,
    );

    const redirectUri = `${
      authorizeRequest.redirect_uri
    }?access_token=${accessToken}&error=${false}&token_type=bearer&state=${
      authorizeRequest.state
    }`;
    response.redirect(redirectUri);
}

After the redirect I get this error,

Sorry, something went wrong, so I couldn't sign you in. But you can try again later.

This is the dialogflow code

dialogFlowApp.intent(
    'Default Welcome Intent',
    async (conv: DialogflowConversation) => {
      conv.ask(new SignIn('to access your data'));
    },
);

dialogFlowApp.intent('sign_in', (conv, params, signIn) => {
    console.log('SIGN IN', signIn)
    conv.ask('how are you?');
})

And the console log for the signIn value is

SIGN IN { '@type': 'type.googleapis.com/google.actions.v2.SignInValue', status: 'ERROR' }

That's it, I can't figure out what is it that is going wrong. There is no descriptive enough error that should explain where this are going wrong.


Solution

  • it was a silly mistake on my part. The issue was in the redirect url, instead of sending the access_token and other parameters as url fragment, I was sending them as query parameter. So changing the access token generation to this fixed the issue.

    const redirectUri = `${
      authorizeRequest.redirect_uri
    }#access_token=${accessToken}&error=${false}&token_type=bearer&state=${
      authorizeRequest.state
    }`;
    

    Though, I still think the error reporting should be more comprehensive from google's end. It was a silly mistake which should have taken 10 seconds to fix instead of hours if the error was something more meaningful than Something went wrong