Create and send email messages
Stay organized with collections
Save and categorize content based on your preferences.
This document explains how to create and send email messages using the Gmail API.
There are two ways to send email using the Gmail API:
- You can send it directly using the
messages.sendmethod. - You can send it from a draft, using the
drafts.sendmethod. For more information on sending a draft message, see Send drafts.
Gmail messages are sent as base64URL encoded strings within the
raw
field of a messages
resource. To send an email message:
- Create the email content and encode it as a base64URL string.
- Create a new message resource and set its
rawproperty to the base64URL string you just created. - Call the
messages.sendmethod, or, if sending a draft, call thedrafts.sendmethod, to send the message.
The details of this workflow can vary depending on your choice of client library and programming language.
Create messages
The Gmail API requires MIME email messages compliant with RFC 2822 and encoded as base64URL strings. Many programming languages have libraries or utilities that simplify the process of creating and encoding MIME messages.
The following code samples show how to create a MIME message using Google API client libraries for various languages:
Java
Creating an email message can be simplified with the MimeMessage class in
the javax.mail.internet package. The following code sample shows how to
create the email message, including the headers:
importjava.util.Properties; importjavax.mail.MessagingException; importjavax.mail.Session; importjavax.mail.internet.InternetAddress; importjavax.mail.internet.MimeMessage; /* Class to demonstrate the use of Gmail Create Email API */ publicclass CreateEmail{ /** * Create a MimeMessage using the parameters provided. * * @param toEmailAddress email address of the receiver * @param fromEmailAddress email address of the sender, the mailbox account * @param subject subject of the email * @param bodyText body text of the email * @return the MimeMessage to be used to send email * @throws MessagingException - if a wrongly formatted address is encountered. */ publicstaticMimeMessagecreateEmail(StringtoEmailAddress, StringfromEmailAddress, Stringsubject, StringbodyText) throwsMessagingException{ Propertiesprops=newProperties(); Sessionsession=Session.getDefaultInstance(props,null); MimeMessageemail=newMimeMessage(session); email.setFrom(newInternetAddress(fromEmailAddress)); email.addRecipient(javax.mail.Message.RecipientType.TO, newInternetAddress(toEmailAddress)); email.setSubject(subject); email.setText(bodyText); returnemail; } }
Next, encode the MimeMessage, instantiate a messages object, and set the
base64URL encoded message string as the value of the raw property.
importcom.google.api.services.gmail.model.Message; importjava.io.ByteArrayOutputStream; importjava.io.IOException; importjavax.mail.MessagingException; importjavax.mail.internet.MimeMessage; importorg.apache.commons.codec.binary.Base64; /* Class to demonstrate the use of Gmail Create Message API */ publicclass CreateMessage{ /** * Create a message from an email. * * @param emailContent Email to be set to raw of message * @return a message containing a base64url encoded email * @throws IOException - if service account credentials file not found. * @throws MessagingException - if a wrongly formatted address is encountered. */ publicstaticMessagecreateMessageWithEmail(MimeMessageemailContent) throwsMessagingException,IOException{ ByteArrayOutputStreambuffer=newByteArrayOutputStream(); emailContent.writeTo(buffer); byte[]bytes=buffer.toByteArray(); StringencodedEmail=Base64.encodeBase64URLSafeString(bytes); Messagemessage=newMessage(); message.setRaw(encodedEmail); returnmessage; } }
Python
The following code sample shows how to create a MIME message, encode it to a
base64URL string, and assign it to the raw field of the messages
resource:
importbase64 fromemail.messageimport EmailMessage importgoogle.auth fromgoogleapiclient.discoveryimport build fromgoogleapiclient.errorsimport HttpError defgmail_create_draft(): """Create and insert a draft email. Print the returned draft's message and id. Returns: Draft object, including draft id and message meta data. Load pre-authorized user credentials from the environment. TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for the application. """ creds, _ = google.auth.default() try: # create gmail api client service = build("gmail", "v1", credentials=creds) message = EmailMessage() message.set_content("This is automated draft mail") message["To"] = "gduser1@workspacesamples.dev" message["From"] = "gduser2@workspacesamples.dev" message["Subject"] = "Automated draft" # encoded message encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode() create_message = {"message": {"raw": encoded_message}} # pylint: disable=E1101 draft = ( service.users() .drafts() .create(userId="me", body=create_message) .execute() ) print(f'Draft id: {draft["id"]}\nDraft message: {draft["message"]}') except HttpError as error: print(f"An error occurred: {error}") draft = None return draft if __name__ == "__main__": gmail_create_draft()
cURL
curl--requestPOST\
'https://gmail.googleapis.com/gmail/v1/users/me/drafts'\
--header'Authorization: Bearer ACCESS_TOKEN'\
--header'Accept: application/json'\
--header'Content-Type: application/json'\
--data'{"message":{"raw":"MESSAGE"}}'
Replace the following:
ACCESS_TOKEN: the access token that grants access to the API.MESSAGE: the RFC 2822 formatted MIME message, encoded as base64URL.
Create messages with attachments
Creating a message with an attachment is like creating any other message, but the process of uploading the file as a multi-part MIME message depends on the programming language.
The following code samples show possible ways of creating a multi-part MIME message with an attachment:
Java
The following code sample shows how to create a multi-part MIME message. The encoding and assignment steps are the same as create messages.
importcom.google.api.client.googleapis.json.GoogleJsonError; importcom.google.api.client.googleapis.json.GoogleJsonResponseException; importcom.google.api.client.http.HttpRequestInitializer; importcom.google.api.client.http.javanet.NetHttpTransport; importcom.google.api.client.json.gson.GsonFactory; importcom.google.api.services.gmail.Gmail; importcom.google.api.services.gmail.GmailScopes; importcom.google.api.services.gmail.model.Draft; importcom.google.api.services.gmail.model.Message; importcom.google.auth.http.HttpCredentialsAdapter; importcom.google.auth.oauth2.GoogleCredentials; importjava.io.ByteArrayOutputStream; importjava.io.File; importjava.io.IOException; importjava.util.Properties; importjavax.activation.DataHandler; importjavax.activation.DataSource; importjavax.activation.FileDataSource; importjavax.mail.MessagingException; importjavax.mail.Multipart; importjavax.mail.Session; importjavax.mail.internet.InternetAddress; importjavax.mail.internet.MimeBodyPart; importjavax.mail.internet.MimeMessage; importjavax.mail.internet.MimeMultipart; importorg.apache.commons.codec.binary.Base64; /* Class to demonstrate the use of Gmail Create Draft with attachment API */ publicclass CreateDraftWithAttachment{ /** * Create a draft email with attachment. * * @param fromEmailAddress - Email address to appear in the from: header. * @param toEmailAddress - Email address of the recipient. * @param file - Path to the file to be attached. * @return the created draft, {@code null} otherwise. * @throws MessagingException - if a wrongly formatted address is encountered. * @throws IOException - if service account credentials file not found. */ publicstaticDraftcreateDraftMessageWithAttachment(StringfromEmailAddress, StringtoEmailAddress, Filefile) throwsMessagingException,IOException{ /* Load pre-authorized user credentials from the environment. TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for your application.*/ GoogleCredentialscredentials=GoogleCredentials.getApplicationDefault() .createScoped(GmailScopes.GMAIL_COMPOSE); HttpRequestInitializerrequestInitializer=newHttpCredentialsAdapter(credentials); // Create the gmail API client Gmailservice=newGmail.Builder(newNetHttpTransport(), GsonFactory.getDefaultInstance(), requestInitializer) .setApplicationName("Gmail samples") .build(); // Create the email content StringmessageSubject="Test message"; StringbodyText="lorem ipsum."; // Encode as MIME message Propertiesprops=newProperties(); Sessionsession=Session.getDefaultInstance(props,null); MimeMessageemail=newMimeMessage(session); email.setFrom(newInternetAddress(fromEmailAddress)); email.addRecipient(javax.mail.Message.RecipientType.TO, newInternetAddress(toEmailAddress)); email.setSubject(messageSubject); MimeBodyPartmimeBodyPart=newMimeBodyPart(); mimeBodyPart.setContent(bodyText,"text/plain"); Multipartmultipart=newMimeMultipart(); multipart.addBodyPart(mimeBodyPart); mimeBodyPart=newMimeBodyPart(); DataSourcesource=newFileDataSource(file); mimeBodyPart.setDataHandler(newDataHandler(source)); mimeBodyPart.setFileName(file.getName()); multipart.addBodyPart(mimeBodyPart); email.setContent(multipart); // Encode and wrap the MIME message into a gmail message ByteArrayOutputStreambuffer=newByteArrayOutputStream(); email.writeTo(buffer); byte[]rawMessageBytes=buffer.toByteArray(); StringencodedEmail=Base64.encodeBase64URLSafeString(rawMessageBytes); Messagemessage=newMessage(); message.setRaw(encodedEmail); try{ // Create the draft message Draftdraft=newDraft(); draft.setMessage(message); draft=service.users().drafts().create("me",draft).execute(); System.out.println("Draft id: "+draft.getId()); System.out.println(draft.toPrettyString()); returndraft; }catch(GoogleJsonResponseExceptione){ // TODO(developer) - handle error appropriately GoogleJsonErrorerror=e.getDetails(); if(error.getCode()==403){ System.err.println("Unable to create draft: "+e.getDetails()); }else{ throwe; } } returnnull; } }
Python
Similar to the create messages example, this example
also handles encoding the message to base64URL and assigning it to the raw
field of the messages resource.
importbase64 importmimetypes importos fromemail.messageimport EmailMessage fromemail.mime.audioimport MIMEAudio fromemail.mime.baseimport MIMEBase fromemail.mime.imageimport MIMEImage fromemail.mime.textimport MIMEText importgoogle.auth fromgoogleapiclient.discoveryimport build fromgoogleapiclient.errorsimport HttpError defgmail_create_draft_with_attachment(): """Create and insert a draft email with attachment. Print the returned draft's message and id. Returns: Draft object, including draft id and message meta data. Load pre-authorized user credentials from the environment. TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for the application. """ creds, _ = google.auth.default() try: # create gmail api client service = build("gmail", "v1", credentials=creds) mime_message = EmailMessage() # headers mime_message["To"] = "gduser1@workspacesamples.dev" mime_message["From"] = "gduser2@workspacesamples.dev" mime_message["Subject"] = "sample with attachment" # text mime_message.set_content( "Hi, this is automated mail with attachment.Please do not reply." ) # attachment attachment_filename = "photo.jpg" # guessing the MIME type type_subtype, _ = mimetypes.guess_type(attachment_filename) maintype, subtype = type_subtype.split("/") with open(attachment_filename, "rb") as fp: attachment_data = fp.read() mime_message.add_attachment(attachment_data, maintype, subtype) encoded_message = base64.urlsafe_b64encode(mime_message.as_bytes()).decode() create_draft_request_body = {"message": {"raw": encoded_message}} # pylint: disable=E1101 draft = ( service.users() .drafts() .create(userId="me", body=create_draft_request_body) .execute() ) print(f'Draft id: {draft["id"]}\nDraft message: {draft["message"]}') except HttpError as error: print(f"An error occurred: {error}") draft = None return draft defbuild_file_part(file): """Creates a MIME part for a file. Args: file: The path to the file to be attached. Returns: A MIME part that can be attached to a message. """ content_type, encoding = mimetypes.guess_type(file) if content_type is None or encoding is not None: content_type = "application/octet-stream" main_type, sub_type = content_type.split("/", 1) if main_type == "text": with open(file, "rb"): msg = MIMEText("r", _subtype=sub_type) elif main_type == "image": with open(file, "rb"): msg = MIMEImage("r", _subtype=sub_type) elif main_type == "audio": with open(file, "rb"): msg = MIMEAudio("r", _subtype=sub_type) else: with open(file, "rb"): msg = MIMEBase(main_type, sub_type) msg.set_payload(file.read()) filename = os.path.basename(file) msg.add_header("Content-Disposition", "attachment", filename=filename) return msg if __name__ == "__main__": gmail_create_draft_with_attachment()
cURL
curl--requestPOST\
'https://gmail.googleapis.com/gmail/v1/users/me/drafts'\
--header'Authorization: Bearer ACCESS_TOKEN'\
--header'Accept: application/json'\
--header'Content-Type: application/json'\
--data'{"message":{"raw":"MESSAGE"}}'
Replace the following:
ACCESS_TOKEN: the access token that grants access to the API.MESSAGE: the RFC 2822 formatted MIME message containing an attachment, encoded as base64URL.
Send messages
Once you have created a message, you can send it by supplying it in the request
body of the
messages.send
method, as shown in the following examples:
Java
importcom.google.api.client.googleapis.json.GoogleJsonError; importcom.google.api.client.googleapis.json.GoogleJsonResponseException; importcom.google.api.client.http.HttpRequestInitializer; importcom.google.api.client.http.javanet.NetHttpTransport; importcom.google.api.client.json.gson.GsonFactory; importcom.google.api.services.gmail.Gmail; importcom.google.api.services.gmail.GmailScopes; importcom.google.api.services.gmail.model.Message; importcom.google.auth.http.HttpCredentialsAdapter; importcom.google.auth.oauth2.GoogleCredentials; importjava.io.ByteArrayOutputStream; importjava.io.IOException; importjava.util.Properties; importjavax.mail.MessagingException; importjavax.mail.Session; importjavax.mail.internet.InternetAddress; importjavax.mail.internet.MimeMessage; importorg.apache.commons.codec.binary.Base64; /* Class to demonstrate the use of Gmail Send Message API */ publicclass SendMessage{ /** * Send an email from the user's mailbox to its recipient. * * @param fromEmailAddress - Email address to appear in the from: header * @param toEmailAddress - Email address of the recipient * @return the sent message, {@code null} otherwise. * @throws MessagingException - if a wrongly formatted address is encountered. * @throws IOException - if service account credentials file not found. */ publicstaticMessagesendEmail(StringfromEmailAddress, StringtoEmailAddress) throwsMessagingException,IOException{ /* Load pre-authorized user credentials from the environment. TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for your application.*/ GoogleCredentialscredentials=GoogleCredentials.getApplicationDefault() .createScoped(GmailScopes.GMAIL_SEND); HttpRequestInitializerrequestInitializer=newHttpCredentialsAdapter(credentials); // Create the gmail API client Gmailservice=newGmail.Builder(newNetHttpTransport(), GsonFactory.getDefaultInstance(), requestInitializer) .setApplicationName("Gmail samples") .build(); // Create the email content StringmessageSubject="Test message"; StringbodyText="lorem ipsum."; // Encode as MIME message Propertiesprops=newProperties(); Sessionsession=Session.getDefaultInstance(props,null); MimeMessageemail=newMimeMessage(session); email.setFrom(newInternetAddress(fromEmailAddress)); email.addRecipient(javax.mail.Message.RecipientType.TO, newInternetAddress(toEmailAddress)); email.setSubject(messageSubject); email.setText(bodyText); // Encode and wrap the MIME message into a gmail message ByteArrayOutputStreambuffer=newByteArrayOutputStream(); email.writeTo(buffer); byte[]rawMessageBytes=buffer.toByteArray(); StringencodedEmail=Base64.encodeBase64URLSafeString(rawMessageBytes); Messagemessage=newMessage(); message.setRaw(encodedEmail); try{ // Create send message message=service.users().messages().send("me",message).execute(); System.out.println("Message id: "+message.getId()); System.out.println(message.toPrettyString()); returnmessage; }catch(GoogleJsonResponseExceptione){ // TODO(developer) - handle error appropriately GoogleJsonErrorerror=e.getDetails(); if(error.getCode()==403){ System.err.println("Unable to send message: "+e.getDetails()); }else{ throwe; } } returnnull; } }
Python
importbase64 fromemail.messageimport EmailMessage importgoogle.auth fromgoogleapiclient.discoveryimport build fromgoogleapiclient.errorsimport HttpError defgmail_send_message(): """Create and send an email message Print the returned message id Returns: Message object, including message id Load pre-authorized user credentials from the environment. TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for the application. """ creds, _ = google.auth.default() try: service = build("gmail", "v1", credentials=creds) message = EmailMessage() message.set_content("This is automated draft mail") message["To"] = "gduser1@workspacesamples.dev" message["From"] = "gduser2@workspacesamples.dev" message["Subject"] = "Automated draft" # encoded message encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode() create_message = {"raw": encoded_message} # pylint: disable=E1101 send_message = ( service.users() .messages() .send(userId="me", body=create_message) .execute() ) print(f'Message Id: {send_message["id"]}') except HttpError as error: print(f"An error occurred: {error}") send_message = None return send_message if __name__ == "__main__": gmail_send_message()
cURL
curl--requestPOST\
'https://gmail.googleapis.com/gmail/v1/users/me/messages/send'\
--header'Authorization: Bearer ACCESS_TOKEN'\
--header'Accept: application/json'\
--header'Content-Type: application/json'\
--data'{"raw":"MESSAGE"}'
Replace the following:
ACCESS_TOKEN: the access token that grants access to the API.MESSAGE: the RFC 2822 formatted MIME message, encoded as base64URL.
If you're trying to send a reply and want the email to be grouped into a thread, make sure that:
- The
Subjectheaders match - The
ReferencesandIn-Reply-Toheaders follow the RFC 2822 standard.