File size: 5,494 Bytes
80d4bc1
 
 
 
 
 
 
 
 
 
 
 
 
 
7d2a19c
80d4bc1
 
 
 
 
 
 
 
7d2a19c
 
 
 
 
 
 
 
65d6a69
 
 
 
 
 
 
80d4bc1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7d2a19c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80d4bc1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65d6a69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80d4bc1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import axios from 'axios';
import { createLogger } from '../../utils/logger';

const logger = createLogger('VirtualNumberService');

export interface Country {
    id: string;
    name: string;
    count: number;
}

export interface PriceInfo {
    cost: number;
    count: number;
    rate?: number;
}

export interface ServicePrice {
    [country: string]: {
        [operator: string]: PriceInfo;
    };
}

export interface ProductPrices {
    [service: string]: {
        [country: string]: {
            [operator: string]: PriceInfo;
        };
    };
}

export interface MaxPrice {
    id: number;
    product: string;
    price: number;
    CreatedAt: string; // date string
}

export class VirtualNumberService {
    private static instance: VirtualNumberService;
    private apiKey: string;
    private baseUrl: string = 'https://5sim.net/v1';
    
    private constructor() {
        this.apiKey = process.env.FIVESIM_API_KEY || '';
        if (!this.apiKey) {
            logger.error('5sim API key not found in environment variables');
        }
    }

    public static getInstance(): VirtualNumberService {
        if (!VirtualNumberService.instance) {
            VirtualNumberService.instance = new VirtualNumberService();
        }
        return VirtualNumberService.instance;
    }

    /**
     * Get available countries for a specific service
     */
    async getAvailableCountries(service: string): Promise<Country[]> {
        try {
            const response = await axios.get(`${this.baseUrl}/guest/countries/${service}`, {
                headers: {
                    'Authorization': `Bearer ${this.apiKey}`,
                    'Accept': 'application/json',
                }
            });
            
            return response.data;
        } catch (error: any) {
            logger.error(`Error fetching countries for ${service}: ${error.message}`);
            throw new Error(`Failed to fetch available countries: ${error.message}`);
        }
    }

    /**
     * Get all prices for a specific product
     */
    async getProductPrices(product: string): Promise<ProductPrices> {
        try {
            const response = await axios.get(`${this.baseUrl}/guest/prices?product=${product}`, {
                headers: {
                    'Accept': 'application/json',
                }
            });
            
            return response.data;
        } catch (error: any) {
            logger.error(`Error fetching prices for product ${product}: ${error.message}`);
            throw new Error(`Failed to fetch product prices: ${error.message}`);
        }
    }

    /**
     * Get prices for a specific service and country
     */
    async getPrices(service: string, country: string): Promise<ServicePrice> {
        try {
            const response = await axios.get(`${this.baseUrl}/guest/prices?product=${service}&country=${country}`, {
                headers: {
                    'Authorization': `Bearer ${this.apiKey}`,
                    'Accept': 'application/json',
                }
            });
            
            return response.data;
        } catch (error: any) {
            logger.error(`Error fetching prices for ${service} in ${country}: ${error.message}`);
            throw new Error(`Failed to fetch prices: ${error.message}`);
        }
    }

    /**
     * Purchase a number for a specific service and country
     */
    async purchaseNumber(service: string, country: string, operator: string): Promise<any> {
        try {
            const response = await axios.get(
                `${this.baseUrl}/user/buy/activation/${country}/${operator}/${service}`, 
                {
                    headers: {
                        'Authorization': `Bearer ${this.apiKey}`,
                        'Accept': 'application/json',
                    }
                }
            );
            
            return response.data;
        } catch (error: any) {
            logger.error(`Error purchasing number for ${service} in ${country}: ${error.message}`);
            throw new Error(`Failed to purchase number: ${error.message}`);
        }
    }

    /**
     * Check for SMS received for a specific order
     */
    async checkSMS(orderId: string | number): Promise<any> {
        try {
            const response = await axios.get(
                `${this.baseUrl}/user/check/${orderId}`, 
                {
                    headers: {
                        'Authorization': `Bearer ${this.apiKey}`,
                        'Accept': 'application/json',
                    }
                }
            );
            
            return response.data;
        } catch (error: any) {
            logger.error(`Error checking SMS for order ${orderId}: ${error.message}`);
            throw new Error(`Failed to check SMS: ${error.message}`);
        }
    }

    /**
     * Get a list of established price limits.
     */
    async getMaxPrices(): Promise<MaxPrice[]> {
        try {
            const response = await axios.get(`${this.baseUrl}/user/max-prices`, {
                headers: {
                    'Authorization': `Bearer ${this.apiKey}`,
                    'Accept': 'application/json',
                }
            });
            
            return response.data;
        } catch (error: any) {
            logger.error(`Error fetching max prices: ${error.message}`);
            throw new Error(`Failed to fetch max prices: ${error.message}`);
        }
    }
}