Las apps de chat que usan la autenticación de usuarios deben admitir permisos de OAuth detallados para permitir que los usuarios otorguen un subconjunto de los permisos solicitados. Por ejemplo, un usuario podría otorgar acceso a su nombre, pero rechazar el acceso a su calendario.
El manejo de permisos detallados de OAuth depende de cómo compiles tu app de Chat:
- Complementos de Apps Script para Google Workspace que extienden Chat
- Apps independientes de Chat creadas con Apps Script
- Complementos de Google Workspace basados en HTTP que extienden Chat
- Apps de Chat HTTP independientes
Apps Script
Si compilas tu app de Chat con Apps Script, Apps Script controla los permisos detallados de OAuth automáticamente. Sin embargo, asegúrate de que tu código controle los casos en los que un usuario no otorga todos los permisos solicitados. El método depende de si tu Apps Script es un complemento de Google Workspace que extiende Google Chat con Apps Script o una app de Chat independiente creada con Apps Script y eventos de interacción.
Complementos de Google Workspace que extienden Chat
Si compilas tu app de Chat como un complemento de Google Workspace que extiende Google Chat con Apps Script, sigue las instrucciones que se indican en Cómo controlar los permisos detallados de OAuth en Apps Script.
Apps independientes de Apps Script para Chat
Si compilas tu app de Chat con Apps Script y eventos de interacción, las instrucciones que se indican en Cómo controlar los permisos detallados de OAuth en Apps Script funcionan con una consideración:
ScriptApp.requireScopes detiene la ejecución de la secuencia de comandos si no se otorgan los permisos especificados, pero el usuario ve una tarjeta de configuración en Chat en lugar de la pantalla de consentimiento de OAuth. La tarjeta de configuración siempre le solicita al usuario que otorgue todos los permisos solicitados en lugar de solo los que no se otorgaron.
Para proporcionar verificaciones individuales a nivel del alcance de la autorización, usa ScriptApp.getAuthorizationInfo para verificar la autorización y, si es necesario, solicitarla con un mensaje privado.
En el siguiente ejemplo, se muestra cómo verificar si falta un permiso específico (como el acceso al calendario) y, si es así, devolver un mensaje privado con la URL de autorización requerida.
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.
// ...
}
Extremos HTTP
Si compilas tu app de Chat con endpoints HTTP, esta debe admitir permisos de OAuth detallados.
Complementos de Google Workspace que extienden Chat
Si creas tu app de Chat como un complemento de Google Workspace (por ejemplo, si extiende otras apps de Google Workspace, como Google Drive o Gmail), configura tu archivo de manifiesto y tu código para controlar los permisos detallados de OAuth:
En el archivo de manifiesto de tu complemento, establece el campo
granularOauthPermissionSupportenOPT_IN. Para obtener más información sobre el campogranularOauthPermissionSupport, consulta Migra al flujo de permisos detallados de 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 ver qué permisos otorgó el usuario, consulta el campo
authorizationEventObject.authorizedScopesen tu código. Si falta un alcance obligatorio, devuelve una acciónrequesting_google_scopespara solicitarle al usuario los alcances faltantes.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 los permisos asociados con el complemento, establece
all_scopesentrue: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 obtener instrucciones detalladas, consulta Cómo administrar permisos detallados para complementos de Google Workspace basados en HTTP.
Apps de Chat HTTP independientes
Si tu app de Chat es un servicio HTTP independiente (no un complemento de Google Workspace), tú mismo administras el flujo de OAuth 2.0.
Cuando recuperes un token almacenado o intercambies un código de autorización, verifica qué permisos se otorgaron. Si faltan los alcances obligatorios, solicita al usuario que los autorice.
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 obtener más información, consulta Permisos de OAuth detallados.
Temas relacionados
- Para obtener una descripción general de la autenticación y la autorización en Google Chat, consulta Información sobre la autenticación y la autorización.
- Para configurar la autenticación de usuarios, consulta Autentica y autoriza como usuario de Google Chat.
- Para obtener ayuda con la configuración de permisos detallados de OAuth en Apps Script o en complementos HTTP de Google Workspace, consulta los siguientes recursos:
- Para obtener más información sobre los permisos detallados de OAuth, consulta Permisos detallados de OAuth.