-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
174 lines (152 loc) · 4.06 KB
/
main.go
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
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"time"
)
//struct for storing API responses
type UpiResponse struct {
IsUpiRegistered bool `json: "isUpiRegistered, bool"`
Name string `json: "name, string"`
Message string `json: "message, string"`
}
//perform the actual network request with a suitable user agent
func makeAPIRequest(number string, suffix string) string {
useragent := "BulkVPALookup/1.0"
baseurl := "https://upibankvalidator.com/api/upiValidation?upi="
//prepare request
vpa := number + "@" + suffix
postBody, _ := json.Marshal(map[string]string{
"upi": vpa,
})
reqBody := bytes.NewBuffer(postBody)
client := &http.Client{}
//make request
req, err := http.NewRequest("POST", baseurl+vpa, reqBody)
if err != nil {
log.Println("Error occurred!")
log.Fatalln(err)
}
req.Header.Set("User-Agent", useragent)
resp, err := client.Do(req)
if err != nil {
log.Fatalln(err)
}
defer resp.Body.Close()
//process response
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println("Error occurred!")
log.Fatalln(err)
}
sb := string(respBody)
return sb
}
//returns name if exists, empty string otherwise
func getNameIfExists(number string, suffix string) string {
var processedResp UpiResponse
rawResp := makeAPIRequest(number, suffix)
//unmarshal response into struct
err := json.Unmarshal([]byte(rawResp), &processedResp)
if err != nil {
log.Println("Error occurred!")
if rawResp == "error code: 1015" {
log.Fatalln("Too many requests!")
}
log.Println(rawResp)
log.Fatalln(err)
}
if !processedResp.IsUpiRegistered {
return ""
}
return processedResp.Name
}
//bridge between network requests and going through all numbers given to us
func sendToChannel(number string, suffix string, mappings map[string]string) {
if mappings[number] != "" {
return
}
name := getNameIfExists(number, suffix)
//name := "Dummy McDumbface" //dummy request response for testing
if name == "" {
return
}
mappings[number] = name
fmt.Println(number, ":", name)
}
func performBulkLookup(numbers []string, lookedUpNames map[string]string) {
var suffices = []string{"paytm", "ybl"}
for _, suffix := range suffices {
for _, number := range numbers {
if len(number) != 10 || lookedUpNames[number] != "" {
continue
}
sendToChannel(number, suffix, lookedUpNames)
time.Sleep(500 * time.Millisecond)
}
}
}
//somewhat redundant function created as a result of bad network conditions halting the program before it could create the VCF
func getBulkLookupResults(filename string) map[string]string {
rawcontent, err := os.ReadFile(filename)
if err != nil {
log.Fatalln(err)
}
m := make(map[string]string)
content := string(rawcontent)
lines := strings.Split(content, "\n")
for line := range lines {
pair := strings.Split(lines[line], ":")
if m[pair[0]] == "" {
if len(pair) > 1 {
m[pair[0]] = pair[1]
}
}
}
return m
}
//help export our results to VCF for easy importing
func writeResultsToVCF(lookedUpNames map[string]string, filename string) {
file, err := os.Create(filename)
if err != nil {
log.Fatalln(err)
}
defer file.Close()
for number, name := range lookedUpNames {
file.Write([]byte("BEGIN:VCARD\nVERSION:3.0\n"))
file.Write([]byte("FN:" + name + "\n"))
splitrep := strings.Split(name, " ")
newrep := ""
for word := range splitrep {
if word == 0 {
newrep = splitrep[word]
} else {
newrep = splitrep[word] + ";" + newrep
}
}
newrep += ";;"
file.Write([]byte("N:" + newrep + "\n"))
file.Write([]byte("TEL;TYPE=cell:+91 " + number + "\n"))
file.Write([]byte("END:VCARD\n\n"))
}
}
func main() {
argLength := len(os.Args[1:])
if argLength != 2 {
log.Fatalln("USAGE: ./main /path/to/list/of/phone/nums.txt /path/to/vcf/file.vcf")
}
numbersFile, err := os.ReadFile(os.Args[1])
if err != nil {
log.Fatalln(err)
}
numbers := strings.Split(string(numbersFile[:]), "\n")
var lookedUpNames = make(map[string]string)
performBulkLookup(numbers, lookedUpNames)
writeResultsToVCF(lookedUpNames, os.Args[2])
}