{"id":23916871,"url":"https://github.com/syahrulbhudif/vexora-api","last_synced_at":"2025-06-30T02:07:36.759Z","repository":{"id":260825800,"uuid":"874060036","full_name":"SyahrulBhudiF/Vexora-Api","owner":"SyahrulBhudiF","description":"Vexora is a mobile application that provides personalized Spotify music recommendations based on facial emotion recognition","archived":false,"fork":false,"pushed_at":"2024-12-20T20:35:06.000Z","size":30279,"stargazers_count":17,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-12T09:59:44.970Z","etag":null,"topics":["docker","docker-compose","fiber","golang","imagekit","jwt-authentication","otp-verification","postgresql","redis","spotify"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SyahrulBhudiF.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-10-17T07:26:51.000Z","updated_at":"2025-05-16T03:39:48.000Z","dependencies_parsed_at":"2024-11-02T21:19:43.231Z","dependency_job_id":"2625b10e-bc7d-43dd-96f6-467559e1bc08","html_url":"https://github.com/SyahrulBhudiF/Vexora-Api","commit_stats":null,"previous_names":["syahrulbhudif/vexora-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SyahrulBhudiF/Vexora-Api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SyahrulBhudiF%2FVexora-Api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SyahrulBhudiF%2FVexora-Api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SyahrulBhudiF%2FVexora-Api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SyahrulBhudiF%2FVexora-Api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SyahrulBhudiF","download_url":"https://codeload.github.com/SyahrulBhudiF/Vexora-Api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SyahrulBhudiF%2FVexora-Api/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262697277,"owners_count":23349894,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-compose","fiber","golang","imagekit","jwt-authentication","otp-verification","postgresql","redis","spotify"],"created_at":"2025-01-05T12:14:44.618Z","updated_at":"2025-06-30T02:07:36.732Z","avatar_url":"https://github.com/SyahrulBhudiF.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vexora API\n\nVexora is a mood-based music recommendation system that uses facial emotion detection to suggest personalized music\nplaylists. The system leverages CNN for emotion detection.\n![Desktop - 6](https://github.com/user-attachments/assets/d13f70af-e420-43a9-80e1-605d7dde7d3c)\n\n## Database Schema\n\n![img.png](schema.png)\n\n## 🎯 Features\n\n- 👤 User authentication and profile management\n- 😊 Facial emotion detection using CNN\n- 🎵 Mood-based music recommendations\n- 📝 Music history tracking\n- 🎼 Playlist management\n\n## 🎭 Supported Mood Categories\n\n- Happy 😊\n- Sad 😢\n- Angry 😠\n- Neutral/Calm 😐\n\n## TechStack\n\n- Fiber Go\n- PostgreSQL\n- Redis\n- ImageKit\n\n## 🚀 Getting Started\n\n### Run Localy\n\n```\ndocker compose watch\n```\n\n### Authentication\n\nThe API uses JWT Bearer token authentication. Include your token in the Authorization header:\n\n```\nAuthorization: Bearer \u003cyour_token\u003e\n```\n\n## 📋 API Endpoints\n\n### Authentication\n\n#### 1. Register New User\n\n```http\nPOST /register\n```\n\n**Request Body:**\n\n```json\n{\n  \"name\": \"John Doe\",\n  \"email\": \"john@example.com\",\n  \"username\": \"john_doe\",\n  \"password\": \"********\"\n}\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": true,\n  \"message\": \"register success!\",\n  \"data\": {\n    \"id\": 1,\n    \"profile_picture\": \"https://example.com/default.jpg\",\n    \"file_id\": \"abc123\",\n    \"name\": \"John Doe\",\n    \"email\": \"john@example.com\",\n    \"username\": \"john_doe\",\n    \"created_at\": \"2024-01-01T00:00:00Z\"\n  }\n}\n```\n\n**Error Response (400):**\n\n```json\n{\n  \"success\": false,\n  \"shouldNotify\": true,\n  \"message\": \"username or email already exists\",\n  \"data\": null\n}\n```\n\n#### 2. Login\n\n```http\nPOST /login\n```\n\n**Request Body:**\n\n```json\n{\n  \"username\": \"john_doe\",\n  \"password\": \"********\"\n}\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": true,\n  \"message\": \"login success!\",\n  \"data\": {\n    \"access_token\": \"eyJhbGciOiJIUzI1NiIs...\",\n    \"refresh_token\": \"eyJhbGciOiJIUzI1NiIs...\"\n  }\n}\n```\n\n**Error Response (401):**\n\n```json\n{\n  \"success\": false,\n  \"shouldNotify\": true,\n  \"message\": \"invalid username or password\",\n  \"data\": null\n}\n```\n\n#### 3. Logout\n\n```http\nPOST /logout\n```\n\n**Request Body:**\n\n```json\n{\n  \"refresh_token\": \"eyJhbGciOiJIUzI1NiIs...\"\n}\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": false,\n  \"message\": \"logout success!\",\n  \"data\": null\n}\n```\n\n#### 4. Refresh Token\n\n```http\nPOST /refresh\n```\n\n**Request Body:**\n\n```json\n{\n  \"refresh_token\": \"eyJhbGciOiJIUzI1NiIs...\"\n}\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": false,\n  \"message\": \"refresh token success!\",\n  \"data\": {\n    \"access_token\": \"eyJhbGciOiJIUzI1NiIs...\",\n    \"refresh_token\": \"eyJhbGciOiJIUzI1NiIs...\"\n  }\n}\n```\n\n5. Send OTP\n\n```http request\nPOST /send-otp\n```\n\n**Request Body:**\n\n```json\n{\n  \"email\": \"example@gmail.com\"\n}\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": true,\n  \"message\": \"OTP sent successfully!\",\n  \"data\": null\n}\n```\n\n6. Verify OTP\n\n```http request\nPOST /verify-email\n```\n\n**Request Body:**\n\n```json\n{\n  \"email\": \"example@gmail.com\",\n  \"otp\": \"123456\"\n}\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": true,\n  \"message\": \"email verification success!\",\n  \"data\": null\n}\n```\n\n7. Reset Password\n\n```http request\nPOST /reset-password\n```\n\n**Request Body:**\n\n```json\n{\n  \"email\": \"example@gmail.com\",\n  \"otp\": \"123456\",\n  \"new_password\": \"newpassword\"\n}\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": true,\n  \"message\": \"password reset success!\",\n  \"data\": null\n}\n```\n\n**Error Response (401):**\n\n```json\n{\n  \"success\": false,\n  \"shouldNotify\": true,\n  \"message\": \"invalid or expired refresh token\",\n  \"data\": null\n}\n```\n\n### User Management\n\n#### 1. Get User Profile\n\n```http\nGET /user\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": false,\n  \"message\": \"get profile success!\",\n  \"data\": {\n    \"uuid\": 1,\n    \"profile_picture\": \"https://example.com/profile.jpg\",\n    \"file_id\": \"abc123\",\n    \"name\": \"John Doe\",\n    \"email\": \"john@example.com\",\n    \"username\": \"john_doe\",\n    \"created_at\": \"2024-01-01T00:00:00Z\"\n  }\n}\n```\n\n#### 2. Update Profile\n\n```http\nPUT /user\n```\n\n**Request Body (multipart/form-data):**\n\n- `name`: \"John Doe Updated\"\n- `username`: \"john_doe_updated\"\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": true,\n  \"message\": \"update profile success!\",\n  \"data\": {\n    \"uuid\": 1,\n    \"profile_picture\": \"https://example.com/profile.jpg\",\n    \"file_id\": \"abc123\",\n    \"name\": \"John Doe\",\n    \"email\": \"john@example.com\",\n    \"username\": \"john_doe\",\n    \"created_at\": \"2024-01-01T00:00:00Z\"\n  }\n}\n```\n\n#### 3. Change Password\n\n```http\nPUT /user/change-password\n```\n\n**Request Body:**\n\n```json\n{\n  \"previous_password\": \"currentpass123\",\n  \"new_password\": \"newpass123\"\n}\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": true,\n  \"message\": \"change password success!\",\n  \"data\": null\n}\n```\n\n**Error Response (400):**\n\n```json\n{\n  \"success\": false,\n  \"shouldNotify\": true,\n  \"message\": \"current password is incorrect\",\n  \"data\": null\n}\n```\n\n#### 4. Update Profile Picture\n\n```http\nPUT /user/profile-picture\n```\n\n**Request Body (multipart/form-data):**\n\n- `image`: [File Upload]\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": true,\n  \"message\": \"upload image success!\",\n  \"data\": null\n}\n```\n\n### Music History\n\n#### 1. Get All History\n\n```http\nGET /history\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": false,\n  \"message\": \"history retrieved successfully!\",\n  \"data\": [\n    {\n      \"uuid\": \"abc123\",\n      \"user_id\": 1,\n      \"mood\": \"happy\",\n      \"created_at\": \"2024-01-01T00:00:00Z\"\n    }\n  ]\n}\n```\n\n#### 2. Get Music History By ID\n\n```http\nGET /music/{id}\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": false,\n  \"message\": \"history entry found!\",\n  \"data\": [\n    {\n      \"uuid\": \"2c187355-9a61-4b22-b40b-c4636a01ad52\",\n      \"created_at\": \"2024-11-30T18:36:23.872084Z\",\n      \"history_uuid\": \"aaea230a-6846-438f-b566-3ff9f1256622\",\n      \"id\": \"3puYuuZ7lmlTjIgXBOT01k\",\n      \"playlist_name\": \"Pilihanku\",\n      \"artist\": \"MALIQ \u0026 D'Essentials\",\n      \"path\": \"https://open.spotify.com/track/3puYuuZ7lmlTjIgXBOT01k\",\n      \"thumbnail\": \"https://i.scdn.co/image/ab67616d0000b2734b274090757829034de581df\"\n    }\n  ]\n}\n```\n\n#### 3. Get Most Mood\n\n```http\nGET /history/most-mood\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": false,\n  \"message\": \"success\",\n  \"data\": {\n    \"mood\": \"happy\"\n  }\n}\n```\n\n### Spotify API\n\n#### 1. Get Random Recommendations\n\n```http\nGET /spotify/random-playlist\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": false,\n  \"message\": \"random playlist retrieved successfully!\",\n  \"data\": {\n    \"music\": [\n      {\n        \"id\": \"0lYBSQXN6rCTvUZvg9S0lU\",\n        \"playlist_name\": \"Let Me Love You\",\n        \"artist\": \"DJ Snake\",\n        \"path\": \"https://open.spotify.com/track/0lYBSQXN6rCTvUZvg9S0lU\",\n        \"thumbnail\": \"https://i.scdn.co/image/ab67616d0000b273212d776c31027c511f0ee3bc\"\n      }\n    ]\n  }\n}\n```\n\n#### 2. Get Track By ID\n\n```http\nGET /spotify/{id}\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": false,\n  \"message\": \"success\",\n  \"data\": {\n    \"music\": [\n      {\n        \"id\": \"6TQghwJw3Sh8h9mTcV5BR7\",\n        \"playlist_name\": \"Sewanee Mountain Catfight\",\n        \"artist\": \"Old Crow Medicine Show\",\n        \"path\": \"https://open.spotify.com/track/6TQghwJw3Sh8h9mTcV5BR7\",\n        \"thumbnail\": \"https://i.scdn.co/image/ab67616d0000b27366990be0a5b69a9a1ca8b882\"\n      }\n    ]\n  }\n}\n```\n\n#### 3. Search Tracks\n\n```http\nGET /spotify/search?search={query}\n```\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": false,\n  \"message\": \"success\",\n  \"data\": {\n    \"music\": [\n      {\n        \"id\": \"0PtJbtW50jcvvswNPn3QGd\",\n        \"playlist_name\": \"Serana\",\n        \"artist\": \"For Revenge\",\n        \"path\": \"https://open.spotify.com/track/0PtJbtW50jcvvswNPn3QGd\",\n        \"thumbnail\": \"https://i.scdn.co/image/ab67616d0000b27346f02ffc0922f939ed0fd53f\"\n      },\n      }\n    }\n```\n\n### Mood Detection \u0026 Recommendations\n\n#### Detect Mood and Get Recommendations\n\n```http\nPOST /mood-detection\n```\n\n**Request Body (multipart/form-data):**\n\n- `user_id`: 1\n- `image`: [Selfie Image File]\n\n**Success Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"shouldNotify\": false,\n  \"message\": \"mood detected successfully!\",\n  \"data\": {\n    \"detected_mood\": \"happy\",\n    \"music\": [\n      {\n        \"id\": \"daskd2312opdask\",\n        \"name\": \"Happy Track\",\n        \"artist\": \"Happy Artist\",\n        \"path\": \"https://open.spotify.com/track/123abc\",\n        \"thumbnail\": \"https://example.com/album/cover1\"\n      }\n    ],\n    \"created_at\": \"timestamp\"\n  }\n}\n```\n\n## 📊 Status Codes\n\n- `200`: Success\n- `400`: Bad Request\n- `401`: Unauthorized\n- `404`: Not Found\n- `500`: Internal Server Error\n\n## 🔒 Security Notes\n\n1. All sensitive routes require JWT authentication\n2. Refresh tokens are valid for 30 days\n3. File uploads are restricted to PNG, JPEG, and JPG formats\n4. Profile pictures are processed and stored securely\n\n## 📱 Technical Requirements\n\n- Supports image upload for facial detection\n- Handles multipart/form-data for file uploads\n- Processes JSON for standard requests\n- Returns standardized JSON responses\n\n## 📞 Contact \u0026 Support\n\nFor support or inquiries, please contact:\n\n- Email: syahrul4w@gmail.com\n\n## ⚠️ Rate Limiting\n\nPlease note that API endpoints may have rate limiting applied. Contact support for specific limitations.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsyahrulbhudif%2Fvexora-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsyahrulbhudif%2Fvexora-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsyahrulbhudif%2Fvexora-api/lists"}