Initial commit - SNGLPI
This commit is contained in:
commit
67dce4c1e6
29
.env.example
Normal file
29
.env.example
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Contents of the file: /servicenow-glpi-sync/servicenow-glpi-sync/.env.example
|
||||||
|
|
||||||
|
# This is an example of the environment variables needed for the application.
|
||||||
|
|
||||||
|
# ServiceNow API Configuration
|
||||||
|
SERVICENOW_URL=https://your-instance.service-now.com/api/now/table/
|
||||||
|
SERVICENOW_USERNAME=your_servicenow_username
|
||||||
|
SERVICENOW_PASSWORD=your_servicenow_password
|
||||||
|
|
||||||
|
# GLPI API Configuration
|
||||||
|
GLPI_URL=https://your-glpi-instance/apirest.php/
|
||||||
|
GLPI_APP_TOKEN=your_glpi_app_token
|
||||||
|
GLPI_USER_TOKEN=your_glpi_user_token
|
||||||
|
|
||||||
|
# Database Configuration
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_PORT=3306 # or 5432 for PostgreSQL
|
||||||
|
DB_USER=your_database_user
|
||||||
|
DB_PASSWORD=your_database_password
|
||||||
|
DB_NAME=your_database_name
|
||||||
|
|
||||||
|
# Logging Configuration
|
||||||
|
LOG_LEVEL=info
|
||||||
|
LOG_FILE_PATH=logs/app.log
|
||||||
|
ERROR_LOG_FILE_PATH=logs/error.log
|
||||||
|
|
||||||
|
# Other Configuration
|
||||||
|
PORT=3000
|
||||||
|
NODE_ENV=development
|
||||||
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
node_modules/
|
||||||
|
logs/*.log
|
||||||
|
.env
|
||||||
|
config/*.json
|
||||||
|
.DS_Store
|
||||||
|
*.tmp
|
||||||
80
README.md
Normal file
80
README.md
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# servicenow-glpi-sync/README.md
|
||||||
|
|
||||||
|
# ServiceNow and GLPI Sync
|
||||||
|
|
||||||
|
This project is designed to facilitate the integration between ServiceNow and GLPI, allowing for the synchronization of tickets between the two platforms. It utilizes Node.js and follows the MVC architecture pattern.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Prerequisites](#prerequisites)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Configuration](#configuration)
|
||||||
|
- [Running the Application](#running-the-application)
|
||||||
|
- [Endpoints](#endpoints)
|
||||||
|
- [Logging](#logging)
|
||||||
|
- [Contributing](#contributing)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Node.js (version 14 or higher)
|
||||||
|
- npm (Node Package Manager)
|
||||||
|
- PostgreSQL or MySQL database
|
||||||
|
- Access to ServiceNow and GLPI APIs
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Clone the repository:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/yourusername/servicenow-glpi-sync.git
|
||||||
|
cd servicenow-glpi-sync
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Install the dependencies:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Copy the `.env.example` file to `.env` and fill in the required environment variables:
|
||||||
|
|
||||||
|
```
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
- Update the `.env` file with your ServiceNow and GLPI API credentials, database connection details, and any other necessary configurations.
|
||||||
|
|
||||||
|
## Running the Application
|
||||||
|
|
||||||
|
To start the application, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
node server.js
|
||||||
|
```
|
||||||
|
|
||||||
|
The application will listen on the port specified in the `.env` file.
|
||||||
|
|
||||||
|
## Endpoints
|
||||||
|
|
||||||
|
- `POST /tickets/sync` - Synchronize tickets from ServiceNow to GLPI.
|
||||||
|
- `GET /tickets/:id` - Retrieve details of a specific ticket.
|
||||||
|
- `POST /tickets` - Create a new ticket in GLPI based on ServiceNow data.
|
||||||
|
- `PUT /tickets/:id` - Update an existing ticket in GLPI.
|
||||||
|
|
||||||
|
## Logging
|
||||||
|
|
||||||
|
The application uses Winston for logging. Logs are stored in the `logs` directory:
|
||||||
|
|
||||||
|
- `app.log` - Logs application events.
|
||||||
|
- `error.log` - Logs errors that occur during execution.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Contributions are welcome! Please open an issue or submit a pull request for any improvements or bug fixes.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License. See the LICENSE file for details.
|
||||||
28
config/databaseConfig.js
Normal file
28
config/databaseConfig.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const { Sequelize } = require('sequelize');
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
// Database connection configuration
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
dialect: process.env.DB_DIALECT || 'mysql', // Default to MySQL if not specified
|
||||||
|
logging: false, // Disable logging; set to console.log to enable
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a new Sequelize instance
|
||||||
|
const sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASSWORD, dbConfig);
|
||||||
|
|
||||||
|
// Test the database connection
|
||||||
|
const testConnection = async () => {
|
||||||
|
try {
|
||||||
|
await sequelize.authenticate();
|
||||||
|
console.log('Connection to the database has been established successfully.');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Unable to connect to the database:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Export the sequelize instance and the test connection function
|
||||||
|
module.exports = {
|
||||||
|
sequelize,
|
||||||
|
testConnection,
|
||||||
|
};
|
||||||
202
package-lock.json
generated
Normal file
202
package-lock.json
generated
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
{
|
||||||
|
"name": "servicenow-glpi-sync",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "servicenow-glpi-sync",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.21.1",
|
||||||
|
"dotenv": "^10.0.0",
|
||||||
|
"pg": "^8.7.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/axios": {
|
||||||
|
"version": "0.21.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
|
||||||
|
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.14.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/dotenv": {
|
||||||
|
"version": "10.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
|
||||||
|
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/follow-redirects": {
|
||||||
|
"version": "1.15.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||||
|
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"debug": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg": {
|
||||||
|
"version": "8.16.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz",
|
||||||
|
"integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"pg-connection-string": "^2.9.1",
|
||||||
|
"pg-pool": "^3.10.1",
|
||||||
|
"pg-protocol": "^1.10.3",
|
||||||
|
"pg-types": "2.2.0",
|
||||||
|
"pgpass": "1.0.5"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16.0.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"pg-cloudflare": "^1.2.7"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"pg-native": ">=3.0.1"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"pg-native": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-cloudflare": {
|
||||||
|
"version": "1.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz",
|
||||||
|
"integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"node_modules/pg-connection-string": {
|
||||||
|
"version": "2.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz",
|
||||||
|
"integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/pg-int8": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-pool": {
|
||||||
|
"version": "3.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz",
|
||||||
|
"integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"pg": ">=8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pg-protocol": {
|
||||||
|
"version": "1.10.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz",
|
||||||
|
"integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/pg-types": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"pg-int8": "1.0.1",
|
||||||
|
"postgres-array": "~2.0.0",
|
||||||
|
"postgres-bytea": "~1.0.0",
|
||||||
|
"postgres-date": "~1.0.4",
|
||||||
|
"postgres-interval": "^1.1.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pgpass": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"split2": "^4.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-array": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-bytea": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-date": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
|
||||||
|
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/postgres-interval": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"xtend": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/split2": {
|
||||||
|
"version": "4.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
||||||
|
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xtend": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
package.json
Normal file
18
package.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "servicenow-glpi-sync",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A Node.js application for integrating ServiceNow and GLPI.",
|
||||||
|
"main": "app.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node server.js",
|
||||||
|
"dev": "nodemon server.js",
|
||||||
|
"test": "echo \"No tests specified\" && exit 0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.21.1",
|
||||||
|
"dotenv": "^10.0.0",
|
||||||
|
"pg": "^8.7.1"
|
||||||
|
},
|
||||||
|
"author": "Your Name",
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
29
src/app.js
Normal file
29
src/app.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
const cors = require('cors');
|
||||||
|
const routes = require('./src/routes/index');
|
||||||
|
const { logger } = require('./utils/logger');
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
// Middleware setup
|
||||||
|
app.use(cors()); // Enable CORS for all routes
|
||||||
|
app.use(bodyParser.json()); // Parse JSON request bodies
|
||||||
|
app.use(bodyParser.urlencoded({ extended: true })); // Parse URL-encoded request bodies
|
||||||
|
|
||||||
|
// Logger middleware
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
logger.info(`${req.method} ${req.url}`);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Routes setup
|
||||||
|
app.use('/api', routes);
|
||||||
|
|
||||||
|
// Error handling middleware
|
||||||
|
app.use((err, req, res, next) => {
|
||||||
|
logger.error(err.message);
|
||||||
|
res.status(500).json({ error: 'Internal Server Error' });
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = app;
|
||||||
0
src/controllers/glpiController.js
Normal file
0
src/controllers/glpiController.js
Normal file
0
src/controllers/hubsoftController.js
Normal file
0
src/controllers/hubsoftController.js
Normal file
0
src/controllers/servicenowController.js
Normal file
0
src/controllers/servicenowController.js
Normal file
0
src/data/database.js
Normal file
0
src/data/database.js
Normal file
28
src/models/databaseModel.js
Normal file
28
src/models/databaseModel.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const { Sequelize } = require('sequelize');
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
// Database connection configuration
|
||||||
|
const dbConfig = {
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
dialect: process.env.DB_DIALECT || 'mysql', // Default to MySQL if not specified
|
||||||
|
logging: false, // Disable logging; enable for debugging
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a new Sequelize instance
|
||||||
|
const sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASSWORD, dbConfig);
|
||||||
|
|
||||||
|
// Test the database connection
|
||||||
|
const testConnection = async () => {
|
||||||
|
try {
|
||||||
|
await sequelize.authenticate();
|
||||||
|
console.log('Connection to the database has been established successfully.');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Unable to connect to the database:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Export the sequelize instance and the test function
|
||||||
|
module.exports = {
|
||||||
|
sequelize,
|
||||||
|
testConnection,
|
||||||
|
};
|
||||||
0
src/models/ticketGlpiModel.js
Normal file
0
src/models/ticketGlpiModel.js
Normal file
44
src/models/ticketSnModel.js
Normal file
44
src/models/ticketSnModel.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// src/models/ticketModel.js
|
||||||
|
|
||||||
|
const { DataTypes } = require('sequelize');
|
||||||
|
const db = require('./db');
|
||||||
|
|
||||||
|
// Define the Ticket model
|
||||||
|
const Ticket = db.define('Ticket', {
|
||||||
|
id: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
primaryKey: true,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
short_description: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: DataTypes.TEXT,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
priority: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
allowNull: true,
|
||||||
|
},
|
||||||
|
created_at: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: DataTypes.NOW,
|
||||||
|
},
|
||||||
|
updated_at: {
|
||||||
|
type: DataTypes.DATE,
|
||||||
|
allowNull: false,
|
||||||
|
defaultValue: DataTypes.NOW,
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
timestamps: false, // Disable automatic timestamps
|
||||||
|
});
|
||||||
|
|
||||||
|
// Export the Ticket model
|
||||||
|
module.exports = Ticket;
|
||||||
57
src/services/glpiService.js
Normal file
57
src/services/glpiService.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// src/services/glpiService.js
|
||||||
|
|
||||||
|
const axios = require('axios');
|
||||||
|
const { GLPI_URL, GLPI_APP_TOKEN, GLPI_USER_TOKEN } = process.env;
|
||||||
|
|
||||||
|
// Function to create a ticket in GLPI
|
||||||
|
const createTicketInGLPI = async (ticketData) => {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`${GLPI_URL}/ticket`, ticketData, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'App-Token': GLPI_APP_TOKEN,
|
||||||
|
'Authorization': `Bearer ${GLPI_USER_TOKEN}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Error creating ticket in GLPI: ${error.message}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to update a ticket in GLPI
|
||||||
|
const updateTicketInGLPI = async (ticketId, ticketData) => {
|
||||||
|
try {
|
||||||
|
const response = await axios.put(`${GLPI_URL}/ticket/${ticketId}`, ticketData, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'App-Token': GLPI_APP_TOKEN,
|
||||||
|
'Authorization': `Bearer ${GLPI_USER_TOKEN}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Error updating ticket in GLPI: ${error.message}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to fetch ticket details from GLPI
|
||||||
|
const getTicketFromGLPI = async (ticketId) => {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`${GLPI_URL}/ticket/${ticketId}`, {
|
||||||
|
headers: {
|
||||||
|
'App-Token': GLPI_APP_TOKEN,
|
||||||
|
'Authorization': `Bearer ${GLPI_USER_TOKEN}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Error fetching ticket from GLPI: ${error.message}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
createTicketInGLPI,
|
||||||
|
updateTicketInGLPI,
|
||||||
|
getTicketFromGLPI
|
||||||
|
};
|
||||||
0
src/services/hubsoftService.js
Normal file
0
src/services/hubsoftService.js
Normal file
56
src/services/servicenowService.js
Normal file
56
src/services/servicenowService.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// src/services/servicenowService.js
|
||||||
|
|
||||||
|
const axios = require('axios');
|
||||||
|
const { logError, logInfo } = require('../utils/logger');
|
||||||
|
|
||||||
|
// Configurações da API do ServiceNow
|
||||||
|
const serviceNowConfig = {
|
||||||
|
baseURL: process.env.SERVICENOW_BASE_URL,
|
||||||
|
auth: {
|
||||||
|
username: process.env.SERVICENOW_USERNAME,
|
||||||
|
password: process.env.SERVICENOW_PASSWORD,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Função para buscar um ticket pelo ID
|
||||||
|
const getTicketById = async (ticketId) => {
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`/api/now/table/ticket/${ticketId}`, serviceNowConfig);
|
||||||
|
logInfo(`Ticket ${ticketId} fetched successfully.`);
|
||||||
|
return response.data.result;
|
||||||
|
} catch (error) {
|
||||||
|
logError(`Error fetching ticket ${ticketId}: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Função para criar um novo ticket no ServiceNow
|
||||||
|
const createTicket = async (ticketData) => {
|
||||||
|
try {
|
||||||
|
const response = await axios.post('/api/now/table/ticket', ticketData, serviceNowConfig);
|
||||||
|
logInfo(`Ticket created successfully with ID: ${response.data.result.sys_id}`);
|
||||||
|
return response.data.result;
|
||||||
|
} catch (error) {
|
||||||
|
logError(`Error creating ticket: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Função para atualizar um ticket existente
|
||||||
|
const updateTicket = async (ticketId, ticketData) => {
|
||||||
|
try {
|
||||||
|
const response = await axios.put(`/api/now/table/ticket/${ticketId}`, ticketData, serviceNowConfig);
|
||||||
|
logInfo(`Ticket ${ticketId} updated successfully.`);
|
||||||
|
return response.data.result;
|
||||||
|
} catch (error) {
|
||||||
|
logError(`Error updating ticket ${ticketId}: ${error.message}`);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Exporta as funções para uso em outros módulos
|
||||||
|
module.exports = {
|
||||||
|
getTicketById,
|
||||||
|
createTicket,
|
||||||
|
updateTicket,
|
||||||
|
};
|
||||||
0
src/services/syncService.js
Normal file
0
src/services/syncService.js
Normal file
39
src/utils/logger.js
Normal file
39
src/utils/logger.js
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
const winston = require('winston');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
// Create a logger instance with specified settings
|
||||||
|
const logger = winston.createLogger({
|
||||||
|
level: 'info',
|
||||||
|
format: winston.format.combine(
|
||||||
|
winston.format.timestamp(),
|
||||||
|
winston.format.json()
|
||||||
|
),
|
||||||
|
transports: [
|
||||||
|
// Log to a file for application events
|
||||||
|
new winston.transports.File({ filename: path.join(__dirname, '../../logs/app.log') }),
|
||||||
|
// Log to a file for error events
|
||||||
|
new winston.transports.File({ filename: path.join(__dirname, '../../logs/error.log'), level: 'error' }),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// If not in production, log to the console as well
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
logger.add(new winston.transports.Console({
|
||||||
|
format: winston.format.simple(),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility function to log errors
|
||||||
|
const logError = (error) => {
|
||||||
|
logger.error(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Utility function to log info messages
|
||||||
|
const logInfo = (message) => {
|
||||||
|
logger.info(message);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
logError,
|
||||||
|
logInfo,
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user