2025-09-12 18:47:10 +02:00
<p align="center">
2025-09-13 22:20:50 +02:00
<a href="https://fredy.orange-coding.net/">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/orangecoding/fredy/blob/master/doc/logo_white.png" width="400">
<source media="(prefers-color-scheme: light)" srcset="https://github.com/orangecoding/fredy/blob/master/doc/logo.png" width="400">
<img alt="Jetbrains Open Source" src="https://github.com/orangecoding/fredy/blob/master/doc/logo.png">
</picture>
</a>
</p>
2025-09-12 18:47:10 +02:00
2025-10-02 22:05:49 +02:00
<p align="center">
<a href="https://fredy.orange-coding.net/" target="_blank">Website</a> |
2025-10-11 17:37:51 +02:00
<a href="https://fredy-demo.orange-coding.net/" target="_blank">Demo</a>
2025-10-02 22:05:49 +02:00
</p>
<p align="center">
<img src="https://github.com/orangecoding/fredy/actions/workflows/test.yml/badge.svg" alt="Tests" />
<img src="https://github.com/orangecoding/fredy/actions/workflows/docker.yml/badge.svg" alt="Docker" />
<img src="https://github.com/orangecoding/fredy/actions/workflows/check_source.yml/badge.svg" alt="Source" />
<img src="https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fghcr-badge.elias.eu.org%2Fapi%2Forangecoding%2Ffredy%2Ffredy&query=%24.downloadCount&label=Docker%20Pulls" alt="Docker Pulls" />
</p>
2025-09-12 18:47:10 +02:00
2026-06-02 11:02:05 +02:00
# Fredy 🏡 - Your Self-Hosted Real Estate Finder for Germany
2025-09-03 15:09:35 +02:00
2025-09-04 09:08:25 +02:00
Finding an apartment or house in Germany can be stressful and
time-consuming.\
**Fredy** makes it easier: it automatically scrapes **ImmoScout24,
Immowelt, Immonet, eBay Kleinanzeigen, and WG-Gesucht** and notifies you
2025-09-27 14:27:25 +02:00
instantly via **Slack, Telegram, Email, ntfy, discord and more ** when new
2025-09-04 09:08:25 +02:00
listings appear.
2025-09-03 15:09:35 +02:00
2025-09-04 09:08:25 +02:00
With a modern architecture, Fredy provides a **clean Web UI ** , removes
duplicates across platforms, and stores results so you never see the
same listing twice.
2025-09-03 15:09:35 +02:00
2025-09-04 09:08:25 +02:00
------------------------------------------------------------------------
2021-01-22 13:17:34 +01:00
2025-09-04 09:08:25 +02:00
## ✨ Key Features
2021-07-01 14:26:56 +02:00
2025-09-04 09:08:25 +02:00
- 🏠 Scrapes **ImmoScout24, Immowelt, Immonet, eBay Kleinanzeigen,
WG-Gesucht**
- ⚡ Instant notifications: Slack, Telegram, Email (SendGrid,
2025-09-27 14:27:25 +02:00
Mailjet), ntfy, discord
2025-09-04 09:08:25 +02:00
- 🔎 Uses the **ImmoScout Mobile API ** (reverse engineered)
- 🌍 Runs anywhere: Docker, Node.js, self-hosted
- 🖥️ Intuitive **Web UI ** to manage searches
- 🎯 Easy to use thanks to a user-friendly Web UI
- 🔄 Deduplication across platforms
- ⏱️ Customizable search intervals
2021-01-22 13:17:34 +01:00
2025-09-04 09:08:25 +02:00
------------------------------------------------------------------------
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
## 🤝 Sponsorship [](https://github.com/sponsors/orangecoding)
2023-02-11 21:32:28 +01:00
2026-06-12 14:33:13 +02:00
I maintain Fredy and other open-source projects in my free time, if you find it useful, consider supporting the project ❤️
#### Support me on
2026-06-12 14:34:06 +02:00
[Ko-Fi ](https://ko-fi.com/orangecoding ) | [Github ](https://github.com/sponsors/orangecoding )
2026-06-12 14:33:13 +02:00
----
2023-02-11 21:32:28 +01:00
2025-09-05 12:34:03 +02:00
Fredy is proudly backed by the **JetBrains Open Source Support Program ** .
2025-09-13 22:16:16 +02:00
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://www.jetbrains.com/company/brand/img/logo_jb_dos_3.svg">
<source media="(prefers-color-scheme: light)" srcset="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg">
<img alt="Jetbrains Open Source" src="https://resources.jetbrains.com/storage/products/company/brand/logos/jetbrains.svg">
</picture>
2025-09-03 15:09:35 +02:00
2025-09-04 09:08:25 +02:00
------------------------------------------------------------------------
2025-09-12 13:00:43 +02:00
## 👨🏫 Demo
You can try out Fredy here: [Fredy Demo ](https://fredy-demo.orange-coding.net/ )
------------------------------------------------------------------------
2025-09-04 09:08:25 +02:00
## 🚀 Quick Start
### With Docker
2025-09-07 16:46:43 +02:00
> [!NOTE]
> In order to start Fredy, you must provide a config.json. As a start, use the one in this repo: https://github.com/orangecoding/fredy/blob/master/conf/config.json
2025-09-04 09:08:25 +02:00
``` bash
2025-09-10 11:31:49 +02:00
docker run -d --name fredy \
-v fredy_conf:/conf \
-v fredy_db:/db \
-p 9998:9998 \
ghcr.io/orangecoding/fredy:master
2025-09-04 09:08:25 +02:00
```
2025-09-03 15:09:35 +02:00
2025-09-04 09:08:25 +02:00
Logs:
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
``` bash
docker logs fredy -f
```
2024-11-22 09:38:50 +01:00
2025-09-04 09:08:25 +02:00
### Manual (Node.js)
2021-01-22 13:17:34 +01:00
2025-09-18 15:38:23 +02:00
- Requirement: **Node.js 22 or higher **
2025-09-04 09:08:25 +02:00
- Install dependencies and start:
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
``` bash
2025-07-25 13:13:04 +02:00
yarn
2025-09-03 15:09:35 +02:00
yarn run start:backend # in one terminal
yarn run start:frontend # in another terminal
2021-01-21 16:09:23 +01:00
```
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
👉 Open <http://localhost:9998>
2025-09-03 15:09:35 +02:00
2025-12-10 09:09:20 +01:00
### With Unraid
Should you use [Unraid ](https://unraid.net/ ), you can now install Fredy from the community store :)
2025-09-04 09:08:25 +02:00
**Default Login:**
- Username: `admin`
- Password: `admin`
2025-09-03 15:09:35 +02:00
2025-09-04 09:08:25 +02:00
------------------------------------------------------------------------
2020-07-17 15:39:11 +02:00
2025-09-04 09:08:25 +02:00
## 📸 Screenshots
2025-09-03 14:52:58 +02:00
2026-01-12 15:00:36 +01:00
| Fredy Maps View | Dashboard | Found Listings |
2025-09-29 20:36:56 +02:00
|--------------------------------------------------|-----------------------------------------------------------------------|-----------------------------------------------------------------------------|
|  |  |  |
2021-05-13 17:22:59 +02:00
2025-09-04 09:08:25 +02:00
------------------------------------------------------------------------
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
## 🧩 Core Concepts
2020-08-15 13:22:38 +02:00
2025-09-04 09:08:25 +02:00
Fredy is built around three simple concepts:
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
### Provider 🌐
2020-08-15 13:22:38 +02:00
2025-09-04 09:08:25 +02:00
A **provider ** is a real-estate platform (e.g. ImmoScout24, Immowelt,
Immonet, eBay Kleinanzeigen, WG-Gesucht).\
When you create a job, you paste the search URL from the platform into
Fredy.\
⚠️ Always make sure the search results are sorted by **date ** , so Fredy
picks up the newest listings first.
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
### Adapter 📡
2020-02-26 09:05:20 +01:00
2025-09-04 09:08:25 +02:00
An **adapter ** is the channel through which Fredy notifies you (Slack,
2025-09-27 14:27:25 +02:00
Telegram, Email, ntfy, discord ...).\
2025-09-04 09:08:25 +02:00
Each adapter has its own configuration (e.g. API keys, webhook URLs).\
You can use multiple adapters at once --- Fredy will send new listings
through all of them.
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
### Job 📅
2020-02-26 09:05:20 +01:00
2025-09-04 09:08:25 +02:00
A **job ** combines providers and adapters.\
Example: "Search apartments on ImmoScout24 + Immowelt and send results
to Slack + Telegram."\
Jobs run automatically at the interval you configure (see
`/conf/config.json` ).
2025-07-26 20:42:58 +02:00
2026-03-09 15:35:29 +01:00
### MCP Server 🤖
Starting with **V20 ** , Fredy ships with a built-in **MCP Server ** . This allows you to connect Fredy to LLMs (like Claude, ChatGPT, or local models via LM Studio) and query your real estate data using natural language.
The local LLM can even enrich existing listings by checking the listing online.
2026-03-09 16:26:53 +01:00
For more information on how to set it up and use it, please refer to the [MCP Readme ](lib/mcp/README.md ).
2026-03-09 15:35:29 +01:00
2025-09-04 09:08:25 +02:00
------------------------------------------------------------------------
2020-02-26 09:05:20 +01:00
2025-09-04 09:08:25 +02:00
## Immoscout
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
Immoscout has implemented advanced bot detection. In order to work around this, we are using a reversed engineered version of their mobile api. See [Immoscout Reverse Engineering Documentation ](https://github.com/orangecoding/fredy/blob/master/reverse-engineered-immoscout.md )
2021-01-21 16:09:23 +01:00
2026-05-24 20:49:27 +02:00
## 🛡️ Bot Detection & Proxies
Most browser-based providers (immowelt, immonet, kleinanzeigen, ...) are scraped through a hardened headless browser ([CloakBrowser ](https://www.npmjs.com/package/cloakbrowser )). It makes the **browser fingerprint ** indistinguishable from a real Chrome, which is enough when you run Fredy on a normal home connection.
On a **server / VPS the requests usually originate from a datacenter IP ** , and providers behind anti-bot systems (e.g. AWS CloudFront/WAF) block those based on **IP reputation alone ** , no matter how perfect the fingerprint is. The typical symptom: it works locally but you get `We have been detected as a bot :-/` on the server.
### The fix: a residential proxy
A **residential proxy ** routes Fredy's browser through the internet connection of a real household, so the provider sees a "normal user" IP instead of a datacenter. For German portals, use a **German (DE) residential ** (or mobile/4G) proxy. Plain VPNs and **datacenter proxies do not help ** here, they share the same bad reputation as your server.
**Configure it** under **Settings → Execution → Proxy URL ** . Supported formats:
```
http://user:pass@host:port
socks5://user:pass@host:port
```
Leave the field empty to disable. The proxy applies to all headless-browser providers and takes effect on the next job run (no restart needed). Immoscout uses a separate mobile API and is not affected.
### Where to get a residential proxy
Residential proxies are a paid service (usually billed per GB, Fredy's traffic is small). Well-known providers offering German residential IPs include:
| Provider | Notes |
|---|---|
| [IPRoyal ](https://iproyal.com ) | Pay-as-you-go, no monthly minimum, good for low volume |
| [Webshare ](https://www.webshare.io ) | Cheap entry tier, has a small free plan to test with |
| [Decodo (formerly Smartproxy) ](https://decodo.com ) | Easy setup, country/city targeting |
| [SOAX ](https://soax.com ) | Residential + mobile, fine-grained geo-targeting |
| [Bright Data ](https://brightdata.com ) | Largest pool, most features, higher complexity/price |
| [Oxylabs ](https://oxylabs.io ) | Enterprise-grade, larger plans |
This is not an endorsement, pick whatever fits your budget. For low-volume use like Fredy, a pay-as-you-go plan (e.g. IPRoyal) or a cheap entry tier (e.g. Webshare) is usually plenty. Make sure to select **Germany ** as the proxy location and keep the search interval reasonable (the higher the interval, the less you look like a bot).
2025-09-04 09:08:25 +02:00
## Analytics
2021-01-21 16:09:23 +01:00
2025-09-04 09:08:25 +02:00
Fredy is completely free (and will always remain free). However, it would be a huge help if you’ d allow me to collect some analytical data.
Before you freak out, let me explain...
2025-09-12 13:38:53 +02:00
If you agree, Fredy will send a ping once every 6 hours to my internal tracking project (Will be open sourced soon).
2025-09-04 09:08:25 +02:00
The data includes: names of active adapters/providers, OS, architecture, Node version, and language. The information is entirely anonymous and helps me understand which adapters/providers are most frequently used.</p>
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
**Thanks**🤘
2025-07-26 20:42:58 +02:00
2026-06-09 15:42:25 +02:00
## 🐞 Debug Information
Since Fredy **22.5.0 ** there is a built-in way to capture everything Fredy logs into the
database for a limited time and download it as a single zip file. This is the recommended
way to attach diagnostics to a bug report. I decided against simply putting all logs into
a debug bundle due to privacy reasons!
**How it works**
- Debug logging is **opt-in ** and admin-only. As long as it is off, Fredy behaves exactly
as before (console output only, nothing in the DB).
- When you turn it on, every log line (`debug` , `info` , `warn` , `error` ) is additionally
written into the `debug_logs` SQLite table. The console keeps logging at its usual level.
- The recorded data is hard-capped at **5 MiB ** via a rolling buffer: once the cap is hit,
the oldest entries are dropped automatically so the newest ones always survive.
- The on/off flag is persisted, so debug logging stays on across restarts (and you'll see
the warning banner everywhere until you turn it off again).
**Capturing a debug bundle**
1. Open Fredy as an **admin ** and go to **Settings → Debug ** .
2. Click * * "Enable debug logging" / "Debug-Logging aktivieren"**. A red banner appears on
every page while recording is on.
3. **Reproduce the bug ** .
4. Come back to **Settings → Debug ** and check the progress bar, if it stayed at 0 %,
nothing was captured.
5. Click * * "Download debug information" / "Debug Informationen herunterladen"**. You get a
zip named `YYYY-MM-DD-FredyDebug-<version>.zip` containing two files:
- `logs.txt` - every log line captured while recording was on, prefixed with timestamp
and level.
- `sys.txt` - runtime snapshot (Fredy version, Node.js version, OS, Docker detection,
CPU, memory, sanitized settings). Proxy credentials and session secrets are
**stripped ** before export.
6. Attach the zip to the bug report.
7. Optional but recommended: click * * "Disable debug logging"** to stop recording, and
* * "Delete stored debug logs"** once you've sent the zip so the DB does not keep them
around.
**What is _ not _ included**
- passwords/privacy relevant things
- Anything that Fredy itself does not pass through its `logger` . If a third-party library
writes directly to `process.stderr` , that output stays on the console only.
2025-09-04 09:08:25 +02:00
## 🛠️ Development
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
### Development Mode
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
``` bash
yarn run start:backend:dev
2025-07-25 13:13:04 +02:00
yarn run start:frontend:dev
2021-01-21 16:09:23 +01:00
```
2022-12-19 21:44:10 +01:00
You should now be able to access _ Fredy _ from your browser. Check your Terminal to see what port the frontend is running on.
2021-01-21 16:09:23 +01:00
2025-09-04 09:08:25 +02:00
### Run Tests
2025-07-26 20:42:58 +02:00
2026-04-21 13:37:00 +02:00
## "Online" tests
These tests are directly executed against the actual providers.
2025-09-04 09:08:25 +02:00
``` bash
2021-01-21 16:09:23 +01:00
yarn run test
```
2026-04-21 13:37:00 +02:00
## "Offline" tests
These tests are using the test fixtures instead of the actual providers. Much faster and "good enough" to test the core functionality.
``` bash
yarn run test:offline
```
## Download new fixtures
If you have to refresh the fixtures (every once in a while needed because the providers change their code), run this command:
``` bash
yarn run download-fixtures
```
2026-06-04 10:35:42 +02:00
## Adding a new language
Fredy's UI is fully multilingual. Translation files live in `ui/src/locales/` . To add a new language, create a single JSON file there, no code changes required.
**Example: `ui/src/locales/fr.json` **
```json
{
"_meta": {
"flag": "🇫🇷",
"name": "Français",
"locale": "fr-FR",
"semiLocale": "fr"
},
"nav.dashboard": "Tableau de bord",
"common.save": "Enregistrer",
...
}
```
The `_meta` fields:
| Field | Description |
|---|---|
| `flag` | Unicode flag emoji shown in the language selector |
| `name` | Display name shown in the language selector |
| `locale` | BCP 47 locale string used for date and number formatting (e.g. `fr-FR` ) |
| `semiLocale` | Semi UI locale key for component-level strings (date pickers, pagination, etc.) |
> **Important:** `semiLocale` must exactly match a locale filename from the Semi UI locale sources (without the `.js` extension). See the [available Semi UI locales on GitHub](https://github.com/DouyinFE/semi-design/tree/main/packages/semi-ui/locale/source) for the full list of supported keys.
After adding the file, rebuild the frontend (`yarn build:frontend` or restart the dev server) and the new language will appear automatically in **Settings → User Settings → Language ** .
2026-04-21 13:37:00 +02:00
2025-09-04 09:08:25 +02:00
------------------------------------------------------------------------
2025-07-26 20:42:58 +02:00
2025-09-04 09:08:25 +02:00
## 📐 Architecture
``` mermaid
2025-08-02 07:18:19 +02:00
flowchart TD
subgraph Jobs["Jobs"]
A1["Job 1"]
A2["Job 2"]
A3["Job 3"]
end
subgraph Providers["Providers"]
C1["Provider 1"]
C2["Provider 2"]
C3["Provider 3"]
end
subgraph NotificationAdapters["Notification Adapters"]
2025-09-04 09:08:25 +02:00
F1["Adapter 1"]
F2["Adapter 2"]
2025-08-02 07:18:19 +02:00
end
2025-12-18 19:16:28 +01:00
A1 --> B["FredyPipelineExecutioner"]
2025-08-02 07:18:19 +02:00
A2 --> B
A3 --> B
B --> C1 & C2 & C3
2025-09-04 09:08:25 +02:00
C1 --> D["Similarity Check"]
2025-08-02 07:18:19 +02:00
C2 --> D
C3 --> D
2025-09-04 09:08:25 +02:00
D --> E{"Duplicate?"}
2025-08-02 07:18:19 +02:00
E -- No --> F1
F1 --> F2
```
2021-01-21 16:09:23 +01:00
2026-04-27 15:58:41 +02:00
------------------------------------------------------------------------
## 🤖 Using AI such as Claude Code
When I started building Fredy, LLMs were still basically the wet dream of a few nerdy scientists.
Nowadays, it’ s easier than ever to throw a prompt into the LLM of your choice and let 'the AI' build your stuff. I’ m not against that. I use Claude Code myself for smaller tasks, and I do think these tools can be really useful.
That said, I still believe humans should stay in charge. AI is great-ish at writing code, but it still lacks creativity, context, and the ability to see the full picture.
So, if you want to contribute to Fredy, using AI tools to get things done is totally fine. Just please don’ t stop thinking.
I’ ve had one too many PRs full of hallucinated bullshit.
**Thanks ;)**
2025-09-04 09:08:25 +02:00
------------------------------------------------------------------------
2025-05-17 09:09:42 +02:00
2025-09-04 09:08:25 +02:00
## 👐 Contributing
2025-05-17 09:09:42 +02:00
2025-09-04 09:08:25 +02:00
Thanks to everyone who has contributed!
2025-07-26 20:42:58 +02:00
2025-09-05 12:35:20 +02:00
<a href="https://github.com/orangecoding/fredy/graphs/contributors"><img src="https://contrib.rocks/image?repo=orangecoding/fredy" /></a>
2024-11-20 22:23:05 +01:00
2025-09-04 09:08:25 +02:00
See the [Contributing
Guide](https://github.com/orangecoding/fredy/blob/master/CONTRIBUTING.md).
2024-11-20 22:23:05 +01:00
2025-09-04 09:08:25 +02:00
------------------------------------------------------------------------
2024-11-20 22:23:05 +01:00
2025-09-04 09:08:25 +02:00
## ⭐ Star History
2025-05-17 09:09:42 +02:00
2025-09-04 09:08:25 +02:00
[](https://www.star-history.com/#orangecoding/fredy &Date)