0

I am using httplib2 with the Mailgun API to send an email attachment which I downloaded using the Google Drive, the email is sending but without attachments.. below is my code..

DRIVE = discovery.build('drive', 'v3', http=http_auth)

        request = DRIVE.files().export_media(fileId=file_id, mimeType='application/pdf')

        fh = io.BytesIO()
        downloader = MediaIoBaseDownload(fh, request)

        done = False
        while done is False:
            status, done = downloader.next_chunk()
            logging.info("Download %d%%." % int(status.progress() * 100))

        messages = {
            "from": sender,
            "to": recipient,
            "subject": 'Attachment Mail from Mailgun',
            "text": 'Testing',
            "attachment": fh.getvalue()
        }

         url = URL

        data = {
            "from": messages['from'],
            "to": messages['to'],
            "subject": messages['subject'],
            "text": messages['text'],
            "attachment": messages['attachment']
        }

        pl = urllib.urlencode(data)

        http = httplib2.Http()
        http.add_credentials('api', API)

        resp, content = http.request(
            url, 'POST', pl,
            headers={"Content-Type": "application/x-www-form-urlencoded"})
Isaac
  • 296
  • 1
  • 4
  • 14

3 Answers3

1

We use the mailgun API to send emails using Appengine and reading from cloud storage, the same principles will apply to google drive:

The first thing I would suggest is looking into StringIO. It allows you to simulate working with files inside the appengine sandbox in an easier way than BytesIO, but both produce what python calls file objects that support .read() so this should work with both.

Once you have your file as a file like object, you just need to pass it correctly to the API. The following example uses the requests library as it makes it really easy to POST with files and is compatible with appengine.

Notice that in this case open(FILE_PATH_1, 'rb') is a file like object, you just need to replace that with your file object:

def send_complex_message():
    return requests.post("https://api.mailgun.net/v2/DOMAIN/messages",
          auth=("api", "key-SECRET"),
          files={
              "attachment[0]": ("FileName1.ext", open(FILE_PATH_1, 'rb')),
              "attachment[1]": ("FileName2.ext", open(FILE_PATH_2, 'rb'))
          },
          data={"from": "FROM_EMAIL",
                "to": [TO_EMAIL],
                "subject": SUBJECT,
                "html": HTML_CONTENT
          })
Zebs
  • 5,378
  • 2
  • 35
  • 49
0

def send_mailgun(to,subject,html,file,file_name,cc,bcc ):

MAILGUN_URL='https://api.mailgun.net/v3/DOMAIN/messages' MAILGUN_KEY='key-secret'

data = { "subject": subject, "from": "FROM_EMAIL", "to": to, "html": html }

if cc!="": data["cc"] = cc

if bcc!="": data["bcc"] = bcc

if file_name and file_name!="": resp = requests.post( MAILGUN_URL, auth=("api", MAILGUN_KEY), files=[("attachment", (file_name,file))], data=data) else: resp = requests.post( MAILGUN_URL, auth=("api", MAILGUN_KEY), data=data)

0

This is late though... I solved this long time ago.. below was what I did:

import io
import base64
from google.appengine.api import urlfetch
from libs.poster.encode import multipart_encode, MultipartParam

from oauth2client.appengine import AppAssertionCredentials
from googleapiclient.http import MediaIoBaseDownload
from apiclient.discovery import build
from httplib2 import Http

request = drive.files().export_media(fileId=spreadsheet_id, mimeType='application/pdf')

        fh = io.BytesIO()
        downloader = MediaIoBaseDownload(fh, request)

        done = False
        while done is False:
            status, done = downloader.next_chunk()

        message = {
            'from': 'noreply',
            'to': 'recipient',
            'subject': mail_subject,
            'text': text,
            'filename': filename,
            'attachment': fh.getvalue()
        }

        # send email using mailgun
        resp = send_attachment_email(message)


# Compose an email with an attachment
def send_attachment_email(messages):

url = 'mailgun_api_url'
api = 'api-key'

load = {
    "from": messages['from'],
    "to": messages['to'],
    "subject": messages['subject'],
    "text": messages['text'],
    "attachment": MultipartParam(
        "attachment",
        filename=messages['filename'],
        filetype='application/pdf',
        value=messages['attachment'])
}

payload, hd = multipart_encode(load)

hd['Authorization'] = 'Basic %s' % (base64.b64encode(api),)

resp = urlfetch.fetch(url=url, payload="".join(payload), method='POST',
                      headers=hd, validate_certificate=True)
logging.info(resp.status_code)
logging.info(resp.content)

return resp.status_code
Isaac
  • 296
  • 1
  • 4
  • 14