我正在构建一个带有 Pub/Sub 触发器的 Google Cloud Function 来处理电子邮件附件。该函数应该将允许的电子邮件地址中的附件保存到指定的 Cloud Storage 存储桶中。
虽然 Pub/Sub 触发器工作并且日志确认函数调用,但没有附件被保存到存储桶中。此外,在某些情况下,即使测试电子邮件中包含有效附件,功能日志也会显示“电子邮件中未找到有效附件”。
设置详情 云功能:
触发器:Pub/Sub 主题 运行时:Python 3.9 权限:所有相关角色(云函数调用者、Pub/Sub 发布者、存储管理员)均已授予关联的服务帐户。 发布/订阅主题:
使用默认设置创建的主题(添加订阅、拉取传递类型、7 天消息保留)。 预期流量:
电子邮件附件通过 Pub/Sub 消息接收。 函数处理 Pub/Sub 消息,验证发件人和主题,并将附件保存到指定的 Cloud Storage 存储桶。 当前观察:
Pub/Sub消息发布成功,函数日志显示调用情况。 但是,没有附件保存到存储桶中。 在某些情况下,尽管发送了有效附件,但日志仍显示“在电子邮件中找不到有效附件”。 有时,电子邮件会因未送达而被退回,日志中没有进一步的错误详细信息。
供参考的代码片段 这是该函数的代码。任何识别问题的反馈或建议将不胜感激:
@functions_framework.cloud_event
def handle_email_attachment(cloud_event):
"""Handles email attachments sent via Pub/Sub."""
try:
pubsub_message = base64.b64decode(cloud_event.data["message"]["data"]).decode("utf-8")
email_message = message_from_bytes(base64.b64decode(pubsub_message))
# Extract sender, recipient, and subject
sender_email = email_message.get("from", "").strip()
recipient_email = email_message.get("to", "").strip()
subject = email_message.get("subject", "").strip()
# Validate sender email
if sender_email not in ALLOWED_EMAILS:
print(f"Email from {sender_email} is not allowed. Ignoring.")
return
# Process attachments
for part in email_message.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
file_name = part.get_filename()
file_data = part.get_payload(decode=True)
if file_name:
save_to_storage(sender_email, file_name, file_data)
except Exception as e:
print(f"Error processing email attachment: {e}")
def save_to_storage(sender_email, file_name, file_data):
"""Save the attachment to Cloud Storage."""
folder_name = sender_email.replace("@", "at").replace(".", "_")
bucket = storage_client.bucket(ATTACHMENT_BUCKET)
blob = bucket.blob(f"{folder_name}/{file_name}")
blob.upload_from_string(file_data)
print(f"File {file_name} uploaded to folder {folder_name} in bucket {ATTACHMENT_BUCKET}.")
发布/订阅消息结构:
正确处理电子邮件附件是否需要特定的 Pub/Sub 消息结构?
电子邮件验证:
Gmail 或其他域等电子邮件提供商触发的 Pub/Sub 消息中的“发件人”或“收件人”字段格式是否不同?
附件处理:
是否有必须在云函数中显式处理的特定内容类型(例如,text/csv、application/vnd.ms-excel)?
测试环境:
调试 Pub/Sub 触发的云功能是否需要额外的步骤,特别是附件处理?
据我了解,您正在尝试将电子邮件附件保存到特定的 Google Cloud Storage,但没有附件保存到存储桶中。
您首先需要考虑的是关联服务帐号所需的权限或角色,以便在 Cloud Storage 存储桶中创建对象或验证该函数对 Cloud Storage 存储桶具有正确的权限。仔细检查存储对象管理员等角色或至少存储对象创建者。
回答您的问题:
正确处理电子邮件附件是否需要特定的 Pub/Sub 消息结构?
Gmail 或其他域等电子邮件提供商触发的 Pub/Sub 消息中的“发件人”或“收件人”字段格式是否不同?
是否有必须在云函数中显式处理的特定内容类型(例如text/csv、application/vnd.ms-excel)?
是的,您当前的代码不会检查附件的特定内容类型(例如应用程序/pdf、图像/jpeg)。如果您想按类型过滤附件(仅保存PDF或图像),可以修改代码以在保存文件之前检查
part.get\_content\_type()
。
if part.get_content_type() == 'application/pdf':
# Only save PDF attachments
file_name = part.get_filename()
file_data = part.get_payload(decode=True)
save_to_storage(sender_email, file_name, file_data)
调试 Pub/Sub 触发的云函数(特别是附件处理)是否需要额外的步骤?
例如:
print(f"Attachment found: {file_name}, Content-Type: {part.get_content_type()}")