Os apps de chat que usam autenticação de usuário precisam oferecer suporte a permissões granulares do OAuth para permitir que os usuários concedam um subconjunto dos escopos solicitados. Por exemplo, um usuário pode conceder acesso ao nome, mas negar acesso à agenda.
O processamento de permissões granulares do OAuth depende de como você cria seu app de chat:
- Complementos do Apps Script para o Google Workspace que ampliam o Chat
- Apps do Chat independentes do Apps Script
- Complementos HTTP do Google Workspace que estendem o Chat
- Apps de chat HTTP independentes
Apps Script
Se você criar seu app do Chat usando o Apps Script, ele vai processar as permissões granulares do OAuth automaticamente. No entanto, verifique se o código processa casos em que um usuário não concede todos os escopos solicitados. O método depende de o Apps Script ser um complemento do Google Workspace que estende o Google Chat usando o Apps Script ou um app independente do Chat criado com o Apps Script e eventos de interação.
Complementos do Google Workspace que estendem o Chat
Se você criar seu app do Chat como um complemento do Google Workspace que estende o Google Chat usando o Apps Script, siga as instruções em Processar permissões OAuth detalhadas no Apps Script.
Apps do Chat independentes do Google Apps Script
Se você criar seu app do Chat usando o Apps Script e eventos de interação, as instruções em Processar permissões OAuth detalhadas no Apps Script funcionam com uma consideração:
ScriptApp.requireScopes
interrompe a execução do script se os escopos especificados
não forem concedidos, mas o usuário vê um card de configuração no Chat
em vez da tela de permissão do OAuth. O card de configuração sempre pede que o usuário conceda todos os escopos solicitados, em vez de apenas os não concedidos.
Para fornecer verificações individuais de autorização no nível do escopo, use
ScriptApp.getAuthorizationInfo
para verificar a autorização e, se necessário, solicite a autorização usando uma
mensagem privada.
O exemplo a seguir mostra como verificar uma permissão específica (como acesso à agenda) e, se ela estiver faltando, retornar uma mensagem particular com o URL de autorização necessário.
Apps Script
/**
* Responds to a MESSAGE event in Google Chat.
* Checks for required permissions and if missing asks for them.
*
* @param {Object} event the event object from Chat
* @return {Object} JSON response
*/
function onMessage(event) {
// Check if the script has the necessary permissions.
// In this example, the script checks for the "calendar.events" scope.
var requiredScopes = ['https://www.googleapis.com/auth/calendar.events'];
var authInfo = ScriptApp.getAuthorizationInfo(ScriptApp.AuthMode.FULL, requiredScopes);
// If permissions are missing, return a message with the authorization URL.
if (authInfo.getAuthorizationStatus() === ScriptApp.AuthorizationStatus.REQUIRED) {
var authUrl = authInfo.getAuthorizationUrl();
return {
"text": "This action requires authorization. Please <" + authUrl + "|click here to authorize>.",
"privateMessageViewer": {
"name": event.user.name
}
};
}
// Permission granted; proceed with the application logic.
// ...
}
Endpoints HTTP
Se você criar seu app Chat usando endpoints HTTP, ele precisará oferecer suporte a permissões granulares do OAuth.
Complementos do Google Workspace que estendem o Chat
Se você criar seu app do Chat como um complemento do Google Workspace (por exemplo, se ele estender outros apps do Google Workspace, como o Google Drive ou o Gmail), configure o arquivo de manifesto e o código para processar permissões granulares do OAuth:
No arquivo de manifesto do complemento, defina o campo
granularOauthPermissionSupportcomoOPT_IN. Para saber mais sobre o campogranularOauthPermissionSupport, consulte Migrar para o fluxo de permissões granulares do OAuth.JSON
{ "oauthScopes": [ "https://www.googleapis.com/auth/chat.messages", "https://www.googleapis.com/auth/calendar.events" ], "addOns": { "common": { "name": "My Chat App", "logoUrl": "https://lh3.googleusercontent.com/..." }, "chat": {}, "httpOptions": { "granularOauthPermissionSupport": "OPT_IN" } } }Para conferir quais escopos o usuário concedeu, verifique o campo
authorizationEventObject.authorizedScopesno seu código. Se um escopo obrigatório estiver ausente, retorne uma açãorequesting_google_scopespara pedir ao usuário os escopos ausentes.Node.js
// Check for authorized scopes. const authorizedScopes = req.body.authorizationEventObject.authorizedScopes || []; if (!authorizedScopes.includes('https://www.googleapis.com/auth/chat.messages')) { // Respond with a request for the missing scope. res.send({ 'requesting_google_scopes': { 'scopes': ['https://www.googleapis.com/auth/chat.messages'] } }); return; }Python
from flask import jsonify, request # Check for authorized scopes. event_data = request.get_json() authorized_scopes = event_data.get('authorizationEventObject', {}).get('authorizedScopes', []) if 'https://www.googleapis.com/auth/chat.messages' not in authorized_scopes: # Respond with a request for the missing scope. return jsonify({ 'requesting_google_scopes': { 'scopes': ['https://www.googleapis.com/auth/chat.messages'] } })Java
import com.google.gson.JsonArray; import com.google.gson.JsonObject; import java.util.List; // Check for authorized scopes. List<String> authorizedScopes = event.getAuthorizationEventObject().getAuthorizedScopes(); if (!authorizedScopes.contains("https://www.googleapis.com/auth/chat.messages")) { // Respond with a request for the missing scope. JsonObject requestingGoogleScopes = new JsonObject(); JsonArray scopes = new JsonArray(); scopes.add("https://www.googleapis.com/auth/chat.messages"); requestingGoogleScopes.add("scopes", scopes); JsonObject response = new JsonObject(); response.add("requesting_google_scopes", requestingGoogleScopes); return response.toString(); }Para solicitar todos os escopos associados ao complemento, defina
all_scopescomotrue:Node.js
res.send({ 'requesting_google_scopes': { 'all_scopes': true } });Python
from flask import jsonify return jsonify({ 'requesting_google_scopes': { 'all_scopes': True } })Java
import com.google.gson.JsonObject; JsonObject requestingGoogleScopes = new JsonObject(); requestingGoogleScopes.addProperty("all_scopes", true); JsonObject response = new JsonObject(); response.add("requesting_google_scopes", requestingGoogleScopes); return response.toString();
Para instruções detalhadas, consulte Gerenciar permissões granulares para complementos HTTP do Google Workspace.
Apps de chat HTTP independentes
Se o app do Chat for um serviço HTTP independente (não um complemento do Google Workspace), você vai gerenciar o fluxo do OAuth 2.0.
Ao recuperar um token armazenado ou trocar um código de autorização, verifique quais escopos foram concedidos. Se os escopos necessários estiverem ausentes, peça ao usuário para autorizá-los.
Node.js
// 1. List authorized scopes.
const fs = require('fs');
const tokens = JSON.parse(fs.readFileSync('token.json'));
const grantedScopes = tokens.scope.split(' ');
// 2. Detect missing scopes.
const requiredScopes = ['https://www.googleapis.com/auth/chat.messages'];
const missingScopes = requiredScopes.filter(scope => !grantedScopes.includes(scope));
if (missingScopes.length > 0) {
// 3. Request missing scopes.
const authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: missingScopes,
include_granted_scopes: true
});
res.redirect(authUrl);
}
// To request all scopes instead of just the missing ones:
const allScopesAuthUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: requiredScopes,
include_granted_scopes: true
});
Python
from flask import redirect
from google.oauth2.credentials import Credentials
# 1. List authorized scopes.
credentials = Credentials.from_authorized_user_file('token.json')
granted_scopes = set(credentials.scopes)
# 2. Detect missing scopes.
required_scopes = {'https://www.googleapis.com/auth/chat.messages'}
missing_scopes = required_scopes - granted_scopes
if missing_scopes:
# 3. Request missing scopes.
flow.scope = list(missing_scopes)
auth_url, _ = flow.authorization_url(
access_type='offline',
include_granted_scopes=True
)
return redirect(auth_url)
# To request all scopes instead of just the missing ones:
flow.scope = list(required_scopes)
all_scopes_auth_url, _ = flow.authorization_url(
access_type='offline',
include_granted_scopes='true'
)
Java
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
// 1. List authorized scopes.
// The "user" string is the user ID for which to load credentials.
Credential credential = flow.loadCredential("user");
Collection<String> grantedScopes = credential.getScopes();
// 2. Detect missing scopes.
// The `requiredScopes` variable contains a list of the OAuth scopes
// that your app requires to function. Define this variable with the
// scopes needed by your application.
List<String> requiredScopes = Arrays.asList("https://www.googleapis.com/auth/chat.messages");
List<String> missingScopes = new ArrayList<>();
for (String scope : requiredScopes) {
if (!grantedScopes.contains(scope)) {
missingScopes.add(scope);
}
}
if (!missingScopes.isEmpty()) {
// 3. Request missing scopes.
GoogleAuthorizationCodeRequestUrl urlBuilder = new GoogleAuthorizationCodeRequestUrl(
clientId, redirectUri, missingScopes)
.setAccessType("offline")
.set("include_granted_scopes", "true");
String authUrl = urlBuilder.build();
response.sendRedirect(authUrl);
}
// To request all scopes instead of just the missing ones:
GoogleAuthorizationCodeRequestUrl allScopesUrlBuilder = new GoogleAuthorizationCodeRequestUrl(
clientId, redirectUri, requiredScopes)
.setAccessType("offline")
.set("include_granted_scopes", "true");
String allScopesAuthUrl = allScopesUrlBuilder.build();
Para mais informações, consulte Permissões granulares do OAuth.
Temas relacionados
- Para ter uma visão geral da autenticação e autorização no Google Chat, consulte Saiba mais sobre autenticação e autorização.
- Para configurar a autenticação de usuários, consulte Autenticação e autorização como usuário do Google Chat.
- Para receber ajuda na configuração de permissões granulares do OAuth no Apps Script ou em complementos HTTP do Google Workspace, consulte:
- Para saber mais sobre as permissões granulares do OAuth, consulte Permissões granulares do OAuth.