web-dev-qa-db-ja.com

python=

GMail APIの例:メールの送信 のサンプルコードを使用し、認証のルールに従うと、プログラムで生成された電子メールをgmailアカウント経由で送信するのは簡単です。この例から明らかでないのは、そのメールをHTML形式に設定する方法です。


質問

pythonを使用して、gmail-api送信メッセージでHTMLフォーマットを取得するにはどうすればよいですか?

私はこれを持っています...

_message_body = "Hello!\nYou've just received a test message!\n\nSincerely,\n-Test Message Generator\n"_

そして、私はそれがこれになりたい...

_Hello!
You've just received a test message!

Sincerely,
-Test Message Generator
_

GMail-APIのソースコードの例

以下は、サンプルのわずかに変更されたバージョンですが、引き続き機能します。

_import argparse
import base64
from pprint import pformat
from pprint import pprint
import httplib2
import os
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText

from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage


SCOPES = 'https://mail.google.com/'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Test EMail App'


def get_credentials():
    """Gets valid user credentials from storage.

    If nothing has been stored, or if the stored credentials are invalid,
    the OAuth2 flow is completed to obtain the new credentials.

    Returns:
        Credentials, the obtained credential.
    """

    home_dir = os.path.expanduser('~')
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir,
                                   'gmail-python-quickstart.json')

    store = Storage(credential_path)
    credentials = store.get()
    if not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        if flags:
            credentials = tools.run_flow(flow, store, flags)
        else: # Needed only for compatibility with Python 2.6
            credentials = tools.run(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials

def create_message(sender, to, cc, subject, message_text):
    """Create a message for an email.

    Args:
    sender: Email address of the sender.
    to: Email address of the receiver.
    subject: The subject of the email message.
    message_text: The text of the email message.

    Returns:
    An object containing a base64url encoded email object.
    """
    print(sender + ', ' + to + ', ' + subject + ', ' + message_text)
    message = MIMEText(message_text)
    message['to'] = to
    message['from'] = sender
    message['subject'] = subject
    message['cc'] = cc
    pprint(message)
    return {'raw': base64.urlsafe_b64encode(message.as_string())}

def send_message(service, user_id, message_in):
    """Send an email message.

    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.
    message: Message to be sent.

    Returns:
    Sent Message.
    """
    pprint(message_in)
    try:
        message = (service.users().messages().send(userId=user_id, body=message_in).execute())
        pprint(message)
        print ('Message Id: %s' % message['id'])
        return message
    except errors.HttpError, error:
        print ('An error occurred: %s' % error)

def main(cli):
    """Shows basic usage of the Gmail API.

    Creates a Gmail API service object and outputs a list of label names
    of the user's Gmail account.
    """


    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('gmail', 'v1', http=http)

    email_msg = create_message(cli.addr_from, cli.addr_to, cli.addr_cc, cli.subject, cli.message)
    msg_out = service.users().messages().send(userId = 'me', body = email_msg).execute()
    pprint(msg_out)


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-m', '--message',   help = 'The message to send in the email', default='<MESSAGE = unfinished>')
    parser.add_argument('-t', '--addr_to',   help = 'the list of comma separated emails to send', default='[email protected]')
    parser.add_argument('-s', '--subject',   help = 'the email subject', default='<SUBJECT = undefined>')
    parser.add_argument('-c', '--addr_cc',   help = 'email CC\'s', default='')
    parser.add_argument('-f', '--addr_from', help = 'Email address to send from', default='[email protected]')
    cli = parser.parse_args()
    pprint(dir(cli))

    main(cli)
_

このコードとそのバリエーションを使用して、私は試しましたが、html形式のコードを取得することも、必要な場所にキャリッジリターンを作成するための簡単なエスケープ文字を取得することもできませんでした。


うまくいかなかったのは次のとおりです

以下を試してもうまくいきませんでした。

  1. _line 69_を変更して、追加のメッセージディクショナリパラメータを追加します...すなわち
    • {'raw': base64.urlsafe_b64encode(message.as_string()), 'payload': {'mimeType': 'text/html'}}
    • GMail API Docs に記載されているとおり
    • enter image description here
  2. エスケープされたさまざまなバックスラッシュをメッセージテキストに追加する:
    • _\n_...すなわち:_\\n_も_\\\n_であり、まさにそれらの正確な文字としてレンダリングされる
    • _<br> </br> <br/>_を追加しても新しい行は追加されず、正確な文字として表示されます
    • _\r_を追加しても新しい行は追加されず、正確な文字として表示されます

これは重複した質問ではない理由

23
Andrew

多くのことを掘り下げた後、メッセージ処理のpython側を調べ始めたところ、実際にメッセージを構築しているpythonオブジェクトbase64エンコード用にgmail-apiメッセージオブジェクトコンストラクターに送信されます。

上記の63行目を参照してください:message = MIMEText(message_text)

ヘッダー値とペイロードdict(messageオブジェクト)、設定することでした(_line 63_):

  • message = MIMEText(message_text, 'html') <-MIMETextオブジェクトコンストラクターの2番目のパラメーターとして_'html'_を追加します

Gmail API用にGoogleが提供するデフォルトコードは、プレーンテキストメールの送信方法のみを示していますが、その方法を隠しています。 ala ... message = MIMEText(message_text)

python class _email.mime.text.MIMEText_ オブジェクトを検索する必要がありました。MIMETextオブジェクトのコンストラクターの次の定義が表示されます。

  • class email.mime.text.MIMEText(_text [、_subtype [、_charset]])値を明示的に__subtype_に渡したいです。この場合、_'html'_を__subtype_として渡します。

これで、Googleによるメッセージへの予期しないWordラッピングの適用、またはPython _mime.text.MIMEText_オブジェクト


固定コード

_def create_message(sender, to, cc, subject, message_text):
    """Create a message for an email.

    Args:
    sender: Email address of the sender.
    to: Email address of the receiver.
    subject: The subject of the email message.
    message_text: The text of the email message.

    Returns:
    An object containing a base64url encoded email object.
    """
    print(sender + ', ' + to + ', ' + subject + ', ' + message_text)
    message = MIMEText(message_text,'html')
    message['to'] = to
    message['from'] = sender
    message['subject'] = subject
    message['cc'] = cc
    pprint(message)
    return {'raw': base64.urlsafe_b64encode(message.as_string())}
_
22
Andrew

これを試して:

    def CreateMessage(emailSubject, emailTo, emailFrom, message_body, emailCc, html_content=None):
        try:
            message = MIMEMultipart('alternative')
            message['to'] = emailTo
            message['from'] = emailFrom
            message['subject'] = emailSubject
            message['Cc'] = emailCc
            body_mime = MIMEText(message_body, 'plain')
            message.attach(body_mime)
            if html_content:
                html_mime = MIMEText(html_content, 'html')
                message.attach(html_mime)
            return {
                'raw': base64.urlsafe_b64encode(
                    bytes(
                        message.as_string(),
                        "utf-8")).decode("utf-8")}
        except Exception as e:
            print('Error in CreateMessage()', e)
            return '400'
0