Как извлечь адреса электронной почты, помеченные определенным ярлыком Gmail

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Extract Emails')
      .addItem('Extract Emails...', 'extractEmails')
      .addToUi();
}

// extract emails from label in Gmail
function extractEmails() {
  
  // get the spreadsheet
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet();
  var label = sheet.getRange(1,2).getValue();
  
  // get all email threads that match label from Sheet
  var threads = GmailApp.search("label:" + label);
  
  // get all the messages for the current batch of threads
  var messages = GmailApp.getMessagesForThreads(threads);
  
  var emailArray = [];
  
  // get array of email addresses and subjects
  messages.forEach(function(message) {
    message.forEach(function(d) {
      emailArray.push([d.getFrom(), d.getTo(), d.getSubject()]);
    });
  });
  
  // de-duplicate the array based on email addresses
  var uniqueEmailArray = emailArray.filter(function(item, pos, self) {
    return self.findIndex(e => e[0] === item[0] && e[1] === item[1]) === pos;
  });
  
  var cleanedEmailArray = uniqueEmailArray.map(function(el) {
    var name = "";
    var email = "";
    var subject = el[2];
    
    var matches = el[0].match(/\s*"?([^"<>]*)"?\s+<(.+)>/);
    
    if (matches) {
      name = matches[1]; 
      email = matches[2];
    } else {
      name = "N/k";
      email = el[0];
    }
    
    return [name, email, subject];
  }).filter(function(d) {
    if (
         d[1] !== "annaoleks88@gmail.com" &&
         d[1] !== "_casper_1983@inbox.ru" 
       ) {
      return d;
    }
  });
  
  // clear any old data
  sheet.getRange(4,1,sheet.getLastRow(),3).clearContent();
  
  // paste in new names, emails, and subjects and sort by email address A - Z
  sheet.getRange(4,1,cleanedEmailArray.length,3).setValues(cleanedEmailArray).sort(2);
}

1. Добавление настраиваемого меню в Google Sheets

function onOpen() {
  let ui = SpreadsheetApp.getUi();
  ui.createMenu('Extract Emails')
      .addItem('Extract Emails...', 'extractEmails')
      .addToUi();
}

onOpen() – это функция, которая выполняется автоматически при открытии Google Таблицы.

SpreadsheetApp.getUi() – получает объект пользовательского интерфейса (UI) Google Таблицы.

createMenu('Extract Emails') – создаёт новое меню с именем Extract Emails в Google Sheets.

.addItem('Extract Emails...', 'extractEmails') – добавляет в меню пункт Extract Emails..., при выборе которого вызывается функция extractEmails().

.addToUi() – добавляет созданное меню в пользовательский интерфейс Google Sheets.

2. Функция extractEmails(): Извлечение email-адресов из Gmail

function extractEmails() {

Функция extractEmails() будет извлекать email-адреса из почты и вставлять их в таблицу.

2.1. Получение активного листа и ярлыка Gmail

let ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getActiveSheet();
let label = sheet.getRange(1,2).getValue();

SpreadsheetApp.getActiveSpreadsheet() – получает активную электронную таблицу.

ss.getActiveSheet() – получает текущий (активный) лист.

sheet.getRange(1,2).getValue() – получает значение из ячейки B1 (первая строка, второй столбец). В этой ячейке пользователь должен указать название ярлыка Gmail, из которого нужно извлечь email-адреса.

2.2. Поиск писем в Gmail по ярлыку

let threads = GmailApp.search("label:" + label);

GmailApp.search("label:" + label) – выполняет поиск писем в Gmail по указанному ярлыку. Возвращает массив объектов “почтовый поток” (threads).

2.3. Получение всех сообщений из найденных потоков

let messages = GmailApp.getMessagesForThreads(threads);

GmailApp.getMessagesForThreads(threads) – получает все сообщения для каждого потока из массива threads.

Возвращает массив массивов, где каждый подмассив содержит сообщения из одного почтового потока.

2.4. Извлечение email-адресов

let emailArray = [];
messages.forEach(function(message) {
  message.forEach(function(d) {
    emailArray.push([d.getFrom(), d.getTo(), d.getSubject()]);
  });
});

let emailArray = []; – создаётся пустой массив для хранения email-адресов.

messages.forEach(function(message) {...}) – проходим по каждому массиву сообщений в messages.

message.forEach(function(d) {...}) – проходим по каждому сообщению внутри одного почтового потока.

d.getFrom() – получает email-адрес отправителя.

d.getTo() – получает email-адрес получателя.

d.getSubject() – получаем тему письма.

emailArray.push(d.getFrom(), d.getTo()); – добавляем оба email-адреса в массив emailArray.

2.5. Удаление дубликатов

let uniqueEmailArray = emailArray.filter(function(item, pos, self) {
  return self.findIndex(e => e[0] === item[0] && e[1] === item[1]) === pos;
});

emailArray.filter(function(item, pos) {...}) – фильтруем массив emailArray.

  • filter() – стандартный метод JavaScript, который создаёт новый массив, содержащий только элементы, удовлетворяющие условию. Аргументы filter():
    • item – текущий элемент массива.
    • pos – индекс текущего элемента в массиве.
    • self – это сам массив (emailArray), чтобы иметь доступ ко всем его элементам.

self.findIndex(e => e[0] === item[0] && e[1] === item[1]) === pos – Этот код проверяет, является ли текущий элемент (item) первым появлением в массиве.

  1. self.findIndex(e => e[0] === item[0] && e[1] === item[1])
    • findIndex() ищет первый индекс в emailArray, где:
      • e[0] === item[0] → совпадает email отправителя (from).
      • e[1] === item[1] → совпадает email получателя (to).
  2. === pos
    • Если найденный индекс (findIndex()) совпадает с текущей позицией (pos), значит, это первое появление комбинации from + to, и мы оставляем этот элемент.
    • Если индекс отличается (pos > findIndex()), значит, этот элемент уже встречался раньше, и мы его отбрасываем.

2.6. Очистка email-адресов (отделение имени и email-а)

let cleanedEmailArray = uniqueEmailArray.map(function(el) {
  let name = "";
  let email = "";
  let subject = el[2];
     
  let matches = el[0].match(/\s*"?([^"<>]*)"?\s+<(.+)>/);
     
  if (matches) {
    name = matches[1]; 
    email = matches[2];
  }
  else {
    name = "N/k";
    email = el[0];
  }
     
  return [name, email, subject];
}).filter(function(d) {

.map(function(el) {...}) – обрабатываем каждый email в uniqueEmailArray.

Регулярное выражение /\s*"?([^"]*)"?\s+<(.+)>/:

  • Ищет email в формате "Имя Фамилия" <email@domain.com>.
  • ([^"]*) – захватывает имя (если есть).
  • <(.+)> – захватывает email.

matches[1] – имя. matches[2] – email.

Если email записан без имени (example@gmail.com), записываем N/k в поле имени.

2.7. Фильтрация ненужных email-адресов

    if (
       d[1] !== "annaoleks88@gmail.com" &&
       d[1] !== "_casper_1983@inbox.ru" 
    ) {
    return d;
  }
});

Исключаем email-адреса, которые не нужны в итоговом списке.

2.8. Очистка старых данных и вставка новых email-адресов

sheet.getRange(4,1,sheet.getLastRow(),3).clearContent();

getRange(4,1,sheet.getLastRow(),3) – выбираем диапазон от строки 4 до последней строки во втором столбце.

.clearContent() – очищаем старые данные.

sheet.getRange(4,1,cleanedEmailArray.length,3).setValues(cleanedEmailArray).sort(2);

getRange(4,1,cleanedEmailArray.length,3) – выбираем диапазон для вставки данных.

.setValues(cleanedEmailArray) – вставляем новые email-адреса.

.sort(2) – сортируем по второму столбцу (email) в алфавитном порядке.

Итоговый разбор кода

  1. При открытии таблицы добавляется меню "Extract Emails".
  2. При выборе "Extract Emails..." запускается extractEmails().
  3. Функция получает название ярлыка Gmail из ячейки B1.
  4. Из Gmail загружаются все email-адреса отправителей и получателей по этому ярлыку.
  5. Удаляются дубликаты email-адресов.
  6. Из email-адресов выделяются имена и email.
  7. Удаляются нежелательные email-адреса.
  8. В Google Таблицу вставляются новые email-адреса (начиная с A4), старые данные очищаются.