You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Google Calendar API为事件添加附件?Python代码问题求助

Google Calendar API 添加Drive附件失败(无报错)

我正在用Python开发Google API相关功能,过往相关问题的答案大多已过时。遵循官方文档指引时,发现文档代码无法适配最新版API——文档提到使用alternateLink字段,但Drive API v3中该字段已不存在,根据资料改用webViewLink字段后,事件能成功创建,但附件未添加,且无任何报错信息。

补充代码

上传文件至Drive

def upload_file(drive_service, file_path):
    file_name = file_path.split("/")[-1]

    file_metadata = {
        "name": file_name,
        "parents": ["id to a folder in drive"],
        "mimeType": "application/pdf",
    }
    try:
        logging.info(f"Uploading the file {file_name}")
        media = MediaFileUpload(file_path, resumable=True)
        file = (
            drive_service.files()
            .create(
                body=file_metadata,
                media_body=media,
                fields="id, mimeType, webContentLink",
            )
            .execute()
        )
        logging.info("File uploaded.")
        return file

    except HttpError as e:
        logging.error(f"An error occurred while uploading the file to drive: {e}")
        return

该函数返回包含id, mimeType, webContentLink字段的字典。

创建事件主体

def create_event_dict(info_list, attachment = []):
    from utils import date

    start_date = date.change_date_format(info_list[0], info_list[1])
    end_date = date.change_date_format(info_list[3], info_list[4])

    if attachment:
        attachment[0]["fileUrl"] = attachment[0]["webContentLink"]
        attachment[0].pop("webContentLink")

    event = {
        "summary": f"{info_list[2]} -> {info_list[5]}",
        "location": info_list[6],
        "start": {"dateTime": start_date.isoformat(), "timeZone": "Europe/Madrid"},
        "end": {"dateTime": end_date.isoformat(), "timeZone": "Europe/Madrid"},
        "reminders": {"useDefault": True},
        "attachment": attachment,
    }

    return event

提交事件

def post_event(service, event, calendar_id):
    event = (
        service.events()
        .insert(calendarId=calendar_id, body=event, supportsAttachments=True)
        .execute()
    )
    print(f"Event created: {event.get('htmlLink')}")
    return event

解决方案

问题出在四个关键细节上,逐一修正即可解决:

  1. 字段名错误:单数/复数混淆
    Calendar API要求的附件字段是复数attachments,而非代码中的单数attachment。API会忽略不存在的字段,这是附件未添加但无报错的核心原因。

  2. 附件缺少必填字段
    Calendar API的附件对象必须包含fileUrl、title、mimeType三个字段,原代码未提供title,需要从Drive返回的文件信息中获取文件名补充。

  3. Drive文件权限不足
    上传的Drive文件默认是私有权限,Calendar API无法访问。需要在文件上传后添加公开读取权限,或授予特定用户/服务账号访问权限。

  4. 上传时未获取文件名
    原upload_file函数的fields参数未包含name,无法获取文件名作为附件的title,需要修改该参数。

修正后的代码片段

修正上传文件函数(添加权限+返回文件名)

def upload_file(drive_service, file_path):
    file_name = file_path.split("/")[-1]

    file_metadata = {
        "name": file_name,
        "parents": ["id to a folder in drive"],
        "mimeType": "application/pdf",
    }
    try:
        logging.info(f"Uploading the file {file_name}")
        media = MediaFileUpload(file_path, resumable=True)
        file = (
            drive_service.files()
            .create(
                body=file_metadata,
                media_body=media,
                fields="id, name, mimeType, webContentLink",  # 添加name字段
            )
            .execute()
        )
        # 给文件添加公开读取权限,确保Calendar能访问
        permission = {
            "type": "anyone",
            "role": "reader"
        }
        drive_service.permissions().create(fileId=file["id"], body=permission).execute()
        logging.info("File uploaded and permission set.")
        return file

    except HttpError as e:
        logging.error(f"An error occurred while uploading the file to drive: {e}")
        return

修正创建事件主体函数(复数字段+完整附件参数)

def create_event_dict(info_list, attachment = []):
    from utils import date

    start_date = date.change_date_format(info_list[0], info_list[1])
    end_date = date.change_date_format(info_list[3], info_list[4])

    attachments = []
    if attachment:
        # 构造符合Calendar API要求的附件对象
        attachments.append({
            "fileUrl": attachment[0]["webContentLink"],
            "title": attachment[0]["name"],
            "mimeType": attachment[0]["mimeType"]
        })

    event = {
        "summary": f"{info_list[2]} -> {info_list[5]}",
        "location": info_list[6],
        "start": {"dateTime": start_date.isoformat(), "timeZone": "Europe/Madrid"},
        "end": {"dateTime": end_date.isoformat(), "timeZone": "Europe/Madrid"},
        "reminders": {"useDefault": True},
        "attachments": attachments,  # 改为复数字段
    }

    return event

额外检查项

  • 确保已启用Google Calendar API和Google Drive API
  • OAuth2权限范围需包含https://www.googleapis.com/auth/calendar和https://www.googleapis.com/auth/drive.file

内容的提问来源于stack exchange,提问作者Tamames

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 02:05:58