Google Chat uygulamaları için ayrıntılı OAuth izinlerini yönetme

Kullanıcı kimlik doğrulaması kullanan sohbet uygulamaları, kullanıcıların istenen kapsamların bir alt kümesini vermesine olanak tanımak için ayrıntılı OAuth izinlerini desteklemelidir. Örneğin, bir kullanıcı adının erişimine izin verebilir ancak takviminin erişimini reddedebilir.

Ayrıntılı OAuth izinlerinin işlenmesi, sohbet uygulamanızı nasıl oluşturduğunuza bağlıdır:

Apps Komut Dosyası

Chat uygulamanızı Apps Komut Dosyası'nı kullanarak oluşturursanız Apps Komut Dosyası, ayrıntılı OAuth izinlerini otomatik olarak işler. Ancak kodunuzun, kullanıcının istenen tüm kapsamları vermediği durumları işlediğinden emin olun. Yöntem, Apps Komut Dosyası'nın Apps Komut Dosyası kullanılarak Google Chat'i genişleten bir Google Workspace eklentisi mi yoksa Apps Komut Dosyası ve etkileşim etkinlikleriyle oluşturulmuş bağımsız bir Chat uygulaması mı olduğuna bağlıdır.

Chat'i genişleten Google Workspace eklentileri

Chat uygulamanızı Apps Komut Dosyası'nı kullanarak Google Chat'i genişleten bir Google Workspace eklentisi olarak oluşturursanız Apps Komut Dosyası'nda ayrıntılı OAuth izinlerini işleme bölümündeki talimatları uygulayın.

Bağımsız Apps Komut Dosyası Chat uygulamaları

Chat uygulamanızı Apps Komut Dosyası ve etkileşim etkinliklerini kullanarak oluşturuyorsanız Apps Komut Dosyası'nda ayrıntılı OAuth izinlerini işleme başlıklı makaledeki talimatlar bir husus göz önünde bulundurularak uygulanır:

ScriptApp.requireScopes Belirtilen kapsamlar verilmezse komut dosyası yürütmeyi durdurur ancak kullanıcı, OAuth izin ekranı yerine Chat'te bir yapılandırma kartı görür. Yapılandırma kartı, kullanıcıdan her zaman yalnızca verilmeyen kapsamlar yerine istenen tüm kapsamları vermesini ister.

Bireysel yetkilendirme kapsamı düzeyinde kontroller sağlamak için ScriptApp.getAuthorizationInfo kullanarak yetkilendirmeyi kontrol edin ve gerekirse özel mesaj kullanarak yetkilendirme isteğinde bulunun.

Aşağıdaki örnekte, belirli bir iznin (ör. takvim erişimi) nasıl kontrol edileceği ve eksikse gerekli yetkilendirme URL'sini içeren bir özel mesajın nasıl döndürüleceği gösterilmektedir.

Apps Komut Dosyası

/**
* 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.
  // ...
}

HTTP uç noktaları

Chat uygulamanızı HTTP uç noktalarını kullanarak oluşturursanız Chat uygulamanız ayrıntılı OAuth izinlerini desteklemelidir.

Chat'i genişleten Google Workspace eklentileri

Chat uygulamanızı Google Workspace eklentisi olarak oluşturursanız (örneğin, Google Drive veya Gmail gibi diğer Google Workspace uygulamalarını genişletiyorsa) manifest dosyanızı ve kodunuzu ayrıntılı OAuth izinlerini işleyecek şekilde yapılandırın:

  1. Eklentinizin manifest dosyasında, granularOauthPermissionSupport alanını OPT_IN olarak ayarlayın. granularOauthPermissionSupport alanı hakkında daha fazla bilgi edinmek için Ayrıntılı OAuth izinleri akışına geçiş başlıklı makaleyi inceleyin.

    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"
        }
      }
    }
    
  2. Kullanıcının hangi kapsamları verdiğini görmek için kodunuzda authorizationEventObject.authorizedScopes alanını kontrol edin. Gerekli bir kapsam eksikse kullanıcıdan eksik kapsamları istemek için requesting_google_scopes işlemini döndürün.

    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();
    }
    

    Eklentiyle ilişkili tüm kapsamları istemek için all_scopes değerini true olarak ayarlayın:

    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();
    

Ayrıntılı talimatlar için HTTP Google Workspace eklentileri için ayrıntılı izinleri yönetme başlıklı makaleyi inceleyin.

Bağımsız HTTP Chat uygulamaları

Chat uygulamanız bağımsız bir HTTP hizmetiyse (Google Workspace eklentisi değilse) OAuth 2.0 akışını kendiniz yönetirsiniz.

Kayıtlı bir jetonu aldığınızda veya bir yetkilendirme kodunu değiştirdiğinizde hangi kapsamların verildiğini kontrol edin. Gerekli kapsamlar eksikse kullanıcıdan bunları yetkilendirmesini isteyin.

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();

Daha fazla bilgi için Ayrıntılı OAuth izinleri başlıklı makaleyi inceleyin.