Skip to content

Commit

Permalink
refactor(config): use znv to parse and validate env variable
Browse files Browse the repository at this point in the history
  • Loading branch information
tfkhdyt committed Oct 5, 2023
1 parent 380d67c commit 0c60fce
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 47 deletions.
Binary file modified bun.lockb
Binary file not shown.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"fastify": "^4.23.2",
"midtrans-node-client": "^0.0.6",
"telegraf": "^4.14.0",
"xendit-node": "^3.2.0"
"xendit-node": "^3.2.0",
"znv": "^0.4.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.7.4",
Expand Down
49 changes: 30 additions & 19 deletions src/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
export default {
botDomain: process.env.BOT_DOMAIN as string,
port: (process.env.PORT || 3000) as number,
botToken: process.env.BOT_TOKEN as string,
nodeEnv: process.env.NODE_ENV as string,
adminId: process.env.ADMIN_ID as string,
scraperAPIKey: process.env.SCRAPER_API_KEY as string,
databaseUrl: process.env.DATABASE_URL as string,
databaseAuthToken: process.env.DATABASE_AUTH_TOKEN as string,
xenditSecret: process.env.XENDIT_SECRET as string,
midtransServerKey: process.env.MIDTRANS_SERVER_KEY as string,
midtransClientKey: process.env.MIDTRANS_CLIENT_KEY as string,
message: {
start: `Selamat datang di bot *KBBI*
import { parseEnv, port, z } from 'znv'

Dengan bot ini kalian dapat mencari pengertian dari suatu kata dalam KBBI. Kalian hanya perlu mengirim sebuah kata kepada bot ini, maka bot ini akan mengirim definisi dari kata Tersebut.
export const {
BOT_DOMAIN,
PORT,
BOT_TOKEN,
NODE_ENV,
ADMIN_ID,
DATABASE_URL,
DATABASE_AUTH_TOKEN,
MIDTRANS_SERVER_KEY,
MIDTRANS_CLIENT_KEY,
} = parseEnv(process.env, {
BOT_DOMAIN: z.string().url().optional(),
PORT: port().default(3000),
BOT_TOKEN: z.string().min(1),
NODE_ENV: z.enum(['production', 'development']).default('development'),
ADMIN_ID: z.number().int().positive(),
DATABASE_URL: z.string().min(1),
DATABASE_AUTH_TOKEN: z.string().optional(),
MIDTRANS_SERVER_KEY: z.string().min(1),
MIDTRANS_CLIENT_KEY: z.string().min(1),
})

Data dari bot ini diambil dari situs resmi KBBI melalui metode _Web Scraping_ dengan *Node.js*, *Telegraf*, dan *Cheerio*.
export const message = {
start: `Selamat datang di bot *KBBI*
Untuk pertanyaan lebih lanjut, silakan hubungi @tfkhdyt.`,
help: 'Untuk menggunakan bot ini, kalian hanya perlu mengirimkan kata yang ingin kalian cari kepada bot ini.\nUntuk pertanyaan lebih lanjut, silakan hubungi @tfkhdyt.',
},
Dengan bot ini kalian dapat mencari pengertian dari suatu kata dalam KBBI. Kalian hanya perlu mengirim sebuah kata kepada bot ini, maka bot ini akan mengirim definisi dari kata Tersebut.
Data dari bot ini diambil dari situs resmi KBBI melalui metode _Web Scraping_ dengan *Node.js*, *Telegraf*, dan *Cheerio*.
Untuk pertanyaan lebih lanjut, silakan hubungi @tfkhdyt.`,
help: 'Untuk menggunakan bot ini, kalian hanya perlu mengirimkan kata yang ingin kalian cari kepada bot ini.\nUntuk pertanyaan lebih lanjut, silakan hubungi @tfkhdyt.',
}
6 changes: 3 additions & 3 deletions src/db/sqlite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { createClient } from '@libsql/client'
import { drizzle } from 'drizzle-orm/libsql'
import { migrate } from 'drizzle-orm/libsql/migrator'

import config from '../../config/config.js'
import { DATABASE_AUTH_TOKEN, DATABASE_URL } from '../../config/config.js'

const client = createClient({
url: config.databaseUrl,
authToken: config.databaseAuthToken,
url: DATABASE_URL,
authToken: DATABASE_AUTH_TOKEN,
})
export const db = drizzle(client)
export type DB = typeof db
Expand Down
11 changes: 7 additions & 4 deletions src/db/sqlite/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import { createClient } from '@libsql/client'
import { drizzle } from 'drizzle-orm/libsql'
import { migrate } from 'drizzle-orm/libsql/migrator'

import config from '../../config/config.js'
import {
DATABASE_AUTH_TOKEN,
DATABASE_URL,
NODE_ENV,
} from '../../config/config.js'

const client = createClient({
url: config.databaseUrl,
authToken:
config.nodeEnv === 'production' ? config.databaseAuthToken : undefined,
url: DATABASE_URL,
authToken: NODE_ENV === 'production' ? DATABASE_AUTH_TOKEN : undefined,
})
const db = drizzle(client)

Expand Down
4 changes: 2 additions & 2 deletions src/handlers/callback.handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FastifyReply, FastifyRequest } from 'fastify'

import config from '../config/config.js'
import { ADMIN_ID } from '../config/config.js'
import { bot } from '../lib/telegraf.js'
import { increaseCredits } from '../repositories/user.repository.js'
import { PaymentBody } from '../types/paymentBody.js'
Expand All @@ -25,7 +25,7 @@ export const callbackHandler = async (
`Topup sejumlah ${amount} saldo melalui "${paymentChannel.toUpperCase()}" telah berhasil! Terima kasih telah menggunakan layanan kami`,
),
bot.telegram.sendMessage(
config.adminId,
ADMIN_ID,
`Topup sejumlah ${amount} saldo melalui "${paymentChannel.toUpperCase()}" telah berhasil!`,
),
])
Expand Down
12 changes: 8 additions & 4 deletions src/lib/midtrans.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { MidtransClient } from 'midtrans-node-client'

import config from '../config/config.js'
import {
MIDTRANS_CLIENT_KEY,
MIDTRANS_SERVER_KEY,
NODE_ENV,
} from '../config/config.js'

export const snap = new MidtransClient.Snap({
isProduction: config.nodeEnv === 'production',
serverKey: config.midtransServerKey,
clientKey: config.midtransClientKey,
isProduction: NODE_ENV === 'production',
serverKey: MIDTRANS_SERVER_KEY,
clientKey: MIDTRANS_CLIENT_KEY,
})
4 changes: 2 additions & 2 deletions src/lib/telegraf.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Telegraf } from 'telegraf'

import config from '../config/config.js'
import { BOT_TOKEN } from '../config/config.js'
import { MyContext } from '../types/context.js'

export const bot = new Telegraf<MyContext>(config.botToken)
export const bot = new Telegraf<MyContext>(BOT_TOKEN)
10 changes: 5 additions & 5 deletions src/lib/xendit.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Invoice } from 'xendit-node'
// import { Invoice } from 'xendit-node'

import config from '../config/config.js'
// import config from '../config/config.js'

export const xenditClient = new Invoice({
secretKey: config.xenditSecret,
})
// export const xenditClient = new Invoice({
// secretKey: config.xenditSecret,
// })
14 changes: 7 additions & 7 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'dotenv/config.js'
import fastify from 'fastify'
import { message } from 'telegraf/filters'

import config from './config/config.js'
import { BOT_DOMAIN, message as msg, NODE_ENV, PORT } from './config/config.js'
import { callbackHandler } from './handlers/callback.handler.js'
import { invoiceHandler } from './handlers/invoice.handler.js'
import { saldoHandler } from './handlers/saldo.handler.js'
Expand All @@ -20,23 +20,23 @@ const server = fastify()
server.get('/', () => 'Hello world')
server.post('/receive_callback', callbackHandler)

bot.start((ctx) => ctx.replyWithMarkdown(config.message.start))
bot.help((ctx) => ctx.replyWithMarkdown(config.message.help))
bot.start((ctx) => ctx.replyWithMarkdown(msg.start))
bot.help((ctx) => ctx.replyWithMarkdown(msg.help))

bot.use(checkUserMiddleware)
bot.command('saldo', saldoHandler)
bot.command('topup', topupHandler)
bot.action(/^topup:([A-z0-9]+)$/, invoiceHandler)
bot.on(message('text'), (ctx) => textHandler(ctx))

if (config.nodeEnv === 'production') {
if (NODE_ENV === 'production' && BOT_DOMAIN !== undefined) {
console.log('Bot is running in production')
const webhook = await bot.createWebhook({ domain: config.botDomain })
const webhook = await bot.createWebhook({ domain: BOT_DOMAIN })
// @ts-expect-error fastify and telegraf webhook issue
server.post(`/telegraf/${bot.secretPathComponent()}`, webhook)
await server.listen({ port: config.port, host: '0.0.0.0' })
await server.listen({ port: PORT, host: '0.0.0.0' })
} else {
console.log('Bot is running in development')
await server.listen({ port: config.port })
await server.listen({ port: PORT })
await bot.launch()
}

0 comments on commit 0c60fce

Please sign in to comment.