From 1b2fc795362c90c31343c8aa2dab87c19200e188 Mon Sep 17 00:00:00 2001 From: Efe Date: Tue, 18 Nov 2025 12:23:50 +0100 Subject: [PATCH 1/5] feat: add http adapter (#231) * feat: add http adapter --- lib/notification/adapter/http.js | 57 ++++++++++++++++++++++++++++++++ lib/notification/adapter/http.md | 43 ++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 lib/notification/adapter/http.js create mode 100644 lib/notification/adapter/http.md diff --git a/lib/notification/adapter/http.js b/lib/notification/adapter/http.js new file mode 100644 index 0000000..29a3ca1 --- /dev/null +++ b/lib/notification/adapter/http.js @@ -0,0 +1,57 @@ +import { markdown2Html } from '../../services/markdown.js'; + +const mapListing = (listing) => ({ + address: listing.address, + description: listing.description, + id: listing.id, + imageUrl: listing.image, + price: listing.price, + size: listing.size, + title: listing.title, + url: listing.link, +}); + +export const send = ({ serviceName, newListings, notificationConfig, jobKey }) => { + const { authToken, endpointUrl } = notificationConfig.find((a) => a.id === config.id).fields; + + const listings = newListings.map(mapListing); + const body = { + jobId: jobKey, + timestamp: new Date().toISOString(), + provider: serviceName, + listings, + }; + + const headers = { + 'Content-Type': 'application/json', + }; + if (authToken != null) { + headers['Authorization'] = `Bearer ${authToken}`; + } + + return fetch(endpointUrl, { + method: 'POST', + headers: headers, + body: JSON.stringify(body), + }); +}; + +export const config = { + id: 'http', + name: 'HTTP', + readme: markdown2Html('lib/notification/adapter/http.md'), + description: 'Fredy will send a generic HTTP POST request.', + fields: { + endpointUrl: { + description: "Your application's endpoint URL.", + label: 'Endpoint URL', + type: 'text', + }, + authToken: { + description: "Your application's auth token, if required by your endpoint.", + label: 'Auth token (optional)', + optional: true, + type: 'text', + }, + }, +}; diff --git a/lib/notification/adapter/http.md b/lib/notification/adapter/http.md new file mode 100644 index 0000000..497db02 --- /dev/null +++ b/lib/notification/adapter/http.md @@ -0,0 +1,43 @@ +### HTTP Adapter + +This is a generic adapter for sending notifications via HTTP requests. +You can leverage this adapter to integrate with various webhooks or APIs that accept HTTP requests. (e.g. Supabase +Functions, a Node.js server, etc.) + +HTTP adapter supports a `authToken` field, which can be used to include an authorization token in the request headers. +Your token would be included as a Bearer token in the `Authorization` header, which is a common method for securing API requests. + +Request Details: +
+Request Method: POST + +Headers: + +``` +Content Type: `application/json` +Authorization: Bearer {your-optional-auth-token} +``` + +Body: + +```json +{ + "jobId": "mg1waX4RHmIzL5NDYtYp-", + "provider": "immoscout", + "timestamp": "2024-06-15T12:34:56Z", + "listings": [ + { + "address": "Str. 123, Bielefeld, Germany", + "description": "Möbliert: Einziehen & wohlfühlen: Neu möbliert.", + "id": "123456789", + "imageUrl": "https://.com/listings/123456789.jpg", + "price": "1.240 €", + "size": "38 m²", + "title": "Schöne 1-Zimmer-Wohnung in Bielefeld", + "url": "https://.com/listings/123456789" + } + ] +} +``` + +
From 3eb3f6ee66c0760e000c8b45efe00adfdb0fe75f Mon Sep 17 00:00:00 2001 From: Efe Date: Tue, 18 Nov 2025 12:24:27 +0100 Subject: [PATCH 2/5] fix: notification adapter modal improvements (#230) * fix: fix notification modal --- ui/src/views/jobs/mutation/JobMutation.jsx | 12 ++++++++-- .../NotificationAdapterMutator.jsx | 23 +++++++++++-------- .../components/provider/ProviderMutator.jsx | 7 +++++- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/ui/src/views/jobs/mutation/JobMutation.jsx b/ui/src/views/jobs/mutation/JobMutation.jsx index a008076..faff37f 100644 --- a/ui/src/views/jobs/mutation/JobMutation.jsx +++ b/ui/src/views/jobs/mutation/JobMutation.jsx @@ -11,7 +11,15 @@ import { useNavigate, useParams } from 'react-router-dom'; import { Divider, Input, Switch, Button, TagInput, Toast, Select } from '@douyinfe/semi-ui'; import './JobMutation.less'; import { SegmentPart } from '../../../components/segment/SegmentPart'; -import { IconBell, IconBriefcase, IconPaperclip, IconPlayCircle, IconPlusCircle, IconUser } from '@douyinfe/semi-icons'; +import { + IconBell, + IconBriefcase, + IconPaperclip, + IconPlayCircle, + IconPlusCircle, + IconUser, + IconClear, +} from '@douyinfe/semi-icons'; export default function JobMutator() { const jobs = useSelector((state) => state.jobs.jobs); @@ -160,7 +168,7 @@ export default function JobMutator() { diff --git a/ui/src/views/jobs/mutation/components/notificationAdapter/NotificationAdapterMutator.jsx b/ui/src/views/jobs/mutation/components/notificationAdapter/NotificationAdapterMutator.jsx index 3da6c05..d6ccec9 100644 --- a/ui/src/views/jobs/mutation/components/notificationAdapter/NotificationAdapterMutator.jsx +++ b/ui/src/views/jobs/mutation/components/notificationAdapter/NotificationAdapterMutator.jsx @@ -7,6 +7,7 @@ import { useSelector } from '../../../../../services/state/store'; import { Banner, Button, Form, Modal, Select, Switch } from '@douyinfe/semi-ui'; import './NotificationAdapterMutator.less'; +import { useScreenWidth } from '../../../../../hooks/screenWidth.js'; const sortAdapter = (a, b) => { if (a.name < b.name) { @@ -70,6 +71,9 @@ export default function NotificationAdapterMutator({ const [validationMessage, setValidationMessage] = useState(null); const [successMessage, setSuccessMessage] = useState(null); + const width = useScreenWidth(); + const isMobile = width <= 850; + const onSubmit = (doStore) => { if (doStore) { const validationResults = validate(selectedAdapter); @@ -170,18 +174,19 @@ export default function NotificationAdapterMutator({ onSubmit(false)} footer={
- - - +
} > @@ -207,9 +212,9 @@ export default function NotificationAdapterMutator({ )}

- When Fredy found new listings, we like to report them to you. To do so, notification adapter can be configured.{' '} -
- There are multiple ways how Fredy can send new listings to you. Chose your weapon... + When Fredy finds new listings, we like to report them to you. To do so, the notification adapter can be + configured.
+ There are multiple ways Fredy can send new listings to you. Choose your weapon...