Files
backend_fiesta/controllers/utilsController.go
2026-05-25 11:52:26 +05:30

315 lines
7.3 KiB
Go

package controllers
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"nearle/models"
"nearle/services"
"net/http"
"strconv"
"github.com/gofiber/fiber/v2"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
type UtilsController struct {
utilsService services.UtilsService
}
func NewUtilsController(utilsService services.UtilsService) *UtilsController {
return &UtilsController{utilsService: utilsService}
}
const (
fcmURL = "https://fcm.googleapis.com/v1/projects/nearle-gear/messages:send"
scope = "https://www.googleapis.com/auth/firebase.messaging"
serviceAcc = "nearle-gear-firebase-adminsdk-l9oha-23ca3b3609.json" // Path to your service account JSON
)
var client *http.Client
func (ctl *UtilsController) GetAppTypes(c *fiber.Ctx) error {
tag := c.Query("tag")
result, err := ctl.utilsService.GetApptypes(tag)
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
"code": http.StatusInternalServerError,
"message": err.Error(),
"status": false,
})
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}
func (ctl *UtilsController) NotifyUser(c *fiber.Ctx) error {
var body struct {
Token string `json:"token"`
Notification models.FcmNotification `json:"notification"`
Data map[string]string `json:"data"`
}
if err := c.BodyParser(&body); err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"code": http.StatusBadRequest,
"message": fmt.Sprintf("Error parsing request body: %v", err),
"status": false,
})
}
err := ctl.utilsService.SendNotification(body.Token, body.Notification, body.Data)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"code": http.StatusInternalServerError,
"message": fmt.Sprintf("Error sending notification: %v", err),
"status": false,
})
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "FCM message sent successfully!",
"status": true,
})
}
func (ctl *UtilsController) GetSubcategories(c *fiber.Ctx) error {
mid, _ := strconv.Atoi(c.Query("moduleid"))
cid, _ := strconv.Atoi(c.Query("categoryid"))
result, err := ctl.utilsService.GetSubcategories(mid, cid)
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
"code": http.StatusInternalServerError,
"message": err.Error(),
"status": false,
})
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}
func (ctl *UtilsController) GetApplocations(c *fiber.Ctx) error {
aid, err := strconv.Atoi(c.Query("applocationid"))
if err != nil {
return c.Status(http.StatusBadRequest).JSON(fiber.Map{
"code": http.StatusBadRequest,
"message": "Invalid applocationid",
"status": false,
})
}
result, err := ctl.utilsService.GetApplocations(aid)
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
"code": http.StatusInternalServerError,
"message": err.Error(),
"status": false,
})
}
return c.JSON(fiber.Map{
"status": true,
"code": http.StatusOK,
"message": "Successful",
"details": result,
})
}
func (ctl *UtilsController) GetApplocationConfig(c *fiber.Ctx) error {
aid, err := strconv.Atoi(c.Query("applocationid"))
if err != nil {
return c.Status(http.StatusBadRequest).JSON(fiber.Map{
"code": http.StatusBadRequest,
"message": "Invalid applocationid",
"status": false,
})
}
result, err := ctl.utilsService.GetApplocationConfig(aid)
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
"code": http.StatusInternalServerError,
"message": err.Error(),
"status": false,
})
}
return c.JSON(fiber.Map{
"status": true,
"code": http.StatusOK,
"message": "Successful",
"details": result,
})
}
type Notification struct {
Title string `json:"title"`
Body string `json:"body"`
}
type FCMRequestBody struct {
Message struct {
Notification Notification `json:"notification"`
Token string `json:"token"`
} `json:"message"`
}
func GetClientFromServiceAccount() (*http.Client, error) {
data, err := ioutil.ReadFile(serviceAcc)
if err != nil {
return nil, fmt.Errorf("failed to read service account file: %v", err)
}
config, err := google.JWTConfigFromJSON(data, scope)
if err != nil {
return nil, fmt.Errorf("failed to parse service account JSON: %v", err)
}
client := config.Client(oauth2.NoContext)
return client, nil
}
func sendFCMMessage(token, title, body string) error {
if client == nil {
var err error
client, err = GetClientFromServiceAccount()
if err != nil {
return fmt.Errorf("failed to get client: %v", err)
}
}
notification := Notification{
Title: title,
Body: body,
}
fcmRequest := FCMRequestBody{}
fcmRequest.Message.Notification = notification
fcmRequest.Message.Token = token
requestBody, err := json.Marshal(fcmRequest)
if err != nil {
return err
}
req, err := http.NewRequest("POST", fcmURL, bytes.NewBuffer(requestBody))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
bodyBytes, _ := ioutil.ReadAll(resp.Body)
return fmt.Errorf("failed to send message: %s", string(bodyBytes))
}
return nil
}
func (ctl *UtilsController) NotifyAdmin(c *fiber.Ctx) error {
body := new(struct {
Token []string `json:"token"`
Notification struct {
Title string `json:"title"`
Body string `json:"body"`
Sound string `json:"sound"`
Type string `json:"type"`
} `json:"notification"`
})
if err := c.BodyParser(body); err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid request body")
}
if len(body.Token) == 0 {
return fiber.NewError(fiber.StatusBadRequest, "No tokens provided")
}
var successCount, failureCount int
for _, token := range body.Token {
err := sendFCMMessage(token, body.Notification.Title, body.Notification.Body)
if err != nil {
log.Printf("❌ Failed to send to %s: %v", token, err)
failureCount++
} else {
log.Printf("✅ Notification sent to %s", token)
successCount++
}
}
return c.Status(fiber.StatusOK).JSON(fiber.Map{
"message": "Admin notifications sent",
"success": successCount,
"failure": failureCount,
})
}
func (ctl *UtilsController) GetAppConfig(c *fiber.Ctx) error {
cid, _ := strconv.Atoi(c.Query("configid"))
result, err := ctl.utilsService.GetAppConfig(cid)
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
"code": 500,
"message": "Failed to fetch app config",
"status": false,
})
}
return c.Status(http.StatusOK).JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}
func (ctl *UtilsController) GetAppCategory(c *fiber.Ctx) error {
result, err := ctl.utilsService.GetAppCategory()
if err != nil {
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
"code": 500,
"message": "Failed to fetch app categories",
"status": false,
})
}
return c.Status(http.StatusOK).JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
"details": result,
})
}