diff --git a/src/bot.ts b/src/bot.ts index 099a53e6..1676391a 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -112,6 +112,12 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { firstResponseTime: 0n, actualResponseTime: 0n, sessionState: RequestState.Initial + }, + payment: { + paymentTotal: 0, + paymentFreeCredits: 0, + paymentOneCredits: 0, + paymentFiatCredits: 0 } } const transaction = Sentry.startTransaction({ name: 'bot-command' }) @@ -139,6 +145,7 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { } await next() transaction.finish() + if (ctx.transient.analytics.module) { const userId = Number(ctx.message?.from?.id ?? '0') const username = ctx.message?.from?.username ?? '' @@ -151,6 +158,9 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { const totalProcessingTime = (now() - startTime).toString() const firstResponseTime = (ctx.transient.analytics.firstResponseTime - startTime).toString() const actualResponseTime = (ctx.transient.analytics.actualResponseTime - startTime).toString() + + const { paymentTotal, paymentFreeCredits, paymentOneCredits, paymentFiatCredits } = ctx.transient.payment + ES.add({ command, text: ctx.message?.text ?? '', @@ -161,7 +171,11 @@ bot.use(async (ctx: BotContext, next: NextFunction): Promise => { actualResponseTime, refunded: ctx.transient.refunded, sessionState: ctx.transient.analytics.sessionState, - totalProcessingTime + totalProcessingTime, + paymentTotal, + paymentFreeCredits, + paymentOneCredits, + paymentFiatCredits }).catch((ex: any) => { logger.error({ errorMsg: ex.message }, 'Failed to add data to ES') }) diff --git a/src/database/chat.service.ts b/src/database/chat.service.ts index 5170bb67..355d8381 100644 --- a/src/database/chat.service.ts +++ b/src/database/chat.service.ts @@ -21,6 +21,13 @@ interface UserCredits { totalCreditsAmount: bn } +interface CreditsPayment { + totalCredits: string + freeCredits: string + oneCredits: string + fiatCredits: string +} + export class ChatService { creditsAssignedCache = new LRUCache({ max: 1000, ttl: 24 * 60 * 60 * 1000 }) @@ -109,7 +116,13 @@ export class ChatService { } } - public async withdrawCredits (accountId: number, payAmount: bn): Promise { + public async withdrawCredits ( + accountId: number, + payAmount: bn + ): Promise<{ + userPayment: CreditsPayment + userCredits: UserCredits + }> { const { totalCreditsAmount, creditAmount, @@ -139,7 +152,18 @@ export class ChatService { oneCreditAmount: oneCreditsNext.toFixed(), fiatCreditAmount: fiatCreditNext.toFixed() }) - return await this.getUserCredits(accountId) + + const userCredits = await this.getUserCredits(accountId) + + return { + userPayment: { + totalCredits: payAmount.toFixed(), + freeCredits: creditsPayAmount.toFixed(), + oneCredits: oneCreditsPay.toFixed(), + fiatCredits: fiatCreditPay.toFixed() + }, + userCredits + } } public async initChat ({ tgUserId, accountId, tgUsername = '' }: { tgUserId: number, accountId: number, tgUsername?: string }): Promise { diff --git a/src/es/index.ts b/src/es/index.ts index 90ebd1bf..209611ff 100644 --- a/src/es/index.ts +++ b/src/es/index.ts @@ -23,6 +23,10 @@ export interface BotLogData { actualResponseTime: string // converted from bigint refunded: boolean sessionState: string + paymentTotal: number // float + paymentFreeCredits: number // float + paymentOneCredits: number // float + paymentFiatCredits: number // float } const Index = config.es.index ?? 'bot-logs' diff --git a/src/es/schemas/bot-logs.json b/src/es/schemas/bot-logs.json index abc4d548..98a9abef 100644 --- a/src/es/schemas/bot-logs.json +++ b/src/es/schemas/bot-logs.json @@ -34,6 +34,18 @@ }, "sessionState": { "type": "keyword" + }, + "paymentTotal": { + "type": "double" + }, + "paymentFreeCredits": { + "type": "double" + }, + "paymentOneCredits": { + "type": "double" + }, + "paymentFiatCredits": { + "type": "double" } } } diff --git a/src/modules/payment/index.ts b/src/modules/payment/index.ts index 41027d9a..61f1cf51 100644 --- a/src/modules/payment/index.ts +++ b/src/modules/payment/index.ts @@ -183,6 +183,12 @@ export class BotPayments { return +value } + public async fromONEToUSD (amountWei: string, fractionalDigits = 4): Promise { + const currentRate = await this.getOneRate() + const amountONE = this.web3.utils.fromWei(amountWei, 'ether') + return +(currentRate * +amountONE).toFixed(fractionalDigits) + } + public async getAddressBalance (address: string): Promise { const balance = await this.web3.eth.getBalance(address) return bn(balance.toString()) @@ -397,13 +403,19 @@ export class BotPayments { ) if (totalBalanceDelta.gte(0)) { - const balanceAfter = await chatService.withdrawCredits(accountId, totalPayAmount) + const { userPayment, userCredits: userCreditsAfter } = await chatService.withdrawCredits(accountId, totalPayAmount) this.logger.info(`[${from.id} @${ from.username - }] successfully paid from credits, credits balance after: ${balanceAfter.totalCreditsAmount}`) + }] successfully paid from credits, credits balance after: ${userCreditsAfter.totalCreditsAmount}`) - freeCreditsFeeCounter.inc(this.convertBigNumber(totalPayAmount)) await this.writePaymentLog(ctx, totalPayAmount) + + ctx.transient.payment.paymentTotal = await this.fromONEToUSD(userPayment.totalCredits) + ctx.transient.payment.paymentFreeCredits = await this.fromONEToUSD(userPayment.freeCredits) + ctx.transient.payment.paymentOneCredits = await this.fromONEToUSD(userPayment.oneCredits) + ctx.transient.payment.paymentFiatCredits = await this.fromONEToUSD(userPayment.fiatCredits) + + freeCreditsFeeCounter.inc(this.convertBigNumber(totalPayAmount)) return true } else { const oneBalance = await this.getAddressBalance(userAccount.address) diff --git a/src/modules/types.ts b/src/modules/types.ts index 2ee8a626..1cf56bc8 100644 --- a/src/modules/types.ts +++ b/src/modules/types.ts @@ -108,7 +108,13 @@ export interface Analytics { actualResponseTime: bigint sessionState: RequestState module: string +} +export interface PaymentAnalytics { + paymentTotal: number + paymentFreeCredits: number + paymentOneCredits: number + paymentFiatCredits: number } export interface BotSessionData { @@ -123,6 +129,7 @@ export interface TransientStateContext { transient: { analytics: Analytics refunded: boolean + payment: PaymentAnalytics } }