This is an personnal project.
| Url | Version | Contact | Terms of Service | License |
|---|---|---|---|---|
| 127.0.0.1:8080/ | 1.0.0 | area@epitech.eu | http://localhost:8080/api-docs | Apache 2.0 |
The goal of this project is to make a action-reaction web app to gather areas from multiple triggers APIs.
The project is organized in three parts:
- The client_mobile is located under
flutter/ - The client_web is located under
client/ - The back-server is located under
server/
- Docker
- Server:
- JavaScript
- Express-JS
- Eslint
- Swagger
- DB:
- Postgresql
- Client Web:
- React
- React-bootstrap
- TypeScript
- Mobile:
- flutter
- Docker 🐳
- Android SDK / Xcode
- Clone the project:
git clone https://github.com/XriM/area
Then run the following commands to start the app.
./script.shOr
docker-compose --env-file ./backend/.env up --buildAPI (back-end):
Client mobile:
Client web:
- services:
- youtube
- outlook / onedrive
- weather
- steam
- trello
- bourse/crypto
- github
- discord
- actions reactions:
- email (action) ✅
- meteo ville (action) ✅ OK
- crypto (action) ✅ OK
- joueurs steam (action) ✅ OK
- onedrive (action) ✅
- github (action) ✅ OK
- youtube (action) ✅ OK
- reddit (action) ✅ OK
- carte trello (reaction) ✅
- outlook send (reaction) ✅
- discord webhook (reaction) ✅ OK
- github (reaction) ✅
- connexion:
- basic auth
- oauth2 → google
{
"email": "test.area@outlook.fr",
"username": "areaTest",
"password": "mypassword"
}- Response when signup request is successfull (Status code: 200):
{
"message": "Account created!"
}
- Response when signup request failed because an email address is already in use (Status code: 400):
{
"message": "Email address already in use!"
}- Response when signup request failed for other reasons (missing a field, wrong email format... Status code: 400):
{
"message": "Failed to create an account!"
}{
"email": "test.area@outlook.fr",
"password": "mypassword"
}- Response when user successfully logged in (status code: 200):
{
"token": "cjhdbfb76579yazdbhzebfd",
"message": "Successfully logged in!",
"username": "username"
}- Response when user password is wrong (status code: 400):
{
"message": "Wrong password!"
}- Response when email doesn’t exist (status code: 400):
{
"message": "Email doesn't exist!"
}- Response when signin request failed for other reasons (missing a field, wrong email format... Status code: 400):
{
"message": "Failed to log in!"
}{
"Authorization": "Bearer cjhdbfb76579yazdbhzebfd"
}- Response when request succeded
{
"message": "Successfully logged out!"
}- Response when request failed because no token was passed (status code: 401):
{
"message": "You need to signin to an account!"
}- Response when request failed because the token is invalid or expired (status code: 498):
{
"message": "Invalid token!"
}{
"Authorization": "Bearer cjhdbfb76579yazdbhzebfd"
}- Response when request suceeded (status code: 200):
{
"users": [
{
"username": "maxime"
},
{
"username": "david"
},
{
"username": "briann"
},
{
"username": "jeff"
},
]
}- Response when request failed because no token was passed (status code: 401):
{
"message": "You need to signin to an account!"
}- Response when request failed because the token is invalid or expired (status code: 498):
{
"message": "Invalid token!"
}{
"Authorization": "Bearer cjhdbfb76579yazdbhzebfd"
}- Response when request succeeded
{
"username": "david",
"email": "david@area.com"
}- Response when request failed because no token was passed (status code: 401):
{
"message": "You need to signin to an account!"
}- Response when request failed because the token is invalid or expired (status code: 498):
{
"message": "Invalid token!"
}{
"Authorization": "Bearer cjhdbfb76579yazdbhzebfd"
}{
"email": "test@area.fr"
}{
"password": "myNewPassword"
}{
"username": "myNewUsername"
}{
"email": "my.newEmail@area.fr",
"password": "myNewPassword",
"username": "myNewUsername"
}- Response when request succeeded
{
"message": "User profile successfully modified!"
}- Response when no fields are specified (status code: 401):
{
"message": "No fields specified!"
}- Response when request failed because no token was passed (status code: 401):
{
"message": "You need to signin to an account!"
}- Response when request failed because the token is invalid or expired (status code: 498):
{
"message": "Invalid token!"
}{
"Authorization": "Bearer cjhdbfb76579yazdbhzebfd"
}- Response when request succeded
{
"message": "Successfully deleted user"
}- Response when request failed because no token was passed (status code: 401):
{
"message": "You need to signin to an account!"
}- Response when request failed because the token is invalid or expired (status code: 498):
{
"message": "Invalid token!"
}{
"Authorization": "Bearer cjhdbfb76579yazdbhzebfd"
}- Response when request is successfull (status code: 200)
{
"services": [
{
"name": "AccuWeather"
},
{
"name": "Google Calendar"
},
{
"name": "Gmail"
}
]
}- Response when request failed because no token was passed (status code: 401):
{
"message": "You need to signin to an account!"
}- Response when request failed because the token is invalid or expired (status code: 498):
{
"message": "Invalid token!"
}{
"Authorization": "Bearer cjhdbfb76579yazdbhzebfd"
}- Response when request is successfull (status code: 200)
{
"name": "Google Calendar",
"actions_id": [
{
"id": 1
},
{
"id": 4
},
{
"id": 5
},
],
"reactions_id": [
{
"id": 3
},
{
"id": 6
},
{
"id": 8
},
],
"token": "fenfnzef987vdgzefbehfl"
}- Response when request failed because no token was passed (status code: 401):
{
"message": "You need to signin to an account!"
}- Response when request failed because the token is invalid or expired (status code: 498):
{
"message": "Invalid token!"
}{
"Authorization": "Bearer cjhdbfb76579yazdbhzebfd"
}{
"token": "dvcdzcdjzlcb678edhzfjdknzed"
}- Response when request succeeded (status code: 200)
{
"message": "Service token successfully loaded!"
}- Response when request failed because no token was passed (status code: 401):
{
"message": "You need to signin to an account!"
}- Response when request failed because the token is invalid or expired (status code: 498):
{
"message": "Invalid token!"
}{
"Authorization": "Bearer cjhdbfb76579yazdbhzebfd"
}{
"token": "dvcdzcdjzlcb678edhzfjdknzed"
}- Response when request succeeded (status code: 200)
{
"message": "Service token successfully loaded!"
}- Response when request failed because no token was passed (status code: 401):
{
"message": "You need to signin to an account!"
}- Response when request failed because the token is invalid or expired (status code: 498):
{
"message": "Invalid token!"
}{
"Authorization": "Bearer cjhdbfb76579yazdbhzebfd"
}{
"Authorization": "Bearer <token>"
}a
- Response when request succeeded (status code: 200):
{
"areas": [
{
"id": 1,
"name": "Area 1",
"action": {
"id": 6,
"name": "Steam players changed"
},
"reaction": {
"id": 1,
"name": "Send email"
}
},
{
"id": 2,
"name": "Area 2",
"action": {
"id": 6,
"name": "Steam players changed"
},
"reaction": {
"id": 1,
"name": "Send email"
}
}
]- Response when request failed because no token was passed (status code: 401):
{
"message": "You need to signin to an account!"
}- Response when request failed because the token is invalid or expired (status code: 498):
{
"message": "Invalid token!"
}{
"Authorization": "Bearer chbzhfbzef"
}{
"action_id": 1,
"reaction_id": 1,
"name": "area name",
"config":{
"param1": "value1",
"param2": "value2"
}
}- Response when request succeeded (status code: 200)
{
"message": "Area successfully created!"
}- Response when request failed because no token was passed (status code: 401):
{
"message": "You need to signin to an account!"
}- Response when request failed because the token is invalid or expired (status code: 498):
{
"message": "Invalid token!"
}service Table
| ID PRIMARY KEY | NAME VARCHAR |
|---|---|
action Table
| ID PRIMARY KEY | NAME VARCHAR |
|---|---|
reaction Table
| ID PRIMARY KEY | NAME VARCHAR | |
|---|---|---|
area Table
| ID PRIMARY KEY | ACTION_ID (Foreign key) | REACTION_ID (Foreign Key) | |
|---|---|---|---|
service_reaction Table
| ID PRIMARY KEY | SERVICE_ID FOREIGN KEY(Service) | TRIGGER_ID FOREIGN KEY(Trigger) |
|---|---|---|
users Table
| ID PRIMARY KEY | EMAIL VARCHAR | USERNAME VARCHAR | PASSWORD? VARCHAR |
|---|---|---|---|
user_service table
| ID PRIMARY KEY | USER_ID FOREIGN KEY(User) | SERVICE_ID FOREIGN KEY(Service) | TOKEN? VARCHAR |
|---|---|---|---|
user_area Table
| ID PRIMARY KEY | USER_ID FOREIGN KEY(User) | TRIGGER_ID FOREIGN KEY(Trigger) | CONFIG VARCHAR (json) |
|---|---|---|---|
Weather (action):
{
"city": "Ville_à_surveiller"
"temp_min": "température_min_à_surveiller"
"temp_max": "température_max_à_surveiller"
}Crypto (action):
{
"crypto": "pair_à_surveiller"
"value_min": "valeur_mini_à_surveiller"
"value_max": "valeur_max_à_surveiller"
}owGitHub (action):
au lieu d’envoyer le token il faut envoyer le code à “POST /users/:username/services/:id” avec ce body:
{
"token": "code"
} ensuite pour le JSon config:
{
"github": "repo_a_surveiller"
"owner": "owner_du_repo"
}GitHub (reaction):
{
"github": "repo_pour_issue"
"owner": "owner_du_repo"
"title": "titre_de_lissue"
"message": "message_de_lissue"
}Outlook (action):
{
"email": "email.à.surveiller@epitech.eu"
}Outlook (reaction):
{
"to": [
"briann.gerbaux@epitech.eu",
"david.nikolic@epitech.eu"
],
"cc": [
"maxime.sarres@epitech.eu",
"jefferson.guiot@epitech.eu"
],
"subject": "my subject (objet)"
"message": "Mon message (text)"
}OneDrive (action):
{
"drive": "le dossier onedrive que tu veux surveiller (vide si tu veux surveiller le root)"
}Trello (reaction):
{
"idBoard": "azertytreza",
"idList": "this format : 61813589d337958524eec066",
"name": "title",
"description": "message",
}Discord (reaction):
exemple d’URL webhook: “https://discord.com/api/webhooks/947890664128016516/4lI_Gz_Fr5gU0pafNv9639HoxlhQWFuhoQ2BsKRugdVpSq8eggIMH2xw3sZsm-hC4ZlV”
l’id du webhook: “947890664128016516” (première partie du lien)
token du webhook: “4lI_Gz_Fr5gU0pafNv9639HoxlhQWFuhoQ2BsKRugdVpSq8eggIMH2xw3sZsm-hC4ZlV” (deuxième partie du lien)
{
"discord": "webhook_url_id",
"url_token": "webhook_url_token"
}Steam (action):
{
"steam": "app_id",
"players_min": "players_min_for_trigger"
"players_max": "players_max_for_trigger"
}Youtube (action):
Rien faut juste que l’user se connecte
Reddit (action):
{
"subreddit": "r/france",
}id: 1, name: 'Received email' id: 2, name: 'Youtube subscribers changed' id: 3, name: 'Subreddit subscriber' id: 4, name: 'Github repo starred' id: 5, name: 'Weather changed' id: 6, name: 'Steam players changed' id: 7, name: 'CryptoCurrency price changed' id: 8, name 'File added'
id: 1, name: 'Send email' id: 2, name: 'Add trello card' id: 3, name: 'Send Git issue' id: 4, name: 'Send Discord message’
id: 1, name, 'Trello id: 2, name: 'Reddit' id: 3, name: 'Discord' id: 4, name: 'Weather' id: 5, name: 'Crypto' id: 6, name: 'GitHub' id: 7, name: 'Outlook' id: 8, name: 'Steam' id: 9, name: 'Youtube'