Lewati ke konten
Skematik

Cara Kirim Email Otomatis dari Google Spreadsheet (Apps Script + MailApp)

8 menit baca · Diperbarui 2026-07-15

Ada pesanan baru masuk ke Spreadsheet, dan kamu mau email langsung nyamber ke tim gudang sebelum ada yang sempat buka sheet-nya. Atau tiap Senin pagi laporan minggu lalu terkirim sendiri ke atasan. Dua-duanya bisa dari Google Apps Script, tanpa Zapier dan tanpa langganan apa pun. Modalnya satu fungsi bawaan: MailApp.

Email keluar dari akun Google yang kamu pakai buka script itu. Jadi tidak ada setup SMTP, tidak ada API key pihak ketiga. Di bawah ini pola yang benar, dari kirim satu email sampai kirim ke ratusan baris, plus jebakan yang bikin inbox orang kebanjiran email dobel.

MailApp atau GmailApp? Pilih yang mana

Apps Script punya dua cara kirim email. MailApp cuma bisa mengirim: kasih tujuan, subjek, isi, selesai. GmailApp lebih berat karena ikut menyentuh kotak Gmail-mu (baca thread, buat draf, tempel label). Buat notifikasi otomatis, MailApp yang kamu mau. Lebih ringan, dan izin yang diminta lebih sempit karena tidak butuh akses baca ke seluruh Gmail-mu.

Aturan praktisnya: kalau cuma butuh 'kirim', pakai MailApp. Kalau butuh baca email masuk atau bikin draf, baru GmailApp. Sisa artikel ini pakai MailApp.

Kirim satu email dengan MailApp.sendEmail

MailApp.sendEmail menerima tiga argumen (tujuan, subjek, isi teks), atau satu objek kalau kamu butuh kontrol lebih: subjek dinamis, isi HTML, sampai nama pengirim. Versi objek yang bakal sering kamu pakai:

function kirimEmailPesanan(tujuan, namaPelanggan, noPesanan, total) {
  const subjek = 'Pesanan #' + noPesanan + ' dari ' + namaPelanggan;
  const html =
    '<h2>Pesanan baru masuk</h2>' +
    '<p>Pelanggan: <b>' + namaPelanggan + '</b></p>' +
    '<p>Nomor: ' + noPesanan + '</p>' +
    '<p>Total: Rp ' + Number(total).toLocaleString('id-ID') + '</p>';

  MailApp.sendEmail({
    to: tujuan,
    subject: subjek,                     // subjek dinamis per pesanan
    htmlBody: html,                      // isi HTML
    body: 'Pesanan #' + noPesanan,       // cadangan teks polos
    name: 'Notifikasi Toko',             // nama pengirim
  });
}

Perhatikan htmlBody dan body dipasang berbarengan. htmlBody yang tampil di klien email modern; body jadi cadangan teks polos buat klien yang tak bisa render HTML. Subjeknya dirakit dari data baris, jadi tiap email punya judul sendiri, bukan 'Notifikasi' generik yang gampang diabaikan.

Kirim ke banyak penerima dari baris Spreadsheet

Ini kasus paling umum: satu tab berisi daftar orang, kamu mau kirim ke semuanya. Kuncinya baca seluruh data sekali pakai getValues(), lalu loop di memori. Jangan panggil getRange().getValue() di dalam loop; untuk ratusan baris itu lambat banget dan bisa mentok batas waktu.

Tapi loop mentah punya bahaya besar. Kalau script berhenti di tengah jalan (error, atau kamu keburu tutup tab) lalu dijalankan lagi, semua orang yang tadi sudah dikirim bakal dikirimi ulang. Penyelamatnya kolom status: tandai tiap baris 'TERKIRIM' begitu emailnya keluar, dan lewati baris yang sudah bertanda itu.

function kirimNotifikasiMassal() {
  const sheet = SpreadsheetApp.getActive().getSheetByName('Pesanan');
  const data = sheet.getDataRange().getValues();   // baca sekali (batch)
  // header: [0]Nomor [1]Nama [2]Email [3]Total [4]Status
  const HEADER = 1;

  let sisaKuota = MailApp.getRemainingDailyQuota();
  if (sisaKuota <= 0) {
    console.warn('Kuota email habis hari ini, tunda ke besok.');
    return;
  }

  for (let i = HEADER; i < data.length; i++) {
    const [nomor, nama, email, total, status] = data[i];
    if (status === 'TERKIRIM') continue;   // lewati yang sudah dikirim
    if (!email) continue;
    if (sisaKuota <= 0) break;             // stop sebelum kena limit

    kirimEmailPesanan(email, nama, nomor, total);

    // tandai LANGSUNG (kolom E) supaya tidak dobel saat script jalan lagi
    sheet.getRange(i + 1, 5).setValue('TERKIRIM');
    sisaKuota--;
    Utilities.sleep(300);                  // jeda kecil antar kirim
  }
}

Kuota harian: kamu tidak bisa kirim tanpa batas

MailApp punya jatah harian dan gampang kelewat kalau datamu banyak. Akun gmail.com gratis dibatasi sekitar 100 penerima per hari. Akun Google Workspace berbayar sekitar 1.500 penerima per hari. Lewat dari itu, sendEmail langsung melempar error dan sisa barismu gagal terkirim.

Makanya di kode tadi ada MailApp.getRemainingDailyQuota(). Fungsi ini mengembalikan sisa jatah hari ini. Cek di awal, dan berhenti (break) begitu sisanya nol, jadi baris yang belum kebagian tetap bertanda kosong dan dikirim besok.

Kuota email cuma salah satu dari sekian batas GAS. Ada juga batas waktu eksekusi dan batas panggilan layanan lain yang perlu kamu tahu sebelum bikin sesuatu yang jalan otomatis. Rangkumannya kami tulis di batas kuota Google Apps Script.

Jalankan otomatis lewat trigger (dan batas 6 menit)

Sejauh ini kamu masih pencet tombol Run manual. Biar benar-benar otomatis, pasang trigger yang jalanin fungsinya di jadwal. Cara detailnya ada di panduan menjalankan script terjadwal, termasuk cara menghindari trigger dobel.

Satu hal yang wajib diingat: satu eksekusi GAS dibatasi sekitar 6 menit di akun gratis. Kalau kamu jeda 300ms di antara 1.000 email, jeda-nya saja sudah 5 menit, belum termasuk waktu kirim, dan script mati di tengah. Untuk batch besar, kirim per potongan (misalnya 100 baris per run) dan biarkan trigger per jam menuntaskan sisanya. Kolom status tadi yang bikin ini aman: run berikutnya otomatis lanjut dari baris yang belum bertanda.

Rapikan dari rencana, bukan dari tebak-tebakan

Fitur kirim email jarang berdiri sendiri. Dia nempel di aplikasi yang lebih besar: pencatatan pesanan, pendaftaran, absensi, reminder servis. Yang bikin proyek GAS berantakan bukan sintaks MailApp-nya, tapi lupa menyiapkan kolom status, lupa menandai baris yang sudah diproses, atau nama tab yang berubah-ubah di tengah jalan.

Kalau kamu merancang tab, kolom status, dan titik-titik pengiriman notifikasi dari awal, kode yang keluar dari AI coding agent langsung sadar polanya. Itu yang dikerjakan mode Web GAS di Skematik: PRD khusus Apps Script yang memetakan skema tab, fungsi server, plus konvensi yang tahu batas 6 menit dan kuota harian. Belum paham cara Spreadsheet jadi aplikasi web? Mulai dari cara membuat web app dari Google Spreadsheet dulu.

Buat PRD Web GAS gratis di Skematik →

MailApp cuma satu baris. Yang bikin repot itu semua di sekitarnya: status, kuota, trigger. Beresin rencananya dulu, sisanya tinggal ngetik.

Cara Kirim Email Otomatis dari Google Spreadsheet (Apps Script + MailApp) — Skematik