Golang SMTP Gmail With Oauth Google

Golang SMTP Gmail With Oauth Google

Pada postingan kali ini, gw mau bahas cara kirim email pake gmail dengan Oauth2 Google. Singkat cerita, kantor pakai SMTP buat kirim OTP email via Gmail dan pada waktu itu kita pakai app password di 2FA Auth google dan waktu itu harus aktifkan 2FA/2 Step Verification dengan memasukkan nomor hp, bukan pake less secure app access yaa, kurleb kaya gini tampilannya:

App passowrd

Nah dulu simple nih, cuman pake package dari sini

Oke done all is well semua berjalan sempurna. Hingga suatu waktu yang genting, ada yang mengganti email password yang dipakai buat kirim-kirim OTP tersebut, alhasil user pada complain karena tidak menerima OTP, setelah dicek lognya, ternyata ada error yang kurang lebih berbunyi:

CLIENT: 535-5.7.8 Username and Password not accepted. Learn more at535 5.7.8 https://support.google.com/mail/? p=BadCredentials 31sm5142207oto.18 - gsmtp SMTP ERROR: Password command failed: 535-5.7.8 Username and Password not accepted. Learn more at535 5.7.8 https://support.google.com/mail/?p=BadCredentials 31sm5142207oto.18 - gsmtp

Jedddder!! ibarat kesambar petir, kenapa lagi ini ya Allah 🙁. Akhirnya setelah dicari tahu akhirnya ditemukan bahwasannya google ga akan lagi support auth pake user & pass (generate app password) untuk yang baru-baru, nah yg lama-lama masih bisa dipakai dan digunakan. Kan nyebelin ya, gara-gara ganti password akhirnya kena case yg cukup baru ini haha. Untuk beritanya bisa kalian liat di blognya google sini.

Atau kalo mager buka link bisa liat sekilas di ss berikut:

Blog Google 1

Jika this announcement dibuka:

Blog Google 2

Hah Menghela nafas, merenung, chill dulu. Jadi buat teman-teman yang melihat tampilan app password di account google dari yang:

App password old

terus pas buka lagi yang baru kaya gini:

App password new

Nah kalian kemungkinan akan mengalami error diatas, meskipun sudah memakai generate password 16 digit di tampilan yang baru. Karena package tadi tidak bisa support oauth, maka kita akan sedikit config-config dan bikin sendiri.

Solusi: Memakai Oauth2 server to server Google 🍉

Secara step memang agak sedikit rumit, karena ada beberapa config yang harus dilakukan di cloud, admin, membuat utility helper untuk retrieve token JWT api google, mempelajari dokumen api service google, dan testing memakai postman atau memakai Oauth2 Playground Google.

  1. Langkah pertama: Buat account_key.json dan aktifkan service api gmail

    • Untuk membuat accountKey bisa dilakukan di cloud console yaa, linknya disini tinggal isi aja yg required, sisanya skip aja. Kalo bingung cari di source lain gimana cara bikin accountKey. Nah terus di tab key bikin key baru format json terus download, file json account_key ini sangat rahasia yaa jadi harap disimpan ditempat yang aman. Saat di git maupun prod kalau bisa jangan di expose, patch/taruh file key.json saat proses build saja.
    
    
    • Setelah itu aktifkan service api gmail, dengan search gmail di library. Pilih gmail api dan aktifkan.

    Gmail API

  2. Langkah kedua: Create Domain-wide delegation di admin

Domain wide delegation

  • Isi client ID dengan menyalinnya dari menu cloud console account key kolom Oauth 2 client Id

Domain wide delegation filling

  • isi Oauth scopes meggunakan: https://mail.google.com/ dan klik authorize.
  • Kenapa harus menambahkan domain wide delegation? itu dilakukan agar account_key tadi memiliki otorisasi ke email service yang sudah kita aktifkan tadi. Jika tidak menambahkan authorize makan nanti akan keluar error:
   oauth2: cannot fetch token: 401 Unauthorized
   Response: {
      "error": "unauthorized_client",
      "error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."
   }

Another source: disini

  1. Langkah ketiga: Bikin library/helper untuk retrieve JWT token

    • Untuk source code bisa dilihat di git saya, oiya itu pakai golang yaaa, jika kebetulan teman-teman memakai bahasa lain, bisa disesuaikan saja.
    • Library ini general yaa, jadi scope nya disesuaikan dengan kebutuhan google api yg akan dipake
    • Untuk token max berlaku 1 jam yaa, jadi teman-teman bisa memakai contoh strategi caching dengan time to live yaa atau mungkin bisa pakai strategi yang lain juga.
  2. Langkah keempat: Bikin http request

{
  "raw": "RnJvbTogZGV2QHRoZWJlYW0uY28KVG86IHViYWlkaWxsYWhoZkBnbWFpbC5jb20KU3ViamVjdDogT1RQIE9hdXRoIFRlc3RpbmcKRGF0ZTogVGh1LCA4IE9jdCAyMDIwIDA5OjU1OjA2IC0wNjAwCk1lc3NhZ2UtSUQ6IDwxMjM0QGxvY2FsLm1hY2hpbmUuZXhhbXBsZT4KClllYWgsIGl0cyB3b3JraW5nIQ=="
}
  • Untuk raw: ini diisi data yang di encode menggunakan base64, untuk isi datanya berisi kurang lebih begini:
From: from@gmail.com
To: to@gmail.com
Subject: OTP Oauth Testing
Date: Thu, 8 Oct 2023 09:55:06 -0600
Message-ID: <from@gmail.com>

Message here!
  • Jika berhasil maka akan mendapat response succes:
{
   "id": "18b02c5a3a3eb910",
   "threadId": "18b024443a3eb660",
   "labelIds": [
   "SENT"
   ]
}
  • Cek email to@gmail.com, jika berhasil maka akan masuk di kotak masuk.
  • Selesai, sekian hasil dari research SMTP with Oauth. Terimakasih.

Other resource:

About the author

Hey, I'm Ubaidillah Hakim Fadly, a software engineer, stock investor, and entrepreneur. I publish articles and tutorials about programming and devOps from my own research.

Get the newsletterBuy me a coffee

Ubaidillah