mirror of
https://github.com/orangecoding/fredy.git
synced 2026-06-16 12:31:07 +00:00
committed by
GitHub
parent
7d0ec72a0c
commit
2c5eceb0c1
@@ -1,19 +1,12 @@
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
import { markdown2Html } from '../../services/markdown.js';
|
||||
|
||||
/**
|
||||
* simply prints out the found data to the console
|
||||
* @param serviceName e.g immowelt
|
||||
* @param newListings an array with newly found listings
|
||||
* @param jobKey name of the current job that is being executed
|
||||
*/
|
||||
exports.send = ({ serviceName, newListings, jobKey }) => {
|
||||
export const 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),
|
||||
export const config = {
|
||||
id: 'console',
|
||||
name: 'Console',
|
||||
description: 'This adapter sends new listings to the console. It is mostly useful for debugging.',
|
||||
config: {},
|
||||
|
||||
@@ -1,33 +1,22 @@
|
||||
const mailjet = require('node-mailjet');
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const template = fs.readFileSync(path.resolve(__dirname, '../', 'emailTemplate/template.hbs'), 'utf8');
|
||||
|
||||
const Handlebars = require('handlebars');
|
||||
import mailjet from 'node-mailjet';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import Handlebars from 'handlebars';
|
||||
import { markdown2Html } from '../../services/markdown.js';
|
||||
import { getDirName } from '../../utils.js';
|
||||
const __dirname = getDirName();
|
||||
const template = fs.readFileSync(path.resolve(__dirname + '/notification/emailTemplate/template.hbs'), 'utf8');
|
||||
const emailTemplate = Handlebars.compile(template);
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
|
||||
/**
|
||||
* sends a new listing using MailJet
|
||||
* @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 }) => {
|
||||
export const send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
const { apiPublicKey, apiPrivateKey, receiver, from } = notificationConfig.find(
|
||||
(adapter) => adapter.id === 'mailJet'
|
||||
).fields;
|
||||
|
||||
const to = receiver
|
||||
.trim()
|
||||
.split(',')
|
||||
.map((r) => ({
|
||||
Email: r.trim(),
|
||||
}));
|
||||
|
||||
return mailjet
|
||||
.connect(apiPublicKey, apiPrivateKey)
|
||||
.post('send', { version: 'v3.1' })
|
||||
@@ -49,9 +38,8 @@ exports.send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
exports.config = {
|
||||
id: __filename.slice(__dirname.length + 1, -3),
|
||||
export const config = {
|
||||
id: 'mailjet',
|
||||
name: 'MailJet',
|
||||
description: 'MailJet is being used to send new listings via mail.',
|
||||
readme: markdown2Html('lib/notification/adapter/mailJet.md'),
|
||||
|
||||
@@ -1,26 +1,15 @@
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
const { getJob } = require('../../services/storage/jobStorage');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
/**
|
||||
* sends new listings to mattermost
|
||||
* @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 }) => {
|
||||
import { markdown2Html } from '../../services/markdown.js';
|
||||
import { getJob } from '../../services/storage/jobStorage.js';
|
||||
import fetch from 'node-fetch';
|
||||
export const send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
const { webhook, channel } = notificationConfig.find((adapter) => adapter.id === 'mattermost').fields;
|
||||
const job = getJob(jobKey);
|
||||
const jobName = job == null ? jobKey : job.name;
|
||||
|
||||
let message = `### *${jobName}* (${serviceName}) found **${newListings.length}** new listings:\n\n`;
|
||||
message += `| Title | Address | Size | Price |\n|:----|:----|:----|:----|\n`;
|
||||
message += newListings.map(
|
||||
(o) => `| [${o.title}](${o.link}) | ` + [o.address, o.size.replace(/2m/g, '$m^2$'), o.price].join(' | ') + ' |\n'
|
||||
);
|
||||
|
||||
return fetch(webhook, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -30,14 +19,8 @@ exports.send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 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),
|
||||
export const config = {
|
||||
id: 'mattermost',
|
||||
name: 'Mattermost',
|
||||
readme: markdown2Html('lib/notification/adapter/mattermost.md'),
|
||||
description: 'Fredy will send new listings to your mattermost team chat.',
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
const sgMail = require('@sendgrid/mail');
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
|
||||
/**
|
||||
* sends a new listing using SendGrid
|
||||
* @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 }) => {
|
||||
import sgMail from '@sendgrid/mail';
|
||||
import { markdown2Html } from '../../services/markdown.js';
|
||||
export const send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
const { apiKey, receiver, from, templateId } = notificationConfig.find((adapter) => adapter.id === 'sendGrid').fields;
|
||||
sgMail.setApiKey(apiKey);
|
||||
const msg = {
|
||||
@@ -28,9 +19,8 @@ exports.send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
};
|
||||
return sgMail.send(msg);
|
||||
};
|
||||
|
||||
exports.config = {
|
||||
id: __filename.slice(__dirname.length + 1, -3),
|
||||
export const config = {
|
||||
id: 'sendgrid',
|
||||
name: 'SendGrid',
|
||||
description: 'SendGrid is being used to send new listings via mail.',
|
||||
readme: markdown2Html('lib/notification/adapter/sendGrid.md'),
|
||||
|
||||
@@ -1,16 +1,7 @@
|
||||
const Slack = require('slack');
|
||||
import Slack from 'slack';
|
||||
import { markdown2Html } from '../../services/markdown.js';
|
||||
const msg = Slack.chat.postMessage;
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
|
||||
/**
|
||||
* sends a new listing to slack
|
||||
* @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 }) => {
|
||||
export const send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
const { token, channel } = notificationConfig.find((adapter) => adapter.id === 'slack').fields;
|
||||
return newListings.map((payload) =>
|
||||
msg({
|
||||
@@ -47,9 +38,8 @@ exports.send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
exports.config = {
|
||||
id: __filename.slice(__dirname.length + 1, -3),
|
||||
export const config = {
|
||||
id: 'slack',
|
||||
name: 'Slack',
|
||||
readme: markdown2Html('lib/notification/adapter/slack.md'),
|
||||
description: 'Fredy will send new listings to the slack channel of your choice..',
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
const Database = require('better-sqlite3');
|
||||
|
||||
/**
|
||||
* Stores data in a sqlite db in order to use the search results for later analytics
|
||||
* @param serviceName e.g immowelt
|
||||
* @param newListings an array with newly found listings
|
||||
* @param jobKey name of the current job that is being executed
|
||||
*/
|
||||
exports.send = ({ serviceName, newListings, jobKey }) => {
|
||||
import { markdown2Html } from '../../services/markdown.js';
|
||||
import Database from 'better-sqlite3';
|
||||
export const send = ({ serviceName, newListings, jobKey }) => {
|
||||
const db = new Database('db/listings.db');
|
||||
const fields = ['serviceName', 'jobKey', 'id', 'size', 'rooms', 'price', 'address', 'title', 'link', 'description'];
|
||||
db.prepare(`CREATE TABLE IF NOT EXISTS listing (${fields.join(' TEXT, ')} TEXT);`).run();
|
||||
@@ -23,9 +16,8 @@ exports.send = ({ serviceName, newListings, jobKey }) => {
|
||||
});
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
exports.config = {
|
||||
id: __filename.slice(__dirname.length + 1, -3),
|
||||
export const config = {
|
||||
id: 'sqlite',
|
||||
name: 'Sqlite',
|
||||
description: 'This adapter stores listings in a local sqlite3 database.',
|
||||
config: {},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
const { markdown2Html } = require('../../services/markdown');
|
||||
const { getJob } = require('../../services/storage/jobStorage');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
import { markdown2Html } from '../../services/markdown.js';
|
||||
import { getJob } from '../../services/storage/jobStorage.js';
|
||||
import fetch from 'node-fetch';
|
||||
const MAX_ENTITIES_PER_CHUNK = 8;
|
||||
const RATE_LIMIT_INTERVAL = 1010;
|
||||
/**
|
||||
@@ -16,32 +15,23 @@ const arrayChunks = (inputArray, perChunk) =>
|
||||
all[ch] = [].concat(all[ch] || [], one);
|
||||
return all;
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* sends new listings to telegram
|
||||
* @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 }) => {
|
||||
function shorten(str, len = 30) {
|
||||
return str.length > len ? str.substring(0, len) + '...' : str;
|
||||
}
|
||||
export const send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
const { token, chatId } = notificationConfig.find((adapter) => adapter.id === 'telegram').fields;
|
||||
const job = getJob(jobKey);
|
||||
const jobName = job == null ? jobKey : job.name;
|
||||
|
||||
//we have to split messages into chunk, because otherwise messages are going to become too big and will fail
|
||||
const chunks = arrayChunks(newListings, MAX_ENTITIES_PER_CHUNK);
|
||||
|
||||
const promises = chunks.map((chunk) => {
|
||||
let message = `<i>${jobName}</i> (${serviceName}) found <b>${newListings.length}</b> new listings:\n\n`;
|
||||
message += chunk.map(
|
||||
(o) =>
|
||||
`<a href="${o.link}"><b>${shorten(o.title.replace(/\*/g, ''), 45).trim()}</b></a>\n` +
|
||||
`<a href='${o.link}'><b>${shorten(o.title.replace(/\*/g, ''), 45).trim()}</b></a>\n` +
|
||||
[o.address, o.price, o.size].join(' | ') +
|
||||
'\n\n'
|
||||
);
|
||||
|
||||
/**
|
||||
* This is to not break the rate limit. It is to only send 1 message per second
|
||||
*/
|
||||
@@ -66,21 +56,10 @@ exports.send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
|
||||
}, RATE_LIMIT_INTERVAL);
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(promises);
|
||||
};
|
||||
|
||||
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),
|
||||
export const config = {
|
||||
id: 'telegram',
|
||||
name: 'Telegram',
|
||||
readme: markdown2Html('lib/notification/adapter/telegram.md'),
|
||||
description: 'Fredy will send new listings to your mobile, using Telegram.',
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
const fs = require('fs');
|
||||
import fs from 'fs';
|
||||
const path = './adapter';
|
||||
|
||||
/** Read every integration existing in ./adapter **/
|
||||
const adapter = fs
|
||||
.readdirSync('./lib/notification/adapter')
|
||||
.filter((file) => file.endsWith('.js'))
|
||||
.map((integPath) => require(`${path}/${integPath}`));
|
||||
const adapter = await Promise.all(
|
||||
fs
|
||||
.readdirSync('./lib/notification/adapter')
|
||||
.filter((file) => file.endsWith('.js'))
|
||||
.map(async (integPath) => await import(`${path}/${integPath}`))
|
||||
);
|
||||
|
||||
if (adapter.length === 0) {
|
||||
throw new Error('Please specify at least one notification provider');
|
||||
}
|
||||
|
||||
exports.send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
const findAdapter = (notificationAdapter) => {
|
||||
return adapter.find((a) => a.config.id === notificationAdapter.id);
|
||||
};
|
||||
export const send = (serviceName, newListings, notificationConfig, jobKey) => {
|
||||
//this is not being used in tests, therefore adapter are always set
|
||||
return notificationConfig
|
||||
.filter((notificationAdapter) => findAdapter(notificationAdapter) != null)
|
||||
.map((notificationAdapter) => findAdapter(notificationAdapter))
|
||||
.map((a) => a.send({ serviceName, newListings, notificationConfig, jobKey }));
|
||||
};
|
||||
|
||||
const findAdapter = (notificationAdapter) => {
|
||||
return adapter.find((a) => a.config.id === notificationAdapter.id);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user