UNPKG

truecallerjs

Version:

TruecallerJS: A library for effortless retrieval of phone number details using the Truecaller API in Node.js, JavaScript, and TypeScript projects.

424 lines (417 loc) 20.2 kB
#!/usr/bin/env node "use strict"; /* // MIT License // Copyright (c) 2021 Emmadi Sumith Kumar // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const yargs_1 = __importDefault(require("yargs")); const helpers_1 = require("yargs/helpers"); const fs_1 = __importDefault(require("fs")); const chalk_1 = __importDefault(require("chalk")); const path_1 = __importDefault(require("path")); const inquirer_1 = __importDefault(require("inquirer")); const awesome_phonenumber_1 = require("awesome-phonenumber"); const os_1 = __importDefault(require("os")); const login_js_1 = require("./login.js"); const verifyOtp_js_1 = require("./verifyOtp.js"); const search_js_1 = require("./search.js"); const json_colorizer_1 = __importDefault(require("json-colorizer")); const homePath = os_1.default.homedir(); const truecallerjsAuthDirPath = path_1.default.join(homePath, ".config", "truecallerjs"); const requestFilePath = path_1.default.join(truecallerjsAuthDirPath, "request.json"); const authKeyFilePath = path_1.default.join(truecallerjsAuthDirPath, "authkey.json"); const runCLI = () => __awaiter(void 0, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f, _g; const args = (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv)) .usage("Usage: \n$0 login (Login to truecaller).\n$0 -s [number] (command to search a number).") .option("search", { alias: "s", description: "To search caller name and related information of a number", }) .option("raw", { alias: "r", description: "Print's raw output", type: "boolean", }) .option("bulksearch", { alias: "bs", description: "Make a bulk number search", }) .option("name", { alias: "n", description: "Print's user name of phone number ", type: "boolean", }) .option("email", { alias: "e", description: "Print's email assigned to the phonenumber", type: "boolean", }) .option("json", { description: "print's output in json", type: "boolean", }) .option("xml", { description: "print's output in XML", type: "boolean", }) .option("yaml", { description: "Print's output in YAML", type: "boolean", }) .option("text", { description: "Print's output as plain text(TXT)", type: "boolean", }) .option("nc", { alias: "no_color", description: "Print without color", type: "boolean", }) .option("installationid", { alias: "i", description: "shows your InstallationId", type: "boolean", }) .option("verbose", { alias: "v", description: "Show additional information", type: "count", }) .help() .alias("help", "h") .parseSync(); if (args._.includes("login") && !args.s && !args.bs) { // Create the auth directory for truecallerjs if it doesn't exist if (!fs_1.default.existsSync(truecallerjsAuthDirPath)) { try { fs_1.default.mkdirSync(truecallerjsAuthDirPath, { recursive: true }); } catch (error) { console.log(error); process.exit(1); } } // Starts here if (args._[0] === "login" && args._.length <= 2) { console.log(chalk_1.default.yellow.bold("Login\n\n Enter mobile number in International Format\n Example : ") + chalk_1.default.magenta("+919912345678") + ".\n"); const inputNumber = yield inquirer_1.default.prompt({ type: "input", name: "phonenumber", message: "Enter your phone number :", validate: (input) => __awaiter(void 0, void 0, void 0, function* () { var _h, _j; const check = (0, awesome_phonenumber_1.parsePhoneNumber)(input); if (input !== ((_j = (_h = check === null || check === void 0 ? void 0 : check.number) === null || _h === void 0 ? void 0 : _h.e164) !== null && _j !== void 0 ? _j : "")) { return "Enter a valid phone number in International Format"; } if (!(check === null || check === void 0 ? void 0 : check.valid)) { return "Invalid Phone Number"; } return true; }), }); const pn = (0, awesome_phonenumber_1.parsePhoneNumber)(inputNumber.phonenumber); let response; let new_req = true; if (fs_1.default.existsSync(requestFilePath)) { const fileData = JSON.parse(fs_1.default.readFileSync(requestFilePath, "utf8")); if ("parsedPhoneNumber" in fileData && `+${fileData.parsedPhoneNumber}` == ((_a = pn === null || pn === void 0 ? void 0 : pn.number) === null || _a === void 0 ? void 0 : _a.e164)) { console.log(chalk_1.default.magenta("\nPrevious request was found for this mobile number.\n")); const x = yield inquirer_1.default.prompt({ type: "confirm", name: "status", message: "Do you want to enter previous OTP ", }); if (x.status) { new_req = false; response = fileData; } } } if (new_req) { response = yield (0, login_js_1.login)(String((_b = pn === null || pn === void 0 ? void 0 : pn.number) === null || _b === void 0 ? void 0 : _b.e164)); console.log(chalk_1.default.yellow(`Sending OTP to ${chalk_1.default.green((_d = (_c = pn === null || pn === void 0 ? void 0 : pn.number) === null || _c === void 0 ? void 0 : _c.e164) !== null && _d !== void 0 ? _d : "")}.`)); } if (response.status == 1 || response.status == 9 || response.message == "Sent") { // Otp sent try { fs_1.default.writeFileSync(requestFilePath, JSON.stringify(response, null, 4)); if (new_req) { console.log(chalk_1.default.green("OTP sent successfully.")); } const token = yield inquirer_1.default.prompt({ type: "input", name: "otp", message: "Enter Received OTP:", validate: (input) => __awaiter(void 0, void 0, void 0, function* () { const isnum = /^\d+$/.test(String(input)); if (input.length !== 6 || !isnum) { return "Enter a valid 6-digit OTP."; } return true; }), }); const response1 = yield (0, verifyOtp_js_1.verifyOtp)(String((_e = pn === null || pn === void 0 ? void 0 : pn.number) === null || _e === void 0 ? void 0 : _e.e164), response, token.otp); if (response1.status === 2 && !response1.suspended) { console.log(chalk_1.default.yellow.bold("Your installationId: ") + chalk_1.default.green(response1.installationId)); console.log(`This is the installationId: ${chalk_1.default.green(response1.installationId)} used to authenticate with Truecaller.`); // Save the file fs_1.default.writeFileSync(authKeyFilePath, JSON.stringify(response1, null, 3)); console.log(chalk_1.default.green("Logged in successfully.")); fs_1.default.unlinkSync(requestFilePath); } else if (response1.status === 11) { console.log(chalk_1.default.red("! Invalid OTP")); console.log(`OTP not valid. Enter the 6-digit OTP received on ${(_f = pn === null || pn === void 0 ? void 0 : pn.number) === null || _f === void 0 ? void 0 : _f.e164}.`); } else if (response1.status === 7) { console.log(chalk_1.default.red("Retries limit exceeded")); console.log(`Retries on secret code reached for ${(_g = pn === null || pn === void 0 ? void 0 : pn.number) === null || _g === void 0 ? void 0 : _g.e164}.`); } else if (response1.suspended) { console.log(chalk_1.default.red("Oops... Your account is suspended.")); console.log("Your account has been suspended by Truecaller."); } else if ("message" in response1) { console.log(chalk_1.default.red(response1.message)); } else { console.log(JSON.stringify(response1, null, 4)); } } catch (error) { if (error instanceof Error) { console.log(chalk_1.default.red(error.message)); } else { console.log(chalk_1.default.red("An error occurred.")); } process.exit(1); } } else if (response.status == 6 || response.status == 5) { if (fs_1.default.existsSync(requestFilePath)) { fs_1.default.unlinkSync(requestFilePath); } console.log(chalk_1.default.red("You have exceeded the limit of verification attempts.\nPlease try again after some time.")); } else { console.log(chalk_1.default.red(response.message)); } } } else if (args.s && !args.bs && !args._.includes("login") && !args.i) { if (!fs_1.default.existsSync(authKeyFilePath)) { console.error(chalk_1.default.magenta.bold("Please login to your account.")); process.exit(); } try { const data = fs_1.default.readFileSync(authKeyFilePath, "utf8"); const jsonAuthKey = JSON.parse(data); const countryCode = jsonAuthKey.phones[0].countryCode; const installationId = jsonAuthKey.installationId; const search_result = yield (0, search_js_1.search)({ number: String(args.s), countryCode, installationId, }); if (args.json || args.xml || args.text || args.yaml) { if (args.json && !args.xml && !args.text && !args.yaml) { if (args.r) { console.log(!args.nc ? (0, json_colorizer_1.default)(JSON.stringify(search_result.json()), { colors: { STRING_KEY: "blue", STRING_LITERAL: "green", NUMBER_LITERAL: "magenta", }, }) : JSON.stringify(search_result.json())); } else { console.log(!args.nc ? (0, json_colorizer_1.default)(JSON.stringify(search_result.json()), { pretty: true, colors: { STRING_KEY: "blue", STRING_LITERAL: "green", NUMBER_LITERAL: "magenta", }, }) : JSON.stringify(search_result.json(), null, 2)); } } else if (args.xml && !args.json && !args.text && !args.yaml) { console.log(search_result.xml(!args.nc)); } else if (args.yaml && !args.xml && !args.text && !args.json) { console.log(search_result.yaml(!args.nc)); } else { console.log(search_result.text(!args.nc, true)); } } else { if (args.n && !args.r && !args.e) { console.log(chalk_1.default.blue.bold("Name"), " : ", chalk_1.default.green(search_result.getName())); } else if (args.n && args.r && !args.e) { console.log(search_result.getName()); } else if (!args.n && !args.r && args.e) { console.log(chalk_1.default.blue.bold("Email"), " : ", chalk_1.default.green(search_result.getEmailId())); } else if (!args.n && args.r && args.e) { console.log(search_result.getEmailId()); } else { console.log(search_result.text(!args.nc, true)); } } } catch (error) { if (error instanceof Error) { console.log(chalk_1.default.red(error.message)); } else { console.log(chalk_1.default.red("An error occurred.")); } process.exit(1); } } else if (args.bs && !args._.includes("login") && !args.i) { if (!fs_1.default.existsSync(authKeyFilePath)) { console.error(chalk_1.default.magenta.bold("Please login to your account.")); process.exit(1); } try { const data = fs_1.default.readFileSync(authKeyFilePath, "utf8"); const jsonAuthKey = JSON.parse(data); const countryCode = jsonAuthKey.phones[0].countryCode; const installationId = jsonAuthKey.installationId; const searchResult = yield (0, search_js_1.bulkSearch)(String(args === null || args === void 0 ? void 0 : args.bs), countryCode, installationId); if (args.r) { console.log(!args.nc ? (0, json_colorizer_1.default)(JSON.stringify(searchResult), { colors: { STRING_KEY: "blue", STRING_LITERAL: "green", NUMBER_LITERAL: "magenta", }, }) : JSON.stringify(searchResult)); } else { console.log(!args.nc ? (0, json_colorizer_1.default)(JSON.stringify(searchResult), { pretty: true, colors: { STRING_KEY: "blue", STRING_LITERAL: "green", NUMBER_LITERAL: "magenta", }, }) : JSON.stringify(searchResult, null, 2)); } } catch (error) { if (error instanceof Error) { console.log(chalk_1.default.red(error.message)); } else { console.log(chalk_1.default.red("An error occurred.")); } process.exit(1); } } else if (args.i && !args.s) { if (!fs_1.default.existsSync(authKeyFilePath)) { console.error(chalk_1.default.magenta.bold("Please login to your account.")); process.exit(1); } try { const data = fs_1.default.readFileSync(authKeyFilePath, "utf8"); const jsonAuthKey = JSON.parse(data); // let countryCode = jsonAuthKey.phones[0].countryCode; const installationId = jsonAuthKey.installationId; if (args.r) { console.log(installationId); } else { args.nc ? console.log("Your InstallationId : " + installationId) : console.log(chalk_1.default.blue.bold("Your InstallationId") + " : " + chalk_1.default.green(installationId)); } } catch (error) { if (error instanceof Error) { console.log(chalk_1.default.red(error.message)); } else { console.log(chalk_1.default.red("An error occurred.")); } process.exit(1); } } else { console.log(`Usage: ${chalk_1.default.green("truecallerjs")} login (Login to truecaller). ${chalk_1.default.green("truecallerjs")} -s [number] (command to search a number). Options: --version Show version number [boolean] -s, --search To search caller name and related information of a num ber -r, --raw Print's raw output [boolean] --bulksearch, --bs Make a bulk number search -n, --name Print's user name of phone number [boolean] -e, --email Print's email assigned to the phonenumber [boolean] --json print's output in json [boolean] --xml print's output in XML [boolean] --yaml Print's output in YAML [boolean] --text Print's output as plain text(TXT) [boolean] --nc, --no_color Print without color [boolean] -i, --installationid shows your InstallationId [boolean] -v, --verbose Show additional information [count] -h, --help Show help [boolean] Repository => https://github.com/sumithemmadi/truecallerjs `); } }); runCLI();