import { Injectable, Logger } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { SmsConfig } from './sms.config'; interface AuthkeyResponse { LogID?: string; Message?: string; Status?: string; Details?: string; } @Injectable() export class SmsService { private readonly logger = new Logger(SmsService.name); private readonly config: SmsConfig; constructor(private configService: ConfigService) { this.config = new SmsConfig(configService); } async sendOtpSms(phone: string, otp: string): Promise { try { this.logger.log(`📱 Attempting to send SMS OTP to: ${phone}`); this.logger.log(`📱 OTP Code: ${otp}`); // Create form data const formData = new FormData(); formData.append('authkey', this.config.apiKey); formData.append('mobile', phone); formData.append('country_code', '91'); // Default to India formData.append('sid', '30718'); // Default SID for OTP formData.append('otp', otp); formData.append('company', this.config.companyName); this.logger.log('📱 Request payload:', { authkey: this.config.apiKey.substring(0, 8) + '...', mobile: phone, country_code: '91', sid: '30718', otp: otp, company: this.config.companyName, }); const response = await fetch( 'https://console.authkey.io/restapi/request.php', { method: 'POST', body: formData, }, ); const responseText = await response.text(); this.logger.log(`📱 Raw Response: ${responseText}`); let result: AuthkeyResponse; try { result = JSON.parse(responseText); } catch (parseError) { this.logger.error('📱 Failed to parse response as JSON:', parseError); throw new Error(`Invalid response from SMS service: ${responseText}`); } this.logger.log('📱 Parsed Response:', result); if (!response.ok || !result.LogID) { this.logger.error('📱 Failed to send OTP SMS:', result); throw new Error( result.Details || result.Message || 'Failed to send OTP SMS', ); } this.logger.log( `📱 ✅ OTP SMS sent successfully to ${phone}. LogID: ${result.LogID}`, ); } catch (error) { this.logger.error('📱 ❌ Error sending OTP SMS:', error); throw error; } } }