سؤال

I've been using RSS2Email to turn Gmail into Google Reader.

I'd like to create a Google Apps Script to do this instead, to get two advantages:

  1. The scheduling would be handled by Google Apps Script. (No need to have a dedicated computer to run the script.)

  2. The resulting emails would be labeled per-feed, nicely organizing things.

Using Google Apps Script would be the same implementation spirit as e.g. Gmail Snooze.


I understand how to fetch the feeds. Where I'm stuck is how to create the emails using a specific label. The approaches I've investigated so far:

  1. The Gmail Service for Google Apps Scripts doesn't allow this, at least not obviously.
    • GmailApp.sendEmail doesn't let you specify a label. Which makes sense since this is for generic email sending. But ...
    • GmailApp.sendEmail returns GmailApp, not something you could use to ID the message and change its label later.
    • The service also doesn't appear to let you create Gmail filters programatically, ruling out another possible way to tackle this.
  2. The Gmail Migration API would be perfect to do this -- but it doesn't work for normal, consumer Gmail accounts. Gah.
  3. Google's IMAP extensions might allow this, but it's unclear to me.

I suppose I could use 1, putting some UID in the Subject that I could use to look up the delivered message, to add the label (and hopefully un-uglify the Subject by removing the UID). But that seems a bit kludgy.

Using 3, IMAP extensions, seems possibly less kludgy, although probably much more work to code and test.

Any recommendations among these? Is there some other API or strategy?

هل كانت مفيدة؟

المحلول

The Google Apps Script GmailApp API does not give a way to add a label to a message as you send it, something you can do from the UI. This appears as Issue 1859 in the issue tracker, visit and star it for updates.

A work-around would be to take advantage of the thread apis. If the message is blind-copied (bcc'd) to the sender, it will also appear as a new message in their inbox, where we can use getInboxThreads() to find it. Add the label to this thread, and optionally mark it read then archive it.

Code also available as a gist.

/**
 * An alternative to GmailApp.sendEmail(), which applies a
 * label to the message thread in the sender's account.
 *
 * Sends an email message with optional arguments. The email can
 * contain plain text or an HTML body. The size of the email
 * (including headers, but excluding attachments) may not
 * exceed 20KB.
 *
 * @param {String} recipient    the addresses of the recipient
 * @param {String} subject      the subject line
 * @param {String} body         the body of the email
 * @param {Object} options      a JavaScript object that specifies
 *                              advanced parameters, as documented
 *                              for GmailApp.sendEmail()
 * @param {String} label        the label to be applied
 */
function sendAndLabel(recipient, subject, body, options, label) {
  var sender = Session.getActiveUser().getEmail();

  // Add sender to bcc list
  if (options.bcc) {
    options.bcc = options.bcc.split(',').concat(sender).join(',');
  }
  else {
    options.bcc = sender;
  }

  GmailApp.sendEmail( recipient, subject, body, options )

  // Check if label already exists, create if it doesn't
  var newLabel = GmailApp.getUserLabelByName(label);
  if (!newLabel) newLabel = GmailApp.createLabel(label);

  // Look for our new message in inbox threads
  Utilities.sleep(2000); // Wait for message to be received
  var inboxThreads = GmailApp.getInboxThreads();
  for (var t = 0; t < inboxThreads.length; t++) {
    var foundSubject = inboxThreads[t].getFirstMessageSubject();
    var numLabels = inboxThreads[t].getLabels().length;  // Could add more criteria
    if (foundSubject === subject && numLabels === 0) {
      // Found our thread - label it
      inboxThreads[t].addLabel(newLabel)
                     .markRead()
                     .moveToArchive();
      break;
    }
  }
}

Example of use:

function test_sendAndLabel() {
  var recipient = Session.getActiveUser().getEmail();
  var subject = "Test Labelling";
  var body = "This email is testing message labelling.";
//  var options = {bcc:"someone@example.com"};
  var options = {};
  var label = "LabelTest";
  sendAndLabel(recipient, subject, body, options, label);
}

نصائح أخرى

yes, IMAP is the right way to go. You can find some third party IMAP lib to easy your job.

the command to add lable is : STORE 123 +X-GM-LABELS (yourLabel)

The official docs about Gmail label :

https://developers.google.com/google-apps/gmail/imap_extensions#access_to_gmail_labels_x-gm-labels

It would be convenient for GmailApp.sendEmail() to return a GmailMessage object so we can get its id and then assign a label. It doesn't, but you can use this workaround:

  1. Create the message as a draft using GmailApp.createDraft()

  2. Send the draft message using GmailDraft.send(). This method does return a GmailMessage object.

  3. Assign the label (either assign it to the whole thread with GmailMessage.getThread().addLabel() or if you want to assign it to the individual message, you'll have to use the Advanced Gmail service as described here).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top