{"_id":"@dan-dr/israeli-bank-scrapers","name":"@dan-dr/israeli-bank-scrapers","dist-tags":{"latest":"6.7.5-dan.1"},"versions":{"6.7.5-dan.1":{"name":"@dan-dr/israeli-bank-scrapers","version":"6.7.5-dan.1","private":false,"description":"Hardened fork of Israeli bank scrapers with Hapoalim OTP and Isracard/Amex WAF handling","engines":{"node":">= 22.13.0"},"publishConfig":{"access":"public","provenance":true},"main":"lib/index.js","types":"lib/index.d.ts","scripts":{"clean":"rimraf lib","test":"jest","test:ci":"ncp src/tests/.tests-config.tpl.js src/tests/.tests-config.js && npm run test","lint":"eslint src && npm run format:check","lint:fix":"eslint src --fix && npm run format","format":"prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md}\"","format:check":"prettier --check \"src/**/*.{ts,tsx,js,jsx,json,md}\"","type-check":"tsc --noEmit","dev":"npm run type-check -- --watch","build":"npm run lint && npm run clean && npm run build:types && npm run build:js","build:types":"tsc --emitDeclarationOnly","build:js":"babel src --out-dir lib --extensions \".ts\" --source-maps inline --verbose","postbuild":"rimraf lib/tests","prepare:core":"git reset --hard && node utils/prepare-israeli-bank-scrapers-core.js && npm i --package-lock-only && npm ci && npm run lint:fix && npm run build","prepare:default":"git reset --hard && npm ci && npm run build","reset":"git reset --hard && npm ci"},"repository":{"type":"git","url":"git+https://github.com/dan-dr/israeli-bank-scrapers.git"},"keywords":["israel","israeli bank","israeli bank scraper"],"author":{"name":"Elad Shaham"},"license":"MIT","bugs":{"url":"https://github.com/dan-dr/israeli-bank-scrapers/issues"},"homepage":"https://github.com/dan-dr/israeli-bank-scrapers#readme","devDependencies":{"@babel/cli":"^7.4.4","@babel/core":"^7.4.5","@babel/preset-env":"^7.4.5","@babel/preset-typescript":"^7.9.0","@json2csv/plainjs":"^7.0.6","@types/debug":"^4.1.7","@types/jest":"^29.5.12","@types/node":"^25.5.2","@types/source-map-support":"^0.5.1","cross-env":"^6.0.3","eslint":"^9.39.4","eslint-config-prettier":"^10.1.8","eslint-import-resolver-typescript":"^4.4.4","eslint-plugin-import-x":"^4.16.2","fs-extra":"^10.0.0","globals":"^16.5.0","husky":"^8.0.3","jest":"^29.7.0","jscodeshift":"^0.16.1","minimist":"^1.2.5","ncp":"^2.0.0","prettier":"^3.5.3","rimraf":"^6.1.3","source-map-support":"^0.5.16","ts-jest":"^29.1.4","typescript":"^4.7.4","typescript-eslint":"^8.58.0"},"dependencies":{"debug":"^4.3.2","moment":"^2.22.2","moment-timezone":"^0.5.37","puppeteer":"^24.40.0"},"_id":"@dan-dr/israeli-bank-scrapers@6.7.5-dan.1","gitHead":"52f145304a322defb5bd1f80395309e0fdc699c0","_nodeVersion":"22.21.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-WM+ybZakldgw/oC7hUfzW8aP1o6SXsNBX7YQPH4fGibC0hgWcI3ZXV4G6KArUMeL3p5YfU2e1wwQjdG3CSFaCg==","shasum":"817ae13ff61dc0eca4e20e23bac55fd3164459be","tarball":"https://registry.npmjs.org/@dan-dr/israeli-bank-scrapers/-/israeli-bank-scrapers-6.7.5-dan.1.tgz","fileCount":85,"unpackedSize":855273,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCFYL3iYFt3gxzxalVghTl6muHwp9l+26JZspmNxUdEwgIhAKD3JX3V3Px3Q4g5LLbBt1Eqt1jbwkifWZVbhzVoMzvR"}]},"_npmUser":{"name":"dan-dr","email":"danrosenshain@gmail.com"},"directories":{},"maintainers":[{"name":"dan-dr","email":"danrosenshain@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/israeli-bank-scrapers_6.7.5-dan.1_1781192926401_0.7828062430990508"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-11T15:48:46.243Z","6.7.5-dan.1":"2026-06-11T15:48:46.631Z","modified":"2026-06-11T15:48:46.900Z"},"maintainers":[{"name":"dan-dr","email":"danrosenshain@gmail.com"}],"description":"Hardened fork of Israeli bank scrapers with Hapoalim OTP and Isracard/Amex WAF handling","homepage":"https://github.com/dan-dr/israeli-bank-scrapers#readme","keywords":["israel","israeli bank","israeli bank scraper"],"repository":{"type":"git","url":"git+https://github.com/dan-dr/israeli-bank-scrapers.git"},"author":{"name":"Elad Shaham"},"bugs":{"url":"https://github.com/dan-dr/israeli-bank-scrapers/issues"},"license":"MIT","readme":"# Israeli Bank Scrapers - Get closer to your own data!\n\n<img src=\"./logo.png\" width=\"100\" height=\"100\" alt=\"Logo\" align=\"left\" />\n\n[![NPM](https://nodei.co/npm/israeli-bank-scrapers.png)](https://nodei.co/npm/israeli-bank-scrapers/)\n\n[![npm version](https://badge.fury.io/js/israeli-bank-scrapers.svg)](https://badge.fury.io/js/israeli-bank-scrapers)\n[![Discord](https://img.shields.io/discord/924617301209260103?logo=discord)](https://discord.gg/2UvGM7aX4p)\n\n> Important!\n> \n> The scrapers are set to use timezone `Asia/Jerusalem` to avoid conflicts in case you're running the scrapers outside Israel.\n\n## Dan's fork\n\nThis fork packages pending Hapoalim OTP/device-trust and Isracard/Amex anti-automation fixes, plus the related review hardening.\n\nBased on upstream contributions from [@eyaleng](https://github.com/eyaleng), [@avivghilai](https://github.com/avivghilai), and [@imrman](https://github.com/imrman).\n\n```sh\nnpm install @dan-dr/israeli-bank-scrapers\n```\n\nUse `@dan-dr/israeli-bank-scrapers` as the import path. The upstream documentation below otherwise applies unchanged.\n \n# What's here?\nWhat you can find here is scrapers for all major Israeli banks and credit card companies. That's the plan at least.\nCurrently only the following banks are supported:\n- Bank Hapoalim (thanks [@sebikaplun](https://github.com/sebikaplun))\n- Leumi Bank (thanks [@esakal](https://github.com/esakal))\n- Discount Bank\n- Mercantile Bank (thanks [@ezzatq](https://github.com/ezzatq) and [@kfirarad](https://github.com/kfirarad)))\n- Mizrahi Bank (thanks [@baruchiro](https://github.com/baruchiro))\n- Otsar Hahayal Bank (thanks [@matanelgabsi](https://github.com/matanelgabsi))\n- Visa Cal (thanks [@erikash](https://github.com/erikash), [@esakal](https://github.com/esakal) and [@nirgin](https://github.com/nirgin))\n- Max (Formerly Leumi Card)\n- Isracard\n- Amex (thanks [@erezd](https://github.com/erezd))\n- Union Bank (Thanks to Intuit FDP OpenSource Team [@dratler](https://github.com/dratler),[@kalinoy](https://github.com/kalinoy),[@shanigad](https://github.com/shanigad),[@dudiventura](https://github.com/dudiventura) and [@NoamGoren](https://github.com/NoamGoren))\n- Beinleumi (Thanks to [@dudiventura](https://github.com/dudiventura) from the Intuit FDP OpenSource Team)\n- Massad\n- Yahav (Thanks to [@gczobel](https://github.com/gczobel))\n- Beyhad Bishvilha - [ביחד בשבילך](https://www.hist.org.il/) (thanks [@esakal](https://github.com/esakal))\n- OneZero (Experimental) (thanks [@orzarchi](https://github.com/orzarchi))\n- Behatsdaa - [בהצדעה](behatsdaa.org.il) (thanks [@daniel-hauser](https://github.com/daniel-hauser))\n\n# Prerequisites\nTo use this you will need to have [Node.js](https://nodejs.org) >= 22.12.0 installed.\n\n# Getting started\nTo use these scrapers you'll need to install the package from npm:\n```sh\nnpm install israeli-bank-scrapers --save\n```\nThen you can simply import and use it in your node module:\n\n```node\nimport { CompanyTypes, createScraper } from 'israeli-bank-scrapers';\n\n(async function() {\n  try {\n    // read documentation below for available options\n    const options = {\n      companyId: CompanyTypes.leumi, \n      startDate: new Date('2020-05-01'),\n      combineInstallments: false,\n      showBrowser: true \n    };\n\n    // read documentation below for information about credentials\n    const credentials = {\n      username: 'vr29485',\n      password: 'sometingsomething'\n    };\n\n    const scraper = createScraper(options);\n    const scrapeResult = await scraper.scrape(credentials);\n\n    if (scrapeResult.success) {\n      scrapeResult.accounts.forEach((account) => {\n        console.log(`found ${account.txns.length} transactions for account number ${account.accountNumber}`);\n      });\n    }\n    else {\n      throw new Error(scrapeResult.errorType);\n    }\n  } catch(e) {\n    console.error(`scraping failed for the following reason: ${e.message}`);\n  }\n})();\n```\n\nCheck the options declaration [here](./src/scrapers/interface.ts#L29) for available options.\n\nRegarding credentials, you should provide the relevant credentials for the chosen company. See [this file](./src/definitions.ts) with list of credentials per company.\n\nThe structure of the result object is as follows:\n\n```node\n{\n  success: boolean,\n  accounts: [{\n    accountNumber: string,\n    balance?: number, // Account balance. Not implemented for all accounts.\n    txns: [{\n      type: string, // can be either 'normal' or 'installments'\n      identifier: int, // only if exists\n      date: string, // ISO date string\n      processedDate: string, // ISO date string\n      originalAmount: double,\n      originalCurrency: string,\n      chargedAmount: double,\n      description: string,\n      memo: string, // can be null or empty\n      installments: { // only if exists\n        number: int, // the current installment number\n        total: int, // the total number of installments\n      },\n      status: string //can either be 'completed' or 'pending'\n    }],\n  }],\n  errorType: \"INVALID_PASSWORD\"|\"CHANGE_PASSWORD\"|\"ACCOUNT_BLOCKED\"|\"UNKNOWN_ERROR\"|\"TIMEOUT\"|\"GENERIC\", // only on success=false\n  errorMessage: string, // only on success=false\n}\n```\n\nYou can also use the `SCRAPERS` list to get scraper metadata:\n```node\nimport { SCRAPERS } from 'israeli-bank-scrapers';\n```\n\nThe return value is a list of scraper metadata:\n```node\n{\n  <companyId>: {\n    name: string, // the name of the scraper\n    loginFields: [ // a list of login field required by this scraper\n      '<some field>' // the name of the field\n    ]\n  }\n}\n```\n\n## Advanced options\n\n### ExternalBrowserOptions\n\nThis option allows you to provide an externally created browser instance. You can get a browser directly from puppeteer via `puppeteer.launch()`.  \nNote that for backwards compatibility, the browser will be closed by the library after the scraper finishes unless `skipCloseBrowser` is set to true.\n\nExample:\n\n```typescript\nimport puppeteer from 'puppeteer';\nimport { CompanyTypes, createScraper } from 'israeli-bank-scrapers';\n\nconst browser = await puppeteer.launch();\nconst options = {\n  companyId: CompanyTypes.leumi,\n  startDate: new Date('2020-05-01'),\n  browser,\n  skipCloseBrowser: true, // Or false [default] if you want it to auto-close\n};\nconst scraper = createScraper(options);\nconst scrapeResult = await scraper.scrape({ username: 'vr29485', password: 'sometingsomething' });\nawait browser.close(); // Or not if `skipCloseBrowser` is false\n```\n\n### ExternalBrowserContextOptions\n\nThis option allows you to provide a [browser context](https://pptr.dev/api/puppeteer.browsercontext). This is useful if you don't want to share cookies with other scrapers (i.e. multiple parallel runs of the same scraper with different users) without creating a new browser for each scraper.\n\nExample:\n\n```typescript\nimport puppeteer from 'puppeteer';\nimport { CompanyTypes, createScraper } from 'israeli-bank-scrapers';\n\nconst browser = await puppeteer.launch();\nconst browserContext = await browser.createBrowserContext();\nconst options = {\n  companyId: CompanyTypes.leumi,\n  startDate: new Date('2020-05-01'),\n  browserContext\n};\nconst scraper = createScraper(options);\nconst scrapeResult = await scraper.scrape({ username: 'vr29485', password: 'sometingsomething' });\nawait browser.close();\n```\n\n### OptIn Features\n\nSome scrapers support opt-in features that can be enabled by passing the `optInFeatures` option when creating the scraper.\nOpt in features are usually used for breaking changes that are not enabled by default to avoid breaking existing users.\n\nSee the [OptInFeatures](https://github.com/eshaham/israeli-bank-scrapers/blob/master/src/scrapers/interface.ts#:~:text=export-,type%20OptInFeatures) interface for available features.\n\n## Two-Factor Authentication Scrapers\n\nSome companies require two-factor authentication, and as such the scraper cannot be fully automated. When using the relevant scrapers, you have three options:\n1. Provide an async callback that knows how to retrieve real time secrets like OTP codes.\n2. When supported by the scraper - provide a \"long term token\". These are usually available if the financial provider only requires Two-Factor authentication periodically, and not on every login. You can retrieve your long term token from the relevant credit/banking app using reverse engineering and a MITM proxy, or use helper functions that are provided by some Two-Factor Auth scrapers (e.g. OneZero).\n3. Use `deviceTrustData` to persist and restore device identity (cookies and localStorage). After a successful login with OTP, the scraper returns `deviceTrustData` in the result. On subsequent runs, pass it back via the `deviceTrustData` option to skip OTP entirely — the bank recognizes the device and doesn't prompt for verification. Currently supported by Hapoalim (see [Bank Hapoalim scraper](#bank-hapoalim-scraper) for a full example).\n\n\n```node\nimport { CompanyTypes, createScraper } from 'israeli-bank-scrapers';\nimport { prompt } from 'enquirer';\n\n// Option 1 - Provide a callback\n\nconst result = await scraper.login({\n email: relevantAccount.credentials.email,\n password: relevantAccount.credentials.password,\n phoneNumber,\n otpCodeRetriever: async () => {\n  let otpCode;\n  while (!otpCode) {\n   otpCode = await questions('OTP Code?');\n  }\n\n  return otpCode[0];\n }\n});\n\n// Option 2 - Retrieve a long term otp token (OneZero)\nawait scraper.triggerTwoFactorAuth(phoneNumber);\n\n// OTP is sent, retrieve it somehow\nconst otpCode='...';\n\nconst result = scraper.getLongTermTwoFactorToken(otpCode);\n/*\nresult = {\n  success: true;\n  longTermTwoFactorAuthToken: 'eyJraWQiOiJiNzU3OGM5Yy0wM2YyLTRkMzktYjBm...';\n}\n */\n```\n\n# Getting deployed version of latest changes in master\nThis library is deployed automatically to NPM with any change merged into the master branch. \n\n# `Israeli-bank-scrapers-core` library\n\n> TL;DR this is the same library as the default library. The only difference is that it is using `puppeteer-core` instead of `puppeteer` which is useful if you are using frameworks like Electron to pack your application. \n>\n> In most cases you will probably want to use the default library (read [Getting Started](#getting-started) section).\n\nIsraeli bank scrapers library is published  twice:\n 1. [israeli-bank-scrapers](https://www.npmjs.com/package/israeli-bank-scrapers) - the default variation, great for common usage as node dependency in server application or cli.\n 2. [israeli-bank-scrapers-core](https://www.npmjs.com/package/israeli-bank-scrapers-core) - extremely useful for applications that bundle `node_modules` like Electron applications. \n \n ## Differences between default and core variations\n  \n The default variation [israeli-bank-scrapers](https://www.npmjs.com/package/israeli-bank-scrapers) is using [puppeteer](https://www.npmjs.com/package/puppeteer) which handles the installation of local chroumium on its' own. This behavior is very handy since it takes care on all the hard work figuring which chromium to download and manage the actual download process.  As a side effect it increases node_modules by several hundred megabytes. \n \n The core variation [israeli-bank-scrapers-core](https://www.npmjs.com/package/israeli-bank-scrapers-core) is using [puppeteer-core](https://www.npmjs.com/package/puppeteer-core) which is exactly the same library as `puppeteer` except that it doesn't download chromium when installed by npm. It is up to you to make sure the specific version of chromium is installed locally and provide a path to that version. It is useful in Electron applications since it doesn't bloat the size of the application and you can provide a much friendlier experience like loading the application and download it later when needed. \n \n To install `israeli-bank-scrapers-core`:\n```sh\nnpm install israeli-bank-scrapers-core --save\n```\n\n## Getting chromium version used by puppeteer-core\nWhen using the `israeli-bank-scrapers-core` it is up to you to make sure the relevant chromium version exists. You must:\n1. query for the specific chromium revision required by the `puppeteer-core` library being used.\n2. make sure that you have local version of that revision.\n3. provide an absolute path to `israeli-bank-scrapers-core` scrapers.\n\nPlease read the following to learn more about the process: \n1. To get the required chromium revision use the following code:\n```\nimport { getPuppeteerConfig } from 'israeli-bank-scrapers-core';\n\nconst chromiumVersion = getPuppeteerConfig().chromiumRevision;\n```\n\n2. Once you have the chromium revision, you can either download it manually or use other liraries like [download-chromium](https://www.npmjs.com/package/download-chromium) to fetch that version. The mentioned library is very handy as it caches the download and provide useful helpers like download progress information.\n \n 3. provide the path to chromium to the library using the option key `executablePath`. \n\n# Specific definitions per scraper\n\n## Bank Hapoalim scraper\nThis scraper expects the following credentials object:\n```node\nconst credentials = {\n  userCode: <user identification code>,\n  password: <user password>\n};\n```\nThis scraper supports fetching transaction from up to one year.\n\n### Two-Factor Authentication (OTP)\nHapoalim may require SMS OTP verification when logging in from an unrecognized device. You can handle this by providing an `otpCodeRetriever` callback and optionally persisting device trust data to skip OTP on subsequent runs:\n\n```typescript\nimport { createScraper, CompanyTypes } from 'israeli-bank-scrapers';\n\nconst scraper = createScraper({\n  companyId: CompanyTypes.hapoalim,\n  startDate: new Date('2024-01-01'),\n  // Optionally inject previously saved trust data to skip OTP\n  deviceTrustData: savedTrustData, // or undefined on first run\n});\n\nconst result = await scraper.scrape({\n  userCode: '...',\n  password: '...',\n  otpCodeRetriever: async ({ attempt }) => {\n    // Called when OTP is required. `attempt` starts at 1 (max 3).\n    return await promptUserForOtpCode();\n  },\n});\n\nif (result.success && result.deviceTrustData) {\n  // Save trust data (cookies + localStorage) for next time.\n  // When injected via the deviceTrustData option, the bank recognizes\n  // the device and skips OTP verification.\n  await saveTrustData(result.deviceTrustData);\n}\n```\n\nThe `deviceTrustData` option is available for all browser-based scrapers, but the OTP flow is currently specific to Hapoalim.\n\n## Bank Leumi scraper\nThis scraper expects the following credentials object:\n```node\nconst credentials = {\n  username: <user name>,\n  password: <user password>\n};\n```\nThis scraper supports fetching transaction from up to one year.\n\n## Discount scraper\nThis scraper expects the following credentials object:\n```node\nconst credentials = {\n  id: <user identification number>,\n  password: <user password>,\n  num: <user identificaiton code>\n};\n```\nThis scraper supports fetching transaction from up to one year (minus 1 day).\n\n## Mercantile scraper\nThis scraper expects the following credentials object:\n```node\nconst credentials = {\n  id: <user identification number>,\n  password: <user password>,\n  num: <user identificaiton code>\n};\n```\nThis scraper supports fetching transaction from up to one year (minus 1 day).\n\n\n### Known Limitations\n- Missing memo field\n\n## Mizrahi scraper\nThis scraper expects the following credentials object:\n```node\nconst credentials = {\n  username: <user identification number>,\n  password: <user password>\n};\n```\nThis scraper supports fetching transaction from up to one year.\n\n## Beinleumi & Massad\nThese scrapers are essentially identical and expect the following credentials object:\n```node\nconst credentials = {\n  username: <user name>,\n  password: <user password>\n};\n```\n\n## Bank Otsar Hahayal scraper\nThis scraper expects the following credentials object:\n```node\nconst credentials = {\n  username: <user name>,\n  password: <user password>\n};\n```\nThis scraper supports fetching transaction from up to one year.\n\n## Visa Cal scraper\nThis scraper expects the following credentials object:\n```node\nconst credentials = {\n  username: <user name>,\n  password: <user password>\n};\n```\nThis scraper supports fetching transaction from up to one year.\n\n## Max scraper (Formerly Leumi-Card)\nThis scraper expects the following credentials object:\n```node\nconst credentials = {\n  username: <user name>,\n  password: <user password>\n};\n```\nThis scraper supports fetching transaction from up to one year.\n\n## Isracard scraper\nThis scraper expects the following credentials object:\n```node\nconst credentials = {\n  id: <user identification number>,\n  card6Digits: <6 last digits of card>\n  password: <user password>\n};\n```\nThis scraper supports fetching transaction from up to one year.\n\n## Amex scraper\nThis scraper expects the following credentials object:\n```node\nconst credentials = {\n  username: <user identification number>,\n  card6Digits: <6 last digits of card>\n  password: <user password>\n};\n```\nThis scraper supports fetching transaction from up to one year.\n\n## Yahav\nThis scraper expects the following credentials object:\n```node\nconst credentials = {\n  username: <user name>,\n  password: <user password>,\n  nationalID: <user national ID>\n};\n```\nThis scraper supports fetching transaction from up to six months.\n\n## Beyhad Bishvilha\nThis scraper expects the following credentials object::\n```node\nconst credentials = {\n  id: <user identification number>,\n  password: <user password>\n};\n```\n\n# Known projects\nThese are the projects known to be using this module:\n- [Israeli YNAB updater](https://github.com/eshaham/israeli-ynab-updater) - A command line tool for exporting banks data to CSVs, formatted specifically for [YNAB](https://www.youneedabudget.com)\n- [Caspion](https://github.com/brafdlog/caspion) - An app for automatically sending transactions from Israeli banks and credit cards to budget tracking apps\n- [Finance Notifier](https://github.com/LiranBri/finance-notifier) - A simple script with the ability to send custom financial alerts to multiple contacts and platforms\n- [Moneyman](https://github.com/daniel-hauser/moneyman) - Automatically save transactions from all major Israeli banks and credit card companies, using GitHub actions (or a self hosted docker image)\n- [Firefly iii Importer](https://github.com/itairaz1/israeli-bank-firefly-importer) - A tool to import your banks data into [Firefly iii](https://www.firefly-iii.org/), a free and open source financial manager.\n- [Actual Budget Importer](https://github.com/tomerh2001/israeli-banks-actual-budget-importer) - A tool to import your banks data into [Actual Budget](https://actualbudget.com/), a free and open source financial manager.\n- [Clarify](https://github.com/tomyweiss/clarify-expences) - A full-stack personal finance app for tracking income and expenses.\n- [Asher MCP](https://github.com/shlomiuziel/asher-mcp) - Scrape & access your financial data with LLM using the Model Context Protocol.\n\nBuilt something interesting you want to share here? [Let me know](https://goo.gl/forms/5Fb9JAjvzMIpmzqo2).\n\n# License\nThe MIT License\n","readmeFilename":"README.md","_rev":"1-dc3f56d9f3cf5a768dfdafe3d076aa50"}