mutasi-scraper
Advanced tools
Comparing version 2.2.25 to 2.2.26
@@ -5,3 +5,20 @@ const ScraperBank = require("../BrowserClasses"); | ||
const log = require("../helper/utils/Logger"); | ||
/** | ||
* Scraper for BCA (Bank Central Asia) that extends ScraperBank class. | ||
* @class ScrapBCA | ||
* @author fdciabdul | ||
* @memberof Bank | ||
*/ | ||
class ScrapBCA extends ScraperBank { | ||
/** | ||
* Constructor for ScrapBCA class. | ||
* @constructor | ||
* @param {string} user - BCA username. | ||
* @param {string} pass - BCA password. | ||
* @param {string} norek - BCA account number. | ||
* @param {object} args - Additional arguments. | ||
* @param {boolean} useFingerprintInjector - Flag to use fingerprint injector. | ||
*/ | ||
constructor(user, pass, norek, args, useFingerprintInjector = false) { | ||
@@ -13,3 +30,6 @@ super(user, pass, args, useFingerprintInjector); | ||
/** | ||
* Logs in to the BCA website. | ||
* @async | ||
*/ | ||
async loginToBCA() { | ||
@@ -41,2 +61,8 @@ this.page = await this.launchBrowser(); | ||
/** | ||
* Processes getting the balance. | ||
* @async | ||
* @param {Object} page - Page object. | ||
* @returns {Object} - New page object. | ||
*/ | ||
async processGetBalance(page) { | ||
@@ -56,2 +82,11 @@ await this.page.goto(BCASelectors.SETTLEMENT_PAGE.url, { | ||
/** | ||
* Selects account and sets date for transactions. | ||
* @async | ||
* @param {number} tglawal - Start date. | ||
* @param {number} blnawal - Start month. | ||
* @param {number} tglakhir - End date. | ||
* @param {number} blnakhir - End month. | ||
* @returns {Object} - New page object. | ||
*/ | ||
async selectAccountAndSetDates(tglawal, blnawal, tglakhir, blnakhir) { | ||
@@ -91,2 +126,7 @@ await this.page.goto(BCASelectors.SETTLEMENT_PAGE.url, { | ||
/** | ||
* Creates a new target page (get new window). | ||
* @async | ||
* @returns {Object} - New page object. | ||
*/ | ||
async createTargetPage() { | ||
@@ -107,37 +147,12 @@ const pageTarget = this.page.target(); | ||
async getBalance(tglawal, blnawal, tglakhir, blnakhir) { | ||
const page = await this.launchAndSetupBrowser(); | ||
this.dialogMessage = null; // Initialize dialogMessage | ||
try { | ||
await this.loginToBCA(page); | ||
const newPage = await this.processGetBalance(page, tglawal, blnawal, tglakhir, blnakhir); | ||
// Check for dialog message | ||
const result = await newPage.evaluate(() => document.body.innerHTML); | ||
const parser = new BCAParser(result, "body > table:nth-child(3)"); | ||
let resultsettlement = parser.parseBalance(); | ||
this.log("[ LOG ] [" + this.user + "] Success get Balance for (" + this.user + ")"); | ||
const exists = await this.checkIfReturnToLogin(newPage, BCASelectors.LOGIN_PAGE.userField); | ||
if (exists) { | ||
throw new Error("Loopback detected"); | ||
} | ||
await this.logoutAndClose(); | ||
return resultsettlement; | ||
} catch (error) { | ||
this.log("[ LOG ] [" + this.user + "] " + error); | ||
await this.logoutAndClose(); | ||
return { | ||
status: false, | ||
error: this.dialogMessage | ||
}; | ||
} | ||
} | ||
/** | ||
* Gets the statement for a specified date range. | ||
* @async | ||
* @param {number} tglawal - Start date. | ||
* @param {number} blnawal - Start month. | ||
* @param {number} tglakhir - End date. | ||
* @param {number} blnakhir - End month. | ||
* @returns {Object} - Statement information. / if not set it will return latest statement | ||
*/ | ||
async getStatement(tglawal, blnawal, tglakhir, blnakhir) { | ||
@@ -185,2 +200,6 @@ this.dialogMessage = null; | ||
/** | ||
* Logs out and closes the session. | ||
* @async | ||
*/ | ||
async logoutAndClose() { | ||
@@ -198,2 +217,8 @@ try { | ||
/** | ||
* Handles dialog and logs out the page. | ||
* @async | ||
* @param {Object} newPage - New page object. | ||
*/ | ||
async handleDialogAndLogout(newPage) { | ||
@@ -208,2 +233,9 @@ newPage.on('dialog', async (dialog) => { | ||
/** | ||
* Checks if it returns to the login page. | ||
* @async | ||
* @param {Object} page - Page object. | ||
* @param {string} selector - Selector to check. | ||
* @returns {boolean} - Returns true if it returns to the login page. | ||
*/ | ||
async checkIfReturnToLogin(page, selector) { | ||
@@ -210,0 +242,0 @@ try { |
const ScraperBank = require("../BrowserClasses"); | ||
const { UA } = require("../helper/utils/UA"); | ||
const BNISelector = require("../helper/selector/BNISelector"); | ||
const { BNIParser } = require("../helper/utils/Parser"); | ||
/** | ||
* Scraper for BNI (Bank Negara Indonesia) that extends ScraperBank class. | ||
* @class ScrapBCA | ||
* @author fdciabdul | ||
* @memberof Bank | ||
*/ | ||
class ScrapBNI extends ScraperBank { | ||
@@ -17,3 +22,2 @@ constructor(user, pass, args, useFingerprintInjector = false) { | ||
const page = await this.launchBrowser(); | ||
await page.setUserAgent(UA()); | ||
await page.goto(BNISelector.LOGIN_PAGE.url, { | ||
@@ -154,2 +158,7 @@ waitUntil: "networkidle2", | ||
/** | ||
* Logout and close the browser | ||
* @date 2023-06-03 | ||
* @returns {Promise} | ||
*/ | ||
async logoutAndClose(page) { | ||
@@ -162,2 +171,8 @@ await page.click(BNISelector.SETTLEMENT_PAGE.logout); | ||
/** | ||
* Check if any statement in page statement | ||
* @date 2023-06-03 | ||
* @returns {Promise} | ||
*/ | ||
async checkSettlement(page, selector) { | ||
@@ -164,0 +179,0 @@ try { |
@@ -7,5 +7,22 @@ | ||
/** | ||
* ScrapBRI class for scraping BRI (Bank Rakyat Indonesia) data. | ||
* @class | ||
* @extends ScraperBank | ||
* @memberof Bank | ||
*/ | ||
class ScrapBRI extends ScraperBank { | ||
constructor(corpID, user, pass, norek,apikey,useFingerprintInjector) { | ||
super(user, pass,useFingerprintInjector); | ||
/** | ||
* Constructor for ScrapBRI class. | ||
* @constructor | ||
* @param {string} corpID - BRI corporate ID. | ||
* @param {string} user - BRI username. | ||
* @param {string} pass - BRI password. | ||
* @param {string} norek - BRI account number. | ||
* @param {string} apiKey - API key for RecaptchaSolver. | ||
* @param {boolean} useFingerprintInjector - Flag to use fingerprint injector. | ||
*/ | ||
constructor(corpID, user, pass, norek, apikey, useFingerprintInjector) { | ||
super(user, pass, useFingerprintInjector); | ||
this.corpID = corpID; | ||
@@ -16,2 +33,7 @@ this.norek = norek; | ||
/** | ||
* Logs in to the BRI website. | ||
* @async | ||
* @returns {Object} - Page object. | ||
*/ | ||
async loginToBRI() { | ||
@@ -23,3 +45,3 @@ this.page = await this.launchBrowser(); | ||
await this.page.waitForSelector(selectors.corpID); | ||
await RecaptchaSolver(this.page,this.apiKey) | ||
await RecaptchaSolver(this.page, this.apiKey) | ||
await this.page.type(selectors.corpID, this.corpID); | ||
@@ -39,7 +61,12 @@ await this.page.type(selectors.userID, this.user); | ||
async getStatement() { | ||
if(!this.apiKey){ | ||
/** | ||
* Gets the account statement from the BRI website. | ||
* @async | ||
* @returns {Object} - Account statement data. | ||
*/ | ||
async getStatement() { | ||
if (!this.apiKey) { | ||
return { | ||
status : false, | ||
message : "you must include the api key" | ||
status: false, | ||
message: "you must include the api key" | ||
} | ||
@@ -89,5 +116,5 @@ } | ||
const result = this.parseAccountData(data); | ||
return result; | ||
} catch(error) { | ||
} catch (error) { | ||
console.log(error) | ||
@@ -97,4 +124,11 @@ } | ||
async fetchAccountDetails(accountValue, formattedDate, token){ | ||
/** | ||
* Fetches account details from the BRI website. | ||
* @async | ||
* @param {string} accountValue - Account value. | ||
* @param {string} formattedDate - Formatted date. | ||
* @param {string} token - Security token. | ||
* @returns {Object} - Account details data. | ||
*/ | ||
async fetchAccountDetails(accountValue, formattedDate, token) { | ||
const accountOption = await this.page.evaluate( | ||
@@ -140,24 +174,34 @@ async (accountValue, formattedDate, token) => { | ||
} | ||
formatCurrentDate(){ | ||
const currentDate = new Date(); | ||
const formattedDate = `${currentDate | ||
.getDate() | ||
.toString() | ||
.padStart(2, "0")}-${(currentDate.getMonth() + 1) | ||
.toString() | ||
.padStart(2, "0")}-${currentDate.getFullYear()} - ${currentDate | ||
.getDate() | ||
.toString() | ||
.padStart(2, "0")}-${(currentDate.getMonth() + 1) | ||
.toString() | ||
.padStart(2, "0")}-${currentDate.getFullYear()}`; | ||
/** | ||
* Formats the current date. | ||
* @returns {string} - Formatted date string. | ||
*/ | ||
formatCurrentDate() { | ||
const currentDate = new Date(); | ||
const formattedDate = `${currentDate | ||
.getDate() | ||
.toString() | ||
.padStart(2, "0")}-${(currentDate.getMonth() + 1) | ||
.toString() | ||
.padStart(2, "0")}-${currentDate.getFullYear()} - ${currentDate | ||
.getDate() | ||
.toString() | ||
.padStart(2, "0")}-${(currentDate.getMonth() + 1) | ||
.toString() | ||
.padStart(2, "0")}-${currentDate.getFullYear()}`; | ||
return formattedDate; | ||
} | ||
} | ||
parseAccountData(data){ | ||
/** | ||
* Parses account data received from the BRI website. | ||
* @param {Object} data - Raw account data. | ||
* @returns {Array} - Parsed account data. | ||
*/ | ||
parseAccountData(data) { | ||
let newData = data.map((obj) => { | ||
if(obj.DESK_TRAN === "Transaksi tidak ditemukan"){ | ||
if (obj.DESK_TRAN === "Transaksi tidak ditemukan") { | ||
return data; | ||
}else{ | ||
} else { | ||
let tanggal = obj.TGL_TRAN.slice(8, 10) + "/" + obj.TGL_TRAN.slice(5, 7); | ||
@@ -169,10 +213,5 @@ let mutasi = obj.MUTASI_DEBET == "0.00" ? "CR" : "DB"; | ||
let saldoakhir = obj.SALDO_AKHIR_MUTASI.replace(".00", ""); | ||
let words = obj.DESK_TRAN.split(" "); | ||
// Get the second and third words as the name | ||
let nama = words[1] + " " + words[2]; | ||
const currentYear = moment().year(); | ||
// Parse the date using the current year | ||
const parsedDate = moment(tanggal + "/" + currentYear, "DD/MM/YYYY"); | ||
@@ -189,3 +228,3 @@ const formattedDate = parsedDate.format("YYYY-MM-DD HH:mm:ss"); | ||
} | ||
}); | ||
@@ -192,0 +231,0 @@ return newData; |
const ScraperBank = require("../BrowserClasses"); | ||
const MANDIRISelector = require("../helper/selector/MANDIRISelector"); | ||
const log = require("../helper/utils/Logger"); | ||
const { UA } = require("../helper/utils/UA"); | ||
/** | ||
* Kopra class for scraping Mandiri (Bank Mandiri) data. | ||
* @class | ||
* @extends ScraperBank | ||
* @memberof Bank | ||
*/ | ||
class Kopra extends ScraperBank { | ||
/** | ||
* Constructor for Kopra class. | ||
* @constructor | ||
* @param {string} corpID - Mandiri corporate ID. | ||
* @param {string} user - Mandiri username. | ||
* @param {string} password - Mandiri password. | ||
* @param {string} noacc - Mandiri account number. | ||
* @param {boolean} useFingerprintInjector - Flag to use fingerprint injector. | ||
*/ | ||
constructor(corpID, user, password, noacc,useFingerprintInjector) { | ||
@@ -17,3 +31,7 @@ super(user, password,useFingerprintInjector); | ||
/** | ||
* Gets the account statement from the Mandiri website. | ||
* @async | ||
* @returns {Object} - Result containing a message and data. | ||
*/ | ||
async getStatement() { | ||
@@ -25,3 +43,2 @@ this.log("login sebagai"); | ||
try { | ||
await page.setUserAgent(UA()); | ||
await page.goto(MANDIRISelector.LOGIN_PAGE.url, { | ||
@@ -130,2 +147,7 @@ waitUntil: "networkidle2", | ||
/** | ||
* Formats transaction data received from the Mandiri website. | ||
* @param {Object} transaction - Raw transaction data. | ||
* @returns {Object} - Formatted transaction data. | ||
*/ | ||
formatTransactionData(transaction) { | ||
@@ -147,3 +169,8 @@ try { | ||
} | ||
/** | ||
* Formats a date object to a string. | ||
* @param {Date} date - Date object to be formatted. | ||
* @returns {string} - Formatted date string. | ||
*/ | ||
formatDate(date) { | ||
@@ -150,0 +177,0 @@ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart( |
@@ -15,2 +15,3 @@ const puppeteer = require("puppeteer-extra"); | ||
* @returns {any} | ||
* @memberof ScraperBank | ||
*/ | ||
@@ -17,0 +18,0 @@ class ScraperBank { |
/** | ||
* Author : @fdciabdul | ||
* Email : taqin2731@gmail.com | ||
* Web : https://imtaqin.id | ||
* @fileoverview Extract name from transaction name | ||
* @date 2023-04-17 | ||
* @param {string} name | ||
* @returns {string} | ||
* Extract Name | ||
* @class NameExtractor | ||
* @author fdciabdul | ||
* @memberof utils | ||
*/ | ||
@@ -22,6 +19,11 @@ class NameExtractor { | ||
} | ||
static extractBNIMutationName(name){ | ||
const regex = /TRANSFER DARI (Bpk|Sdr|Ibu) (.*)/; | ||
const match = name.match(regex); | ||
return match ? match[2] : null; | ||
} | ||
} | ||
module.exports = NameExtractor; |
@@ -0,3 +1,11 @@ | ||
/** | ||
* Logger for bank process | ||
* @param {any} message | ||
* @returns {any} | ||
* @memberof utils | ||
*/ | ||
module.exports = function log(message) { | ||
console.log(`[ LOG ] [${this.username}] ${message}`); | ||
console.log(`[ LOG ] ${message}`); | ||
} |
@@ -10,2 +10,3 @@ const { load } = require("cheerio"); | ||
* @returns {Array} | ||
* @memberof utils | ||
*/ | ||
@@ -18,2 +19,7 @@ class BCAParser { | ||
/** | ||
* Parses raw BCA data. | ||
* @param {Array} data - Raw data to be parsed. | ||
* @returns {Array} - Parsed data. | ||
*/ | ||
parse() { | ||
@@ -65,44 +71,27 @@ let accountNo = this.$(this.selectors.accountNoField).parent().next().next().text().trim(); | ||
class BNIParser{ | ||
parse(data){ | ||
let arrayfilter = []; | ||
for (let i = 0; i < data.length; i++) { | ||
const filtered = data[i].filter(function (el) { | ||
return el != "-"; | ||
}); | ||
if (filtered.length > 0) { | ||
arrayfilter.push(filtered); | ||
} | ||
} | ||
let arr = []; | ||
const res = arrayfilter.slice(6, -7); | ||
const string = res.join("\n"); | ||
const potong = string.split("Tanggal Transaksi"); | ||
for (let i = 1; i < potong.length; i++) { | ||
let potong2 = potong[i].split("\n"); | ||
let mutasi; | ||
if(potong2[5] === "Cr"){ | ||
mutasi = "CR" | ||
} else if(potong2[5] === "Db"){ | ||
mutasi = "DB" | ||
} | ||
let name; | ||
const regex = /TRANSFER DARI (Bpk|Sdr|Ibu) (.*)/; | ||
const match = potong2[3].match(regex); | ||
if (match) { | ||
name = match[2]; | ||
} | ||
arr.push({ | ||
tanggal: potong2[1], | ||
keterangan: potong2[3], | ||
mutasi: mutasi, | ||
nominal: potong2[7], | ||
saldoakhir: potong2[9], | ||
nama: name | ||
}); | ||
} | ||
/** | ||
* Parses raw BNI data. | ||
* @param {Array} data - Raw data to be parsed. | ||
* @returns {Array} - Parsed data. | ||
*/ | ||
parse(data) { | ||
const arrayFilter = data.map(item => item.filter(el => el !== "-")).filter(filtered => filtered.length > 0); | ||
const arr = arrayFilter.slice(6, -7).map(entry => { | ||
const [tanggal, , , keterangan, , , , , , mutasi, , nominal, , , , , saldoakhir] = entry; | ||
const mutasiType = (mutasi === "Cr") ? "CR" : ((mutasi === "Db") ? "DB" : undefined); | ||
const name = NameExtractor.extractBNIMutationName(keterangan); | ||
return { | ||
tanggal, | ||
keterangan, | ||
mutasi: mutasiType, | ||
nominal, | ||
saldoakhir, | ||
nama: name | ||
}; | ||
}); | ||
return arr; | ||
} | ||
} | ||
@@ -109,0 +98,0 @@ |
{ | ||
"name": "mutasi-scraper", | ||
"version": "2.2.25", | ||
"version": "2.2.26", | ||
"main": "index.js", | ||
@@ -5,0 +5,0 @@ "directories": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
89647
1150
25