Transformer API Bot
Middleware adalah sebuah function yang menangani sebuah object context, misalnya data yang masuk.
grammY juga menyediakan kebalikannya. Function transformer adalah sebuah function yang menangani data yang keluar, contohnya:
- Pemanggilan method API Bot, serta
- Object payload yang cocok dengan suatu method tertentu.
Alih-alih memasukkan next
sebagai argument terakhir untuk memanggil middleware hilir (downstream), kamu akan menerima prev
sebagai argument pertama untuk memanfaatkan function transformer hulu (upstream). Kalau dilihat dari type signature-nya Transformer
(referensi API grammY), kita bisa melihat bagaimana ia diimplentasikan. Perlu diketahui bahwa Payload<M
merujuk ke object payload yang akan dicocokkan dengan method yang diberikan, serta Api
adalah type pengembalian dari method yang dipanggil.
Function transformer yang terakhir dipanggil adalah pemanggilan bawaan yang melakukan beberapa hal seperti JSON serialization untuk field tertentu dan terkadang juga memanggil fetch
.
Function transformer tidak memiliki sebuah class yang setara dengan Composer
. Tetapi, jika kamu membutuhkannya, kamu bisa membuatnya sendiri. Kami siap menerima pull request-mu! 😉
Memasang Function Transformer
Function Transformer bisa dipasang di bot
. Berikut contoh function transformer yang tidak melakukan apapun:
// Meneruskan ke function transformer
bot.api.config.use((prev, method, payload, signal) =>
prev(method, payload, signal)
);
// Perbandingan jika diteruskan ke middleware
bot.use((ctx, next) => next());
Berikut contoh function transformer yang mencegah semua pemanggilan API:
// Mengembalikan undefined alih-alih type object yang bersangkutan.
bot.api.config.use((prev, method, payload) => undefined as any);
Kamu juga bisa memasang function transformer di object API milik object context. Function transformer hanya akan digunakan sementara untuk request API yang dilakukan di object context tersebut, sehingga pemanggilan bot
tidak terpengaruh. Pemanggilan melalui object context dari middleware yang berjalan secara bersamaan (concurrent) juga tidak terpengaruh. Segera setelah middleware yang bersangkutan selesai, function transformer tersebut langsung dibuang.
bot.on("message", (ctx) => {
// Pasang di semua object context yang memproses pesan.
ctx.api.config.use((prev, method, payload, signal) =>
prev(method, payload, signal)
);
});
Parameter
signal
harus selalu diteruskan keprev
. Ia diperlukan untuk membatalkan request serta menjaga agarbot
bekerja dengan baik..stop
Function transformer yang dipasang di bot
juga akan terpasang di setiap object ctx
. Sehingga, pemanggilan ctx
akan ditransformasikan oleh kedua transformer baik di ctx
maupun di bot
.
Penggunaan Function Transformer
Function transformer sama fleksibelnya dengan middleware, serta penerapannya pun juga beragam.
Sebagai contoh, plugin menu grammY menggunakan sebuah function transformer untuk mengubah output instance menu menjadi payload yang sesuai. Kamu juga bisa bisa menggunakannya untuk:
- Mengimplementasikan pengaturan flood,
- Mock request API selama pengetesan,
- Mengatur perilaku retry,
- Dan lain-lain.
Namun, perlu diperhatikan bahwa mengulang kembali (retry) pemanggilan API bisa memiliki efek samping yang aneh, contohnya disaat kamu memanggil send
dan meneruskan instance stream ke Input
, maka stream akan dibaca saat pertama kali request dicoba. Jika kamu memanggil prev
lagi, stream tersebut mungkin sudah (sebagian) terpakai, sehingga file menjadi rusak. Oleh karena itu, cara yang lebih baik adalah dengan meneruskan path file ke Input
, sehingga grammY bisa membuat ulang stream jika diperlukan.
Menggunakan API Flavor
grammY memiliki fitur context flavor yang bisa digunakan untuk mengatur type context. Flavor juga bisa digunakan di method API, baik yang secara langsung ada di object context seperti ctx
maupun semua method di ctx
dan ctx
. Tetapi, kamu tidak bisa mengatur type bot
dan bot
melalui context flavor.
Itulah kenapa grammY mendukung API flavor. Ia dapat menyelesaikan permasalahan berikut:
import { Api, Bot, Context } from "grammy";
import { SomeApiFlavor, SomeContextFlavor, somePlugin } from "myPlugin";
// Buat Context flavor.
type MyContext = Context & SomeContextFlavor;
// Buat API flavor.
type MyApi = Api & SomeApiFlavor;
// Gunakan kedua flavor.
const bot = new Bot<MyContext, MyApi>("my-token");
// Gunakan sebuah plugin.
bot.api.config.use(somePlugin());
// Sekarang panggil `bot.api` dengan type yang sudah disesuaikan dari API flavor.
bot.api.somePluginMethod();
// Gunakan juga type yang sudah disesuaikan dari context flavor.
bot.on("message", (ctx) => ctx.api.somePluginMethod());
API flavor berjalan sama persis seperti context flavor. Baik jenis additive maupun transformative juga tersedia, dan berbagai macam API flavor juga bisa dikombinasikan sama halnya dengan yang kamu lakukan dengan context flavor. Kalau kamu belum paham bagaimana cara menggunakannya, baca kembali materi tentang context flavor.