mirror of
https://github.com/orangecoding/fredy.git
synced 2026-06-16 12:31:07 +00:00
UI (#15)
Adding new Admin UI. Updating Fredy to V3.0.0 as it has been a large rewrite. Thanks for all contributions and help on the way!
This commit is contained in:
committed by
GitHub
parent
8185bfe818
commit
b2847f6834
@@ -1,16 +1,21 @@
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
|
||||
/**
|
||||
* simply prints out the found data to the console
|
||||
* @param serviceName e.g immoscout
|
||||
* @param serviceName e.g immowelt
|
||||
* @param newListings an array with newly found listings
|
||||
* @param notificationConfig config of this notification adapter
|
||||
* @param jobKey name of the current job that is being executed
|
||||
*/
|
||||
exports.send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
const { enabled } = notificationConfig.console;
|
||||
if (!enabled) {
|
||||
return [Promise.resolve()];
|
||||
}
|
||||
exports.send = ({ serviceName, newListings, jobKey }) => {
|
||||
/* eslint-disable no-console */
|
||||
return [Promise.resolve(console.info(`Found entry from service ${serviceName}, Job: ${jobKey}:`, newListings))];
|
||||
/* eslint-enable no-console */
|
||||
};
|
||||
|
||||
exports.config = {
|
||||
id: __filename.slice(__dirname.length + 1, -3),
|
||||
name: 'Console',
|
||||
description: 'This adapter sends new listings to the console. It is mostly useful for debugging.',
|
||||
config: {},
|
||||
readme: markdown2Html('lib/notification/adapter/console.md'),
|
||||
};
|
||||
|
||||
4
lib/notification/adapter/console.md
Normal file
4
lib/notification/adapter/console.md
Normal file
@@ -0,0 +1,4 @@
|
||||
### Console Adapter
|
||||
|
||||
The console adapter prints everything found by Fredy into the console (not sending any notifications to you). This can be useful when you want to check if your search
|
||||
criteria meet the expectations.
|
||||
@@ -6,21 +6,20 @@ const template = fs.readFileSync(path.resolve(__dirname, '../', 'emailTemplate/t
|
||||
|
||||
const Handlebars = require('handlebars');
|
||||
const emailTemplate = Handlebars.compile(template);
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
|
||||
/**
|
||||
* sends a new listing using MailJet
|
||||
* @param serviceName e.g immoscout
|
||||
* @param serviceName e.g immowelt
|
||||
* @param newListings an array with newly found listings
|
||||
* @param notificationConfig config of this notification adapter
|
||||
* * @param jobKey name of the current job that is being executed
|
||||
* @returns {Promise<Chat.PostMessage.Response> | void}
|
||||
*/
|
||||
exports.send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
const { apiPublicKey, apiPrivateKey, enabled, receiver, from } = notificationConfig.mailJet;
|
||||
|
||||
if (!enabled) {
|
||||
return [Promise.resolve()];
|
||||
}
|
||||
exports.send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
const { apiPublicKey, apiPrivateKey, receiver, from } = notificationConfig.find(
|
||||
(adapter) => adapter.id === 'mailJet'
|
||||
).fields;
|
||||
|
||||
return mailjet
|
||||
.connect(apiPublicKey, apiPrivateKey)
|
||||
@@ -47,3 +46,33 @@ exports.send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
exports.config = {
|
||||
id: __filename.slice(__dirname.length + 1, -3),
|
||||
name: 'MailJet',
|
||||
description: 'MailJet is being used to send new listings via mail.',
|
||||
readme: markdown2Html('lib/notification/adapter/mailJet.md'),
|
||||
fields: {
|
||||
apiPublicKey: {
|
||||
type: 'text',
|
||||
label: 'Public Api Key',
|
||||
description: 'The public api key needed to access this service.',
|
||||
},
|
||||
apiPrivateKey: {
|
||||
type: 'text',
|
||||
label: 'Private Api Key',
|
||||
description: 'The private api key needed to access this service.',
|
||||
},
|
||||
receiver: {
|
||||
type: 'email',
|
||||
label: 'Receiver Email',
|
||||
description: 'The email address (single one) which Fredy is using to send notifications to.',
|
||||
},
|
||||
from: {
|
||||
type: 'email',
|
||||
label: 'Sender email',
|
||||
description:
|
||||
'The email address from which Fredy send email. Beware, this email address needs to be verified by Sendgrid.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
9
lib/notification/adapter/mailJet.md
Normal file
9
lib/notification/adapter/mailJet.md
Normal file
@@ -0,0 +1,9 @@
|
||||
### MailJet Adapter
|
||||
|
||||
|
||||
|
||||
SendGrid is a free email service (free as in "you cannot send more than 100(Sendgrid) and 200(Mailjet) emails a day"), which is more than enough for Fredy.
|
||||
|
||||
To use [SendGrid](https://sendgrid.com/), you need to create an account. You'll need to decided from which email address you want Fredy to send from. E.g. if you use yourGmailAccount@gmail.com, you have to add this to sendgrid and verify it as well.
|
||||
|
||||
Lastly you have to create an api-key and feed it into Fredy's config, as well as creating a new template. For this new template, I recommend copying and pasting the one I have provided under `/lib/notification/emailTemplate/template.hbs`.
|
||||
@@ -1,18 +1,16 @@
|
||||
const sgMail = require('@sendgrid/mail');
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
|
||||
/**
|
||||
* sends a new listing using SendGrid
|
||||
* @param serviceName e.g immoscout
|
||||
* @param serviceName e.g immowelt
|
||||
* @param newListings an array with newly found listings
|
||||
* @param notificationConfig config of this notification adapter
|
||||
* * @param jobKey name of the current job that is being executed
|
||||
* @param jobKey name of the current job that is being executed
|
||||
* @returns {Promise<Chat.PostMessage.Response> | void}
|
||||
*/
|
||||
exports.send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
const { apiKey, enabled, receiver, from, templateId } = notificationConfig.sendGrid;
|
||||
if (!enabled) {
|
||||
return [Promise.resolve()];
|
||||
}
|
||||
exports.send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
const { apiKey, receiver, from, templateId } = notificationConfig.find((adapter) => adapter.id === 'sendGrid').fields;
|
||||
sgMail.setApiKey(apiKey);
|
||||
const msg = {
|
||||
templateId,
|
||||
@@ -27,3 +25,33 @@ exports.send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
};
|
||||
return sgMail.send(msg);
|
||||
};
|
||||
|
||||
exports.config = {
|
||||
id: __filename.slice(__dirname.length + 1, -3),
|
||||
name: 'SendGrid',
|
||||
description: 'SendGrid is being used to send new listings via mail.',
|
||||
readme: markdown2Html('lib/notification/adapter/sendGrid.md'),
|
||||
fields: {
|
||||
apiKey: {
|
||||
type: 'text',
|
||||
label: 'Api Key',
|
||||
description: 'The api key needed to access this service.',
|
||||
},
|
||||
receiver: {
|
||||
type: 'email',
|
||||
label: 'Receiver Email',
|
||||
description: 'The email address (single one) which Fredy is using to send notifications to.',
|
||||
},
|
||||
from: {
|
||||
type: 'email',
|
||||
label: 'Sender Email',
|
||||
description:
|
||||
'The email address from which Fredy send email. Beware, this email address needs to be verified by Sendgrid.',
|
||||
},
|
||||
templateId: {
|
||||
type: 'text',
|
||||
label: 'Template Id',
|
||||
description: 'Sendgrid supports templates which Fredy is using to send out emails that looks awesome ;)',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
7
lib/notification/adapter/sendGrid.md
Normal file
7
lib/notification/adapter/sendGrid.md
Normal file
@@ -0,0 +1,7 @@
|
||||
### SendGrid Adapter
|
||||
|
||||
|
||||
To use [MailJet](https://mailjet.com), you need to create an account. You'll need to decided from which email address you want Fredy to send from.
|
||||
|
||||
E.g. if you use yourGmailAccount@gmail.com, you have to add this to MailJet and verify it as well.
|
||||
The given public/private api keys are needed in order to use MailJet with Fredy. Fredy will use the same template, it is using for SendGrid.
|
||||
@@ -1,19 +1,17 @@
|
||||
const Slack = require('slack');
|
||||
const msg = Slack.chat.postMessage;
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
|
||||
/**
|
||||
* sends a new listing to slack
|
||||
* @param serviceName e.g immoscout
|
||||
* @param serviceName e.g immowelt
|
||||
* @param newListings an array with newly found listings
|
||||
* @param notificationConfig config of this notification adapter
|
||||
* * @param jobKey name of the current job that is being executed
|
||||
* @returns {Promise<Chat.PostMessage.Response> | void}
|
||||
*/
|
||||
exports.send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
const { token, channel, enabled } = notificationConfig.slack;
|
||||
if (!enabled) {
|
||||
return [Promise.resolve()];
|
||||
}
|
||||
exports.send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
const { token, channel } = notificationConfig.find((adapter) => adapter.id === 'slack').fields;
|
||||
return newListings.map((payload) =>
|
||||
msg({
|
||||
token,
|
||||
@@ -49,3 +47,22 @@ exports.send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
exports.config = {
|
||||
id: __filename.slice(__dirname.length + 1, -3),
|
||||
name: 'Slack',
|
||||
readme: markdown2Html('lib/notification/adapter/slack.md'),
|
||||
description: 'Fredy will send new listings to the slack channel of your choice..',
|
||||
fields: {
|
||||
token: {
|
||||
type: 'text',
|
||||
label: 'Token',
|
||||
description: 'The token needed to send notifications to slack.',
|
||||
},
|
||||
channel: {
|
||||
type: 'channel',
|
||||
label: 'Channel',
|
||||
description: 'The channel where fredy should send notifications to.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
6
lib/notification/adapter/slack.md
Normal file
6
lib/notification/adapter/slack.md
Normal file
@@ -0,0 +1,6 @@
|
||||
### Slack Adapter
|
||||
|
||||
|
||||
In order to use [Slack](https://slack.com), you need to create an account. When done, you need to create a new App in your workspace. Give it the permission `chat:write:bot` and `chat:write:user`.
|
||||
|
||||
Now you need to create a user token and a channel. Make sure the bot is installed to this channel.
|
||||
@@ -1,20 +1,17 @@
|
||||
const TelegramBot = require('tg-yarl');
|
||||
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
const opts = { parse_mode: 'Markdown' };
|
||||
|
||||
/**
|
||||
* sends new listings to telegram
|
||||
* @param serviceName e.g immoscout
|
||||
* @param serviceName e.g immowelt
|
||||
* @param newListings an array with newly found listings
|
||||
* @param notificationConfig config of this notification adapter
|
||||
* * @param jobKey name of the current job that is being executed
|
||||
* @returns {Promise<Void> | void}
|
||||
*/
|
||||
exports.send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
const { enabled, token, chatId } = notificationConfig.telegram;
|
||||
if (!enabled) {
|
||||
return [Promise.resolve()];
|
||||
}
|
||||
exports.send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
const { token, chatId } = notificationConfig.find((adapter) => adapter.id === 'telegram').fields;
|
||||
|
||||
const bot = new TelegramBot(token);
|
||||
|
||||
@@ -34,3 +31,27 @@ exports.send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
function shorten(str, len = 30) {
|
||||
return str.length > len ? str.substring(0, len) + '...' : str;
|
||||
}
|
||||
|
||||
/**
|
||||
* exported config is being used in the frontend to generate the fields
|
||||
* incoming values will be the keys (and values) of the fields
|
||||
*
|
||||
*/
|
||||
exports.config = {
|
||||
id: __filename.slice(__dirname.length + 1, -3),
|
||||
name: 'Telegram',
|
||||
readme: markdown2Html('lib/notification/adapter/telegram.md'),
|
||||
description: 'Fredy will send new listings to your mobile, using Telegram.',
|
||||
fields: {
|
||||
token: {
|
||||
type: 'text',
|
||||
label: 'Token',
|
||||
description: 'The token needed to access this service.',
|
||||
},
|
||||
chatId: {
|
||||
type: 'chatId',
|
||||
label: 'Chat Id',
|
||||
description: 'The chat id to send messages to you.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
13
lib/notification/adapter/telegram.md
Normal file
13
lib/notification/adapter/telegram.md
Normal file
@@ -0,0 +1,13 @@
|
||||
### Telegram Adapter
|
||||
|
||||
|
||||
For Telegram, you need to create a Bot. This is pretty easy. Open [this](https://telegram.me/BotFather) url on your smartphone and follow the instructions.
|
||||
|
||||
A telegram bot is not allowed to send messages directly to a user, you as a user need to first contact the bot to get a chatId.
|
||||
After the user has send a message to your bot the first time, you can gather the chatId like this:
|
||||
|
||||
```
|
||||
curl -X GET https://api.telegram.org/bot{YOUR_TELEGRAM_TOKEN}/getUpdates
|
||||
```
|
||||
|
||||
A more detailed list of instructions can be found here [https://core.telegram.org/bots#botfather](https://core.telegram.org/bots#botfather)
|
||||
@@ -2,13 +2,20 @@ const fs = require('fs');
|
||||
const path = './adapter';
|
||||
|
||||
/** Read every integration existing in ./adapter **/
|
||||
const adapter = fs.readdirSync('./lib/notification/adapter').map((integPath) => require(`${path}/${integPath}`));
|
||||
const adapter = fs
|
||||
.readdirSync('./lib/notification/adapter')
|
||||
.filter((file) => file.endsWith('.js'))
|
||||
.map((integPath) => require(`${path}/${integPath}`));
|
||||
|
||||
if (adapter.length === 0) {
|
||||
throw new Error('Please specify at least one notification provider');
|
||||
}
|
||||
|
||||
exports.send = (serviceName, payload, notificationConfig, jobKey) => {
|
||||
//this is not being used in tests, therefor adapter are always set
|
||||
return adapter.map((a) => a.send(serviceName, payload, notificationConfig, jobKey));
|
||||
exports.send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
//this is not being used in tests, therefore adapter are always set
|
||||
return adapter
|
||||
.filter((notificationAdapter) => {
|
||||
return notificationConfig.find((config) => config.id === notificationAdapter.config.id);
|
||||
})
|
||||
.map((a) => a.send({ serviceName, newListings, notificationConfig, jobKey }));
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user