Hosting: Heroku
Kami mengasumsikan bahwa kamu sudah memiliki pengetahuan dasar dalam membuat sebuah bot menggunakan grammY. Jika belum, silahkan baca panduan yang telah kami buat dengan sepenuh hati! ❤️
Tutorial ini akan mengajari kamu cara men-deploy bot Telegram ke Heroku, baik menggunakan webhooks maupun long polling. Kami juga mengasumsikan kalau kamu sudah mempunyai akun Heroku.
Persiapan
Pertama-tama, instal beberapa dependency.
# Buat sebuah direktori proyek.
mkdir grammy-bot
cd grammy-bot
npm init --y
# Instal dependency utama.
npm install grammy express
# Instal dependency untuk development.
npm install -D typescript @types/express @types/node
# Buat konfigurasi TypeScript-nya.
npx tsc --init
2
3
4
5
6
7
8
9
10
11
12
13
Kita akan menyimpan file TypeScript di dalam sebuah folder src
, sedangkan file hasil compile kita taruh di folder dist
. Buat kedua folder tersebut di direktori root proyek. Selanjutnya, buat sebuah file baru bernama bot
di dalam folder src
. Struktur folder kita kurang lebih mirip seperti ini:
.
├── node_modules/
├── dist/
├── src/
│ └── bot.ts
├── package.json
├── package-lock.json
└── tsconfig.json
Setelah itu, buka file tsconfig
lalu ubah konfigurasinya menjadi seperti ini:
{
"compilerOptions": {
"target": "ESNEXT",
"module": "ESNext", // ubah dari commonjs menjadi esnext
"lib": ["ES2021"],
"outDir": "./dist/",
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src"]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
Karena opsi module
di atas telah kita ubah commonjs
menjadi esnext
, maka kita harus menambahkan "type":
ke file package
. File package
kita kurang lebih tampak seperti ini:
{
"name": "grammy-bot",
"version": "0.0.1",
"description": "",
"main": "dist/app.js",
"type": "module", // tambah property "type": "module"
"scripts": {
"dev-build": "tsc"
},
"author": "",
"license": "ISC",
"dependencies": {
"grammy": "^1.2.0",
"express": "^4.17.1"
},
"devDependencies": {
"typescript": "^4.3.5",
"@types/express": "^4.17.13",
"@types/node": "^16.3.1"
},
"keywords": []
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Seperti yang sudah dijelaskan di awal, kita memiliki dua opsi untuk menerima data dari Telegram: webhook dan long polling. Kamu bisa mempelajari kelebihan dan kekurangan dari kedua jenis deployment tersebut di materi ini!
Webhooks
Jika kamu lebih memilih untuk menggunakan long polling, langsung saja lompat ke bagian long polling. 🚀
Singkatnya, tidak seperti long polling, webhook tidak perlu berjalan terus-menerus untuk mengecek pesan masuk dari Telegram. Dengan begitu, beban kerja server dan penggunaan kuota dyno hours bisa dikurangi, terutama jika kamu menggunakan paket Eco. 😁
Oke, lanjut! Masih ingat kita punya bot
di awal tadi? Kita tidak akan asal menaruh semua kode di file tersebut. Sebaliknya, kita akan membuat sebuah file baru bernama app
sebagai entry point utama kita. Artinya, setiap kali Telegram (atau orang lain) mengunjungi website kita, express
akan menentukan server mana yang bertanggung jawab untuk menangani request tersebut. Ini berguna ketika kamu men-deploy baik website maupun bot di domain yang sama. Selain itu, kode kita akan terlihat lebih rapi dengan membaginya menjadi beberapa bagian ke beberapa file. ✨
Express Beserta Middleware-nya
Sekarang, buat app
di dalam folder src
, lalu masukkan kode berikut ke dalamnya:
import express from "express";
import { webhookCallback } from "grammy";
import { bot } from "./bot.js";
const domain = String(process.env.DOMAIN);
const secretPath = String(process.env.BOT_TOKEN);
const app = express();
app.use(express.json());
app.use(`/${secretPath}`, webhookCallback(bot, "express"));
app.listen(Number(process.env.PORT), async () => {
// Pastikan menggunakan `https` bukan `http`!
await bot.api.setWebhook(`https://${domain}/${secretPath}`);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Mari kita lihat kode yang telah kita buat di atas:
process
: Ingat, JANGAN menyimpan informasi-informasi rahasia di kode kamu! Untuk membuat environment variable di Heroku, lihat panduan berikut..env secret
: Ini bisa berupaPath TOKEN
atau teks acak lainnya. Kita dianjurkan untuk menyembunyikan alamat URL bot, seperti yang sudah dijelaskan oleh Telegram._BOT
⚡ Optimisasi (opsional)
bot
di baris kode ke-14 di atas, akan selalu dijalankan setiap kali Heroku memulai server kamu. Untuk bot yang memiliki traffic rendah, ia akan dijalankan untuk setiap request. Kita tidak perlu baris kode ini dijalankan setiap kali ada request masuk. Oleh karena itu, kita bisa menghapusnya dan hanya menjalankan GET
sekali secara manual. Buka link ini di web browser setelah men-deploy bot:
https://api.telegram.org/bot<token_bot>/setWebhook?url=<url_webhook>
Perlu diperhatikan bahwa beberapa browser mengharuskan kamu secara manual mengurl
sebelum ditambahkan ke URL. Contohnya, jika kamu memiliki token bot abcd:
dan URL https://
, link tersebut seharusnya akan tampak seperti ini:
https://api.telegram.org/botabcd:1234/setWebhook?url=https%3A%2F%2Fgrammybot.herokuapp.com%2Fsecret_path
⚡ Optimisasi (opsional)
Gunakan Webhook Reply agar lebih efisien.
Membuat bot.ts
(Webhooks)
Langkah berikutnya, buat bot
lalu tulis kode berikut:
import { Bot } from "grammy";
const token = process.env.BOT_TOKEN;
if (!token) throw new Error("BOT_TOKEN belum diisi");
export const bot = new Bot(token);
bot.command("start", (ctx) => ctx.reply("Haloooo!"));
bot.on("message", (ctx) => ctx.reply("Dapat pesan baru!"));
2
3
4
5
6
7
8
9
Mantap! Kita telah berhasil menyelesaikan coding-an utamanya. Sebelum kita melangkah ke tahap deployment, kita bisa melakukan optimisasi kecil lainnya. Seperti biasa, langkah ini adalah opsional.
⚡ Optimisasi (opsional)
Setiap kali server dimulai, grammY akan mengambil sejumlah informasi mengenai bot terkait dari Telegram agar ctx
tersedia di object context. Kita bisa mengisi informasi bot tersebut secara manual untuk menghindari pemanggilan get
secara berlebihan.
Buka link
https://
di web browser favoritmu. Kami merekomendasikan untuk menggunakan browser Firefox karena ia mampu menampilkan formatapi .telegram .org /bot<bot _token> /get Me json
dengan baik.Ubah kode di baris ke-4 di atas dengan value yang telah kita dapat dari
get
tadi:Me tsconst token = process.env.BOT_TOKEN; if (!token) throw new Error("BOT_TOKEN belum diisi"); export const bot = new Bot(token, { botInfo: { id: 111111111, is_bot: true, first_name: "xxxxxxxxx", username: "xxxxxxbot", can_join_groups: true, can_read_all_group_messages: false, supports_inline_queries: false, }, });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Keren! Sekarang waktunya mempersiapkan environment deployment kita! Mari menuju bagian Deployment, saudara-saudara sekalian! 💪
Long Polling
Script Kamu Akan Dijalankan secara Terus-menerus ketika Menggunakan Long Polling
Pastikan kamu memiliki dyno hours yang cukup, kecuali jika kamu tahu cara mengatasinya.
Lebih memilih webhook? Lompat ke bagian webhooks di atas. 🚀
Menggunakan long polling di server bukanlah ide yang buruk. Terkadang, deployment jenis ini cocok untuk bot pengoleksi data, dimana ia tidak memerlukan respon yang cepat serta membutuhkan waktu yang lama untuk memproses banyak data. Jika ingin melakukannya setiap satu jam sekali, kamu bisa melakukannya dengan sangat mudah. Hal-hal semacam itu yang tidak bisa kamu kontrol di webhooks. Jika bot kamu dibanjiri banyak pesan, kamu akan melihat banyak sekali request webhooks, sedangkan di long polling kamu bisa membatasinya dengan mudah.
Membuat bot.ts
(Long Polling)
Mari kita buka file bot
yang telah kita buat di awal tadi. Pastikan ia memiliki baris-baris kode berikut:
import { Bot } from "grammy";
const token = process.env.BOT_TOKEN;
if (!token) throw new Error("BOT_TOKEN belum diisi");
const bot = new Bot(token);
bot.command(
"start",
(ctx) => ctx.reply("Aku berjalan di Heroku menggunakan long polling!"),
);
bot.start();
2
3
4
5
6
7
8
9
10
11
12
13
Selesai! Kita siap untuk men-deploy-nya. Cukup simpel, bukan? 😃 Jika kamu pikir ini terlalu mudah, coba lihat daftar Deployment yang telah kami buat! 🚀
Deployment
Eitss… Bot Roket kita masih belum siap untuk diluncurkan. Selesaikan tahapan-tahapan ini dulu!
Compile File-nya
Jalankan kode ini di terminal untuk meng-compile file TypeScript menjadi JavaScript:
npx tsc
Jika berhasil dijalankan dan tidak ada pesan error yang muncul, file-file yang telah di-compile akan tersedia di folder dist
dengan ekstension .js
di akhir namanya.
Siapkan File Procfile
Heroku
memiliki beberapa jenis dynos. Dua diantaranya adalah:
Web dynos:
Web dynos adalah sebuah dyno untuk memproses “web” yang menerima traffic HTTP dari berbagai router. Dyno tipe ini memiliki waktu timeout selama 30 detik untuk menjalankan kode. Selain itu, ia akan tidur jika tidak ada request yang dikerjakan dalam rentang waktu 30 menit. Jenis dyno seperti ini cocok digunakan untuk webhooks.
Worker dynos:
Worker dynos digunakan untuk memproses kode di belakang layar. Ia TIDAK memiliki waktu timeout dan TIDAK akan tidur jika tidak ada request web yang dikerjakan. Sehingga, ia cocok digunakan untuk long polling.
Buat file dengan nama Procfile
tanpa extension file di direktori root proyek kita. Contohnya, Procfile
dan procfile
bukan nama yang valid. Lalu, tulis satu baris kode berikut:
<jenis dyno>: <perintah untuk menjalankan file entry kita>
Untuk contoh kali ini, kita akan menulisnya seperti berikut:
web: node dist/app.js
worker: node dist/bot.js
Atur Git
Kita akan men-deploy bot menggunakan Git dan Heroku CLI. Berikut link cara penginstalannya:
Kami mengasumsikan kamu telah menginstal kedua software tersebut, dan kamu juga sudah membuka terminal yang mengarah ke direktori root proyek kita. Sekarang, buat repositori git lokal dengan menjalankan kode ini di terminal:
git init
Selanjutnya, kita perlu mencegah beberapa file tidak ikut terunggah ke server produksi kita, dalam hal ini Heroku
. Buat sebuah file bernama .gitignore
di direktori root proyek kita. Kemudian, tambahkan daftar berikut:
node_modules/
src/
tsconfig.json
2
3
Hasil akhir struktur folder kita akan tampak seperti ini:
.
├── .git/
├── node_modules/
├── dist/
│ ├── bot.js
│ └── app.js
├── src/
│ ├── bot.ts
│ └── app.ts
├── package.json
├── package-lock.json
├── tsconfig.json
├── Procfile
└── .gitignore
.
├── .git/
├── node_modules/
├── dist/
│ └── bot.js
├── src/
│ └── bot.ts
├── package.json
├── package-lock.json
├── tsconfig.json
├── Procfile
└── .gitignore
Commit file-file tersebut ke repositori git kita:
git add .
git commit -m "Commit pertamaku"
2
Atur Remote Heroku
Jika kamu sudah membuat Heroku app, masukkan nama app
tersebut ke <my
di bawah, kemudian jalankan kodenya. Kalau belum punya, jalankan New app
.
heroku create
git remote -v
2
heroku git:remote -a <myApp>
Men-deploy Kode
Terakhir, tekan tombol merah berikut dan meluncur! 🚀
git push heroku main
Jika kode di atas tidak bekerja, kemungkinan besar branch git kita bukanlah main
, tetapi master
. Kalau begitu, tekan tombol biru berikut:
git push heroku master