The main purpose of Pipedeals is listen to Pipedrive deal's won
update event, prepare buy order data, save it on a database and finally send it to Bling's API. Also expose two resources, opportunities
that are buy orders sent to Bling and reports
that aggregates opportunities by day and amount (sum of products' prices in that day).
Easy peasy lemon squeezy:
$ yarn
Or:
$ npm install
Was installed and configured the
eslint
andprettier
to keep the code clean and patterned.
The application uses just one database: MongoDB. For the fastest setup is recommended to use docker-compose, you just need to up all services:
$ docker-compose up -d
Store opportunities sent to Bling, reports and the users utilized by application. If for any reason you would like to create a MongoDB container instead of use docker-compose
, you can do it by running the following command:
$ docker run --name pipedeals-mongo -d -p 27017:27017 mongo
In this file you may configure your MongoDB and Redis database connection, JWT settings, the environment, app's port, url to documentation (this will be returned with error responses, see error section) and Pipedrive and Bling's keys. Rename the .env.example
in the root directory to .env
then just update with your settings.
key | description | default |
---|---|---|
APP_PORT | Port number where the app will run. | 3333 |
NODE_ENV | App environment. | development |
JWT_SECRET | An alphanumeric random string. Used to create signed tokens. | - |
JWT_EXPIRATION_TIME | How long time will be the token valid. See jsonwebtoken repo for more information. | 7d |
MONGO_URL | MongoDB's server url. | mongodb://mongo:27017/pipedeals |
PIPEDRIVE_API_TOKEN | Pipedrive API's token. See How to find the API token for more information. | - |
PIPEDRIVE_DOMAIN_NAME | Pipedrive domain name (company name), see How to get the company domain. | - |
PIPEDRIVE_USER and PIPEDRIVE_PWD | Basic auth's user and password (respectively). Used to ensure that the deal's event is coming from Pipedrive webhook, see Webhook for more information about it. | - |
BLING_API_KEY | Bling's api key. See Bling's API key section. | - |
DOCS_URL | An url to docs where users can find more information about the app's internal code errors. | https://github.com/DiegoVictor/pipedeals#errors-reference |
Instructions to configure the Pipedrive's webhook, custom fields and products.
Create a webhook to listen updated.deal
event, remember to set a user (PIPEDRIVE_USER
) and password (PIPEDRIVE_PWD
), for more information see:
The webhook's url should be something like:
https://<your-domain>/v1/pipedrive/events
If you are running the application local I recommend you to use ngrok to export a url to access the application. (e.g.
https://25752eff.ngrok.io/v1/pipedrive/events
)
Bling make some fields mandatory, they are: Payment Method
and Supplier
, this application makes Parcels
mandatory too. To create custom fields to deal on Pipedrive see Adding Custom Fields.
Just create a field named Parcels, must be a number.
Supplier, must be free text field.
Payment Method, must be unique option field.
Payments methods that not exists in Bling will be created before the opportunity be sent to it.
Also you need to create a product and attach to deal, fill only the mandatory fields is enough (Product name
and Unit price
). For more information see Adding New Products.
Remember to link the product to deals, see how to do it in this article How can I link products to a deal?.
To get a Bling's API key, go to user list:
Then create a new user, select USUÁRIO API
, copy the API key
(maybe be necessary click on GERAR
), configure the permissions, save the user, paste the API key
in the BLING_API_KEY
key in the .env
file.
The following permissions are necessary to the API user:
permissions | menu | description |
---|---|---|
Contas Contábeis , Notas Fiscais , NFCe and Pedidos de Venda |
Vendas | Enable just one is enough. Allow to get lists and create payment methods. |
Pedidos de Compra |
Suprimentos | Allow to create new buy orders. |
To start up the app run:
$ yarn start
Or:
$ npm run start
Then create new deals, make it pass through your funnel, etc, when you mark that deal as won
the magic will happens :)
Instead of only throw a simple message and HTTP Status Code this API return friendly errors:
{
"statusCode": 401,
"error": "Unauthorized",
"message": "You are not authorized!",
"code": 741,
"docs": "https://github.com/DiegoVictor/pipedeals#errors-reference"
}
Errors are implemented with @hapi/boom. As you can see a url to errors docs are returned too. To configure this url update the
DOCS_URL
key from.env
file. In the next sub section (Errors Reference) you can see the errorscode
description.
code | message | description |
---|---|---|
531 | An error occurred while trying to retrieve the deal from Pipedrive | An error occurred during the request to get the deal in Pipedrive API, look the details key for more information. |
532 | An error occurred while trying to retrieve the deal's custom fields from Pipedrive | The request to get custom fields from Pipedrive API throw an error. Look the details key for more information. |
533 | An error occurred while trying to retrieve the deal's products from Pipedrive | Occurred an error while trying to retrieve deal's products, in details key will be more information about the error. |
534 | An error occurred while trying to save the order at Bling | Something goes wrong when tried to send the opportunity to Bling. There are two steps here: payment method verification and buy order creation. For more information see the details key in the response. |
244 | Report not found | The id sent not references an existing report in the database. |
344 | Opportunity not found | The id sent not references an existing opportunity in the database. |
440 | User not exists | The email sent not references an existing user in the database. |
450 | User and/or password not match | User and/or password is incorrect. |
140 | Email already in use | Already exists an user with the same email. |
640 | Missing authorization | Pipedrive's webhook is not sending the Basic auth's user and password. |
641 | You are not authorized! | Pipedrive's webhook is sending wrong Basic credentials. |
740 | Missing authorization token | The Bearer Token was not sent. |
741 | You are not authorized! | The Bearer Token provided is invalid or expired. |
All the routes with pagination returns 10 records per page, to navigate to other pages just send the page
query parameter with the number of the page.
- To get the third page of opportunities:
GET http://localhost:3333/v1/opportunities?page=3
Also in the headers of every route with pagination the Link
header is returned with links to first
, last
, next
and prev
(previous) page.
<http://localhost:3333/v1/opportunities?page=7>; rel="last",
<http://localhost:3333/v1/opportunities?page=4>; rel="next",
<http://localhost:3333/v1/opportunities?page=1>; rel="first",
<http://localhost:3333/v1/opportunities?page=2>; rel="prev"
See more about this header in this MDN doc: Link - HTTP.
Another header returned in routes with pagination, this bring the total records amount.
All reports and oppotunities routes expect a Bearer Token in an Authorization
header.
You can see these routes in the routes section.
GET http://localhost:3333/v1/reports?page=1 Authorization: Bearer <token>
To achieve this token you just need authenticate through the
/sessions
route and it will return thetoken
key with a valid Bearer Token.
A simple versioning was made. Just remember to set after the host
the /v1/
string to your requests.
GET http://localhost:3333/v1/reports
route | HTTP Method | pagination | params | description | auth method |
---|---|---|---|---|---|
/sessions |
POST | ❌ | Body with user's email and password . |
Authenticates user, return a Bearer Token and user's id and email. | ❌ |
/users |
POST | ❌ | Body with user's email and password . |
Create new users. | ❌ |
/pipedrive/events |
POST | ❌ | Body with event's event , current.id and current.status . |
Receive Piedrive deal's won event. | Basic |
/reports |
GET | ✔️ | page query parameter. |
List reports. | Bearer |
/reports/:id |
GET | ❌ | :id of the report. |
Return one report. | Bearer |
/reports/:id/opportunities |
GET | ✔️ | :id of the report and page query parameter. |
List report's opportunities. | Bearer |
/reports/:report_id/opportunities/:id |
GET | ❌ | :report_id of the report and :id of the opportunity. |
Return one report's opportunity. | Bearer |
Routes with
Bearer
as auth method expect anAuthorization
header. See Bearer Token section for more information.Basic
authentication is a base64 encoding ofPIPEDRIVE_USER
andPIPEDRIVE_PWD
joined by a:
, but you should not make manual requests to this endpoint (this will be responsability of the Pipedrive's webhook).
POST /session
Request body:
{
"email": "diegovictorgonzaga@gmail.com",
"password": "123456"
}
POST /users
Request body:
{
"email": "diegovictorgonzaga@gmail.com",
"password": "123456"
}
POST /pipedrive/events
Request body:
{
"current": {
"id": 1,
"status": "won"
},
"event": "updated.deal"
}
Jest was the choice to test the app, to run:
$ yarn test
Or:
$ npm run test
You can see the coverage report inside tests/coverage
. They are automatically created after the tests run.