Telegram Welcome Bot Custom Text, Template dan Button Inline (GAS II-09)

14 menit saja |

Materi ini bisa disebut lanjutan welcome sebelumnya, atau bisa juga welcome versi library versi 2. Namun, sedikit berbeda, kali ini custome text welcome nya tidak dibuat di dalam codingan. Namun, bisa di set on the fly oleh admin (atau yang berwenang) secara langsung di grup. Ya, seperti GeDebug!

"Welcome 2021"

Pendahuluan

Panjang bener judul materi ini. Saya sendiri juga bingung dikasih judul apa haha..

Meski materi welcome sudah pernah dibahas, akan tetapi masih perlu kiranya sedikit diperdalam dalam beberapa materi lagi. Karena hakikatnya, welcome message itu memiliki banyak sekali variasi nya.

Kali ini akan dibahas beberapa variasi di dalamnya. Siapkan waktu khusus buat belajarnya ya!

Notes

Tulisan ini dibuat tanggal 8 Desember 2020. Tapi kok gak kelar-kelar ya..

✌🏻 Mohon maaf yak, bagi yang menunggu next materi gak nongol-nongol.

Sebagai gantinya, kita buat materi ini lebih padat dan berisi #halah haha

Level

Level materi ini adalah: beginner - middle - advanced

Dengan tingkat kesulitan 4/5. Belum sampai rumit-rumit amat, cuma satu aja bagian yang paling rumit. Itu pun bisa di copas, iya kan.. iya kan? Mana yang hobinya copas copas haha

So.. sesuaikan sendiri level kalian berada. Jika sudah ga sanggup, ya sudah la yaa.. lanjutkan esok hari saja. Baring-baringan, jalan-jalan, atau ngemil-ngemil. Atau jurus terakhir lambaikan tangan ke arah kamera :-D

Pengayaan

Di dalam materi ini ada pengayaan dan pendalaman, sehingga sangat direkomendasikan untuk tetap ikut menyimak untuk para haus ilmu perbotan, meski sehari-hari bisa jadi tidak pakai bot welcome.

Materi pengayaan itu adalah:

  • penggunaan custom variable atau template, sebagai pengganti untuk user atau triger-triger lainnya
  • try and catch, sangat berfungsi untuk menghandle error script. Bahkan juga dapat mengurangi rate error pada GAS.
  • penerapan simpan dan muat nilai ke dalam database mini, dalam hal ini adalah user properties
  • pembatasan akses, user siapa saja yang boleh mengubah set welcome
  • pembuatan button inline secara otomatis tersusun berapa kolomnya

"Yuk Belajar"

Let’s Go!

Penerapan coding ini dibuat dengan asumsi start dari codingan Helo Bot.

Jika botmu sudah campur aduk di oprek-oprek, silakan disesuaikan sendiri.

Jika menemui kegagalan, banyak error, atau tidak mengerti. Sebaiknya mulai lagi aja dari awal Helo Bot dan dilanjutkan materi ini.

Preview I

Sesi Pertama, kira-kira akan dibuat seperti ini:

User Join

Ini kita sebut sebagai EVENT USER JOIN CHAT dan SAY WELCOME.

Mirip seperti materi welcome di lib v1, hanya terjadi penyesuaian sedikit.

Letakkan dibawah :

if (update.message) { 

    // penyederhanaan variable
    var msg = update.message;

Tambahkan coding sebagai berikut :

// EVENT NEW USER dan SAY WELCOME BOT    
    
if (msg.new_chat_members) {
    // return tg.sendMsg(msg, tg.util.outToJSON(msg));
      
    // variable baru untuk new chat member, ambil yang pertama saja
    var newUser =  msg.new_chat_members[0];
      
    // definisikan nama user yang masuk
    var nama = newUser.first_name;
      
    // jika punya last name, kita tambahkan juga
    if (newUser.last_name)
      nama += " " + newUser.last_name;
      
    // Merangkai ucapan selamatnya di variable teks
    var teks = "Selamat datang, "+nama+ ". Semoga kamu betah di sini ya!";
      
    // kirim pesan welcome
    // jika ingin menyesuaikan pake parse mode, silakan baca di materi parse mode
    return tg.sendMsg(msg, teks);
      
}

Semestinya codingan di atas jika di test akan berjalan dan bot sudah dapat memberikan welcome.

PEMULA: Sampai Di SINI BELAJARNYA sudah cukup. Bot sudah bisa welcome!

Welcomeee

Set Welcome I

Sekarang kita akan bikin welcome bot, yang dapat di custom oleh admin ya.

Kali ini levelnya naik sedikit lebih rumit ya. Level moderate. Jadi buat yang baru belajar, silakan berhati-hati memahami dan copas nya.

Hak Akses

Pertama, kita kan tidak ingin semua user di grup bisa set welcome. Maka tentukan dulu siapa saja user yang boleh set welcome ini.

Kita buat manual, di list data user id nya.

Letakkan list tersebut dan coding kan di file Code.gs atau Kode.gs:

// list Global adminBot 
var adminBot = [ 
    213567634 // @hasanudinhs    
]

Jika lebih dari satu, silakan di set seperti ini :

// list Global adminBot 
var adminBot = [ 
    213567634, // @hasanudinhs
    123456789, // si fulan
    987654321  // dan si fulanah
    // dst
]

List Admin ini dibuat secara global. Artinya bot diletakkan dimana pun, admin bot nya adalah yang di list tersebut. Bukan mengambil dari admin group ya.

Jika ingin admin grup, silakan disesuaikan sendiri. Ini PR pengembangan di materi ini ya! :-)

Event SET Welcome

Contoh interaktif yang akan dibuat :

user: !setwelcome Selamat datang di grup MateMaTika<!
bot : ⛔️ ERROR: {"ok":false,"error_code":400,"description":"Bad Request: can't parse entities: Unclosed start tag at byte offset XX"}
user: !setwelcome Hai {nama}, selamat datang di {grup}.
bot : βœ… WELCOME: Hai {nama}, selamat datang di {grup}.

Parse mode yang ditentukan kali ini adalah HTML ya. Sehingga penulisan pesan karakter khusus yang tidak tepat akan error seperti pesan bot pertama di atas.

⚠️ Pastikan sudah mengerti / membaca / praktek di materi Format Text dan Parse Mode ya.

OK kembali ke Proses.gs, kita akan buat set welcome oleh admin bot.

Seperti biasa, tambahkan event trigger text nya. Dimana letakkanya, apa maksudnya kode-kode pola? Pastikan sudah belajar materi Custom Command dan Regex ya.

Letakkan sesudah // -- mulai custom text -- :

// trigger set Welcome
var pola = /^([!\/]setwelcome )/i;
if ( cocok = pola.exec(msg.text) ){
  
  // periksa dulu user ID nya, jika tidak ada akses tolak saja.
  if (! tg.util.punyaAkses(adminBot, msg.from.id)  ) 
    return tg.sendMsg(msg, '🚫 Kamu tidak punya akses.', false, false, msg.message_id);
  
  // buang pola yang di dapatkan dengan menggantinya dengan karakter kosong atau tidak ada
  var pesanWelcome = msg.text.replace(cocok[1],'');
  
  // uji dulu pesan yang diset bener atau enggak dalam format html :
  
  try {
    // kirim pesan berhasil disimpan
    tg.sendMsg(msg, 'βœ… <b>WELCOME</b>: '+pesanWelcome, 'HTML', false, msg.message_id);

    // simpan pesanWelcome
    user.setValue('welcomeMessage'+msg.chat.id, pesanWelcome);
    
  } catch (e) {
    // jika gagal, keluarkan pesan error
    var pesanError = e.message;
    
    // tangkep pesan error yang dari Telegram saja
    if (error = /({(?:.*)})/gmi.exec(pesanError) )
    pesanError = error[1];        
    
    // kalau Error gak usah di format HTML, buat keperluan debugging
    tg.sendMsg(msg, '⛔️ ERROR: '+pesanError, false, false, msg.message_id);
  }
  
  // selesai kecocokan pola, kembalikan
  return;
}

Cek Welcome

Untuk mengecek welcome, kita buat trigger 1 lagi deh ya.

Ini gak harus sih, cuma sekadar lihat sudah tersimpan dan sesuai atau enggak.

// trigger cek Welcome
var pola = /^[!\/]cekwelcome$/i;
if ( cocok = pola.exec(msg.text) ){
  
  // periksa dulu user ID nya, jika tidak ada akses tolak saja.
  if (! tg.util.punyaAkses(adminBot, msg.from.id)  )
    return tg.sendMsg(msg, '🚫 Kamu tidak punya akses.', false, false, msg.message_id);
  
  // buang pola yang di dapatkan dengan menggantinya dengan karakter kosong atau tidak ada
  var pesanWelcome = user.getValue('welcomeMessage'+msg.chat.id);
  
  // jika kosong variablenya
  if (!pesanWelcome) return tg.sendMsg(msg, '🚫 Tidak ada welcome.', false, false, msg.message_id);
  
  // kirim pesan welcome:
  return tg.sendMsg(msg, 'πŸ—£ WELCOME: '+pesanWelcome, 'HTML', false, msg.message_id);
}

Custome Template / Variable

Terakhir, biar makin canggih kan ya.. ala-ala GeDebug Welcome kita buat custom variable atau semacam template.

  • {nama}, {name} untuk menyebut nama user
  • {username} untuk menyebut username, jika ada
  • {iduser} untuk menyebut id user
  • {grup}, {group} untuk menyebut nama (title) grup
  • {idgrup}, {idgroup} untuk menyebut id grup

Kita benerin atau ubah, code yang di EVENT USER JOIN CHAT.

// EVENT NEW USER dan SAY WELCOME BOT    
    
if (msg.new_chat_members) {
    // return tg.sendMsg(msg, tg.util.outToJSON(msg));
      
    // variable baru untuk new chat member, ambil yang pertama saja
    var newUser =  msg.new_chat_members[0];
      
    // mendefinisikan {nama}
    var namaUser = newUser.first_name;      
    // jika punya last name, kita tambahkan juga
    if (newUser.last_name)
      namaUser += " " + newUser.last_name;

    // bersihkan nama dari tag HTML
    namaUser = tg.util.clearHTML(namaUser);

    // mendifiniksan username
    var username = newUser.username ? '@'+newUser.username : '';

    // mendifinisikan iduser
    var idUser = newUser.id;

    // mendefinisikan grup title
    var namaGrup = msg.chat.title;

    // bersihkan nama grup dari tag HTML
    namaGrup = tg.util.clearHTML(namaGrup);

    // mendefinisikan id grup
    var idGrup = msg.chat.id;
      
    // Merangkai ucapan selamatnya digabung variable ke pesanWelcome
    // ambil dulu pesan di database User
    var pesanWelcome = user.getValue('welcomeMessage'+msg.chat.id);

    // jika tidak ada pesan welcome, ya udah balik aja
    if (!pesanWelcome) return false;

    // masukkan variable-variablenya
    var teks = pesanWelcome
        .replace(/{nam[ae]}/ig, namaUser) // mengubah template nama, name
        .replace(/{username}/ig, username) // mengubah template username
        .replace(/{iduser}/ig, idUser) // mengubah template id user
        .replace(/{gro?up}/ig, namaGrup) // mengubah template title group
        .replace(/{idgro?up}/ig, idGrup) // mengubah template id group
      
    // kirim pesan welcome
    return tg.sendMsg(msg, teks, 'HTML')      
}

Dari sini silakan dicoba dulu, memastikan bot dapat bekerja dengan baik ya.

Set Welcome Reply

Kita lanjut sedikit untuk sesi pertama, yakni set welcome dari reply pesan ya.

Prinsipnya serupa dengan atasnya kok. Yuk, let’s go.

Triger Reply Set Welcome

Di sini kita bedakan polanya, kalau sebelumnya setelah kata !setwelcome harus pake spasi. Sedangkan untuk reply hanya setwelcome saja.

Tambahkan lagi code buat trigger reply pesan:

// trigger reply set Welcome
var pola = /^[!\/]setwelcome$/i;
if ( cocok = pola.exec(msg.text) ){
  
  // periksa dulu user ID nya, jika tidak ada akses tolak saja.
  if (! tg.util.punyaAkses(adminBot, msg.from.id)  ) 
    return tg.sendMsg(msg, '🚫 Kamu tidak punya akses.', false, false, msg.message_id);

  // periksa ada reply atau tidak
  if (!msg.reply_to_message) 
    return tg.sendMsg(msg, '🚫 Harus reply pesan', false, false, msg.message_id);

  // sederhanakan variable reply_to_message
  var msgr = msg.reply_to_message;

  // periksa lagi, yang di reply text atau bukan
  if (!msgr.text) 
    return tg.sendMsg(msg, '🚫 Harus tipe teks', false, false, msg.message_id);
  
  // set up message yang akan di olah
  var pesanWelcome = msgr.text;
  
  
  // uji dulu pesan yang diset bener atau enggak dalam format html :
  
  try {
    // kirim pesan berhasil disimpan
    tg.sendMsg(msg, 'βœ… <b>WELCOME</b>: '+pesanWelcome, 'HTML', false, msg.message_id);

    // simpan pesanWelcome
    user.setValue('welcomeMessage'+msg.chat.id, pesanWelcome);
    
  } catch (e) {
    // jika gagal, keluarkan pesan error
    var pesanError = e.message;
    
    // tangkep pesan error yang dari Telegram saja
    if (error = /({(?:.*)})/gmi.exec(pesanError) )
    pesanError = error[1];        
    
    // kalau Error gak usah di format HTML, buat keperluan debugging
    tg.sendMsg(msg, '⛔️ ERROR: '+pesanError, false, false, msg.message_id);
  }
  
  // selesai kecocokan pola, kembalikan
  return;
}

OK, enough!

Semestinya bot sudah berjalan dengan baik :-)

Video I

Isi materi video pertama

Cukup segini dulu.. sebut aja session pertama untuk video nya hehe.

Silakan tarik nafas, istirahat dulu.

"Yuk Belajar"

SESI II - Advanced

Kali ini materi sesi kelas advanced nya. Alias lanjutannya yang lebih rumit lagi.

Preview II

Button Inline

Kita buat welcome dengan fitur button inline. Set Welcome Inline ini hanya berlaku untuk reply message ya.

Syntax

Format yang kita pakai menggunakan format standar markdown saja ya.

Ketentuannya sebagai berikut :

  • harus reply pesan yang dijadikan welcome
  • (reply) !buttonWelcome jmlKolomButton SYNTAX_URL
  • jmlKolomButton adalah banyaknya kolom dalam 1 baris, dikasih berapa banyak tombol.
  • SYNTAX_URL adalah, penulisan format URL pada parse mode markdown. Yakni: [judul link](URL)
  • penulisan SYNTAX_URL bebas pakai ENTER, spasi, koma atau lainnya.

Contoh:

  user: (REPLY PESAN) !buttonWelcome 2
        [bangHasan](https://blog.banghasan.com)
        [botIndonesia](https://t.me/botindonesia)
        [Google](https://www.google.com)
  bot : (menampilkan welcome dengan button 2 column)

Pola Button

Regex untuk mendeteksi pola link adalah:

/\[([^\]]+)\]\((https?:\/\/[^\)]+)\)/gmi

atau dikasih nama group menjadi:

/\[(?<judul>[^\]]+)\]\((?<url>https?:\/\/[^\)]+)\)/gmi

Peloti saja ya, jelasinya agak susah haha.. atau lihat di video nya aja.

Intinya dibagi jadi 2 grup :

  1. judul link yang berada di dalam kurung kotak [judul link]
  2. Link target (url), harus diawali dengan protokol URI yang benar. Dalam hal ini http atau https. Tidak boleh menggunakan link internal atau link dummy (#).

Trigger

Kita buat pemicu set button welcomenya ini.

// trigger untuk button Welcome
// level: advance

/* syntax: !buttonWelcome jmlKolomButton SYNTAX_URL
  
   jmlKolomButton banyaknya kolom dalam 1 baris: button1, button2
   SYNTAX_URL format markdown [title](URL)
   
   URL protocol yang benar (http/https).
   
   SYNTAX_URL dipisahkan apa aja, boleh spasi, ENTER, koma, dlsb
*/
var pola = /^[!\/]buttonWelcome (\d+)/i;
if ( cocok = pola.exec(msg.text) ){
  
  // periksa dulu user ID nya, jika tidak ada akses tolak saja.
  if (! tg.util.punyaAkses(adminBot, msg.from.id)  ) 
    return tg.sendMsg(msg, '🚫 Kamu tidak punya akses.', false, false, msg.message_id);

  // periksa ada reply atau tidak, keluarkan pesan error
  if (!msg.reply_to_message) 
    return tg.sendMsg(msg, '🚫 Harus reply pesan.', false, false, msg.message_id);

  // sederhanakan variable reply_to_message
  var msgr = msg.reply_to_message;

  // periksa lagi, yang di reply text atau bukan
  if (!msgr.text)
    return tg.sendMsg(msg, '🚫 Harus bertipe text.', false, false, msg.message_id);
  
  // set up message yang akan di olah
  var pesanWelcome = msgr.text;
  
  // sekarang kita parsing button nya
  // jangan kebalik ya, yang diparsing adalah msg biasa, bukan msgr (messsage reply)
  var pesanButton = msg.text;

  // sanitasi: ubah ke Integer
  var jmlKolomButton = parseInt(cocok[1]);

  // periksa berapa nilainya, jika 0 batalin aja
  if (jmlKolomButton<1) 
    return tg.sendMsg(msg, '🚫 Minimal 1', false, false, msg.message_id); 

  // kasih batas maksimal aja juga, terserah berapa sepantasnya
  // di sini aku kasih 5 aja
  var jmlMaxKolomButton = 5;
  if (jmlKolomButton>jmlMaxKolomButton) 
    return tg.sendMsg(msg, '🚫 Maksimal '+jmlMaxKolomButton, false, false, msg.message_id); 

  // proses pembuatan / penyusunan button
  // dipahami sendiri ya, ini rumit bagi yang baru memulai. Makanya level nya advance

  // pola button
  var polaButton = /\[(?<judul>[^\]]+)\]\((?<url>https?:\/\/[^\)]+)\)/gmi;

  // buat variable pendukung
  var keyboard= []
  var baris = [];
  var nBaris = 0;
  var kolom = []
  var nKolom = 0;

  // proses penyusunan
  while (cocokButton = polaButton.exec(pesanButton) ) {

    // buat 1 button di variable button
    tombol = tg.button.url(cocokButton.groups.judul, cocokButton.groups.url);

    // susun dalam baris
    baris.push(tombol);

    // tambah index button kolom
    nKolom++;

    // jika index button kolom sesuai jmlKolomButton
    if (nKolom == jmlKolomButton) {
        // masukkan ke dalam susunan keyboard
        keyboard[[nBaris][0]] = baris;
        
        // tambahkan index baris / row keyboardnya
        nBaris++;

        // reset index kolom dan baris
        nKolom = 0;
        baris = [];    
    }
  }

  // sisa baris yang tidak diakomodir, masukkan di baris paling akhir
  if (nKolom>0)
    keyboard[[nBaris][0]] = baris; 

  // keyboard udah jadi, tinggal di coba send


  // uji dulu pesan yang diset bener atau enggak dalam format html
  // verifikasi text dan keyboad
  
  try {
    // kirim pesan berhasil disimpan
    // syntax lib 2 API: sendMsgKeyboardInline(msg, text, keyboard, parse_mode, disable_web_page_preview, reply_to_message_id)
    tg.sendMsgKeyboardInline(msg, pesanWelcome, keyboard, 'HTML', false, msg.message_id);

    // simpan pesanWelcome
    user.setValue('welcomeMessage'+msg.chat.id, pesanWelcome);
    // simpan buttonnya juga, bentuk string
    user.setValue('welcomeMessageButton'+msg.chat.id, JSON.stringify(keyboard));
    
  } catch (e) {
    // jika gagal, keluarkan pesan error
    var pesanError = e.message;
    
    // tangkep pesan error yang dari Telegram saja
    if (error = /({(?:.*)})/gmi.exec(pesanError) )
    pesanError = error[1];        
    
    // kalau Error gak usah di format HTML, buat keperluan debugging
    tg.sendMsg(msg, '⛔️ ERROR: '+pesanError, false, false, msg.message_id);
  }
  
  // selesai kecocokan pola, kembalikan
  return;
}

EVENT JOIN USER

Kita sesuaikan lagi di event join user.

// EVENT NEW USER dan SAY WELCOME BOT    
    
if (msg.new_chat_members) {
    // return tg.sendMsg(msg, tg.util.outToJSON(msg));
      
    // variable baru untuk new chat member, ambil yang pertama saja
    var newUser =  msg.new_chat_members[0];
      
    // mendefinisikan {nama}
    var namaUser = newUser.first_name;      
    // jika punya last name, kita tambahkan juga
    if (newUser.last_name)
      namaUser += " " + newUser.last_name;

    // bersihkan nama dari tag HTML
    namaUser = tg.util.clearHTML(namaUser);

    // mendifiniksan username
    var username = newUser.username ? '@'+newUser.username : '';

    // mendifinisikan iduser
    var idUser = newUser.id;

    // mendefinisikan grup title
    var namaGrup = msg.chat.title;

    // bersihkan nama grup dari tag HTML
    namaGrup = tg.util.clearHTML(namaGrup);

    // mendefinisikan id grup
    var idGrup = msg.chat.id;
      
    // Merangkai ucapan selamatnya digabung variable ke pesanWelcome
    // ambil dulu pesan di database User
    var pesanWelcome = user.getValue('welcomeMessage'+msg.chat.id);

    // jika tidak ada pesan welcome, ya udah balik aja
    if (!pesanWelcome) return false;

    // ambil button di database User
    var keyboard = user.getValue('welcomeMessageButton'+msg.chat.id);

    // masukkan variable-variablenya
    var teks = pesanWelcome
        .replace(/{nam[ae]}/ig, namaUser) // mengubah template nama, name
        .replace(/{username}/ig, username) // mengubah template username
        .replace(/{iduser}/ig, idUser) // mengubah template id user
        .replace(/{gro?up}/ig, namaGrup) // mengubah template title group
        .replace(/{idgro?up}/ig, idGrup) // mengubah template id group
      
    // kirim pesan welcome

    // jika terdapat keyboard
    if (keyboard) {

      // parsing ke format yang semestinya
      keyboard = JSON.parse(keyboard);

      // kirim dalam inline button
      return tg.sendMsgKeyboardInline(msg, teks, keyboard, 'HTML', false, msg.message_id);
    }

    // jika jenisnya biasa
    return tg.sendMsg(msg, teks, 'HTML')      
}

RUMIT YA!

Begitulah klo via tulisan.. Ya pelan-pelan saja ya hehe.

Makanya paling enak ya belajar bareng-bareng, bisa berdiskusi di grup tanya-tanya, sharing dan seru.

"Yuk Belajar"

Video II

Isi materi video kedua

PR

"Yuk Belajar"

Pekerjaan Rumah atau Apalah buat nambahin pengalaman ya.

Silakan dikembangkan sendiri variasi-variasi lain.

Misalnya menggunakan tipe foto, video, sticker, dan lain-lainnya.

Bisa juga modifikasi untuk cekWelcome ditambahkan button inline yang belum sempat dibahas di video ini / materi ini.

Referensi

Penutup

"Yuk Belajar"

Jika ada pertanyaan, saran atau masukkan silakan didiskusikan. Jika ingin live dan biasanya tanggapan juga lebih cepat, sangat disarankan bergabung pada group Telegram @botIndonesia. Semoga bermanfaat.