package notificationroute import ( "fmt" "net/http" "sync" "time" "bitbucket.org/nemt/nemt-portal-api/application/applicationservice" "bitbucket.org/nemt/nemt-portal-api/application/notificationservice" "bitbucket.org/nemt/nemt-portal-api/application/tncservice" "bitbucket.org/nemt/nemt-portal-api/application/viewmodel" "bitbucket.org/nemt/nemt-portal-api/infra/config" "bitbucket.org/nemt/nemt-portal-api/server/router/routeutils" "github.com/gorilla/websocket" "github.com/labstack/echo" ) var ( instance *controller once sync.Once upgrader = websocket.Upgrader{} ) type controller struct { cfg *config.Config svc *applicationservice.Service tnc *tncservice.Service notification *notificationservice.Service } func controllerInstance(cfg *config.Config, svc *applicationservice.Service, tnc *tncservice.Service, notification *notificationservice.Service) *controller { once.Do(func() { instance = &controller{ cfg: cfg, svc: svc, tnc: tnc, notification: notification, } }) upgrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { return true }, EnableCompression: true, Error: func(w http.ResponseWriter, r *http.Request, status int, reason error) { fmt.Println("Error on websocket: ", status, " - ", reason) }, } go svc.Notification.DeliverMessage() return instance } func (c *controller) handle(ctx echo.Context) error { return routeutils.ResponseAPIOK(ctx, "OK") } func (c *controller) handleNotification(ctx echo.Context) error { sRead := ctx.QueryParam("read") isRead := (sRead == "true") userUUID, err := routeutils.GetAndValidateStringParam(ctx, "user_uuid", "User ID is mandatory") if err != nil { return err } contactType, err := routeutils.GetAndValidateStringParam(ctx, "status", "User ID is mandatory") if err != nil { return err } n, err := c.svc.Notification.GetByUserUUIDAndReadStatus(viewmodel.User{ID: userUUID}, contactType, isRead) if err != nil { fmt.Println("Error to get notifications: ", err.Error()) } return routeutils.ResponseAPIOK(ctx, n) } func (c *controller) handleSocket(ctx echo.Context) error { ws, err := upgrader.Upgrade(ctx.Response(), ctx.Request(), nil) if err != nil { return err } defer ws.Close() userUUID := ctx.QueryParam("id") if userUUID == "" { fmt.Println("User not found") } user, err := c.svc.Users.GetByUUID(userUUID, "SP") if err != nil { fmt.Println("User not found on our system: ", err.Error()) } if user.ID == "" { user, err = c.svc.Users.GetByUUID(userUUID, "US") if err != nil { fmt.Println("User not found on our system: ", err.Error()) } } _, err = c.svc.Notification.Subscribe(user, ws) if err != nil { fmt.Println("Error to subscribe user: ", err.Error()) } n, err := c.svc.Notification.GetByUserUUIDAndReadStatus(user, "app", false) if err != nil { fmt.Println("Error to get notifications: ", err.Error()) } loc, _ := time.LoadLocation("America/Chicago") for _, i := range n { m := viewmodel.Message{ DeliveryID: user.ID, NotificationID: i.UUID, CreateDate: i.Created.In(loc), Read: i.Read, Content: viewmodel.MessageContent{ Payload: i.Ride, Subject: i.Subject, Content: i.Message, Type: i.MessageType, }, } if err := c.svc.Notification.SendMessage(m); err != nil { fmt.Println("Error to send message: ", err.Error()) } } for { var m viewmodel.Message if err := ws.ReadJSON(&m); err != nil { _, ok := err.(*websocket.CloseError) if !ok { fmt.Println("Error to read message: ", err.Error()) } } if m.Content.Type == "disable-notification" { if err := c.svc.Notification.ReadStatus(m.NotificationID, true); err != nil { fmt.Println("Error to disable notification: ", err.Error()) } } else { if err := c.svc.Notification.SendMessage(m); err != nil { fmt.Println("Error to send message: ", err.Error()) } } } }