Google Chat অ্যাপের জন্য গ্রানুলার OAuth অনুমতিগুলি পরিচালনা করুন

যেসব চ্যাট অ্যাপ ব্যবহারকারী প্রমাণীকরণ ব্যবহার করে, সেগুলোতে অবশ্যই সুনির্দিষ্ট OAuth অনুমতির সমর্থন থাকতে হবে, যাতে ব্যবহারকারীরা অনুরোধকৃত স্কোপগুলোর একটি উপসেট মঞ্জুর করতে পারে। উদাহরণস্বরূপ, একজন ব্যবহারকারী তার নামের অ্যাক্সেস মঞ্জুর করতে পারেন কিন্তু তার ক্যালেন্ডারের অ্যাক্সেস প্রত্যাখ্যান করতে পারেন।

আপনার চ্যাট অ্যাপটি কীভাবে তৈরি করেছেন, তার ওপর নির্ভর করে সূক্ষ্ম OAuth অনুমতিগুলো কীভাবে পরিচালনা করা হবে:

অ্যাপস স্ক্রিপ্ট

আপনি যদি অ্যাপস স্ক্রিপ্ট ব্যবহার করে আপনার চ্যাট অ্যাপ তৈরি করেন, তাহলে অ্যাপস স্ক্রিপ্ট স্বয়ংক্রিয়ভাবে সূক্ষ্ম OAuth অনুমতিগুলো পরিচালনা করে। তবে, নিশ্চিত করুন যে আপনার কোড এমন পরিস্থিতি সামাল দিতে পারে যেখানে একজন ব্যবহারকারী অনুরোধ করা সমস্ত স্কোপ মঞ্জুর করেন না। এই পদ্ধতিটি নির্ভর করে আপনার অ্যাপস স্ক্রিপ্টটি গুগল ওয়ার্কস্পেসের একটি অ্যাড-অন যা অ্যাপস স্ক্রিপ্ট ব্যবহার করে গুগল চ্যাটকে প্রসারিত করে, নাকি এটি অ্যাপস স্ক্রিপ্ট এবং ইন্টারঅ্যাকশন ইভেন্ট দিয়ে তৈরি একটি স্বতন্ত্র চ্যাট অ্যাপ, তার উপর।

Google Workspace অ্যাড-অন যা চ্যাটকে প্রসারিত করে

আপনি যদি অ্যাপস স্ক্রিপ্ট ব্যবহার করে গুগল চ্যাটকে সম্প্রসারিত করে এমন একটি গুগল ওয়ার্কস্পেস অ্যাড-অন হিসেবে আপনার চ্যাট অ্যাপ তৈরি করেন, তাহলে "অ্যাপস স্ক্রিপ্টে সূক্ষ্ম OAuth অনুমতি পরিচালনা" (Handle granular OAuth permissions in Apps Script) -এর নির্দেশাবলী অনুসরণ করুন।

স্বতন্ত্র অ্যাপস স্ক্রিপ্ট চ্যাট অ্যাপস

যদি আপনি অ্যাপস স্ক্রিপ্ট এবং ইন্টারঅ্যাকশন ইভেন্ট ব্যবহার করে আপনার চ্যাট অ্যাপ তৈরি করেন, তাহলে 'অ্যাপস স্ক্রিপ্টে সূক্ষ্ম OAuth অনুমতি পরিচালনা' শীর্ষক নির্দেশাবলী একটি বিষয় মাথায় রেখে কাজ করবে:

ScriptApp.requireScopes নির্দিষ্ট স্কোপগুলো মঞ্জুর করা না হলে স্ক্রিপ্ট এক্সিকিউশন থামিয়ে দেয়, কিন্তু ব্যবহারকারী OAuth কনসেন্ট স্ক্রিনের পরিবর্তে চ্যাটে একটি কনফিগারেশন কার্ড দেখতে পান। কনফিগারেশন কার্ডটি সবসময় ব্যবহারকারীকে শুধু মঞ্জুর না করা স্কোপগুলোর পরিবর্তে অনুরোধ করা সমস্ত স্কোপ মঞ্জুর করার জন্য অনুরোধ করে।

স্বতন্ত্র অনুমোদন পরিধি-স্তরের যাচাই করার জন্য, অনুমোদন আছে কিনা তা পরীক্ষা করতে ScriptApp.getAuthorizationInfo ব্যবহার করুন এবং প্রয়োজনে একটি ব্যক্তিগত বার্তার মাধ্যমে অনুমোদনের জন্য অনুরোধ করুন।

নিম্নলিখিত উদাহরণটি দেখায় কিভাবে একটি নির্দিষ্ট অনুমতি (যেমন ক্যালেন্ডার অ্যাক্সেস) পরীক্ষা করতে হয় এবং যদি তা না থাকে, তাহলে প্রয়োজনীয় অনুমোদন URL সহ একটি ব্যক্তিগত বার্তা ফেরত পাঠাতে হয়।

অ্যাপস স্ক্রিপ্ট

/**
* 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 এন্ডপয়েন্ট

আপনি যদি HTTP এন্ডপয়েন্ট ব্যবহার করে আপনার চ্যাট অ্যাপ তৈরি করেন, তাহলে আপনার চ্যাট অ্যাপটিতে সূক্ষ্ম OAuth অনুমতির সমর্থন থাকা উচিত।

Google Workspace অ্যাড-অন যা চ্যাটকে প্রসারিত করে

আপনি যদি আপনার চ্যাট অ্যাপটি গুগল ওয়ার্কস্পেস অ্যাড-অন হিসেবে তৈরি করেন, তাহলে সুনির্দিষ্ট OAuth অনুমতিগুলো পরিচালনা করার জন্য আপনার কোড কনফিগার করুন। ব্যবহারকারী কোন কোন অথরাইজেশন স্কোপের অনুমতি দিয়েছেন তা যাচাই করুন এবং প্রয়োজনে, অনুপস্থিত স্কোপগুলোর বা সমস্ত স্কোপের জন্য অনুমতির অনুরোধ করুন।

  1. আপনার অ্যাড-অনের ম্যানিফেস্ট ফাইলে , oauthScopes ফিল্ডে প্রয়োজনীয় অথরাইজেশন স্কোপগুলো উল্লেখ করুন। এই ফিল্ডটি projects.deployments রিসোর্সের একটি অংশ।

    নিম্নলিখিত উদাহরণটির জন্য chat.messages এবং calendar.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": {}
      }
    }
    
  2. ব্যবহারকারী কোন কোন স্কোপের অনুমতি দিয়েছেন তা দেখতে, authorizationEventObject.authorizedScopes ফিল্ডটি দেখুন। যদি কোনো প্রয়োজনীয় স্কোপ অনুপস্থিত থাকে, তাহলে অনুপস্থিত স্কোপগুলোর জন্য ব্যবহারকারীকে জিজ্ঞাসা করতে একটি requesting_google_scopes অ্যাকশন রিটার্ন করুন।

    নোড.জেএস

    // 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;
    }
    

    পাইথন

    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']
            }
        })
    

    জাভা

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

    অ্যাড-অনটির সাথে যুক্ত সমস্ত স্কোপ অনুরোধ করতে, all_scopes true তে সেট করুন:

    নোড.জেএস

    res.send({
      'requesting_google_scopes': { 'all_scopes': true }
    });
    

    পাইথন

    from flask import jsonify
    
    return jsonify({
        'requesting_google_scopes': { 'all_scopes': True }
    })
    

    জাভা

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

বিস্তারিত নির্দেশাবলীর জন্য, HTTP Google Workspace অ্যাড-অনগুলির জন্য সূক্ষ্ম অনুমতি ব্যবস্থাপনা দেখুন।

স্বতন্ত্র HTTP চ্যাট অ্যাপ

আপনার চ্যাট অ্যাপটি যদি একটি স্বতন্ত্র HTTP পরিষেবা হয় (গুগল ওয়ার্কস্পেস অ্যাড-অন নয়), তাহলে আপনাকে নিজেই OAuth 2.0 ফ্লো পরিচালনা করতে হবে।

যখন আপনি একটি সংরক্ষিত টোকেন পুনরুদ্ধার করেন বা একটি অনুমোদন কোড বিনিময় করেন, তখন কোন স্কোপগুলো মঞ্জুর করা হয়েছে তা পরীক্ষা করুন। যদি প্রয়োজনীয় স্কোপগুলো অনুপস্থিত থাকে, তবে ব্যবহারকারীকে সেগুলো অনুমোদন করার জন্য অনুরোধ করুন।

নোড.জেএস

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

পাইথন

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'
)

জাভা

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

আরও তথ্যের জন্য, গ্র্যানুলার OAuth পারমিশন দেখুন।