GmailAPIを使用してGmailデータとGoogle python apiクライアントにアクセスしています。
メッセージの添付ファイルを取得するためのドキュメントによると、Python用のサンプルを1つ提供しました
https://developers.google.com/gmail/api/v1/reference/users/messages/attachments/get
しかし、私が試したのと同じコードで、エラーが発生します:
_AttributeError: 'Resource' object has no attribute 'user'
_
エラーが発生している行:
_message = service.user().messages().get(userId=user_id, id=msg_id).execute()
_
だから私はusers()
を置き換えてuser()
を試しました
_message = service.users().messages().get(userId=user_id, id=msg_id).execute()
_
しかし、私は_part['body']['data']
_で_for part in message['payload']['parts']
_を取得していません
@Ericの回答を拡張して、ドキュメントからGetAttachments関数の次の修正バージョンを作成しました。
# based on Python example from
# https://developers.google.com/gmail/api/v1/reference/users/messages/attachments/get
# which is licensed under Apache 2.0 License
import base64
from apiclient import errors
def GetAttachments(service, user_id, msg_id, prefix=""):
"""Get and store attachment from Message with given id.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
msg_id: ID of Message containing attachment.
prefix: prefix which is added to the attachment filename on saving
"""
try:
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
for part in message['payload']['parts']:
if part['filename']:
if 'data' in part['body']:
data=part['body']['data']
else:
att_id=part['body']['attachmentId']
att=service.users().messages().attachments().get(userId=user_id, messageId=msg_id,id=att_id).execute()
data=att['data']
file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))
path = prefix+part['filename']
with open(path, 'w') as f:
f.write(file_data)
except errors.HttpError, error:
print 'An error occurred: %s' % error
@ Ilya V. Schurovまたは@ Cam Tをフォローすると、添付ファイルを見逃す可能性があります。 -)回答、理由は、メールの構造がmimeType
に基づいて異なる可能性があるためです。
この回答 に触発されて、これが問題への私のアプローチです。
import base64
from apiclient import errors
def GetAttachments(service, user_id, msg_id, store_dir=""):
"""Get and store attachment from Message with given id.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
msg_id: ID of Message containing attachment.
store_dir: The directory used to store attachments.
"""
try:
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
parts = [message['payload']]
while parts:
part = parts.pop()
if part.get('parts'):
parts.extend(part['parts'])
if part.get('filename'):
if 'data' in part['body']:
file_data = base64.urlsafe_b64decode(part['body']['data'].encode('UTF-8'))
#self.stdout.write('FileData for %s, %s found! size: %s' % (message['id'], part['filename'], part['size']))
Elif 'attachmentId' in part['body']:
attachment = service.users().messages().attachments().get(
userId=user_id, messageId=message['id'], id=part['body']['attachmentId']
).execute()
file_data = base64.urlsafe_b64decode(attachment['data'].encode('UTF-8'))
#self.stdout.write('FileData for %s, %s found! size: %s' % (message['id'], part['filename'], attachment['size']))
else:
file_data = None
if file_data:
#do some staff, e.g.
path = ''.join([store_dir, part['filename']])
with open(path, 'w') as f:
f.write(file_data)
except errors.HttpError as error:
print 'An error occurred: %s' % error
上記のコードをテストしましたが、機能しませんでした。そして、私は他の投稿のためにいくつかのものを更新しました。 WriteFileError
import base64
from apiclient import errors
def GetAttachments(service, user_id, msg_id, prefix=""):
"""Get and store attachment from Message with given id.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
msg_id: ID of Message containing attachment.
prefix: prefix which is added to the attachment filename on saving
"""
try:
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
for part in message['payload'].get('parts', ''):
if part['filename']:
if 'data' in part['body']:
data=part['body']['data']
else:
att_id=part['body']['attachmentId']
att=service.users().messages().attachments().get(userId=user_id, messageId=msg_id,id=att_id).execute()
data=att['data']
file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))
path = prefix+part['filename']
with open(path, 'wb') as f:
f.write(file_data)
except errors.HttpError as error:
print('An error occurred: %s' % error)
それは間違いなく「users()」です。応答メッセージの形式は、使用する形式パラメーターに大きく依存します。デフォルト(FULL)を使用する場合、パーツにはpart ['body'] ['data']が含まれるか、データが大きい場合は、messages()。attachments()に渡すことができる「attachment_id」フィールドが含まれます。取得する()。
添付ファイルのドキュメントを見ると、次のことがわかります。 https://developers.google.com/gmail/api/v1/reference/users/messages/attachments
(これがメインメッセージのドキュメントページにも記載されていればいいでしょう。)
上記のコードに次の変更を加えました。添付ドキュメントが含まれるすべてのメールIDで問題なく動作します。これが役立つことを願っています。これは、APIの例ではエラーキーが表示されるためです。
def GetAttachments(service, user_id, msg_id, store_dir):
"""Get and store attachment from Message with given id.
Args:
service: Authorized Gmail API service instance.
user_id: User's email address. The special value "me"
can be used to indicate the authenticated user.
msg_id: ID of Message containing attachment.
prefix: prefix which is added to the attachment filename on saving
"""
try:
message = service.users().messages().get(userId=user_id, id=msg_id).execute()
for part in message['payload']['parts']:
newvar = part['body']
if 'attachmentId' in newvar:
att_id = newvar['attachmentId']
att = service.users().messages().attachments().get(userId=user_id, messageId=msg_id, id=att_id).execute()
data = att['data']
file_data = base64.urlsafe_b64decode(data.encode('UTF-8'))
print(part['filename'])
path = ''.join([store_dir, part['filename']])
f = open(path, 'wb')
f.write(file_data)
f.close()
except errors.HttpError, error:
print 'An error occurred: %s' % error