Going Stellar

Acasă/Metode

Inginerie · Apps Script

Cum faci deploy la cod Google Apps Script prin API, în loc de copy-paste

Codul Google Apps Script se poate citi și scrie prin Apps Script API, deci un script nu mai trebuie lipit de mână în editor. Unealta noastră rulează implicit în modul de probă, face backup proiectului înainte de fiecare scriere, retrimite toate fișierele fiindcă API-ul înlocuiește proiectul întreg și verifică rezultatul de două ori: recitind codul și verificând ce a scris scriptul.

Actualizat

Ce înseamnă deploy la Apps Script prin API

Copy-paste-ul în editorul Google Apps Script se poate înlocui cu trei apeluri către Apps Script API: citești proiectul cu projects.getContent, modifici fișierele local și le scrii înapoi cu projects.updateContent. Făcut cu grijă, fiecare scriere e precedată de o rulare de probă și de un backup, retrimite toate fișierele proiectului și se încheie cu o recitire care dovedește că serverul ține acum codul pe care ai vrut să-l trimiți.

Un proiect Google Apps Script e un set de fișiere: fișiere de script, de tip SERVER_JS, și un manifest numit appsscript, de tip JSON. Proiectul e fie independent (standalone), fie legat de un container, adică atașat unui Sheet, Doc sau Form. Scripturile noastre sunt mai ales legate: construiesc rândurile zilnice de raport în foi de calcul de business, iar fiecare reparație însemna să deschizi editorul, să cauți funcția și să lipești peste ea, fără backup și fără vreo urmă a ce s-a schimbat.

Configurarea de o singură dată

Unealta se autentifică drept cont de serviciu (service account), o identitate Google care nu e om și are propria cheie, prin delegare la nivel de domeniu (domain-wide delegation), o setare Workspace care îi permite contului de serviciu să acționeze în numele unui utilizator al domeniului. Trebuie bifate trei lucruri. Unu, în consola de administrare Workspace, delegarea pentru contul de serviciu cu scope-ul script.projects. Doi, setarea per utilizator Google Apps Script API pornită în setările Apps Script ale contului care deține scripturile. Trei, Apps Script API activat în proiectul cloud în care stă contul de serviciu.

Citirea și scrierea nu sunt simetrice. getContent merge cu contul de serviciu simplu, dacă scriptul e partajat cu el. updateContent eșuează cu 403 User has not enabled the Apps Script API dacă apelul nu se face în numele unui proprietar care are setarea pornită. „User” din mesaj e contul impersonat, nu contul de serviciu, de aceea eroarea derutează prima dată. Delegarea are nevoie și de câteva minute ca să se propage după salvare; până atunci eroarea e unauthorized_client.

Pentru add-on-urile noastre Google Workspace folosim clasp, unealta Google în linie de comandă pentru Apps Script, dintr-un folder local ținut în controlul versiunilor. Unealta prin API descrisă aici e pentru scripturile care trăiesc în foi de calcul de business deținute de un cont Workspace, unde nu există un folder local din care să faci push.

Pasul 1: backup, apoi modificări chirurgicale

1. Găsește ID-ul scriptului. Scripturile independente se pot lista prin Drive. Un script legat de container nu apare acolo; ID-ul lui e în editor, la Project Settings.

2. Citește și salvează proiectul întreg. Comanda get scrie toate fișierele proiectului într-un backup JSON cu dată și oră, înainte de orice altceva. Fișierul acela e calea de revenire.

3. Modifică sursa din backup, nu o copie retastată. Schimbăm codul prin înlocuiri exacte de text și verificăm de câte ori s-a potrivit fiecare tipar, în loc să rescriem fișierul. Urmează o verificare de sintaxă: copiezi fișierul cu extensia .js și rulezi node --check pe el. Șirurile de formule din cod cer atenție: o foaie de calcul cu localizare non-US așteaptă ; ca separator de argumente, deci formulele nu se reformatează din reflex.

Pasul 2: lint pentru bug-urile care au stricat deja producția

Înainte de fiecare push, un linter verifică sursa nouă pentru cele 7 greșeli care au produs deja cifre greșite în rapoartele noastre. Două sunt erori și blochează push-ul. getSheetById nu există în Apps Script, iar folosirea ei era toată cauza unui script care „nu scrie nimic”; metoda care există e getSheetByGid. A doua eroare e un interval sursă mărginit, de pildă un interval care se termină la ultimul rând numărat în momentul rulării. Rândul nostru zilnic se creează înainte ca datele zilei să fie sincronizate în taburile sursă, așa că datele noi ajung dincolo de limita înghețată și toate metricile ies zero. Un interval deschis, fără rând final, prinde datele pe măsură ce intră.

Alte cinci reguli sunt avertismente: SpreadsheetApp.flush() pe o foaie mare, ARRAYFORMULA pe coloane întregi, LET combinat cu funcții pe array (merge doar pe scalari, iar cu array-uri a dat zero), setValue apelat într-o buclă în loc de un singur setValues și citirea din foaie într-o buclă. Linterul nu e un sfat general; fiecare regulă e un bug pe care l-am livrat.

Pasul 3: rulare de probă, apoi scrierea proiectului întreg

push e rulare de probă dacă nu primește --apply: arată ce fișiere s-ar schimba și rulează linterul. Detaliul important e că updateContent înlocuiește proiectul întreg. Un apel direct care trimite doar fișierul de script modificat șterge manifestul și toate celelalte fișiere. De aceea unealta noastră retrimite neschimbat fiecare fișier existent și înlocuiește doar fișierele numite în linia de comandă.

Aceleași reguli se aplică și celorlalte comenzi de scriere. create face un proiect nou, independent sau legat de o foaie de calcul, și e tot rulare de probă implicit. Apps Script API nu are ștergere, așa că trash mută fișierul scriptului în coșul din Drive, de unde se poate recupera cam 30 de zile; refuză orice fișier care nu e proiect Apps Script, ca să nu arunce din greșeală o foaie de calcul.

Pasul 4: verifică prin recitire, apoi prin efect

După scriere, unealta recitește proiectul și îl compară cu ce a trimis. Un apel API reușit dovedește că a avut loc un transfer, nu ce s-a transferat. Am învățat asta pe partea de clasp, când două versiuni de add-on au fost publicate cu fișierele greșite, fiindcă un workflow paralel schimba fișiere în același folder exact în momentul push-ului; de ambele dăți push-ul a raportat succes.

Recitirea codului nu dovedește că scriptul funcționează, iar API-ul nu-l poate rula pentru noi. Am încercat: scripts.run, processes.list și deployments.list au întors toate 403 cu delegarea noastră. Rularea de la distanță ar cere legarea fiecărui script de producție de proiectul cloud al contului de serviciu și adăugarea unui deployment de tip API executable în fiecare, o schimbare prea invazivă. Așa că ultima verificare se face prin efect: după ce rulează triggerul, comanda verify citește ultimele rânduri din tabul țintă și eșuează dacă un rând recent are toate metricile zero (semnătura exactă a bug-ului cu intervalul mărginit), dacă vreo celulă conține o eroare de formulă sau dacă în formulele vii au rămas intervale mărginite.

verify dă alarmă doar la un rând complet zero, niciodată la o singură metrică zero. Altfel, un brand cu reclamele oprite intenționat pe un canal ar da alarmă falsă în fiecare zi, iar o alarmă care sună zilnic ajunge repede ignorată.

Capcanele în care am căzut

Scripturile lente erau lente din cauza foii, nu a codului. Tabul de raport avea cam 9.400 de rânduri cu cam 15 formule vii fiecare, adică în jur de 140k formule recalculate împreună. Transformarea rândurilor mai vechi de 3 zile în valori simple, la finalul fiecărei rulări, a rezolvat viteza.

Reparațiile la un script care doar adaugă rânduri nu repară istoricul. Un script adaugă un rând nou pe zi și nu atinge rândurile vechi, deci o reparație de formulă afectează doar rândurile create după deploy; rândurile vechi păstrează valorile vechi până le rescrii intenționat.

Potrivirea pe nume exact eșuează în tăcere. Când un flux de date a redenumit un magazin, toate sumele legate de vechiul nume exact au întors zero, fără nicio eroare. Potrivirea pe prefix sau pe un tipar care ignoră majusculele prinde și numele vechi, și pe cel nou.

Un număr umflat doar în dashboard e un bug de dashboard. O medie pe o singură zi alimenta un câmp calculat din unealta noastră de dashboard și umfla o cifră de aproximativ 3 ori, în timp ce foaia în sine era corectă. Întâi am golit taburi din foaie căutând o dublă numărare care nu exista.

Unde am greșit și limitele metodei

Am luat „salvat”-ul din editor și răspunsul de succes al API-ului drept dovadă, iar de ambele dăți dovada era în altă parte: în codul ținut de server și în rândurile scrise de script. Am presupus și că execuția de la distanță e un detaliu de configurare; s-a dovedit că cere modificarea fiecărui script de producție, așa că verificăm prin efect.

Metoda are limite. Verificarea prin efect vine abia după următoarea rulare a triggerului, deci un deploy stricat poate trăi până atunci; backup-ul face revenirea rapidă, nu instantanee. Delegarea la nivel de domeniu e o permisiune puternică și aparține doar unui cont de serviciu a cărui cheie stă într-un seif de secrete. Iar linterul prinde doar bug-urile pe care le-am întâlnit deja.

Lista de verificare

1. Configurează o dată delegarea, setarea API per utilizator a proprietarului și API-ul în cloud. 2. Fă backup proiectului întreg înainte de fiecare scriere. 3. Modifică prin înlocuiri exacte și verifică sintaxa. 4. Rulează linterul pentru bug-urile care au stricat deja producția. 5. Întâi rulare de probă; scrie cu --apply, retrimițând toate fișierele. 6. Recitește codul și compară. 7. După următoarea rulare, verifică rândurile scrise de script.

Întrebări și răspunsuri

Pot actualiza cod Google Apps Script fără editor?

Da. Apps Script API permite unui program să citească un proiect cu projects.getContent și să-l scrie cu projects.updateContent. Ai nevoie de API activat într-un proiect cloud și, pentru scriere, de o identitate care acționează în numele unui proprietar care a pornit Google Apps Script API în setările Apps Script. Noi folosim un cont de serviciu cu delegare la nivel de domeniu, ca aceeași unealtă să poată scrie în orice script deținut de un cont din domeniu.

De ce eșuează updateContent cu User has not enabled the Apps Script API?

Eroarea se referă la contul în numele căruia se face apelul. Cu un cont de serviciu, getContent poate merge în timp ce updateContent eșuează, fiindcă scrierea cere impersonarea unui proprietar cu setarea per utilizator Google Apps Script API pornită. Pornește setarea pentru acel proprietar, verifică dacă delegarea include scope-ul script.projects și lasă câteva minute ca delegarea să se propage.

Șterge updateContent fișierele pe care nu le trimit?

Da. projects.updateContent înlocuiește proiectul întreg cu fișierele din cerere, deci dacă trimiți un singur fișier de script dispar manifestul și toate celelalte fișiere. Citește întâi proiectul, păstrează exact cum erau fișierele pe care nu le schimbi, înlocuiește doar ce vrei să modifici și trimite înapoi setul complet. Păstrează rezultatul citirii ca backup.

Cum verific un deploy Apps Script dacă nu pot rula scriptul de la distanță?

Verifică de două ori. Întâi recitește proiectul și compară fișierele cu ce ai trimis. Apoi verifică prin efect: după ce rulează triggerul, citește ultimele rânduri scrise de script și eșuează dacă un rând recent are toate metricile zero sau conține erori de formulă. Cu delegarea noastră, scripts.run, processes.list și deployments.list au întors toate 403, deci efectul a fost singura dovadă disponibilă.

Cum șterg un proiect Apps Script prin API?

Apps Script API nu are metodă de ștergere. Mută în schimb fișierul scriptului în coșul din Drive prin Drive API, ceea ce cere un scope Drive în delegare. Fișierul se poate recupera cam 30 de zile. Verifică întâi tipul fișierului și refuză orice nu e proiect Apps Script, ca să nu ajungă din greșeală la coș o foaie de calcul sau un document.

Cum se citează

Going Stellar (2026). Cum faci deploy la cod Google Apps Script prin API, în loc de copy-paste. GOING STELLAR S.R.L..
https://goingstellar.ro/ro/metode/deploy-google-apps-script-prin-api/

Citește ca Markdown

Toate metodele

Contact

Spune-ne ce nu merge

Scrie în română sau în engleză. Citește un om — de obicei chiar cel care ar face treaba — și răspunde într-o zi lucrătoare.