Skip to content

Commit

Permalink
* [Fix] Reviewed and Fix the remaining code
Browse files Browse the repository at this point in the history
  • Loading branch information
mohammadhb committed Apr 27, 2021
1 parent cba9f11 commit a76e616
Show file tree
Hide file tree
Showing 39 changed files with 392 additions and 423 deletions.
71 changes: 39 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Messenger

## A Simple Facebook Bot Messenger

<img alt="Sample demo of The Messenger Bot" src="./example.gif" width="270" height="480">
Expand All @@ -20,35 +21,35 @@

### Technical Features:

Here are addential **Key Technical Features** implemented into this project.
- [x] **Repository Pattern :** Implemented a single integrated DAO API that is exposed to serve the different perpose of operating on data.
Here are additional **Key Technical Features** implemented into this project.
- [x] **Repository Pattern :** Implemented a single integrated DAO API that is exposed to serve the different purpose of operating on data.
- [x] **Service Discovery Pattern and Being Service-Based :** This Bot is based on a variety of Services that is Implemented in this platform by default ( e.g. Register, Weather). Also developer can add Any Services with minimum effort by just Adding the config and their service-plugin into the Service section.
- [x] **Caching Data :** For performance perposes, I used Redis to cache the data it became much more faster with caching methods ( From 100ms to 4ms On my Personal System )
- [x] **Caching Data :** For performance purposes, I used Redis to cache the data it became more faster with caching methods ( From 100ms to 4ms On my Personal System )
- [x] **Automatic Database Configuration Selection :** You can select your own Database you just need to change the **DATABASE** variable in **.env** and you're good to go!

## Directory Layout

```
root
├── config # Configurations
├── constants # Constant Variables
├── controllers # Router Controllers
├── repository # DAO Repository
├── middlewares # Express middlewares
├── databases # Database Core
| |── mongodb # Mongoose for Mongo DB
| |── postgresql # Sequelize for Postgresql
| └── redis # Redis Client for Caching
├── router # Routes and Router
| |──conversation # Facebook Webhooks routes
| └── message # Messages routes
├── requests # Third party libraries/services
├── services # Service Discovery and Services
| |── user # User Service
| |── weather # Weather Service
| └── example # An Example Service to be added by you
├── tests # Tests
└── utils # Utility and Handy Functions
├── config # Configurations
├── constants # Constant Variables
├── controllers # Router Controllers
├── repository # DAO Repository
├── middlewares # Express middlewares
├── databases # Database Core
| |── mongodb # Mongoose for MongoDB
| |── postgresql # Sequelize for Postgresql
| └── redis # Redis Client for Caching
├── router # Routes and Router
| |──conversation # Facebook Webhooks routes
| └── message # Messages routes
├── requests # Third party libraries/services
├── services # Service Discovery and Services
| |── user # User Service
| |── weather # Weather Service
| └── example # An Example Service to be added by you
├── tests # Tests
└── utils # Utility and Handy Functions
```

### Getting Started:
Expand All @@ -68,13 +69,15 @@ To get the project running first start to clone the project and then follow the
### Installation:

- Install required packages

```shell script
npm i
```

### Configuration

- Copy and modify .env file for Environment Variables

```shell script
cp .env.example .env
```
Expand Down Expand Up @@ -106,13 +109,13 @@ Configuration Key / Category | Title | Description
`POSTGRESQL_TEST_DATABASE_PORT` | Database Port | Database Port
`POSTGRESQL_TEST_DATABASE_USER` | Database Username | Database Username
`POSTGRESQL_TEST_DATABASE_PASS` | Database Password | Database Password
**Mongo DB** | - | -
**MongoDB** | - | -
`MONGODB_DATABASE_NAME` | Database Name | The database you are connecting to
`MONGODB_DATABASE_HOST` | Database Host | The IP or name of the host that database is on it
`MONGODB_DATABASE_PORT` | Database Port | Database Port
`MONGODB_DATABASE_USER` | Database Username | Database Username
`MONGODB_DATABASE_PASS` | Database Password | Database Password
**Mongo DB Test Environment** | - | -
**MongoDB Test Environment** | - | -
`MONGODB_TEST_DATABASE_NAME` | Database Name | The database you are connecting to
`MONGODB_TEST_DATABASE_HOST` | Database Host | The IP or name of the host that database is on it
`MONGODB_TEST_DATABASE_PORT` | Database Port | Database Port
Expand All @@ -131,42 +134,46 @@ Configuration Key / Category | Title | Description
`REDIS_TEST_DATABASE_USER` | Database Username | Database Username
`REDIS_TEST_DATABASE_PASS` | Database Password | Database Password

DATABASE

### Usage

Run the project
- Run the project

```shell script
npm start
```

For the development perposes
- For the development purposes

```shell script
npm i -g nodemon
npm run dev
```

For the deployment perposes
- For the deployment purposes

```shell script
docker-compose up -d
```


### Tests

Run the tests
- Run the tests

```shell script
npm test
```

For coverage run
- For coverage run

```shell script
npm run coverage
```

### Documents

For generate and serve documents
- For generate and serve documents

```shell script
npm run doc
```
1 change: 1 addition & 0 deletions config/api_key.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exports.weather_api_key = process.env.WEATHER_SERVICE_API_KEY;
2 changes: 2 additions & 0 deletions config/bot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
exports.verification_token = process.env.MESSENGER_BOT_VERIFICATION_TOKEN;
exports.access_token = process.env.MESSENGER_BOT_ACESS_TOKEN;
2 changes: 1 addition & 1 deletion config/common.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = {
node_env: process.env.NODE_ENV,
};
};
4 changes: 1 addition & 3 deletions config/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,10 @@ const redisConfig =
options: {},
};

console.log(process.env.DATABASE);

module.exports = {
database,
config: {
temporary: redisConfig,
persistant: database === "POSTGRESQL" ? postgresqlConfig : mongodbConfig,
},
};
};
6 changes: 4 additions & 2 deletions config/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module.exports = {
database: require("./database"),
common: require("./common"),
request: require("./request")
};
request: require("./request"),
bot: require("./bot"),
api_key: require("./api_key"),
};
9 changes: 6 additions & 3 deletions config/request.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
const { access_token } = require("./bot");
const { weather_api_key } = require("./api_key");

exports.messenger = {
config: {
baseURL: "https://graph.facebook.com/v7.0",
Expand All @@ -6,7 +9,7 @@ exports.messenger = {
},
responseType: "json",
},
access_token: process.env.MESSENGER_BOT_ACCESS_TOKEN,
access_token,
};

exports.weather = {
Expand All @@ -17,5 +20,5 @@ exports.weather = {
},
responseType: "json",
},
api_key: process.env.WEATHER_SERVICE_API_KEY,
};
api_key: weather_api_key,
};
2 changes: 0 additions & 2 deletions constants/bot.js

This file was deleted.

6 changes: 3 additions & 3 deletions constants/cache_keys.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
MESSAGE:"MESSAGE",
USER:"USER",
};
MESSAGE: "MESSAGE",
USER: "USER",
};
3 changes: 1 addition & 2 deletions constants/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
module.exports = {
HTTP_CODES: require("./http_codes"),
BOT: require("./bot"),
CACHE_KEYS: require("./cache_keys"),
};
};
50 changes: 22 additions & 28 deletions controller/conversation.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,66 @@
const {Message,User} = require("../repository");
const { Message, User } = require("../repository");
const mainService = require("../services");
const {
bot: { verification_token },
} = require("../config");

/*
A Preset Webhook for Bot to be fetch messages
*/
async function event(request,response){

async function event(request, response) {
const body = request.body;

if (body.object === "page") {

for (let entry of body.entry){

for (let entry of body.entry) {
const event = entry.messaging[0];
response.status(200).send("EVENT_RECEIVED");

//Save any incoming messages
new Message({
recipientId:event.recipient.id,
senderId:event.sender.id,
messageId:event.message.mid,
message:event.message.text,
timestamp:event.timestamp
recipientId: event.recipient.id,
senderId: event.sender.id,
messageId: event.message.mid,
message: event.message.text,
timestamp: event.timestamp,
}).create();

let user = await new User().getBySenderId(event.sender.id);
if(!user){
if (!user) {
user = await new User({
sender_id:event.sender.id
sender_id: event.sender.id,
}).create();
}

//Sending User to Main Service
await mainService(user,event.message.text,event.message.quick_reply?event.message.quick_reply.payload:null);

await mainService(
user,
event.message.text,
event.message.quick_reply ? event.message.quick_reply.payload : null
);
}

} else {

response.sendStatus(404);

}

}

/*
A Preset Webhook for Bot to be verified
*/
function verification(request,response) {

// Your verify token. Should be a random string.
const VERIFY_TOKEN = process.env.MESSENGER_BOT_VERIFICATION_TOKEN;

function verification(request, response) {
let mode = request.query["hub.mode"];
let token = request.query["hub.verify_token"];
let challenge = request.query["hub.challenge"];

if (mode && token) {
if (mode === "subscribe" && token === VERIFY_TOKEN) {
if (mode === "subscribe" && token === verification_token) {
response.status(200).send(challenge);
} else {
response.sendStatus(403);
}
}

}

module.exports = {
event,
verification
};
verification,
};
Loading

0 comments on commit a76e616

Please sign in to comment.