Aprendé a sincronizar Google Sheets con n8n con un diseño push-sync que evita releer toda la hoja. Descubrí cómo implementarlo en tu flujo ahora.
#n8n #googlesheets #appsscript #automatización #webhooks
Aprendé a sincronizar Google Sheets con n8n con un diseño push-sync que evita releer toda la hoja. Descubrí cómo implementarlo en tu flujo ahora.
#n8n #googlesheets #appsscript #automatización #webhooks
#GoogleWorkspace #AppsScript
#GoogleWorkspace #AppsScript
ScriptApp.newTrigger("daily").timeBased().atHour(9).everyDays(1).create();
So never derive "yesterday" from when the trigger ran. Filter on the timestamp in the row.
#AppsScript
ScriptApp.newTrigger("daily").timeBased().atHour(9).everyDays(1).create();
So never derive "yesterday" from when the trigger ran. Filter on the timestamp in the row.
#AppsScript
Google Apps Script, weekly trigger:
const ev = CalendarApp.getEvents(mon, sun);
if (!ev.length) return;
sh.getRange(2,1,ev.length,2).setValues(ev.map(e=>[e.getStartTime(),e.getTitle()]));
A quiet week is 0 rows, and setValues throws. #AppsScript
Google Apps Script, weekly trigger:
const ev = CalendarApp.getEvents(mon, sun);
if (!ev.length) return;
sh.getRange(2,1,ev.length,2).setValues(ev.map(e=>[e.getStartTime(),e.getTitle()]));
A quiet week is 0 rows, and setValues throws. #AppsScript
sheet.appendRow(row) is atomic — the one write that cannot lose that race.
If you must setValues(), take a LockService lock first. #AppsScript
sheet.appendRow(row) is atomic — the one write that cannot lose that race.
If you must setValues(), take a LockService lock first. #AppsScript
Ugly but ultimately ran quicker.
Ugly but ultimately ran quicker.
何故壊れたんや…
私も調べながら何となくの流れしかわからんのに…(´;ω;`)
しゃーない
顧客管理のシステムだしどうにかするしかない
…ご褒美は後日届く洋服達とグッズかな
久々に散財したもんな自分の中で
来月賞与あるし、2万くらい使ったって罰当たらんやろ。笑
何故壊れたんや…
私も調べながら何となくの流れしかわからんのに…(´;ω;`)
しゃーない
顧客管理のシステムだしどうにかするしかない
…ご褒美は後日届く洋服達とグッズかな
久々に散財したもんな自分の中で
来月賞与あるし、2万くらい使ったって罰当たらんやろ。笑
Doing dynamic table selection based on table availability and date. Both Apps Script and pure SQL.
#AppsScript #BigQuery #ChatGPT
Doing dynamic table selection based on table availability and date. Both Apps Script and pure SQL.
#AppsScript #BigQuery #ChatGPT
終わったら……github で history 管理されて TypeScript で書かれた AppsScript が……稼働する……!
なんて平和な世界🕊️
AppsScript GUI なんてXXXXXXまえ!🤬🤬🤬自主規制
終わったら……github で history 管理されて TypeScript で書かれた AppsScript が……稼働する……!
なんて平和な世界🕊️
AppsScript GUI なんてXXXXXXまえ!🤬🤬🤬自主規制
Need an edit-trigger that sends mail or hits an API? Make it an INSTALLABLE onEdit (Triggers → Add) — same function, full scopes. #AppsScript
Need an edit-trigger that sends mail or hits an API? Make it an INSTALLABLE onEdit (Triggers → Add) — same function, full scopes. #AppsScript
Google Apps Script, once:
GmailApp.search("label:invoices filename:pdf newer_than:7d")
.flatMap(t=>t.getMessages())
.forEach(m=>m.getAttachments()
.forEach(a=>folder.createFile(a)));
Trigger it, done. #AppsScript
Google Apps Script, once:
GmailApp.search("label:invoices filename:pdf newer_than:7d")
.flatMap(t=>t.getMessages())
.forEach(m=>m.getAttachments()
.forEach(a=>folder.createFile(a)));
Trigger it, done. #AppsScript
const sh = SpreadsheetApp.getActive().getActiveSheet();
sh.getDataRange().getValues().forEach((r, i) => {
if (r[2] > 1000) sh.getRange(i+1, 1, 1, r.length).setBackground("#fde68a");
});
One pass, every matching row flagged. #AppsScript
const sh = SpreadsheetApp.getActive().getActiveSheet();
sh.getDataRange().getValues().forEach((r, i) => {
if (r[2] > 1000) sh.getRange(i+1, 1, 1, r.length).setBackground("#fde68a");
});
One pass, every matching row flagged. #AppsScript
const files = DriveApp.getFolderById(ID).getFiles();
while (files.hasNext()) {
const f = files.next();
f.setName(f.getName().replace(/ /g, "_"));
}
Whole folder normalized in one run. #AppsScript
const files = DriveApp.getFolderById(ID).getFiles();
while (files.hasNext()) {
const f = files.next();
f.setName(f.getName().replace(/ /g, "_"));
}
Whole folder normalized in one run. #AppsScript
clearContent() actually removes it. Or filter blanks from getValues() before trusting the length.
#AppsScript
clearContent() actually removes it. Or filter blanks from getValues() before trusting the length.
#AppsScript
onEdit(e): if the edited cell is the Status column and e.value == 'Done', appendRow() it to Archive, then deleteRow() from the source.
~8 lines. Pinning down the spec sentence was harder than the code. #AppsScript #GoogleSheets
onEdit(e): if the edited cell is the Status column and e.value == 'Done', appendRow() it to Archive, then deleteRow() from the source.
~8 lines. Pinning down the spec sentence was harder than the code. #AppsScript #GoogleSheets
function archiveOld() {
GmailApp.search("older_than:1y -is:starred")
.forEach(t => t.moveToArchive());
}
One sentence in, four lines out. Put it on a daily trigger and the inbox count stops climbing. #AppsScript #Gmail
function archiveOld() {
GmailApp.search("older_than:1y -is:starred")
.forEach(t => t.moveToArchive());
}
One sentence in, four lines out. Put it on a daily trigger and the inbox count stops climbing. #AppsScript #Gmail