Spaces:
Runtime error
Runtime error
| import { Injectable, NotFoundException } from '@nestjs/common'; | |
| import { migrate } from '@waha/apps/app_sdk/migrations'; | |
| import { IAppService } from '@waha/apps/app_sdk/services/IAppService'; | |
| import { IAppsService } from '@waha/apps/app_sdk/services/IAppsService'; | |
| import { ChatWootAppService } from '@waha/apps/chatwoot/services/ChatWootAppService'; | |
| import { DataStore } from '@waha/core/abc/DataStore'; | |
| import { SessionManager } from '@waha/core/abc/manager.abc'; | |
| import { WhatsappSession } from '@waha/core/abc/session.abc'; | |
| import { generatePrefixedId } from '@waha/utils/ids'; | |
| import { Knex } from 'knex'; | |
| import { InjectPinoLogger, PinoLogger } from 'nestjs-pino'; | |
| import { App, AppName } from '../dto/app.dto'; | |
| import { AppRepository } from '../storage/AppRepository'; | |
| () | |
| export class AppsEnabledService implements IAppsService { | |
| constructor( | |
| protected readonly chatwootService: ChatWootAppService, | |
| ('AppsService') | |
| protected logger: PinoLogger, | |
| ) {} | |
| async list(manager: SessionManager, session: string): Promise<App[]> { | |
| const knex = manager.store.getWAHADatabase(); | |
| const repo = new AppRepository(knex); | |
| const apps = await repo.getAllBySession(session); | |
| apps.forEach((app) => { | |
| delete app.pk; | |
| }); | |
| return apps; | |
| } | |
| async create(manager: SessionManager, app: App): Promise<App> { | |
| await this.checkSessionExists(manager, app.session); | |
| app.id = app.id || generatePrefixedId('app'); | |
| const knex = manager.store.getWAHADatabase(); | |
| const repo = new AppRepository(knex); | |
| const existingApp = await repo.getById(app.id); | |
| if (existingApp) { | |
| throw new Error(`App with ID '${app.id}' already exists.`); | |
| } | |
| // Validate only one Chatwoot app per session | |
| if (app.app === AppName.chatwoot) { | |
| const existingApps = await repo.getAllBySession(app.session); | |
| const existingChatwootApp = existingApps.find( | |
| (existingApp) => existingApp.app === AppName.chatwoot, | |
| ); | |
| if (existingChatwootApp) { | |
| throw new Error( | |
| `Only one Chatwoot app is allowed per session. Session '${app.session}' already has a Chatwoot app with ID '${existingChatwootApp.id}'.`, | |
| ); | |
| } | |
| } | |
| const service = this.getAppService(app); | |
| await service.beforeCreated(app); | |
| const result = await repo.save(app); | |
| await this.restartIfRunning(manager, app.session); | |
| delete result.pk; | |
| return result; | |
| } | |
| async update(manager: SessionManager, app: App) { | |
| await this.checkSessionExists(manager, app.session); | |
| const knex = manager.store.getWAHADatabase(); | |
| const repo = new AppRepository(knex); | |
| const savedApp = await repo.getById(app.id); | |
| if (!savedApp) { | |
| throw new NotFoundException(`App '${app.id}' not found`); | |
| } | |
| if (savedApp.app != app.app) { | |
| throw new Error( | |
| `Can not change app type. Delete and create a new app. Before type: '${savedApp.app}' After type: '${app.app}'`, | |
| ); | |
| } | |
| if (savedApp.session != app.session) { | |
| throw new Error( | |
| `Can not change session. Delete and create a new app. Before session: '${savedApp.session}' After session: '${app.session}'`, | |
| ); | |
| } | |
| const service = this.getAppService(app); | |
| await service.beforeUpdated(savedApp, app); | |
| await repo.update(app.id, app); | |
| await this.restartIfRunning(manager, app.session); | |
| return; | |
| } | |
| async delete(manager: SessionManager, appId: string) { | |
| const knex = manager.store.getWAHADatabase(); | |
| const repo = new AppRepository(knex); | |
| const app = await repo.getById(appId); | |
| if (!app) { | |
| throw new NotFoundException(`App '${appId}' not found`); | |
| } | |
| const service = this.getAppService(app); | |
| await service.beforeDeleted(app); | |
| await repo.delete(app.id); | |
| await this.restartIfRunning(manager, app.session); | |
| return; | |
| } | |
| async beforeSessionStart(session: WhatsappSession, store: DataStore) { | |
| const knex = store.getWAHADatabase(); | |
| const repo = new AppRepository(knex); | |
| const apps = await repo.getAllBySession(session.name); | |
| for (const app of apps) { | |
| const service = this.getAppService(app); | |
| await service.beforeSessionStart(app, session); | |
| } | |
| } | |
| async migrate(knex: Knex): Promise<void> { | |
| await migrate(knex); | |
| } | |
| private restartIfRunning(manager: SessionManager, session: string) { | |
| const isRunning = manager.isRunning(session); | |
| if (!isRunning) { | |
| return; | |
| } | |
| return manager.restart(session); | |
| } | |
| private getAppService(app: App): IAppService { | |
| switch (app.app) { | |
| case AppName.chatwoot: | |
| return this.chatwootService; | |
| default: | |
| throw new Error(`App '${app.app}' not supported`); | |
| } | |
| } | |
| private async checkSessionExists( | |
| manager: SessionManager, | |
| sessionName: string, | |
| ) { | |
| const session = await manager.exists(sessionName); | |
| if (session === null) { | |
| throw new NotFoundException('Session not found'); | |
| } | |
| } | |
| } | |