package lyfthookroute import ( "fmt" "io/ioutil" "strings" "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/labstack/echo" "github.com/pquerna/ffjson/ffjson" ) var ( instance *controller once sync.Once ) 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, } }) return instance } func (c *controller) handleStateChange(ctx echo.Context) error { var rideUUID = ctx.Param("ride_uuid") var status = ctx.Param("status") user, err := c.svc.Users.GetByUUID("573c70ff-733d-11e7-ba8f-0a6ad3fcdeaa", "") if err != nil { fmt.Println("Error: ", err.Error()) return routeutils.HandleAPIError(ctx, err) } ride, err := c.svc.Rides.GetByUUID(rideUUID, user) if err != nil { fmt.Println("Error: ", err.Error()) return routeutils.HandleAPIError(ctx, err) } // var lyftRide viewmodel.RideRequest if ride.CreatedUser.ID != c.cfg.LyftProd.UserUUID { _, err = c.tnc.Lyft.GetRideStatus(viewmodel.RideRequest{RideID: ride.InternalID}, status) go func() { secondCall := func() { ride.InternalID = "s_" + ride.InternalID c.tnc.Lyft.GetRideStatus(viewmodel.RideRequest{RideID: ride.InternalID}, status) } time.AfterFunc(1*time.Second, secondCall) }() } else { _, err = c.tnc.LyftProd.GetRideDetails(viewmodel.RideRequest{RideID: ride.InternalID}) } if err != nil { return routeutils.HandleAPIError(ctx, err) } // if ride.Route.ETA == // UUID, _ := uuid.NewV4() // hook := viewmodel.WebhookResponse{ // Event: lyftRide, // EventID: UUID.String(), // EventType: "ride.status.updated", // HREF: "Test", // OccurredAt: time.Now().UTC().Format("2006-01-02T15:04:05-0700"), // } // ride, err = c.svc.Rides.Update(hook) // if err != nil { // fmt.Println("Error: ", err.Error()) // return routeutils.HandleAPIError(ctx, err) // } // lyftRide.Driver.FirstName = ride.Driver.FirstName // lyftRide.Driver.LastName = ride.Driver.LastName // lyftRide.Status = ride.Status.Key // lyftRide.Vehicle.Color = ride.Vehicle.Color // lyftRide.Vehicle.LicensePlate = ride.Vehicle.LicensePlate // lyftRide.Vehicle.Make = ride.Vehicle.Make // lyftRide.Vehicle.Model = ride.Vehicle.Model // lyftRide.Destination.ETASeconds = &ride.Route.ETA // if lyftRide.Status == "canceled" { // lyftRide.CanceledBy = "driver" // } // if ride.Status.Key == "accepted" || ride.Status.Key == "pickedUp" || ride.Status.Key == "arrived" { // ride.Route.Location = ride.Route.Origin // ride.Route.Location.Address = "" // ride.Route.Location.Name = "" // switch ride.Status.Key { // case "accepted": // if lyftRide.Origin.ETASeconds != nil { // ride.Route.ETA = *lyftRide.Origin.ETASeconds // } else { // ride.Route.ETA = 0 // if c.cfg.App.Debug { // ride.Route.ETA = 350 // } // } // case "pickedUp": // case "arrived": // if lyftRide.Destination.ETASeconds != nil { // ride.Route.ETA = *lyftRide.Destination.ETASeconds // } else { // ride.Route.ETA = 0 // if c.cfg.App.Debug { // ride.Route.ETA = 350 // } // } // } // if lyftRide.Location.Latitude != 0 && lyftRide.Location.Longitude != 0 { // ride.Route.Location.Latitude = lyftRide.Location.Latitude // ride.Route.Location.Longitude = lyftRide.Location.Longitude // ride.Route.Location.Bearing = lyftRide.Location.Bearing // } // } // err = c.svc.Notification.SendNotification(status, ride, lyftRide) // if err != nil { // fmt.Println("Error: ", err.Error()) // return routeutils.HandleAPIError(ctx, err) // } return routeutils.ResponseAPIOK(ctx, ride) } func (c *controller) handle(ctx echo.Context) error { fmt.Println("RECEIVING HOOK: ") body, err := ioutil.ReadAll(ctx.Request().Body) if err != nil { fmt.Println("Error to read the body of the webhook: ", err.Error()) } else { fmt.Println(string(body)) } var requestRide viewmodel.WebhookResponse err = ffjson.Unmarshal(body, &requestRide) if err != nil { fmt.Println(err) return routeutils.ResponseAPIValidationError(ctx, "invalid parameters") } defer ctx.Request().Body.Close() // err = ctx.Bind(&requestRide) // if err != nil { // fmt.Println(err) // return routeutils.ResponseAPIValidationError(ctx, "invalid parameters") // } requestRide.Event.RideID = strings.Replace(requestRide.Event.RideID, "s_", "", -1) requestRide.Event.RideID = strings.Replace(requestRide.Event.RideID, "sandboxevent-", "", -1) ride, err := c.svc.Rides.Update(requestRide) if err != nil { fmt.Println("Error: ", err.Error()) return routeutils.HandleAPIError(ctx, err) } switch requestRide.EventType { case "ride.status.updated": go func() { if err := c.svc.Notification.SendNotification(requestRide.Event.Status, ride, requestRide.Event); err != nil { fmt.Println("Error: ", err.Error()) } }() default: fmt.Println(requestRide.EventType, " :", requestRide.Event.Status) } ctx.Response().Header().Set("Content-Type", "application/json") return routeutils.ResponseAPIOK(ctx, ride) }