├── .idea
├── misc.xml
├── vcs.xml
├── .gitignore
├── modules.xml
└── nodejs-webhook.iml
├── database
└── index.js
├── .gitignore
├── app
├── controllers
│ ├── index.js
│ └── paymentController.js
└── models
│ └── payment.js
├── index.js
├── client-notification
├── package.json
├── model.js
└── index.js
├── package.json
└── readme.md
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/database/index.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose")
2 |
3 | mongoose.connect("mongodb://localhost:27017/webhookjs", {
4 | useNewUrlParser: true,
5 | useUnifiedTopology: true,
6 | })
7 | mongoose.Promise = global.Promise
8 | module.exports = mongoose
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store*
3 | Icon?
4 | ._*
5 |
6 | # Windows
7 | Thumbs.db
8 | ehthumbs.db
9 | Desktop.ini
10 |
11 | # Linux
12 | .directory
13 | *~
14 |
15 |
16 | # npm
17 | node_modules
18 | package-lock.json
19 | *.log
20 | *.gz
21 | client-notification/node-modules/*
--------------------------------------------------------------------------------
/app/controllers/index.js:
--------------------------------------------------------------------------------
1 | const fs = require("fs")
2 | const path = require("path")
3 |
4 | module.exports = (app) => {
5 | fs.readdirSync(__dirname)
6 | .filter((file) => file.indexOf(".") != 0 && file !== "index.js")
7 | .forEach((file) => require(path.resolve(__dirname, file))(app))
8 | }
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/nodejs-webhook.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const bodyParser = require('body-parser');
3 | const morgan = require('morgan');
4 |
5 | const app = express();
6 |
7 | app.use(morgan("dev"));
8 | app.use(bodyParser.urlencoded({ extended: false }))
9 | app.use(bodyParser.json());
10 |
11 | require("./app/controllers/index")(app)
12 |
13 | app.listen(9000, () => {
14 | console.log("Node-Webhook has been stated at: http://localhost:9000");
15 | })
--------------------------------------------------------------------------------
/client-notification/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client-notification",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "body-parser": "^1.19.0",
14 | "express": "^4.17.1",
15 | "mongoose": "^5.9.22",
16 | "morgan": "^1.10.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nodejs-webhook",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "body-parser": "^1.19.0",
14 | "express": "^4.17.1",
15 | "fs": "0.0.1-security",
16 | "mongoose": "^5.9.22",
17 | "morgan": "^1.10.0",
18 | "node-webhooks": "^1.4.2",
19 | "path": "^0.12.7"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/models/payment.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("../../database")
2 |
3 | const PaymentSchema = new mongoose.Schema({
4 | title: {
5 | type: String,
6 | required: true,
7 | },
8 | value: {
9 | type: Number,
10 | required: true
11 | },
12 | status: {
13 | type: Boolean,
14 | default: false,
15 | },
16 | createdAt: {
17 | type: Date,
18 | default: Date.now,
19 | },
20 | })
21 |
22 | const Payment = mongoose.model("Payment", PaymentSchema)
23 |
24 | module.exports = Payment
--------------------------------------------------------------------------------
/client-notification/model.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose')
2 |
3 | const PaymentSchema = new mongoose.Schema({
4 | title: {
5 | type: String,
6 | required: true,
7 | },
8 | value: {
9 | type: Number,
10 | required: true
11 | },
12 | status: {
13 | type: Boolean,
14 | default: false,
15 | },
16 | createdAt: {
17 | type: Date,
18 | default: Date.now,
19 | },
20 | })
21 |
22 | const Payment = mongoose.model("Payment", PaymentSchema)
23 |
24 | module.exports = Payment
--------------------------------------------------------------------------------
/client-notification/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const bodyParser = require('body-parser');
3 | const morgan = require('morgan');
4 | const mongoose = require('mongoose');
5 |
6 | const Model = require('./model');
7 |
8 | const app = express();
9 |
10 | app.use(morgan("dev"));
11 | app.use(bodyParser.urlencoded({ extended: false }))
12 | app.use(bodyParser.json());
13 |
14 | mongoose.connect('mongodb://localhost:27017/webhookjs-client', { useNewUrlParser: true, useUnifiedTopology: true });
15 |
16 | app.post('/webhook-client', async(req, res) => {
17 | console.log('Inside Callback hook', req.body)
18 | const { data } = req.body
19 | await Model.create(data)
20 | return res.status(200).end();
21 | });
22 |
23 | app.listen(8005, () => {
24 | console.log("Client has been stated at: http://localhost:8005");
25 | })
--------------------------------------------------------------------------------
/app/controllers/paymentController.js:
--------------------------------------------------------------------------------
1 | const express = require("express")
2 | const Payment = require('../models/payment')
3 | const webhooks = require('node-webhooks');
4 |
5 | const router = express.Router();
6 |
7 | router.get("/", async(req, res) => {
8 | try {
9 | const paymentsList = await Payment.find({})
10 | return res.send({ data: paymentsList })
11 | } catch (err) {
12 | return res.status(400).send({ message: "payment list failed", error: err })
13 | }
14 | })
15 |
16 | router.post("/", async(req, res) => {
17 | try {
18 | const payment = await Payment.create(req.body)
19 | if(payment){
20 | const hooks = registerHooks();
21 | hooks.trigger('callback_hook', { msg: "new payment created", data: payment});
22 | }
23 | return res.send({ payment })
24 | } catch (err) {
25 | return res.status(400).send({ message: "payment create failed", error: err })
26 | }
27 | })
28 |
29 | const registerHooks = () => {
30 | return new webhooks({
31 | db: {
32 | 'callback_hook': ['http://localhost:8005/webhook-client']
33 | }
34 | });
35 | }
36 |
37 | module.exports = (app) => app.use("/payments", router)
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Projeto Webhook em NodeJS
2 |
3 | O projeto em questão para fins de estudo tem por objetivo
4 | a construção de uma API de pagamentos que
5 | deve notificar um determinado cliente (também construído em NodeJS).
6 |
7 | Esta notificação deve ocorrer quando um novo pagamento for adicionado
8 | ao projeto utilizando o endpoint:
9 | ```
10 | POST /payments HTTP/1.1
11 | Host: localhost:9000
12 | Content-Type: application/json
13 |
14 | {
15 | "title": "Cobranca simples volume 1",
16 | "value": 59.90
17 | }
18 | ```
19 |
20 | O cliente que representa um outro sistema deve receber
21 | o recurso criado e armazenar no banco de dados
22 | da aplicação cliente (representada pela base `webhookjs-client`).
23 |
24 | As informações serão repassadas no formato abaixo
25 | para o cliente a ser notificado:
26 |
27 | ```
28 | {
29 | "msg": "new payment created",
30 | "data": {
31 | "status": false,
32 | "_id": "5f07524eea6d6524e892a629",
33 | "title": "Cobranca simples volume 1",
34 | "value": 59.9,
35 | "createdAt": "2020-07-09T17:22:22.970Z",
36 | "__v": 0
37 | }
38 | }
39 | ```
40 |
41 | ## Diretórios e Arquivos
42 |
43 | - Para rodar a aplicação da API: `node index.js`.
44 | - A aplicação cliente está dentro de client-notification.
45 | - Para rodar a aplicação cliente: `cd client-notification` e `node index.js`.
46 | - Configurações de banco de dados da API estão em database.
47 | - Demais arquivos como controllers e rotas estão alocados dentro de app.
48 |
49 |
50 | ## Conclusão
51 | Este repositorio está sendo mantido para estudos caso tenha alguma duvida favor entrar em contato pelo leandro.souara.web@gmail.com
--------------------------------------------------------------------------------