Technically, this is an alternative solution (I think). In order to create Google Hangouts credentials a GSuite account is required, which I don't have. The Interface HangoutsAdapterOptions docs state the "Shared secret token [is] used" for validation and is found under the Configuration tab. As the fields are locked down, I can't test this.
However, the alternative is to use the built-in OAuth feature of the Bot Framework. I use this in my bot without a hitch. I did navigate to the Google Hangouts web site and it recognized me immediately. By using the OAuth login, a token is returned which you can use to pass into the Hangouts adapter.
I should add that the below implementation produces a sign-in magic code which some people don't like (it doesn't bother me). There may be a SSO option, but I haven't researched that.
First, you need to setup Google credentials which will provide you with a "Client id" and "Client secret". General instructions can be found here. Credentials can be created here. You can ignore any coding references as they aren't necessary (thanks to the BF OAuth feature).
From the Credentials Page, click on "Credentials" in the left menu. There are two areas you need to configure, once there: "OAuth consent screen" and "Credentials".

For OAuth consent screen, provide an app name. This doesn't need to match the associated requesting app and is just for reference when visiting the Credentials Page. Enter a support email, the scopes you will be using (email, profile, and openid). There may be other required scopes, but this worked for me when I visited the Hangouts web site. Lastly, enter in the Authorized Domains. The botframework.com
domain is required. Others, if any, you will have to experiment with. Save and return to the Credentials Page.
Click the "Create Credentials" button and complete the form. Give your credentials a name (again, not referenced anywhere else for this project), enter any authorized origins, and enter https://token.botframework.com/.auth/web/redirect
as the authorized redirect URI. Save the settings, copy the "Client id" and "Client secret" somewhere, and navigate to Azure and into your bot's settings page.
Here, you need to create your bot's OAuth connection. This is done in the Settings blade. At the bottom of the blade is the "OAuth Connection Settings" section. Click the "Add Setting" button to get started.
Once in, give your connection a name. This name will be referenced by your bot in the next step, so save the name somewhere. Then, select Google from the list of Service Providers and paste the "Client id" and "Client secret", that you saved earlier, into the respective fields. In "Scopes", you will want to enter the same scope values you selected in your Google credentials app ("email profile openid"). Be sure they are space-separated when you enter them.


Lastly, you will want to model your OAuth login off of sample 18.bot-authentication from the Botbuilder-Samples repo. This builds in the functionality you need for enabling a user to log in via your bot.
Add the connection name you assigned to your Google connection setting for your bot into a .env file as a variable, like this: connectionName=<CONNECTION_NAME>
.
When setting up the OAuth prompt, you will pass this variable in:
this.addDialog(new OAuthPrompt(OAUTH_PROMPT, {
connectionName: process.env.connectionName,
text: 'Please Sign In',
title: 'Sign In',
timeout: 300000
}));
At this point, your bot and login process should be good to go. Assuming the flow is setup correctly, a user should be able to login via the OAuth prompt, by use of a magic code. A token is returned back to the bot which will be accessible via the context
on the next step. The token can then be saved to state and passed to the adapter for use. In the below bit, I'm using a simple waterfall with an oauthPrompt
step and a loginResults
step. The token is captured in the second step where I console log it.
async oauthPrompt(step) {
return await step.prompt(OAUTH_PROMPT, {
prompt: {
inputHint: 'ExpectingInput'
}
});
}
async loginResults(step) {
let tokenResponse = step.result;
console.log('TOKEN: ', tokenResponse);
if (tokenResponse != null) {
await step.context.sendActivity('You are now logged in.');
return await step.prompt(CONFIRM_PROMPT, 'Do you want to view your token?', ['yes', 'no']);
}
// Something went wrong, inform the user they were not logged in
await step.context.sendActivity('Login was not successful please try again');
return await step.endDialog();
}

Hope of help!