feat(app): add email sending
This commit is contained in:
parent
8438708050
commit
74b87a91b6
23
index.ts
23
index.ts
@ -1,26 +1,25 @@
|
|||||||
import express from 'express';
|
|
||||||
import cors from 'cors';
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import apiRouter from './src/api';
|
|
||||||
import bodyParser from 'body-parser';
|
import bodyParser from 'body-parser';
|
||||||
|
import cors from 'cors';
|
||||||
|
import express from 'express';
|
||||||
|
|
||||||
|
import apiRouter from './src/api';
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const port = 5000;
|
const port = 5000;
|
||||||
|
|
||||||
app.use(cors())
|
app.use(cors());
|
||||||
app.use('/static', express.static(path.join(__dirname, 'static')))
|
app.use('/static', express.static(path.join(__dirname, 'static')));
|
||||||
// app.use(express.static(path.join(__dirname, 'static')))
|
|
||||||
// @ts-ignore
|
|
||||||
app.use(bodyParser.raw({ type: 'application/soap+xml' }));
|
app.use(bodyParser.raw({ type: 'application/soap+xml' }));
|
||||||
app.use(bodyParser.json({ limit: '20mb' }));
|
app.use(bodyParser.json({ limit: '20mb' }));
|
||||||
// app.use(express.urlencoded({ extended: false }));
|
|
||||||
// @ts-ignore
|
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
app.use('/api', apiRouter)
|
app.use('/api', apiRouter);
|
||||||
|
|
||||||
|
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
console.log(`Arkids backend app start on port ${port}`);
|
console.log(`Arkids backend app start on port ${port}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
"body-parser": "1.20.2",
|
"body-parser": "1.20.2",
|
||||||
"cors": "2.8.5",
|
"cors": "2.8.5",
|
||||||
"express": "4.18.2",
|
"express": "4.18.2",
|
||||||
|
"nodemailer": "^6.9.3",
|
||||||
"nodemon": "2.0.22",
|
"nodemon": "2.0.22",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
"typescript": "5.0.4",
|
"typescript": "5.0.4",
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import servicesRouter from './routes/services';
|
|||||||
import statisticsRouter from './routes/statistic';
|
import statisticsRouter from './routes/statistic';
|
||||||
import storiesRouter from './routes/stories';
|
import storiesRouter from './routes/stories';
|
||||||
import textRouter from './routes/text';
|
import textRouter from './routes/text';
|
||||||
|
import orderRouter from './routes/order';
|
||||||
|
|
||||||
const apiRouter = express.Router();
|
const apiRouter = express.Router();
|
||||||
|
|
||||||
@ -27,5 +28,6 @@ apiRouter.use(ApiRoute.STORIES, storiesRouter);
|
|||||||
apiRouter.use(ApiRoute.STATISTIC_INFO, statisticsRouter);
|
apiRouter.use(ApiRoute.STATISTIC_INFO, statisticsRouter);
|
||||||
apiRouter.use(ApiRoute.QUESTS, questRouter);
|
apiRouter.use(ApiRoute.QUESTS, questRouter);
|
||||||
apiRouter.use(ApiRoute.IMAGE, imageRouter);
|
apiRouter.use(ApiRoute.IMAGE, imageRouter);
|
||||||
|
apiRouter.use(ApiRoute.ORDER, orderRouter);
|
||||||
|
|
||||||
export default apiRouter;
|
export default apiRouter;
|
||||||
|
|||||||
93
src/api/routes/order/controller.ts
Normal file
93
src/api/routes/order/controller.ts
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import { Request, Response } from 'express';
|
||||||
|
|
||||||
|
import mailer from '../../../services/mailer';
|
||||||
|
import { formatter } from '../../../utils';
|
||||||
|
|
||||||
|
export const getNewOrder = async (req: Request, res: Response) => {
|
||||||
|
// @ts-ignore
|
||||||
|
const {
|
||||||
|
name,
|
||||||
|
page,
|
||||||
|
phoneNumber,
|
||||||
|
rate,
|
||||||
|
type,
|
||||||
|
} = req.body;
|
||||||
|
|
||||||
|
const getSubject = () => {
|
||||||
|
switch (type) {
|
||||||
|
case 'callback':
|
||||||
|
return 'Заявка на звонок';
|
||||||
|
|
||||||
|
case 'newRate':
|
||||||
|
return 'Заявка на комбо';
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 'Нужно связаться';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getHtml = () => {
|
||||||
|
const getPageTitle = () => {
|
||||||
|
if (page === 'birthday') {
|
||||||
|
return 'День рождения';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page === 'graduation') {
|
||||||
|
return 'Выпускной';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'Выездной праздник';
|
||||||
|
};
|
||||||
|
switch (type) {
|
||||||
|
case 'callback':
|
||||||
|
return `
|
||||||
|
<p>Имя: <b>${name}</b></p>
|
||||||
|
<p>Телефон: <b>${phoneNumber}</b></p>
|
||||||
|
`;
|
||||||
|
|
||||||
|
case 'newRate':
|
||||||
|
return `
|
||||||
|
<p>Имя: <b>${name}</b></p>
|
||||||
|
<p>Телефон: <b>${phoneNumber}</b></p>
|
||||||
|
<p>Страница: <b>${getPageTitle()}</b></p>
|
||||||
|
<p>Пакет: <b>${rate.title}</b></p>
|
||||||
|
<p>Цена пакета: <b>${formatter.format(rate.price || rate.pricePerPerson)}</b></p>
|
||||||
|
`;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 'ошибка';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const info = await mailer.sendMail({
|
||||||
|
from: '"Arkids Test" <ksv741-test@yandex.ru>',
|
||||||
|
html: getHtml(),
|
||||||
|
subject: getSubject(),
|
||||||
|
to: 'ksv741-test@yandex.ru',
|
||||||
|
});
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'callback':
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('Отправлено письмо с просьбой перезвонить: %s', info.messageId);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'newRate':
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('Отправлено письмо с заявкой на комбо: %s', info.messageId);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('Отправлено письмо: %s', info.messageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
.then(() => res.status(200).json({}))
|
||||||
|
.catch((e) => {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('Mailer error', e);
|
||||||
|
});
|
||||||
|
};
|
||||||
9
src/api/routes/order/index.ts
Normal file
9
src/api/routes/order/index.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import express, { Request, Response } from 'express';
|
||||||
|
|
||||||
|
import { getNewOrder } from './controller';
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.post('/', (req: Request, res: Response) => getNewOrder(req, res));
|
||||||
|
|
||||||
|
export default router;
|
||||||
@ -125,6 +125,7 @@ export enum ApiRoute {
|
|||||||
STATISTIC_INFO = '/statistic',
|
STATISTIC_INFO = '/statistic',
|
||||||
STORIES = '/stories',
|
STORIES = '/stories',
|
||||||
TEXT = '/text',
|
TEXT = '/text',
|
||||||
|
ORDER = '/order',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const servicesList: { [k in SERVICE]: ServiceType } = {
|
export const servicesList: { [k in SERVICE]: ServiceType } = {
|
||||||
|
|||||||
14
src/services/mailer/index.ts
Normal file
14
src/services/mailer/index.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// @ts-ignore
|
||||||
|
import nodemailer from 'nodemailer';
|
||||||
|
|
||||||
|
const mailer = nodemailer.createTransport({
|
||||||
|
auth: {
|
||||||
|
pass: 'vytjrxwzqcnmbpja',
|
||||||
|
user: 'ksv741-test@yandex.ru',
|
||||||
|
},
|
||||||
|
host: 'smtp.yandex.ru',
|
||||||
|
port: 465,
|
||||||
|
secure: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default mailer;
|
||||||
5
src/utils/index.ts
Normal file
5
src/utils/index.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export const formatter = new Intl.NumberFormat('ru-RU', {
|
||||||
|
currency: 'RUB',
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
style: 'currency',
|
||||||
|
});
|
||||||
BIN
yarn-offline-mirror/nodemailer-6.9.3.tgz
Normal file
BIN
yarn-offline-mirror/nodemailer-6.9.3.tgz
Normal file
Binary file not shown.
@ -1669,6 +1669,11 @@ negotiator@0.6.3:
|
|||||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
||||||
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
|
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
|
||||||
|
|
||||||
|
nodemailer@^6.9.3:
|
||||||
|
version "6.9.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.3.tgz#e4425b85f05d83c43c5cd81bf84ab968f8ef5cbe"
|
||||||
|
integrity sha512-fy9v3NgTzBngrMFkDsKEj0r02U7jm6XfC3b52eoNV+GCrGj+s8pt5OqhiJdWKuw51zCTdiNR/IUD1z33LIIGpg==
|
||||||
|
|
||||||
nodemon@2.0.22:
|
nodemon@2.0.22:
|
||||||
version "2.0.22"
|
version "2.0.22"
|
||||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.22.tgz#182c45c3a78da486f673d6c1702e00728daf5258"
|
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.22.tgz#182c45c3a78da486f673d6c1702e00728daf5258"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user