import { BadRequestException, Body, Controller, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Post, Query, Req, UseGuards, } from '@nestjs/common'; import { IntegrationService } from '../service/integration.service'; import { BulkMessageDto, CheckAgentStatusDto, CreateConfigDto, CreateUserIntegrationDto, GenericSendMessageDto, GetIntegrationTemplatesDto, SendGridTemplatesDto, SendGridVerifiedSendersDto, UpdateConfigDto, UpdateUserIntegrationDto, } from '../dto/create-config.dto'; import { JwtAuthGuard } from 'src/module/auth/guards/jwt.guard'; export class ScheduledMessageDto extends GenericSendMessageDto { scheduleFor: Date; timezone?: string; } @Controller('integration') export class IntegrationController { constructor(private readonly integrationService: IntegrationService) {} @Post('send') @HttpCode(HttpStatus.OK) async sendMessage(@Body() sendMessageDto: GenericSendMessageDto) { try { return await this.integrationService.sendGenericMessage(sendMessageDto); } catch (error) { throw new BadRequestException({ success: false, error: 'SEND_MESSAGE_ERROR', message: error.message || 'Failed to send message', code: 'MESSAGE_SEND_ERROR', }); } } @Post('send/bulk') @HttpCode(HttpStatus.OK) async sendBulkMessage(@Body() bulkMessageDto: BulkMessageDto) { try { return await this.integrationService.sendBulkMessage(bulkMessageDto); } catch (error) { throw new BadRequestException({ success: false, error: 'SEND_BULK_MESSAGE_ERROR', message: error.message || 'Failed to send bulk messages', code: 'BULK_MESSAGE_SEND_ERROR', }); } } @Post('send/scheduled') @HttpCode(HttpStatus.OK) async scheduleMessage(@Body() scheduledMessageDto: ScheduledMessageDto) { try { return await this.integrationService.scheduleMessage(scheduledMessageDto); } catch (error) { throw new BadRequestException({ success: false, error: 'SCHEDULE_MESSAGE_ERROR', message: error.message || 'Failed to schedule message', code: 'MESSAGE_SCHEDULE_ERROR', }); } } @Post('send/template') @HttpCode(HttpStatus.OK) async sendTemplateMessage( @Body() templateMessage: { levelId: number; levelType: string; app_code: string; to: string | string[]; templateId: string; variables: Record; type?: 'EMAIL' | 'SMS' | 'WA' | 'TELEPHONE'; }, ) { try { return await this.integrationService.sendTemplateMessage(templateMessage); } catch (error) { throw new BadRequestException({ success: false, error: 'SEND_TEMPLATE_MESSAGE_ERROR', message: error.message || 'Failed to send template message', code: 'TEMPLATE_MESSAGE_SEND_ERROR', }); } } @Post('check-agent-status') @HttpCode(HttpStatus.OK) async checkAgentStatus(@Body() checkAgentStatusDto: CheckAgentStatusDto) { try { const result = await this.integrationService.checkAgentStatus( checkAgentStatusDto.levelId, checkAgentStatusDto.levelType, checkAgentStatusDto.app_code, checkAgentStatusDto.user_id, checkAgentStatusDto.type || 'TELEPHONE', ); return result; } catch (error) { throw new BadRequestException({ success: false, error: 'CHECK_AGENT_STATUS_ERROR', message: error.message || 'Failed to check agent status', code: 'AGENT_STATUS_ERROR', }); } } @Post('config') @HttpCode(HttpStatus.OK) async createConfig(@Body() createConfigDto: CreateConfigDto) { try { const result = await this.integrationService.createIntegrationConfig( createConfigDto.levelId, createConfigDto.levelType, createConfigDto.app_code, createConfigDto.integration_type as | 'EMAIL' | 'SMS' | 'WA' | 'TELEPHONE', createConfigDto.integration_provider, createConfigDto.integration_source_id, createConfigDto.config, createConfigDto.priority, createConfigDto.is_default, ); return result; } catch (error) { // Handle validation errors with BadRequest status if ( error.message?.includes('active') && error.message?.includes('configuration already exists') ) { throw new BadRequestException({ success: false, error: 'DUPLICATE_CONFIGURATION', message: error.message, code: 'VALIDATION_ERROR', }); } // Handle unsupported combination errors if (error.message?.includes('Unsupported combination')) { throw new BadRequestException({ success: false, error: 'UNSUPPORTED_COMBINATION', message: error.message, code: 'VALIDATION_ERROR', }); } // Handle OAuth redirect responses (return as success with OAuth info) if (error.authUrl && error.state) { return { success: false, requiresOAuth: true, authUrl: error.authUrl, state: error.state, message: error.message || 'OAuth authorization required', }; } // Handle other errors as BadRequest throw new BadRequestException({ success: false, error: 'CONFIGURATION_ERROR', message: error.message || 'Failed to create communication configuration', code: 'INTERNAL_ERROR', }); } } @Get('supported-combinations') async getSupportedCombinations() { try { return await this.integrationService.getSupportedCombinations(); } catch (error) { throw new BadRequestException({ success: false, error: 'GET_COMBINATIONS_ERROR', message: error.message || 'Failed to get supported combinations', code: 'FETCH_ERROR', }); } } @Get('level/:id/:type/configs') async getLevelConfigs( @Param('id', ParseIntPipe) levelId: number, @Param('type') levelType: string, @Query('app_code') app_code?: string, @Query('communication_config_type') configType?: 'WA' | 'SMS' | 'EMAIL' | 'TELEPHONE', @Query('provider') provider?: string, ) { try { return await this.integrationService.getLevelConfigs(levelId, levelType, { app_code, integration_type: configType, integration_provider: provider, }); } catch (error) { throw new BadRequestException({ success: false, error: 'GET_LEVEL_CONFIGS_ERROR', message: error.message || 'Failed to get level configurations', code: 'FETCH_ERROR', }); } } @Get('config/:id') async getIntegrationConfigById(@Param('id', ParseIntPipe) hubId: number) { try { const config = await this.integrationService.getIntegrationConfigById(hubId); if (!config) { throw new BadRequestException({ success: false, error: 'NOT_FOUND', message: 'Communication configuration not found', code: 'CONFIGURATION_NOT_FOUND', }); } return { success: true, data: config, }; } catch (error) { if (error instanceof BadRequestException) { throw error; } throw new BadRequestException({ success: false, error: 'FETCH_ERROR', message: error.message || 'Failed to fetch communication configuration', code: 'INTERNAL_ERROR', }); } } @Post('config/:id/update') @HttpCode(HttpStatus.OK) async activateConfig( @Param('id', ParseIntPipe) hubId: number, @Query('status') status: string, ) { try { const statusNumber = parseInt(status, 10); if (isNaN(statusNumber) || (statusNumber !== 0 && statusNumber !== 1)) { throw new BadRequestException('Status must be 0 or 1'); } await this.integrationService.updateConfigStatus(hubId, statusNumber); return { success: true, message: 'Configuration updated successfully', }; } catch (error) { throw new BadRequestException({ success: false, error: 'UPDATE_STATUS_ERROR', }); } } @Post('sendgrid/verified-senders') @HttpCode(HttpStatus.OK) async getSendGridVerifiedSenders(@Body() dto: SendGridVerifiedSendersDto) { try { return await this.integrationService.getSendGridVerifiedSenders(dto.apiKey); } catch (error) { throw new BadRequestException({ success: false, error: 'GET_SENDGRID_SENDERS_ERROR', message: error.message || 'Failed to get SendGrid verified senders', code: 'SENDGRID_ERROR', }); } } @Post('sendgrid/templates') @HttpCode(HttpStatus.OK) async getSendGridTemplates(@Body() dto: SendGridTemplatesDto) { try { return await this.integrationService.getSendGridTemplates( dto.levelId, dto.levelType, dto.app_code, ); } catch (error) { throw new BadRequestException({ success: false, error: 'GET_SENDGRID_TEMPLATES_ERROR', message: error.message || 'Failed to get SendGrid templates', code: 'SENDGRID_ERROR', }); } } @Post('templates') @HttpCode(HttpStatus.OK) async getIntegrationTemplates(@Body() dto: GetIntegrationTemplatesDto) { try { return await this.integrationService.getIntegrationTemplates( dto.levelId, dto.levelType, dto.app_code, dto.integration_type, ); } catch (error) { throw new BadRequestException({ success: false, error: 'GET_TEMPLATES_ERROR', message: error.message || 'Failed to get templates', code: 'INTEGRATION_TEMPLATES_ERROR', }); } } @Post('config/delete/:configId') @HttpCode(HttpStatus.OK) async disconnectConfig(@Param('configId', ParseIntPipe) configId: number) { try { await this.integrationService.deleteConfiguration(configId); return { success: true, message: 'Communication configuration deleted successfully', }; } catch (error) { throw new BadRequestException({ success: false, error: 'DELETE_ERROR', message: error.message || 'Failed to delete communication configuration', code: 'CONFIGURATION_ERROR', }); } } @Post('config/update/:hubId') @HttpCode(HttpStatus.OK) async updateConfig( @Param('hubId', ParseIntPipe) hubId: number, @Body() updateDto: UpdateConfigDto, ) { try { const result = await this.integrationService.updateConfiguration( hubId, updateDto, ); return { success: true, message: 'Communication configuration updated successfully', data: result, }; } catch (error) { throw new BadRequestException({ success: false, error: 'UPDATE_ERROR', message: error.message || 'Failed to update communication configuration', code: 'CONFIGURATION_ERROR', }); } } // UserIntegration Management Endpoints @Post('user-integration') @HttpCode(HttpStatus.OK) async createUserIntegration(@Body() createDto: CreateUserIntegrationDto) { try { const result = await this.integrationService.createUserIntegration(createDto); return { success: true, message: 'User integration mapping created successfully', data: result, }; } catch (error) { throw new BadRequestException({ success: false, error: 'CREATE_USER_INTEGRATION_ERROR', message: error.message || 'Failed to create user integration mapping', code: 'USER_INTEGRATION_ERROR', }); } } @Post('user-integration/bulk') @HttpCode(HttpStatus.OK) async bulkCreateUserIntegration(@Body() userIntegrations: CreateUserIntegrationDto[]) { try { const result = await this.integrationService.bulkCreateUserIntegration({ user_integrations: userIntegrations }); return { success: true, message: `Bulk user integration completed: ${result.summary.created} created, ${result.summary.updated} updated, ${result.summary.failed} failed`, data: result, }; } catch (error) { throw new BadRequestException({ success: false, error: 'BULK_CREATE_USER_INTEGRATION_ERROR', message: error.message || 'Failed to bulk create user integration mappings', code: 'USER_INTEGRATION_ERROR', }); } } @Get('user-integration/user/:userId') async getUserIntegrations(@Param('userId', ParseIntPipe) userId: number) { try { const result = await this.integrationService.getUserIntegrations(userId); return { success: true, data: result, }; } catch (error) { throw new BadRequestException({ success: false, error: 'GET_USER_INTEGRATIONS_ERROR', message: error.message || 'Failed to fetch user integrations', code: 'USER_INTEGRATION_ERROR', }); } } @Get('user-integration/config/:configId') async getConfigUserIntegrations( @Param('configId', ParseIntPipe) configId: number, ) { try { const result = await this.integrationService.getConfigUserIntegrations(configId); return { success: true, data: result, }; } catch (error) { throw new BadRequestException({ success: false, error: 'GET_CONFIG_USER_INTEGRATIONS_ERROR', message: error.message || 'Failed to fetch config user integrations', code: 'USER_INTEGRATION_ERROR', }); } } @Post('user-integration/:id') @HttpCode(HttpStatus.OK) async updateUserIntegration( @Param('id', ParseIntPipe) id: number, @Body() updateDto: UpdateUserIntegrationDto, ) { try { const result = await this.integrationService.updateUserIntegration( id, updateDto, ); return { success: true, message: 'User integration mapping updated successfully', data: result, }; } catch (error) { throw new BadRequestException({ success: false, error: 'UPDATE_USER_INTEGRATION_ERROR', message: error.message || 'Failed to update user integration mapping', code: 'USER_INTEGRATION_ERROR', }); } } @Post('user-integration/delete/:id') @HttpCode(HttpStatus.OK) async deleteUserIntegration(@Param('id', ParseIntPipe) id: number) { try { await this.integrationService.deleteUserIntegration(id); return { success: true, message: 'User integration mapping deleted successfully', }; } catch (error) { throw new BadRequestException({ success: false, error: 'DELETE_USER_INTEGRATION_ERROR', message: error.message || 'Failed to delete user integration mapping', code: 'USER_INTEGRATION_ERROR', }); } } @Get('user-integration/:userId/:configId') async getUserIntegrationByUserAndConfig( @Param('userId', ParseIntPipe) userId: number, @Param('configId', ParseIntPipe) configId: number, ) { try { const result = await this.integrationService.getUserIntegrationByUserAndConfig( userId, configId, ); return { success: true, data: result, }; } catch (error) { throw new BadRequestException({ success: false, error: 'GET_USER_INTEGRATION_ERROR', message: error.message || 'Failed to fetch user integration mapping', code: 'USER_INTEGRATION_ERROR', }); } } @Get('getAll') @UseGuards(JwtAuthGuard) async getAllIntegration( @Req() req: Request & { user: any }, @Query('integration_type') integration_type?: 'EMAIL' | 'SMS' | 'WA' | 'TELEPHONE', ) { try { const loggedInUser = req.user.userData; const allIntegrationData = await this.integrationService.getAllIntegrationData( loggedInUser, integration_type, ); return allIntegrationData; } catch (error) { throw new BadRequestException({ success: false, error: 'GET_ALL_INTEGRATIONS_ERROR', message: error.message || 'Failed to get all integrations', code: 'FETCH_ERROR', }); } } @Get('provider-urls') getProviderUrls( @Query('integration_type') integration_type?: 'EMAIL' | 'SMS' | 'WA' | 'TELEPHONE', @Query('integration_provider') integration_provider?: string, ) { if (integration_type === 'TELEPHONE' && integration_provider) { if (integration_provider.toLowerCase() == 'ozonetel') { return { success: true, data: { baseUrl: 'https://in1-ccaas-api.ozonetel.com', agentLoginUrl: 'https://agent.cloudagent.ozonetel.com/login', }, }; } else if (integration_provider.toLowerCase() == 'tubelight') { return { success: true, data: { baseUrl: 'https://portal.tubelightcommunications.com', agentLoginUrl: 'https://dashboard.hellotubelight.com/sign-in', }, }; } } else if (integration_type === 'WA' && integration_provider) { if (integration_provider.toLowerCase() == 'tubelight') { return { success: true, data: { baseUrl: 'https://portal.tubelightcommunications.com', agentLoginUrl: 'https://dashboard.hellotubelight.com/sign-in', }, }; } else if (integration_provider.toLowerCase() == 'gupshup') { return { success: true, data: { baseUrl: 'https://api.gupshup.io', agentLoginUrl: 'https://login.gupshup.io/u/login', }, }; } } } @Get('active-config') async getActiveConfig( @Query('level_id', ParseIntPipe) levelId: number, @Query('level_type') levelType: string, @Query('app_code') appCode: string, @Query('integration_type') integrationType: 'EMAIL' | 'SMS' | 'WA' | 'TELEPHONE', ) { try { const config = await this.integrationService.getSingleActiveConfig( levelId, levelType, appCode, integrationType, ); if (!config) { return { success: false, message: 'No active configuration found', data: null, }; } return { success: true, data: config, }; } catch (error) { throw new BadRequestException({ success: false, error: 'GET_ACTIVE_CONFIG_ERROR', message: error.message || 'Failed to fetch active configuration', code: 'FETCH_ERROR', }); } } }