如何在 Django 中添加和通过电子邮件向与会者发送邀请(谷歌日历集成)

时间:2021-07-21 11:36:04

标签: python django google-calendar-api

我正在使用 Django 创建一个预订应用程序,它允许人们预订会议,但我遇到了一个问题,即 API 不允许我添加与会者。我不断收到的错误是:

https://www.googleapis.com/calendar/v3/calendars/02g427gf151ggdmcas2pui1suo%40group.calendar.google.com/events?alt=json 时返回“服务帐户无法在没有域范围授权的情况下邀请与会者。”。详细信息:“[{'domain': 'calendar', 'reason': 'forbiddenForServiceAccounts', 'message': '服务帐户不能在没有域范围授权的情况下邀请与会者。'}

我已尝试部署该应用并使用 Google Workspace 委派权限,但这似乎不起作用。我有一个虚拟环境,下面是应用程序的代码:

views.py

from django.shortcuts import render
import datetime
from .calendar_API import *
import stripe

# Create your views here.
def home(request):
    tomorrow = datetime.date.today() + datetime.timedelta(days=1)

    month_from_now = datetime.date.today() + datetime.timedelta(days=30)

    if request.method == "POST":
        subject = request.POST.get('subject')
        desc = request.POST.get("desc")
        date = request.POST.get("daterange")
        email = request.POST.get("email")

        date = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S')
    
        hour_later = date + timedelta(minutes=60)

        hour_later = hour_later.isoformat()

        date = date.isoformat()


        def create_event():

            service = build_service()

            # start_datetime = datetime.datetime.now(tz=pytz.utc)
            event = (
                service.events()
                .insert(
                    calendarId="02g427gf151ggdmcas2pui1suo@group.calendar.google.com",
                    body={
                        "summary": subject,
                        "description": desc,
                        "start": {
                            "dateTime": date,
                            "timeZone":"Europe/London"
                            },
                        "end": {
                            "dateTime": hour_later,
                            "timeZone":"Europe/London"
                        },
                        
                        "attendees": [
                            {
                            "email":email
                            }
                        ],

                        # "sendNotifications": True,
                       
                    },
                )
                .execute()
            )

            print(event)


        create_event()

    context = {'tomorrow' : tomorrow, 'month' : month_from_now}

    return render(request, 'index.html', context)


calendar_API.py

import datetime
from datetime import timedelta

import pytz
from googleapiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
from . import views

service_account_email = "booking-app@booking-app-318011.iam.gserviceaccount.com"
SCOPES = ["https://www.googleapis.com/auth/calendar"]
credentials = ServiceAccountCredentials.from_json_keyfile_name(
    filename="scheduling/credentials.json", scopes=SCOPES
)


def build_service():
    service = build("calendar", "v3", credentials=credentials)
    return service

是否有任何替代方法或文档可供我使用?

2 个答案:

答案 0 :(得分:0)

<块引用>

服务帐户不能在没有域范围授权的情况下邀请与会者

问题在于您使用的是服务帐户。但是您要么忘记在 Google 工作区帐户中设置 domain wide delegation,要么设置不正确。

服务帐户仅适用于 google 日历,但它不适用于普通的 Gmail 帐户。

from google.oauth2 import service_account

SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)
delegated_credentials = credentials.with_subject('user@example.org')

答案 1 :(得分:0)

如果您想使用服务帐户执行任务,执行域范围的委派只是第一步。

您还必须在您的域中模拟另一个有权访问特定日历的帐户才能执行请求。

服务帐户授予域范围权限的主要目的是让这些帐户能够代表您域中的用户访问数据,否则服务帐户< /em> 就像另一个帐户一样,它正在尝试访问自己的日历。

因此,当此服务帐户冒充您域中的另一个用户时,它将能够访问该用户可以访问的日历。

为了执行此操作,您必须在代码中设置凭据时包含要模拟的用户的电子邮件地址。

参考