mirror of
https://github.com/orangecoding/fredy.git
synced 2026-06-16 12:31:07 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95cd4028d7 | ||
|
|
eb01c2107c | ||
|
|
42cd4fa0ae | ||
|
|
6d96fd2bf8 | ||
|
|
ff1d2317a1 | ||
|
|
a47fa41278 | ||
|
|
9654e56846 | ||
|
|
43094640a8 |
@@ -21,7 +21,7 @@ Finding an apartment or house in Germany can be stressful and
|
|||||||
time-consuming.\
|
time-consuming.\
|
||||||
**Fredy** makes it easier: it automatically scrapes **ImmoScout24,
|
**Fredy** makes it easier: it automatically scrapes **ImmoScout24,
|
||||||
Immowelt, Immonet, eBay Kleinanzeigen, and WG-Gesucht** and notifies you
|
Immowelt, Immonet, eBay Kleinanzeigen, and WG-Gesucht** and notifies you
|
||||||
instantly via **Slack, Telegram, Email, ntfy, and more** when new
|
instantly via **Slack, Telegram, Email, ntfy, discord and more** when new
|
||||||
listings appear.
|
listings appear.
|
||||||
|
|
||||||
With a modern architecture, Fredy provides a **clean Web UI**, removes
|
With a modern architecture, Fredy provides a **clean Web UI**, removes
|
||||||
@@ -35,7 +35,7 @@ same listing twice.
|
|||||||
- 🏠 Scrapes **ImmoScout24, Immowelt, Immonet, eBay Kleinanzeigen,
|
- 🏠 Scrapes **ImmoScout24, Immowelt, Immonet, eBay Kleinanzeigen,
|
||||||
WG-Gesucht**
|
WG-Gesucht**
|
||||||
- ⚡ Instant notifications: Slack, Telegram, Email (SendGrid,
|
- ⚡ Instant notifications: Slack, Telegram, Email (SendGrid,
|
||||||
Mailjet), ntfy
|
Mailjet), ntfy, discord
|
||||||
- 🔎 Uses the **ImmoScout Mobile API** (reverse engineered)
|
- 🔎 Uses the **ImmoScout Mobile API** (reverse engineered)
|
||||||
- 🌍 Runs anywhere: Docker, Node.js, self-hosted
|
- 🌍 Runs anywhere: Docker, Node.js, self-hosted
|
||||||
- 🖥️ Intuitive **Web UI** to manage searches
|
- 🖥️ Intuitive **Web UI** to manage searches
|
||||||
@@ -129,7 +129,7 @@ picks up the newest listings first.
|
|||||||
### Adapter 📡
|
### Adapter 📡
|
||||||
|
|
||||||
An **adapter** is the channel through which Fredy notifies you (Slack,
|
An **adapter** is the channel through which Fredy notifies you (Slack,
|
||||||
Telegram, Email, ntfy, ...).\
|
Telegram, Email, ntfy, discord ...).\
|
||||||
Each adapter has its own configuration (e.g. API keys, webhook URLs).\
|
Each adapter has its own configuration (e.g. API keys, webhook URLs).\
|
||||||
You can use multiple adapters at once --- Fredy will send new listings
|
You can use multiple adapters at once --- Fredy will send new listings
|
||||||
through all of them.
|
through all of them.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export const send = ({ serviceName, newListings, notificationConfig, jobKey }) =
|
|||||||
const jobName = job == null ? jobKey : job.name;
|
const jobName = job == null ? jobKey : job.name;
|
||||||
const promises = newListings.map((newListing) => {
|
const promises = newListings.map((newListing) => {
|
||||||
const title = `${jobName} at ${serviceName}: ${newListing.title}`;
|
const title = `${jobName} at ${serviceName}: ${newListing.title}`;
|
||||||
const message = `Address: ${newListing.address}\nSize: ${newListing.size}\nPrice: ${newListing.price}\nink: ${newListing.link}`;
|
const message = `Address: ${newListing.address}\nSize: ${newListing.size}\nPrice: ${newListing.price}\nLink: ${newListing.link}`;
|
||||||
return fetch(server, {
|
return fetch(server, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ export const send = ({ serviceName, newListings, notificationConfig, jobKey }) =
|
|||||||
return fetch(webhook, {
|
return fetch(webhook, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: {
|
body: JSON.stringify({
|
||||||
channel: channel,
|
channel: channel,
|
||||||
text: message,
|
text: message,
|
||||||
},
|
}),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const config = {
|
export const config = {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "fredy",
|
"name": "fredy",
|
||||||
"version": "12.3.0",
|
"version": "12.3.2",
|
||||||
"description": "[F]ind [R]eal [E]states [d]amn eas[y].",
|
"description": "[F]ind [R]eal [E]states [d]amn eas[y].",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "husky",
|
"prepare": "husky",
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export default function JobTable({ jobs = {}, onJobRemoval, onJobStatusChanged,
|
|||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Findings',
|
title: 'Listings',
|
||||||
dataIndex: 'numberOfFoundListings',
|
dataIndex: 'numberOfFoundListings',
|
||||||
render: (value) => {
|
render: (value) => {
|
||||||
return value || 0;
|
return value || 0;
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ const GeneralSettings = function GeneralSettings() {
|
|||||||
<Divider margin="1rem" />
|
<Divider margin="1rem" />
|
||||||
<SegmentPart
|
<SegmentPart
|
||||||
name="Working hours"
|
name="Working hours"
|
||||||
helpText="During this hours, Fredy will search for new apartments. If nothing is configured, Fredy will search around the clock."
|
helpText="During these hours, Fredy will search for new apartments. If nothing is configured, Fredy will search around the clock."
|
||||||
Icon={IconCalendar}
|
Icon={IconCalendar}
|
||||||
>
|
>
|
||||||
<div className="generalSettings__timePickerContainer">
|
<div className="generalSettings__timePickerContainer">
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export default function JobMutator() {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Headline text={jobToBeEdit ? 'Edit a Job' : 'Create a new Job'} />
|
<Headline text={jobToBeEdit ? 'Edit Job' : 'Create new Job'} />
|
||||||
<form>
|
<form>
|
||||||
<SegmentPart name="Name">
|
<SegmentPart name="Name">
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
Reference in New Issue
Block a user