211 lines
6.2 KiB
JavaScript
211 lines
6.2 KiB
JavaScript
async function getPremiumDIDs() {
|
|
return new Promise((resolve, reject) => {
|
|
fetch(`https://portal.bulkvs.com/api/v1.0/tnRecord?Status=Active&Trunk%20Group=${process.env.TRUNK_GROUP}`, {
|
|
headers: {
|
|
"Authorization": `Bearer ${process.env.BVS_TOKEN}`,
|
|
}
|
|
})
|
|
.then(res => {
|
|
if (!res.ok) {
|
|
throw new Error(`Error fetching DIDs: ${res.status} ${res.statusText}`);
|
|
}
|
|
return res.json();
|
|
})
|
|
.then(data => {
|
|
// data.forEach(record => {
|
|
// console.log(record.ReferenceID);
|
|
// });
|
|
// data is array of objects. If object.ReferenceID.split(";;")[0] is premDID, then [1] is the user id, and anything after is a note
|
|
const dids = data.filter(record => record.ReferenceID && record.ReferenceID.startsWith(";;")).map(record => {
|
|
// Get all flags (just keep looking at the next split item until its not a valid flag, after that, it's all a custom note, most likely to be used fo)
|
|
let validFlags = ["bypassNitroReq"];
|
|
let flags = [];
|
|
let note = "";
|
|
let splitReference = record.ReferenceID.split(";;");
|
|
for (let i = 1; i < splitReference.length; i++) {
|
|
if (validFlags.includes(splitReference[i])) {
|
|
flags.push(splitReference[i]);
|
|
}
|
|
}
|
|
return {
|
|
did: record.TN,
|
|
userId: record.ReferenceID.split(";;")[1],
|
|
flags: flags,
|
|
rawRef: record.ReferenceID
|
|
}
|
|
});
|
|
resolve(dids);
|
|
})
|
|
.catch(error => {
|
|
console.error("Error fetching DIDs:", error);
|
|
reject(error);
|
|
});
|
|
});
|
|
}
|
|
|
|
async function getAllDIDs() {
|
|
// Use the same BVS API endpoint, but just get all the results, not just premium ones.
|
|
return new Promise((resolve, reject) => {
|
|
fetch(`https://portal.bulkvs.com/api/v1.0/tnRecord?Status=Active&Trunk%20Group=${process.env.TRUNK_GROUP}`, {
|
|
headers: {
|
|
"Authorization": `Bearer ${process.env.BVS_TOKEN}`,
|
|
}
|
|
})
|
|
.then(res => {
|
|
if (!res.ok) {
|
|
throw new Error(`Error fetching DIDs: ${res.status} ${res.statusText}`);
|
|
}
|
|
return res.json();
|
|
})
|
|
.then(data => {
|
|
const dids = data.map(record => record.TN);
|
|
resolve(dids);
|
|
})
|
|
.catch(error => {
|
|
console.error("Error fetching DIDs:", error);
|
|
reject(error);
|
|
});
|
|
});
|
|
}
|
|
|
|
async function getAccountInfo() {
|
|
const res = await fetch("https://portal.bulkvs.com/api/v1.0/accountDetail", {
|
|
headers: {
|
|
"Authorization": `Bearer ${process.env.BVS_TOKEN}`,
|
|
}
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error(`BVS_TOKEN is invalid: ${res.status} ${res.statusText}`);
|
|
}
|
|
|
|
return res.json();
|
|
}
|
|
|
|
async function searchDIDs(query) {
|
|
// console.log(`q is ${query}`)
|
|
// Query will either be NPA, or NPANXX. Validate with regex, then use the API to find some.
|
|
// API Example: GET https://portal.bulkvs.com/api/v1.0/orderTn?Npa=310&Nxx=906&Lca=true&Limit=100
|
|
query = query.replace(/\D/g, ""); // Remove all non-digit characters
|
|
// Validate query w regex
|
|
if (!/^\d{3}$/.test(query) && !/^\d{6}$/.test(query)) {
|
|
throw new Error("Query must be either NPA (3 digits) or NPANXX (6 digits)");
|
|
}
|
|
|
|
const res = await fetch(`https://portal.bulkvs.com/api/v1.0/orderTn?Npa=${query.slice(0, 3)}&Nxx=${query.slice(3, 6)}&Lca=true&Limit=100`, {
|
|
headers: {
|
|
"Authorization": `Bearer ${process.env.BVS_TOKEN}`,
|
|
}
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error(`Error searching DIDs: ${res.status} ${res.statusText}`);
|
|
}
|
|
|
|
return res.json();
|
|
}
|
|
|
|
async function searchPurchasableDIDs(query) {
|
|
// console.log(`Searching purchasable DIDs with query ${query}`);
|
|
// Use searchDIDs, then filter down to 6 random from the results where the Nrc value == "0.05" and Mrc == "0.06"
|
|
const dids = await searchDIDs(query).catch(error => {
|
|
console.error("Error searching DIDs:", error);
|
|
return [];
|
|
});
|
|
// console.log(dids)
|
|
const purchasableDIDs = dids.filter(did => did.Nrc <= "0.50" && did.Mrc <= "0.10");
|
|
// console.log(purchasableDIDs)
|
|
// Shuffle the purchasableDIDs array, then take the first 6
|
|
let shuffled = [...purchasableDIDs];
|
|
for (let i = 0; i < 5; i++) {
|
|
shuffled = shuffled.sort(() => 0.5 - Math.random());
|
|
}
|
|
// shuffle more
|
|
|
|
return shuffled.slice(0, 6);
|
|
}
|
|
|
|
async function purchaseDID(did, userId) {
|
|
// POST /orderTn with body:
|
|
/*
|
|
{
|
|
"TN": "did to purchase",
|
|
"Lidb": "LITENET",
|
|
"Portout Pin": `${random 12 digit number}`,
|
|
"ReferenceID": `;;${userId}`,
|
|
"Trunk Group": `${process.env.TRUNK_GROUP}`,
|
|
"Sms": false,
|
|
"Mms": false,
|
|
"Webhook": "Default"
|
|
}
|
|
*/
|
|
let portoutPin = "";
|
|
const digits = "0123456789";
|
|
for (let i = 0; i < 12; i++) {
|
|
portoutPin += digits[Math.floor(Math.random() * digits.length)];
|
|
}
|
|
const res = await fetch("https://portal.bulkvs.com/api/v1.0/orderTn", {
|
|
method: "POST",
|
|
headers: {
|
|
"Authorization": `Bearer ${process.env.BVS_TOKEN}`,
|
|
"Content-Type": "application/json"
|
|
},
|
|
body: JSON.stringify({
|
|
"TN": did,
|
|
"Lidb": "LITENET",
|
|
"Portout Pin": portoutPin,
|
|
"ReferenceID": `;;${userId}`,
|
|
"Trunk Group": `${process.env.TRUNK_GROUP}`,
|
|
"Sms": false,
|
|
"Mms": false,
|
|
"Webhook": "Default"
|
|
})
|
|
});
|
|
// If response is 404, check body.json().Description, return the json body.
|
|
if (res.status === 404) {
|
|
const errorData = await res.json();
|
|
throw new Error(`Error purchasing DID: ${res.status} ${res.statusText} - ${errorData.Description}`);
|
|
}
|
|
if (!res.ok) {
|
|
throw new Error(`Error purchasing DID: ${res.status} ${res.statusText}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
function formatPhoneNumber(input) {
|
|
if (/^\d{10}$/.test(input)) {
|
|
input = `1${input}`;
|
|
}
|
|
// Regex to make sure it's a valid 11 digit NA phone number.
|
|
if (!/^\d{11}$/.test(input)) {
|
|
throw new Error("Phone number must be 10 or 11 digits, including country code (1 for US/Canada).");
|
|
}
|
|
// Format to human readable format: +1 (310) 906-1234
|
|
return `+${input[0]} (${input.slice(1, 4)}) ${input.slice(4, 7)}-${input.slice(7)}`;
|
|
}
|
|
|
|
function deleteDID(did) {
|
|
// API to delete msg, DELETE https://portal.bulkvs.com/api/v1.0/tnRecord?Number=did
|
|
return fetch(`https://portal.bulkvs.com/api/v1.0/tnRecord?Number=${did}`, {
|
|
method: "DELETE",
|
|
headers: {
|
|
"Authorization": `Bearer ${process.env.BVS_TOKEN}`,
|
|
}
|
|
})
|
|
.then(res => {
|
|
if (!res.ok) {
|
|
throw new Error(`Error deleting DID: ${res.status} ${res.statusText}`);
|
|
}
|
|
return res.json();
|
|
});
|
|
}
|
|
|
|
module.exports = {
|
|
getAllDIDs,
|
|
getAccountInfo,
|
|
getPremiumDIDs,
|
|
searchDIDs,
|
|
searchPurchasableDIDs,
|
|
purchaseDID,
|
|
formatPhoneNumber
|
|
} |