Перейти к основному содержимому

Готовые сценарии скриптов с кодом

Каждый пример можно вставить в новый скрипт и подстроить под свою таблицу: названия листов и столбцов, идентификаторы чатов и адреса. Перед подключением триггера проверьте скрипт вручную кнопкой «Запустить» или «Запустить с событием».

Во всех примерах столбцы ищутся по заголовкам первой строки, поэтому скрипт не сломается, если столбцы переставят.

Ежедневный отчёт в Telegram​

Каждое утро присылает сумму и число заказов за вчера.

Триггер: по расписанию, раз в день в 9:00. Секрет: TELEGRAM_BOT_TOKEN.

const CHAT_ID = 123456789;

function main() {
const rows = Coverse.table.getSheet("Заказы").getDataRange().getValues();
const head = rows[0];
const dateCol = head.indexOf("Дата");
const sumCol = head.indexOf("Сумма");
if (dateCol === -1 || sumCol === -1) throw new Error("Нужны столбцы «Дата» и «Сумма»");

const from = Utilities.addDays(Utilities.today(), -1);
const to = Utilities.today();
let count = 0;
let total = 0;

for (let i = 1; i < rows.length; i++) {
const date = Utilities.toDate(rows[i][dateCol]);
if (date !== null && date >= from && date < to) {
count++;
total += Number(rows[i][sumCol]) || 0;
}
}

Telegram.send(CHAT_ID, Utilities.formatString(
"Заказы за %s: %d на сумму %s",
Utilities.formatDate(from, "dd.MM.yyyy"),
count,
Utilities.formatNumber(total, { currency: "RUB" }),
));
}

Раскраска строк по статусу​

Для постоянной раскраски не нужен триггер: достаточно один раз создать правила подсветки, дальше таблица красит строки сама.

Триггер: не нужен, запустите один раз.

function main() {
const sheet = Coverse.table.getSheet("Заказы");
const status = sheet.getDataRange().getValues()[0].indexOf("Статус");
if (status === -1) throw new Error("Нет столбца «Статус»");

const letter = String.fromCharCode(65 + status);
sheet.getRange("A2:Z").setConditionalFormat({ formula: '=$' + letter + '2="Оплачен"' }, { background: "#d9ead3" });
sheet.getRange("A2:Z").setConditionalFormat({ formula: '=$' + letter + '2="Отменён"' }, { background: "#f4cccc", strike: true });
}

Повторный запуск не создаёт дубликаты правил.

Лист «Заказы» после правил подсветки: оплаченные строки зелёные, отменённые красные и зачёркнутые

Приём заказов с сайта через вебхук​

Магазин отправляет заказ в JSON, скрипт дописывает строку и пропускает повторы по номеру заказа.

Триггер: по вебхуку, функция onWebhook. Адрес вставьте в настройки магазина, см. Вебхуки.

function onWebhook(event) {
if (!event || !event.json) return;

const order = event.json;
const sheet = Coverse.table.getSheet("Заказы");
const ids = sheet.getDataRange().getValues().map((row) => String(row[0]));

if (ids.includes(String(order.id))) {
console.log("Заказ уже есть:", order.id);
return;
}

sheet.appendRow([order.id, new Date(), order.customer, order.phone, Number(order.total), "Новый"]);
}

Заявки с формы в Telegram​

Триггер: при отправке формы, функция onFormSubmit. Секрет: TELEGRAM_BOT_TOKEN.

const CHAT_ID = 123456789;

function onFormSubmit(event) {
if (!event) return;

const lines = event.answers.map((item) => item.question + ": " + item.answer);
Telegram.send(CHAT_ID, "Новая заявка (строка " + event.row + ")\n" + lines.join("\n"));
}

Курсы валют ЦБ на лист​

Раз в день записывает курсы доллара и евро. В примере используется публичный сервис с курсами ЦБ РФ в JSON.

Триггер: по расписанию, раз в день.

function main() {
const response = Http.fetch("https://www.cbr-xml-daily.ru/daily_json.js");
if (!response.ok) throw new Error("Сервис курсов ответил с кодом " + response.status);

const data = response.json();
const sheet = Coverse.table.getSheetByName("Курсы") || Coverse.table.insertSheet("Курсы");
if (sheet.getLastRow() === 0) sheet.appendRow(["Дата", "USD", "EUR"]);

sheet.appendRow([Utilities.today(), data.Valute.USD.Value, data.Valute.EUR.Value]);
}

Если нужен курс прямо в ячейке без скрипта, используйте функцию =ЦБКУРС, см. Курсы валют ЦБ РФ.

Напоминание о сроках на почту​

Каждое утро отправляет ответственному список задач, у которых срок сегодня или уже прошёл.

Триггер: по расписанию, раз в день в 8:00.

function main() {
const rows = Coverse.table.getSheet("Задачи").getDataRange().getValues();
const head = rows[0];
const task = head.indexOf("Задача");
const due = head.indexOf("Срок");
const done = head.indexOf("Готово");
const today = Utilities.today();
const late = [];

for (let i = 1; i < rows.length; i++) {
const date = Utilities.toDate(rows[i][due]);
if (date !== null && date <= today && rows[i][done] !== true) {
late.push("<li>" + rows[i][task] + " — до " + Utilities.formatDate(date, "dd.MM.yyyy") + "</li>");
}
}

if (late.length === 0) return;
Mail.send("manager@example.com", "Задачи со сроком на сегодня", "", { htmlBody: "<ul>" + late.join("") + "</ul>" });
}

Перенос выполненных строк в архив​

Переносит строки со статусом «Закрыт» на лист «Архив» и оставляет на основном листе только открытые. Работает чтением и записью целых блоков, поэтому подходит и для больших листов.

Триггер: по расписанию, раз в неделю, или пункт меню «Макросы».

function archive() {
const sheet = Coverse.table.getSheet("Заказы");
const rows = sheet.getDataRange().getValues();
const status = rows[0].indexOf("Статус");
const keep = [rows[0]];
const moved = [];

for (let i = 1; i < rows.length; i++) {
(rows[i][status] === "Закрыт" ? moved : keep).push(rows[i]);
}
if (moved.length === 0) return;

const target = Coverse.table.getSheetByName("Архив") || Coverse.table.insertSheet("Архив");
target.appendRows(moved);

sheet.getDataRange().clear();
sheet.getRange(1, 1, keep.length, keep[0].length).setValues(keep);
console.log("Перенесено строк:", moved.length);
}

Если в таблице есть формулы, которые нужно сохранить, читайте их через getFormulas() и записывайте через setFormulas().

Сводная по менеджерам каждую неделю​

Триггер: по расписанию, раз в неделю в понедельник.

function main() {
Coverse.table.insertPivotTable({
source: Coverse.table.getSheet("Заказы").getDataRange(),
rows: ["Менеджер"],
columns: [{ field: "Дата", group: "month" }],
values: [{ field: "Сумма", summarize: "sum" }],
name: "Продажи по менеджерам",
replace: true,
});
}

replace: true пересчитывает ту же сводную на её листе, а не создаёт новую каждую неделю.

Загрузка новых сделок из CRM​

Раз в час забирает сделки, созданные после последней загрузки, и запоминает отметку в «Памяти».

Триггер: по расписанию, каждый час. Секрет: CRM_TOKEN.

function main() {
const since = Properties.script.get("lastSync") || "2026-01-01T00:00:00Z";
const response = Http.fetch("https://crm.example.com/api/deals", {
query: { created_after: since },
headers: { Authorization: "Bearer " + Secrets.get("CRM_TOKEN") },
});
if (!response.ok) throw new Error("CRM ответила с кодом " + response.status);

const deals = response.json();
if (deals.length === 0) return;

Coverse.table.getSheet("Сделки").appendRows(deals.map((deal) => [deal.id, deal.title, Number(deal.amount), deal.stage]));
Properties.script.set("lastSync", deals[deals.length - 1].created_at);
}

Что дальше​