-
-
Notifications
You must be signed in to change notification settings - Fork 305
/
Copy pathhelper.service.ip.ts
executable file
·81 lines (74 loc) · 2.65 KB
/
helper.service.ip.ts
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
/**
* @file IP location service
* @module module/helper/ip.service
* @author Surmon <https://github.com/surmon-china>
*/
import { HttpService } from '@nestjs/axios'
import { Injectable } from '@nestjs/common'
import { getMessageFromAxiosError } from '@app/transformers/error.transformer'
import { createLogger } from '@app/utils/logger'
import { isDevEnv } from '@app/app.environment'
const logger = createLogger({ scope: 'IPService', time: isDevEnv })
export type IP = string
export interface IPLocation {
country: string
country_code: string
region: string
region_code: string
city: string
zip: string
[key: string]: any
}
@Injectable()
export class IPService {
constructor(private readonly httpService: HttpService) {}
// query by https://ip-api.com/docs/api:json
private queryLocationByIpApi(ip: IP): Promise<IPLocation> {
return this.httpService.axiosRef
.get<any>(`http://ip-api.com/json/${ip}?fields=status,message,country,countryCode,region,regionName,city,zip`)
.then((response) => {
return response.data?.status !== 'success'
? Promise.reject(response.data.message)
: Promise.resolve({
country: response.data.country,
country_code: response.data.countryCode,
region: response.data.regionName,
region_code: response.data.region,
city: response.data.city,
zip: response.data.zip
})
})
.catch((error) => {
const message = getMessageFromAxiosError(error)
logger.warn('queryLocationByIpApi failed!', `"${ip}"`, message)
return Promise.reject(message)
})
}
// query by https://ipapi.co/api/#introduction
private queryLocationByApiCo(ip: IP): Promise<IPLocation> {
return this.httpService.axiosRef
.get<any>(`https://ipapi.co/${ip}/json/`)
.then((response) => {
return response.data?.error
? Promise.reject(response.data.reason)
: Promise.resolve({
country: response.data.country_name,
country_code: response.data.country_code,
region: response.data.region,
region_code: response.data.region_code,
city: response.data.city,
zip: response.data.postal
})
})
.catch((error) => {
const message = getMessageFromAxiosError(error)
logger.warn('queryLocationByApiCo failed!', `"${ip}"`, message)
return Promise.reject(message)
})
}
public queryLocation(ip: IP): Promise<IPLocation | null> {
return this.queryLocationByIpApi(ip)
.catch(() => this.queryLocationByApiCo(ip))
.catch(() => null)
}
}