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 o acesso à agenda.
O processamento de permissões granulares do OAuth depende de como você cria o app do Chat:
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. Siga as instruções em Processar permissões OAuth detalhadas no Apps Script.
Endpoints HTTP
Se você criar seu app do Chat usando endpoints HTTP, configure o código para processar permissões granulares do OAuth. Verifique quais escopos de autorização o usuário concedeu e, se necessário, peça autorização para os escopos ausentes ou todos eles.
No arquivo de manifesto do app do Chat, especifique os escopos de autorização necessários no campo
oauthScopes. Esse campo faz parte do recursoprojects.deployments.O exemplo a seguir requer os escopos de autorização
chat.messagesecalendar.events: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": {}, "calendar": {}, "httpOptions": {} } }Para conferir quais escopos o usuário concedeu, verifique o campo
authorizationEventObject.authorizedScopes. 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() != null ? event.getAuthorizationEventObject().getAuthorizedScopes() : null; if (authorizedScopes == null || !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 app Chat, 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 detalhadas para complementos HTTP do Google Workspace.
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 apps HTTP do Chat, consulte:
- Para saber mais sobre as permissões granulares do OAuth, consulte Permissões granulares do OAuth.
Apps do Chat que não são complementos: gerenciar permissões granulares do OAuth para apps do Google Chat
Se você mantém um app do Chat que não é um complemento do Google Workspace, use as instruções a seguir para gerenciar permissões granulares do OAuth.
Apps do Chat do Apps Script que não são complementos
Se você criou um app do Chat que não é um complemento usando o Apps Script, as instruções em Processar permissões granulares do OAuth 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 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.
// ...
}
Apps de chat HTTP que não são complementos
Se o app do Chat que não é um complemento for um serviço HTTP, você vai gerenciar o fluxo do OAuth 2.0 por conta própria.
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 para o usuário 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();