How Do I Automate Fill of GMail Compose Form?

Thank you for this macro, I use it a lot to click buttons on certain web pages.
I'm trying to get it to recognize fields in the Gmail compose window, is that possible?
I'd like to 'target' the 'To', 'Subject' and 'Body' fields in the compose window.

FYI - I tried using the 'set safari field' action to no avail.

Using the Google Chrome Inspect tool, I discovered that the Gmail Compose window offers HTML Element Ids for each of the fields. For example, the Subject field id is ":h7".

Since we have the Element Id, it is easier to just use the document.getElementById() method, rather than using XPath.

So, I used this JavaScript to set the Subject field:

var subjectElem = document.getElementById(":h7")
subjectElem.value = "My TEST Subject"

You would, of course, put all of the JavaScript in a JavaScript in Browser Action.

Hopefully this will be enough to get you started. Good luck!

YIKES! this would be very big indeed IF I could get it to work.
JS is well above my pay grade.
I did copy your suggested JS

var subjectElem = document.getElementById(":h7")
subjectElem.value = “My TEST Subject”

and enter it into an Execute JavaScript in Safari to no avail.
Could you possible push me a little further toward the solution?
I ultimately would like to set the filed ID to a KM variable so that when google changes it’s field codes, I can change one ‘master’ variable and it well effect the 100 or so macros that I will create that use that filed ID.
Or even the whole JS string in a variable that can globally be adjusted.

Also, how did you get the element ID? So that I can get the other fields?

If I could only get the To, From, Subject and Body IDs in a Gmail Compose window, and set them from a variable, my whole work flow will change. More than it already has since KM came along!!!

I just tested the below macro in both Safari and Chrome, and it worked as expected.

MACRO:   GMail Compose Test

VER: 1.0    2016-10-21 ~~~


GMail Compose Test.kmmacros (3.6 KB)


  1. Open Safari or Chrome
  2. Open and sign in to your GMail account
  3. Click on the "Compose" Button"
  4. Trigger this macro


Uses this simple test JavaScript

var subjectElem = document.getElementById(":h7");
subjectElem.value = "My TEST Subject";

See this video to learn how to inspect a web page and find the Element ID and XPath:
Video -- How to Inspect Web Page to Find Element ID and XPath



Maybe this screenshot will help:

1 Like

@troy, I split your question and replies into a new topic since it is significantly different subject and deserves its own topic so others can find it more easily.

thank you for your replies.
Seems that the ID changes every time I open a new compose window.
When I put in the appropriate ID, of course it works.
Problem is, it’s never the same, not consistent.
Is there a way to automate getting that ID, ‘under’ the hood seamlessly?
Or maybe there is a way to get the ‘document.forms’ type of date that can be used in the
action-set safari field to text. ??

In addition, the body field does not have an ID.

That's strange. For me, the IDs are always the same, including the one for "body":

Another approach would be to use the querySelectorAll() method:

var subjectElem = document.querySelectorAll('[name="subjectbox"]');

I have NOT really tested this approach, so you may need to experiment to get it just right.

Hi J, my ID’s keep changing. sometimes alternating between two values, but upon restarting the browser, they are 2 completely different values.
I guess I’ll use the ole’ method of waiting for the compose window to ‘settle’ and then use tabs to go to and fill in the appropriate fields, it was worth a try, and I appreciate your help and awesome effort, thanx.
Can’t get the ‘name’ of the field to work with the subject, IF I could that could be a solution. I see on Chrome , the Body does have a ‘name’ , but on Safari inspect, it doesn’t. hmmm.
Could you get subjectbox method to work?

@troy, what you are seeing is consistently different from what I am seeing.

For example, I just tested this in Safari:

var subjectElem = document.querySelectorAll('[name="subjectbox"]');
subjectElem[0].value = "MY TEST Subject";

Also, the body always has both an ID and name for me.

Sorry, but I don't think I can be of much more help to you.
Since you continually see different HTML than I do, I can't really diagnose your issues.
With a little bit of research and trial and error you should be able to get this to work.

BTW, I'm running macOS 10.11.4.
What version are you running?

with your help, I can now populate both the 'to' field and the 'subject' field by name.
Can't quite get the 'body'. My html doesn't show a name, I did try 'message body' as a name and also role="textbox". And as a 'aria-label' all to no avail.
this is the code I see in Chrome for the 'body' field.
Running 10.12

Is there a way to ‘insert’ the text in the field and not over write any text that may be in the field already.

var subjectElem = document.querySelectorAll(’[name=“subjectbox”]’);
subjectElem[0].value = “Test Subject”;

if the subjectbox already had the text ‘hello world’ then the resulting subjectbox would be "hello worldTestSubject"
many thanx

Just use the += operator:

subjectElem[0].value += "Test Subject";
1 Like

ah, most excellent!

a little help here, is it not a good practice to say ‘thank you’ etc to posts?
that brings it back to the top, maybe the power users don’t like that?

  • just want to do whats best and not intrusive to the community, and yet I like to express my gratitude.

Hey Troy,

Simple Thank You's are really a waste of space.

Use the heart-button to “like” a post instead.

NOTE: I break this rule on occasion when someone deserves real praise.



I am experiencing the same issue that troy previously referenced in that I am unable to discern a consistent tag name or id associated with the body of a received Gmail message! I can successfully identify and obtain the message sender and subject with the approach below, but not the message body.

I have placed the cursor at the start of the message body on my screen and selected Inspect to yield the following.

Can anyone provide guidance?

Hey @KM_Panther,

This works reliably for me.


set jsCmdStr to "
document.getElementsByClassName('Am Al editable LW-avf')[0].outerHTML
set theResult to doJavaScriptInSafari(jsCmdStr)

on doJavaScriptInSafari(jsCMD)
      tell application "Safari" to do JavaScript jsCMD in front document
   on error e
      error "Error in handler doJavaScriptInSafari() of library NLb!" & return & return & e
   end try
end doJavaScriptInSafari

What exactly are you trying to do?



My ultimate goal is to automagically respond to the received message based upon its sender, subject and a specific word(s) found in the message body. Specifically in one case, if the message is from corporate purchasing containing the word "approval", I'll provide my authorization for the purchase with a canned message using the subject content.

Unfortunately, I've not been able to capture the message body. My attempted modification of your script for a received Chrome Gmail message yields the following script editor error:

I need additional guidance on using your script to capture the message body.

If you are unable to script the gmail web client, you might consider using another email app for the Mac (like Apple Mail or Outlook) that is scriptable and supports gmail. I have had great success with Outlook 2011 (can't speak for the latest ver, 2016).


While I probably could as I'm already non-compliant as the only macOS user in the company, all my work material and communications is accomplished through Chrome and Gmail.

I've assumed that my difficulty with Chris' script is my fault as I get the following error after breaking the script down to: