2018-04-25 13:16:36 +02:00
package applicationservice
import (
"fmt"
"net/http"
"reflect"
"strings"
"sync"
"time"
"github.com/pquerna/ffjson/ffjson"
"bitbucket.org/nemt/nemt-portal-api/application/entitymapping"
"bitbucket.org/nemt/nemt-portal-api/application/notificationservice"
"bitbucket.org/nemt/nemt-portal-api/application/viewmodel"
"bitbucket.org/nemt/nemt-portal-api/domain/service"
"bitbucket.org/nemt/nemt-portal-api/infra/config"
"github.com/gorilla/websocket"
"google.golang.org/api/googleapi/transport"
urlshortener "google.golang.org/api/urlshortener/v1"
gomail "gopkg.in/gomail.v2"
redis "gopkg.in/redis.v5"
)
const (
NotificationTypeEmail = "email"
NOtificationTypeSMS = "sms"
NotificationTypeAPP = "app"
StatusPending = "pending"
StatusAccepted = "accepted"
StatusArrived = "arrived"
StatusPickedUp = "pickedUp"
StatusDroppedOff = "droppedOff"
StatusCanceled = "canceled"
StatusScheduled = "scheduled"
StatusWillCall = "willCall"
hourMinuteAMPM = "03:04 PM"
)
// providerService holds methods to provider application service
type notificationService struct {
svc * service . Service
mapEntity * entitymapping . Mapper
notification * notificationservice . Service
cfg * config . Config
store * Store
pubSub * redis . PubSub
redisConn * redis . Client
}
// newProviderService returns a providerService instance
func newNotificationService ( svc * service . Service , mapper * entitymapping . Mapper , notification * notificationservice . Service , cfg * config . Config ) * notificationService {
redisClient := redis . NewFailoverClient ( & redis . FailoverOptions {
MasterName : "master01" ,
SentinelAddrs : [ ] string { fmt . Sprintf ( "%s:%v" , cfg . Cache . Server , cfg . Cache . Port ) } ,
Password : cfg . Cache . Pass ,
DB : cfg . Cache . DB ,
} )
pubSub , err := redisClient . Subscribe ( )
if err != nil {
panic ( err )
}
return & notificationService {
svc : svc ,
mapEntity : mapper ,
notification : notification ,
cfg : cfg ,
redisConn : redisClient ,
store : & Store {
Users : make ( map [ string ] * UserNotification ) ,
redisClient : redisClient ,
pubSub : pubSub ,
} ,
pubSub : pubSub ,
}
}
func ( s * notificationService ) secondsToMinutes ( inSeconds int64 ) string {
minutes := inSeconds / 60
seconds := inSeconds % 60
str := fmt . Sprintf ( "%v minutes" , minutes )
if seconds > 0 {
str += fmt . Sprintf ( " %v seconds" , seconds )
}
return str
}
func ( s * notificationService ) getReadyURLShortened ( ride viewmodel . Ride ) ( string , error ) {
const (
url = "https://portal.bcbsinstitute.com/#/ride/%s/%s/ready"
)
svc , err := urlshortener . New ( & http . Client {
Transport : & transport . APIKey { Key : s . cfg . GoogleShortener . APIKey } ,
} )
if err != nil {
return "" , err
}
userURL := fmt . Sprintf ( url , ride . UUID , ride . User . ID )
shortURL , err := svc . Url . Insert ( & urlshortener . Url {
Kind : "urlshortener#url" , // Not really needed
LongUrl : userURL ,
} ) . Do ( )
if err != nil {
return "" , err
}
return shortURL . Id , nil
}
func ( s * notificationService ) getURLShortened ( ride viewmodel . Ride ) ( string , error ) {
const (
url = "https://portal.bcbsinstitute.com/#/ride/%s/%s"
)
svc , err := urlshortener . New ( & http . Client {
Transport : & transport . APIKey { Key : s . cfg . GoogleShortener . APIKey } ,
} )
if err != nil {
return "" , err
}
userURL := fmt . Sprintf ( url , ride . UUID , ride . User . ID )
shortURL , err := svc . Url . Insert ( & urlshortener . Url {
Kind : "urlshortener#url" , // Not really needed
LongUrl : userURL ,
} ) . Do ( )
if err != nil {
return "" , err
}
return shortURL . Id , nil
}
func ( s * notificationService ) SendNotification ( state string , ride viewmodel . Ride , lyftRide viewmodel . RideRequest ) error {
notifications := make ( [ ] viewmodel . Notification , 0 )
url , err := s . getURLShortened ( ride )
if err != nil {
fmt . Println ( "Error to short url: " , err )
}
loc , _ := time . LoadLocation ( "America/Chicago" )
switch state {
case StatusWillCall :
visitTime := ride . VisitDate . In ( loc ) . Format ( hourMinuteAMPM )
visitDate := ride . VisitDate . In ( loc ) . Format ( "01/02/2006" )
messageMemberSMS := fmt . Sprintf ( MessageSMSWillCallMember , visitTime , ride . Route . Destination . Name , visitDate )
messageMemberSMS += "\n\n" + MessageSMSReplyOrCancel
messageMemberEmail := fmt . Sprintf ( MessageEmailWillCallMember , visitTime , ride . Route . Destination . Name , visitDate )
//messageMemberApp := fmt.Sprintf(MessageAppPendingMember, visitTime, ride.Route.Destination.Name, visitDate, ride.Route.Origin.Address, pickupTime)
urlReady , err := s . getReadyURLShortened ( ride )
if err != nil {
fmt . Println ( err )
}
messageMemberSMS += "\n" + fmt . Sprintf ( MessageSMSIAmReadyOrClick , ride . Route . Destination . Name , urlReady )
messageMemberEmail += "\n" + fmt . Sprintf ( MessageEmailIAmReadyOrClick , ride . Route . Destination . Name , urlReady )
messageDispatcherSMS := fmt . Sprintf ( MessageSMSWillCallDispatcher , ride . User . Name , visitTime , ride . Route . Destination . Name , visitDate )
messageDispatcherSMS += "\n\n" + MessageSMSReplyOrCancel
messageDispatcherEmail := fmt . Sprintf ( MessageEmailWillCallDispatcher , ride . User . Name , visitTime , ride . Route . Destination . Name , visitDate )
//messageDispatcherApp := fmt.Sprintf(MessageAppPendingDispatcher, ride.User.Name, visitTime, ride.Route.Destination.Name, visitDate, ride.Route.Origin.Address, pickupTime)
notifications = append ( notifications , s . GetNotification ( ride , "sms" , MessageSMSWillCallMemberTitle , messageMemberSMS , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "sms" , fmt . Sprintf ( MessageSMSWillCallDispatcherTitle , ride . User . Name ) , messageDispatcherSMS , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , MessageEmailWillCallMemberTitle , messageMemberEmail , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , fmt . Sprintf ( MessageEmailWillCallDispatcherTitle , ride . User . Name ) , messageDispatcherEmail , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , "Ride Scheduled " + strings . ToLower ( ride . TripType . Value ) , fmt . Sprintf ( MessageAppWillCallMemberTitle , ride . Status . Value , ride . Route . Destination . Address ) , false , "ride" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , "Ride Scheduled " + strings . ToLower ( ride . TripType . Value ) , fmt . Sprintf ( MessageAppWillCallDispatcherTitle , ride . Status . Value , ride . Route . Destination . Address ) , true , "ride" ) )
case StatusScheduled :
dateFormat := ride . PickupTime . In ( loc ) . Format ( "01/02/2006 03:04 PM" )
visitTime := ride . VisitDate . In ( loc ) . Format ( hourMinuteAMPM )
pickupTime := ride . PickupTime . In ( loc ) . Format ( hourMinuteAMPM )
visitDate := ride . VisitDate . In ( loc ) . Format ( "01/02/2006" )
if ride . TripType . Key == "from_visit" && lyftRide . ReturnTime != nil {
dateFormat = lyftRide . ReturnTime . In ( loc ) . Format ( "01/02/2006 03:04 PM" )
pickupTime = lyftRide . ReturnTime . In ( loc ) . Format ( hourMinuteAMPM )
}
messageMemberSMS := fmt . Sprintf ( MessageSMSScheduledMember , visitTime , ride . Route . Destination . Name , visitDate , ride . Route . Origin . Address , pickupTime )
messageMemberSMS += "\n\n" + MessageSMSReplyOrCancel
messageMemberEmail := fmt . Sprintf ( MessageEmailScheduledMember , visitTime , ride . Route . Destination . Name , visitDate , ride . Route . Origin . Address , pickupTime )
//messageMemberApp := fmt.Sprintf(MessageAppPendingMember, visitTime, ride.Route.Destination.Name, visitDate, ride.Route.Origin.Address, pickupTime)
messageDispatcherSMS := fmt . Sprintf ( MessageSMSScheduledDispatcher , ride . User . Name , visitTime , ride . Route . Destination . Name , visitDate , ride . Route . Origin . Address , pickupTime )
messageDispatcherSMS += "\n\n" + MessageSMSReplyOrCancel
messageDispatcherEmail := fmt . Sprintf ( MessageEmailScheduledDispatcher , ride . User . Name , visitTime , ride . Route . Destination . Name , visitDate , ride . Route . Origin . Address , pickupTime )
//messageDispatcherApp := fmt.Sprintf(MessageAppPendingDispatcher, ride.User.Name, visitTime, ride.Route.Destination.Name, visitDate, ride.Route.Origin.Address, pickupTime)
notifications = append ( notifications , s . GetNotification ( ride , "sms" , fmt . Sprintf ( MessageSMSScheduledMemberTitle , dateFormat ) , messageMemberSMS , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "sms" , fmt . Sprintf ( MessageSMSScheduledDispatcherTitle , ride . User . Name , dateFormat ) , messageDispatcherSMS , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , fmt . Sprintf ( MessageEmailScheduledMemberTitle , dateFormat ) , messageMemberEmail , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , fmt . Sprintf ( MessageEmailScheduledDispatcherTitle , ride . User . Name , dateFormat ) , messageDispatcherEmail , true , "" ) )
// if ride.TripType.Key == "to_visit" {
notifications = append ( notifications , s . GetNotification ( ride , "app" , fmt . Sprintf ( "%s | " + strings . ToLower ( ride . TripType . Value ) , ride . Status . Value ) , fmt . Sprintf ( MessageAppScheduledMemberTitle , pickupTime , ride . Route . Origin . Name ) , false , "ride" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , fmt . Sprintf ( "%s | " + strings . ToLower ( ride . TripType . Value ) , ride . Status . Value ) , fmt . Sprintf ( MessageAppScheduledDispatcherTitle , pickupTime , ride . Route . Origin . Name ) , true , "ride" ) )
// } else if ride.TripType.Key == "from_visit" {
// notifications = append(notifications, s.GetNotification(ride, "app", fmt.Sprintf("Ride %s "+strings.ToLower(ride.TripType.Value), StatusScheduled), fmt.Sprintf(MessageAppScheduledMemberTitle, pickupTime, ride.Route.Destination.Name), false, "ride"))
// notifications = append(notifications, s.GetNotification(ride, "app", fmt.Sprintf("Ride %s "+strings.ToLower(ride.TripType.Value), StatusScheduled), fmt.Sprintf(MessageAppScheduledDispatcherTitle, pickupTime, ride.Route.Destination.Name), true, "ride"))
// }
case StatusPending :
dateFormat := ride . PickupTime . In ( loc ) . Format ( "01/02/2006 03:04 PM" )
visitTime := ride . VisitDate . In ( loc ) . Format ( hourMinuteAMPM )
pickupTime := ride . PickupTime . In ( loc ) . Format ( hourMinuteAMPM )
visitDate := ride . VisitDate . In ( loc ) . Format ( "01/02/2006" )
messageMemberSMS := fmt . Sprintf ( MessageSMSPendingMember , visitTime , ride . Route . Destination . Name , visitDate , ride . Route . Origin . Address , pickupTime )
messageMemberSMS += "\n\n" + MessageSMSReplyOrCancel
messageMemberEmail := fmt . Sprintf ( MessageEmailPendingMember , visitTime , ride . Route . Destination . Name , visitDate , ride . Route . Origin . Address , pickupTime )
//messageMemberApp := fmt.Sprintf(MessageAppPendingMember, visitTime, ride.Route.Destination.Name, visitDate, ride.Route.Origin.Address, pickupTime)
messageDispatcherSMS := fmt . Sprintf ( MessageSMSPendingDispatcher , ride . User . Name , visitTime , ride . Route . Destination . Name , visitDate , ride . Route . Origin . Address , pickupTime )
messageDispatcherSMS += "\n\n" + MessageSMSReplyOrCancel
messageDispatcherEmail := fmt . Sprintf ( MessageEmailPendingDispatcher , ride . User . Name , visitTime , ride . Route . Destination . Name , visitDate , ride . Route . Origin . Address , pickupTime )
//messageDispatcherApp := fmt.Sprintf(MessageAppPendingDispatcher, ride.User.Name, visitTime, ride.Route.Destination.Name, visitDate, ride.Route.Origin.Address, pickupTime)
notifications = append ( notifications , s . GetNotification ( ride , "sms" , fmt . Sprintf ( MessageSMSPendingMemberTitle , dateFormat ) , messageMemberSMS , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "sms" , fmt . Sprintf ( MessageSMSPendingDispatcherTitle , ride . User . Name , dateFormat ) , messageDispatcherSMS , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , fmt . Sprintf ( MessageEmailPendingMemberTitle , dateFormat ) , messageMemberEmail , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , fmt . Sprintf ( MessageEmailPendingDispatcherTitle , ride . User . Name , dateFormat ) , messageDispatcherEmail , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , fmt . Sprintf ( "%s | " + ride . TripType . Value , ride . Status . Value ) , fmt . Sprintf ( MessageAppPendingMemberTitle , pickupTime , ride . Route . Origin . Name ) , false , "ride" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , fmt . Sprintf ( "%s | " + ride . TripType . Value , ride . Status . Value ) , fmt . Sprintf ( MessageAppPendingDispatcherTitle , pickupTime , ride . Route . Origin . Name ) , true , "ride" ) )
case StatusAccepted :
pickupTime := ride . PickupTime . In ( loc ) . Format ( hourMinuteAMPM )
messageMemberSMS := fmt . Sprintf ( MessageSMSAcceptedMember , lyftRide . Driver . FirstName , ride . Route . Origin . Address , pickupTime , lyftRide . Vehicle . Color , lyftRide . Vehicle . Make , lyftRide . Vehicle . Model , lyftRide . Vehicle . LicensePlate , url )
messageMemberSMS += "\n\n" + MessageSMSReplyOrCancel
messageMemberEmail := fmt . Sprintf ( MessageEmailAcceptedMember , lyftRide . Driver . FirstName , ride . Route . Origin . Address , pickupTime , lyftRide . Vehicle . Color , lyftRide . Vehicle . Make , lyftRide . Vehicle . Model , lyftRide . Vehicle . LicensePlate , url )
//messageMemberApp := fmt.Sprintf(MessageAppAcceptedMember, lyftRide.Driver.FirstName, ride.Route.Origin.Address, visitTime, lyftRide.Vehicle.Color, lyftRide.Vehicle.Make, lyftRide.Vehicle.Model, lyftRide.Vehicle.LicensePlate, url)
messageDispatcherSMS := fmt . Sprintf ( MessageSMSAcceptedDispatcher , lyftRide . Driver . FirstName , ride . Route . Origin . Address , pickupTime , lyftRide . Vehicle . Color , lyftRide . Vehicle . Make , lyftRide . Vehicle . Model , lyftRide . Vehicle . LicensePlate , url )
messageDispatcherSMS += "\n\n" + MessageSMSReplyOrCancel
messageDispatcherEmail := fmt . Sprintf ( MessageEmailAcceptedDispatcher , lyftRide . Driver . FirstName , ride . Route . Origin . Address , pickupTime , lyftRide . Vehicle . Color , lyftRide . Vehicle . Make , lyftRide . Vehicle . Model , lyftRide . Vehicle . LicensePlate , url )
//messageDispatcherApp := fmt.Sprintf(MessageAppAcceptedDispatcher, lyftRide.Driver.FirstName, ride.Route.Origin.Address, visitTime, lyftRide.Vehicle.Color, lyftRide.Vehicle.Make, lyftRide.Vehicle.Model, lyftRide.Vehicle.LicensePlate, url)
notifications = append ( notifications , s . GetNotification ( ride , "sms" , MessageSMSAcceptedMemberTitle , messageMemberSMS , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "sms" , fmt . Sprintf ( MessageSMSAcceptedDispatcherTitle , ride . User . Name ) , messageDispatcherSMS , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , MessageEmailAcceptedMemberTitle , messageMemberEmail , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , fmt . Sprintf ( MessageEmailAcceptedDispatcherTitle , ride . User . Name ) , messageDispatcherEmail , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , fmt . Sprintf ( "%s | " + ride . TripType . Value , ride . Status . Value ) , fmt . Sprintf ( MessageAppAcceptedMemberTitle , s . secondsToMinutes ( * lyftRide . Origin . ETASeconds ) , ride . Route . Origin . Name ) , false , "ride" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , fmt . Sprintf ( "%s | " + ride . TripType . Value , ride . Status . Value ) , fmt . Sprintf ( MessageAppAcceptedDispatcherTitle , s . secondsToMinutes ( * lyftRide . Origin . ETASeconds ) , ride . Route . Origin . Name ) , true , "ride" ) )
case StatusArrived :
messageMemberSMS := fmt . Sprintf ( MessageSMSArrivedMember , ride . Route . Origin . Address , lyftRide . Driver . FirstName , lyftRide . Vehicle . Color , lyftRide . Vehicle . Make , lyftRide . Vehicle . Model , lyftRide . Vehicle . LicensePlate , url )
messageMemberSMS += "\n\n" + MessageSMSReplyOrCancel
messageMemberEmail := fmt . Sprintf ( MessageEmailArrivedMember , ride . Route . Origin . Address , lyftRide . Driver . FirstName , lyftRide . Vehicle . Color , lyftRide . Vehicle . Make , lyftRide . Vehicle . Model , lyftRide . Vehicle . LicensePlate , url )
//messageMemberApp := fmt.Sprintf(MessageAppArrivedMember, ride.Route.Origin.Address, lyftRide.Driver.FirstName, lyftRide.Vehicle.Color, lyftRide.Vehicle.Make, lyftRide.Vehicle.Model, lyftRide.Vehicle.LicensePlate, url)
messageDispatcherSMS := fmt . Sprintf ( MessageSMSArrivedDispatcher , ride . Route . Origin . Address , lyftRide . Driver . FirstName , lyftRide . Vehicle . Color , lyftRide . Vehicle . Make , lyftRide . Vehicle . Model , lyftRide . Vehicle . LicensePlate , url )
messageDispatcherSMS += "\n\n" + MessageSMSReplyOrCancel
messageDispatcherEmail := fmt . Sprintf ( MessageEmailArrivedDispatcher , ride . Route . Origin . Address , lyftRide . Driver . FirstName , lyftRide . Vehicle . Color , lyftRide . Vehicle . Make , lyftRide . Vehicle . Model , lyftRide . Vehicle . LicensePlate , url )
//messageDispatcherApp := fmt.Sprintf(MessageAppArrivedDispatcher, ride.Route.Origin.Address, lyftRide.Driver.FirstName, lyftRide.Vehicle.Color, lyftRide.Vehicle.Make, lyftRide.Vehicle.Model, lyftRide.Vehicle.LicensePlate, url)
notifications = append ( notifications , s . GetNotification ( ride , "sms" , MessageSMSArrivedMemberTitle , messageMemberSMS , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "sms" , fmt . Sprintf ( MessageSMSArrivedDispatcherTitle , ride . User . Name ) , messageDispatcherSMS , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , MessageEmailArrivedMemberTitle , messageMemberEmail , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , fmt . Sprintf ( MessageEmailArrivedDispatcherTitle , ride . User . Name ) , messageDispatcherEmail , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , "Your ride is HERE" , fmt . Sprintf ( MessageAppArrivedMemberTitle , lyftRide . Vehicle . Color , lyftRide . Vehicle . Make , lyftRide . Vehicle . Model , lyftRide . Vehicle . LicensePlate ) , false , "ride" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , "Waiting for member" , fmt . Sprintf ( MessageAppArrivedDispatcherTitle , lyftRide . Vehicle . Color , lyftRide . Vehicle . Make , lyftRide . Vehicle . Model , lyftRide . Vehicle . LicensePlate ) , true , "ride" ) )
case StatusPickedUp :
dateFormat := time . Now ( ) . In ( loc ) . Format ( "01/02/2006 03:04 PM" )
visitTime := ride . VisitDate . In ( loc ) . Format ( hourMinuteAMPM )
pickupTime := lyftRide . Pickup . Time . In ( loc ) . Format ( hourMinuteAMPM )
messageDispatcherSMS := fmt . Sprintf ( MessageSMSPickedUpDispatcher , ride . User . Name , ride . Route . Origin . Address , dateFormat , url , visitTime , s . secondsToMinutes ( * lyftRide . Destination . ETASeconds ) )
messageDispatcherSMS += "\n\n" + MessageSMSReplyOrCancel
messageDispatcherEmail := fmt . Sprintf ( MessageEmailPickedUpDispatcher , ride . User . Name , ride . Route . Origin . Address , dateFormat , url , visitTime , s . secondsToMinutes ( * lyftRide . Destination . ETASeconds ) )
//messageDispatcherApp := fmt.Sprintf(MessageAppPickedUpDispatcher, ride.User.Name, ride.Route.Origin.Address, dateFormat, url, visitTime, s.secondsToMinutes(*lyftRide.Destination.ETASeconds))
notifications = append ( notifications , s . GetNotification ( ride , "sms" , fmt . Sprintf ( MessageSMSPickedUpDispatcherTitle , ride . User . Name ) , messageDispatcherSMS , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , fmt . Sprintf ( MessageEmailPickedUpDispatcherTitle , ride . User . Name ) , messageDispatcherEmail , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , fmt . Sprintf ( "%s | " + ride . TripType . Value , ride . Status . Value ) , fmt . Sprintf ( MessageAppPickedUpDispatcherTitle , pickupTime ) , true , "ride" ) )
case StatusDroppedOff :
dateFormat := time . Now ( ) . In ( loc ) . Format ( "01/02/2006 03:04 PM" )
dropOffTime := lyftRide . DropOff . Time . In ( loc ) . Format ( hourMinuteAMPM )
// messageMemberSMS := MessageSMSDroppedOffMember
// messageMemberEmail := MessageEmailDroppedOffMember
// if ride.Visit.TripType.Key == "roundtrip_call" && ride.TripType.Key == "to_visit" {
// entityRide, err := s.svc.Rides.GetByUUID(ride.UUID)
// if err != nil {
// fmt.Println(err)
// }
// var nextRide entity.Ride
// for _, r := range entityRide.Visit.Rides {
// fmt.Println("Ride Tryp Type: ", r.TripType.Key)
// if r.TripType.Key == "from_visit_call" {
// nextRide = r
// }
// }
// fmt.Println("NextRide Found: ", nextRide.UUID)
// if nextRide.UUID != "" {
// urlReady, err := s.getReadyURLShortened(nextRide)
// if err != nil {
// fmt.Println(err)
// }
// messageMemberSMS += "\n" + fmt.Sprintf(MessageSMSIAmReadyOrClick, nextRide.Route.Destination.Name, urlReady)
// messageMemberEmail += "\n" + fmt.Sprintf(MessageEmailIAmReadyOrClick, nextRide.Route.Destination.Name, urlReady)
// }
// }
// fmt.Println("SMS Message: ", messageMemberSMS)
messageDispatcherSMS := fmt . Sprintf ( MessageSMSDroppedOffDispatcher , ride . User . Name , ride . Route . Destination . Name , dateFormat , url , ride . Visit . ExternalID )
messageDispatcherEmail := fmt . Sprintf ( MessageEmailDroppedOffDispatcher , ride . User . Name , ride . Route . Destination . Name , dateFormat , url , ride . Visit . ExternalID )
//messageDispatcherApp := fmt.Sprintf(MessageAppDroppedOffDispatcher, ride.User.Name, ride.Route.Destination.Name, dateFormat, url, ride.Visit.ExternalID)
//notifications = append(notifications, s.GetNotification(ride, "sms", MessageSMSDroppedOffMemberTitle, messageMemberSMS, false, ""))
notifications = append ( notifications , s . GetNotification ( ride , "sms" , fmt . Sprintf ( MessageSMSDroppedOffDispatcherTitle , ride . User . Name ) , messageDispatcherSMS , true , "" ) )
//notifications = append(notifications, s.GetNotification(ride, "email", MessageEmailDroppedOffMemberTitle, messageMemberEmail, false, ""))
notifications = append ( notifications , s . GetNotification ( ride , "email" , fmt . Sprintf ( MessageEmailDroppedOffDispatcherTitle , ride . User . Name ) , messageDispatcherEmail , true , "" ) )
//notifications = append(notifications, s.GetNotification(ride, "app", fmt.Sprintf(MessageAppDroppedOffMemberTitle, ride.Route.Destination.Name), fmt.Sprintf(MessageAppDroppedOffMemberTitle, ride.Route.Destination.Name), false, "ride"))
notifications = append ( notifications , s . GetNotification ( ride , "app" , fmt . Sprintf ( "%s | " + ride . TripType . Value , ride . Status . Value ) , fmt . Sprintf ( MessageAppDroppedOffDispatcherTitle , dropOffTime ) , true , "ride" ) )
case StatusCanceled :
visitTime := ride . VisitDate . Format ( hourMinuteAMPM )
visitDate := ride . VisitDate . Format ( "01/02/2006" )
var messageMemberSMS string
var messageMemberSMSTitle string
var messageMemberEmail string
var messageMemberEmailTitle string
//var messageMemberApp string
var messageMemberAppTitle string
var messageDispatcherSMS string
var messageDispatcherSMSTitle string
var messageDispatcherEmail string
var messageDispatcherEmailTitle string
//var messageDispatcherApp string
var messageDispatcherAppTitle string
if lyftRide . CanceledBy == "driver" {
messageMemberSMS = fmt . Sprintf ( MessageSMSCanceledByDriverMember , visitTime , ride . Visit . ExternalID )
messageMemberSMSTitle = MessageSMSCanceledByDriverMemberTitle
messageMemberEmail = fmt . Sprintf ( MessageEmailCanceledByDriverMember , visitTime , ride . Visit . ExternalID )
messageMemberEmailTitle = MessageEmailCanceledByDriverMemberTitle
//messageMemberApp = fmt.Sprintf(MessageAppCanceledByDriverMember, visitTime, ride.Visit.ExternalID)
messageMemberAppTitle = MessageAppCanceledByDriverMemberTitle
messageDispatcherSMS = fmt . Sprintf ( MessageSMSCanceledByDriverDispatcher , visitTime , ride . Visit . ExternalID )
messageDispatcherSMSTitle = fmt . Sprintf ( MessageSMSCanceledByDriverDispatcherTitle , ride . User . Name )
messageDispatcherEmail = fmt . Sprintf ( MessageEmailCanceledByDriverDispatcher , visitTime , ride . Visit . ExternalID )
messageDispatcherEmailTitle = fmt . Sprintf ( MessageEmailCanceledByDriverDispatcherTitle , ride . User . Name )
//messageDispatcherApp = fmt.Sprintf(MessageAppCanceledByDriverDispatcher, visitTime, ride.Visit.ExternalID)
messageDispatcherAppTitle = MessageAppCanceledByDriverDispatcherTitle
} else if lyftRide . CanceledBy == "no_drivers_available" {
messageMemberSMS = fmt . Sprintf ( MessageSMSCanceledNoDriverMember , visitTime , ride . Route . Destination . Name , visitDate )
messageMemberSMSTitle = MessageSMSCanceledNoDriverMemberTitle
messageMemberEmail = fmt . Sprintf ( MessageEmailCanceledNoDriverMember , visitTime , ride . Route . Destination . Name , visitDate )
messageMemberEmailTitle = MessageEmailCanceledNoDriverMemberTitle
//messageMemberApp = fmt.Sprintf(MessageAppCanceledNoDriverMember, visitTime, ride.Route.Destination.Name, visitDate)
messageMemberAppTitle = MessageAppCanceledNoDriverMemberTitle
messageDispatcherSMS = fmt . Sprintf ( MessageSMSCanceledNoDriverDispatcher , visitTime , ride . Route . Destination . Name , visitDate , ride . Visit . ExternalID )
messageDispatcherSMSTitle = fmt . Sprintf ( MessageSMSCanceledNoDriverDispatcherTitle , ride . User . Name )
messageDispatcherEmail = fmt . Sprintf ( MessageEmailCanceledNoDriverDispatcher , visitTime , ride . Route . Destination . Name , visitDate , ride . Visit . ExternalID )
messageDispatcherEmailTitle = fmt . Sprintf ( MessageEmailCanceledNoDriverDispatcherTitle , ride . User . Name )
//messageDispatcherApp = fmt.Sprintf(MessageAppCanceledNoDriverDispatcher, visitTime, ride.Route.Destination.Name, visitDate, ride.Visit.ExternalID)
messageDispatcherAppTitle = MessageAppCanceledNoDriverDispatcherTitle
} else {
messageMemberSMS = fmt . Sprintf ( MessageSMSCanceledMember , visitTime , ride . Visit . ExternalID )
messageMemberSMSTitle = MessageSMSCanceledMemberTitle
messageMemberEmail = fmt . Sprintf ( MessageEmailCanceledMember , visitTime , ride . Visit . ExternalID )
messageMemberEmailTitle = MessageEmailCanceledMemberTitle
//messageMemberApp = fmt.Sprintf(MessageAppCanceledMember, visitTime, ride.Visit.ExternalID)
messageMemberAppTitle = MessageAppCanceledMemberTitle
messageDispatcherSMS = fmt . Sprintf ( MessageSMSCanceledDispatcher , visitTime , ride . Visit . ExternalID )
messageDispatcherSMSTitle = fmt . Sprintf ( MessageSMSCanceledDispatcherTitle , ride . User . Name )
messageDispatcherEmail = fmt . Sprintf ( MessageEmailCanceledDispatcher , visitTime , ride . Visit . ExternalID )
messageDispatcherEmailTitle = fmt . Sprintf ( MessageEmailCanceledDispatcherTitle , ride . User . Name )
//messageDispatcherApp = fmt.Sprintf(MessageAppCanceledDispatcher, visitTime, ride.Visit.ExternalID)
messageDispatcherAppTitle = MessageAppCanceledDispatcherTitle //fmt.Sprintf(MessageAppCanceledDispatcherTitle, ride.User.Name)
}
notifications = append ( notifications , s . GetNotification ( ride , "sms" , messageMemberSMSTitle , messageMemberSMS , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "sms" , messageDispatcherSMSTitle , messageDispatcherSMS , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , messageMemberEmailTitle , messageMemberEmail , false , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "email" , messageDispatcherEmailTitle , messageDispatcherEmail , true , "" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , fmt . Sprintf ( "%s | " + ride . TripType . Value , ride . Status . Value ) , messageMemberAppTitle , false , "ride" ) )
notifications = append ( notifications , s . GetNotification ( ride , "app" , fmt . Sprintf ( "%s | " + ride . TripType . Value , ride . Status . Value ) , messageDispatcherAppTitle , true , "ride" ) )
}
notifications , err = s . SendNotifications ( notifications )
if err != nil {
fmt . Println ( "Error to notify" )
return err
}
return nil
}
func ( s * notificationService ) GetNotification ( ride viewmodel . Ride , notificationType string , subject string , message string , isDispatcher bool , messageType string ) viewmodel . Notification {
retVal := viewmodel . Notification {
Type : notificationType ,
Message : message ,
Subject : subject ,
Ride : ride ,
User : ride . User ,
CreatedUser : ride . CreatedUser ,
Read : false ,
MessageType : messageType ,
}
if isDispatcher {
retVal . User = ride . CreatedUser
retVal . CreatedUser = ride . User
}
switch notificationType {
case NotificationTypeEmail :
if isDispatcher {
retVal . To = * ride . CreatedUser . Email
} else {
retVal . To = * ride . User . Email
}
case NOtificationTypeSMS :
if isDispatcher {
retVal . To = * ride . CreatedUser . PhoneNumber
} else {
retVal . To = * ride . User . PhoneNumber
}
case NotificationTypeAPP :
if isDispatcher {
retVal . To = ride . CreatedUser . ID
} else {
retVal . To = ride . User . ID
}
}
return retVal
}
func ( s * notificationService ) SendMessage ( message viewmodel . Message ) error {
bMessage , err := ffjson . Marshal ( message )
if err != nil {
return err
}
return s . store . redisClient . Publish ( message . DeliveryID , string ( bMessage ) ) . Err ( )
}
func ( s * notificationService ) GetByUserUUIDAndReadStatus ( user viewmodel . User , contactType string , isRead bool ) ( [ ] viewmodel . Notification , error ) {
n , err := s . svc . Notification . GetByUserUUIDAndReadStatus ( user . ID , contactType , isRead )
if err != nil {
return nil , err
}
authUser , err := s . svc . Users . GetByUUID ( user . ID , "" )
if err != nil {
return nil , err
}
if ! isRead {
for i , _ := range n {
r , err := s . svc . Rides . GetByID ( n [ i ] . Ride . ID , authUser )
if err != nil {
return nil , err
}
n [ i ] . Ride = r
}
}
return s . mapEntity . Notification . ToNotificationModelSlice ( n ) , nil
}
func ( s * notificationService ) Subscribe ( user viewmodel . User , conn * websocket . Conn ) ( * UserNotification , error ) {
return s . store . Subscribe ( user , conn )
}
func ( s * notificationService ) DeliverMessage ( ) {
for {
v , _ := s . pubSub . Receive ( )
switch t := v . ( type ) {
case * redis . Message :
var m viewmodel . Message
ffjson . Unmarshal ( [ ] byte ( t . Payload ) , & m )
s . store . FindAndDeliver ( m )
case error :
fmt . Println ( "Error to delivery messages: " , t . Error ( ) )
return
default :
if t != nil {
fmt . Println ( "Unknown Event: " , t )
fmt . Println ( "Type: " , reflect . TypeOf ( t ) )
}
}
}
}
//FindAndDeliver will send a message to an open channel
func ( s * Store ) FindAndDeliver ( m viewmodel . Message ) {
if s . Users [ m . DeliveryID ] != nil {
if s . Users [ m . DeliveryID ] . ID != "" {
if len ( s . Users [ m . DeliveryID ] . Conn ) > 0 {
for i , _ := range s . Users [ m . DeliveryID ] . Conn {
if s . Users [ m . DeliveryID ] . Conn [ i ] != nil {
if err := s . Users [ m . DeliveryID ] . Conn [ i ] . WriteJSON ( m ) ; err != nil {
s . Users [ m . DeliveryID ] . Conn [ i ] = nil
}
}
}
}
return
}
}
}
//Subscribe add the user to a subscription
func ( s * Store ) Subscribe ( user viewmodel . User , conn * websocket . Conn ) ( * UserNotification , error ) {
u := s . Users [ user . ID ]
if u == nil {
u := & UserNotification {
ID : user . ID ,
Conn : [ ] * websocket . Conn { conn } ,
User : user ,
}
s . Users [ u . ID ] = u
} else {
u . Conn = append ( u . Conn , conn )
s . Users [ u . ID ] = u
}
err := s . pubSub . Subscribe ( user . ID )
if err != nil {
return nil , err
}
s . Lock ( )
defer s . Unlock ( )
return u , nil
}
func ( s * notificationService ) ReadStatus ( notificationUUID string , isRead bool ) error {
return s . svc . Notification . ReadStatus ( notificationUUID , isRead )
}
2018-05-29 17:22:48 +02:00
//SendNotificationWithoutWritingToDatabase will send notification directly
func ( s * notificationService ) SendNotificationWithoutWritingToDatabase ( n viewmodel . Notification ) ( viewmodel . Notification , error ) {
switch n . Type {
case NOtificationTypeSMS :
if n . From == "" {
if err := s . notification . Twilio . SendSMS ( s . cfg . Twilio . Sender , n . To , n . Message ) ; err != nil {
fmt . Println ( "Error to send SMS: " , err . Error ( ) )
return viewmodel . Notification { } , err
}
if err := s . notification . Twilio . SendSMS ( s . cfg . Twilio . Sender , "+17083038497" , n . Message ) ; err != nil {
fmt . Println ( "Error to send SMS: " , err . Error ( ) )
return viewmodel . Notification { } , err
}
} else {
if err := s . notification . Twilio . SendSMS ( n . From , n . To , n . Message ) ; err != nil {
fmt . Println ( "Error to send SMS: " , err . Error ( ) )
return viewmodel . Notification { } , err
}
if err := s . notification . Twilio . SendSMS ( n . From , "+17083038497" , n . Message ) ; err != nil {
fmt . Println ( "Error to send SMS: " , err . Error ( ) )
return viewmodel . Notification { } , err
}
}
case NotificationTypeEmail :
m := gomail . NewMessage ( )
m . SetHeader ( "From" , s . cfg . Email . Sender )
m . SetHeader ( "To" , n . To )
m . SetHeader ( "Subject" , n . Subject )
m . SetBody ( "text/plain" , n . Message )
d := gomail . NewDialer ( s . cfg . Email . Server , s . cfg . Email . Port , s . cfg . Email . User , s . cfg . Email . Pass )
if err := d . DialAndSend ( m ) ; err != nil {
fmt . Println ( "Error to send Email: " , err . Error ( ) )
return viewmodel . Notification { } , err
}
m = gomail . NewMessage ( )
m . SetHeader ( "From" , s . cfg . Email . Sender )
m . SetHeader ( "To" , "nemt@brighterdevelopment.com" )
m . SetHeader ( "Subject" , n . Subject )
m . SetBody ( "text/plain" , n . Message )
if err := d . DialAndSend ( m ) ; err != nil {
fmt . Println ( "Error to send Email: " , err . Error ( ) )
return viewmodel . Notification { } , err
}
}
return n , nil
}
2018-04-25 13:16:36 +02:00
// SendNotifications will send all the notifications to email or SMS
func ( s * notificationService ) SendNotifications ( notifications [ ] viewmodel . Notification ) ( [ ] viewmodel . Notification , error ) {
if len ( notifications ) > 0 {
retVal := make ( [ ] viewmodel . Notification , 0 )
for _ , n := range notifications {
if n . To != "" {
notification := s . mapEntity . Notification . ToNotificationEntity ( n )
notification , err := s . svc . Notification . Create ( notification )
if err != nil {
return nil , err
}
switch n . Type {
case NOtificationTypeSMS :
if n . From == "" {
if err := s . notification . Twilio . SendSMS ( s . cfg . Twilio . Sender , n . To , n . Message ) ; err != nil {
fmt . Println ( "Error to send SMS: " , err . Error ( ) )
}
if err := s . notification . Twilio . SendSMS ( s . cfg . Twilio . Sender , "+17083038497" , n . Message ) ; err != nil {
fmt . Println ( "Error to send SMS: " , err . Error ( ) )
}
} else {
if err := s . notification . Twilio . SendSMS ( n . From , n . To , n . Message ) ; err != nil {
fmt . Println ( "Error to send SMS: " , err . Error ( ) )
}
if err := s . notification . Twilio . SendSMS ( n . From , "+17083038497" , n . Message ) ; err != nil {
fmt . Println ( "Error to send SMS: " , err . Error ( ) )
}
}
case NotificationTypeEmail :
m := gomail . NewMessage ( )
m . SetHeader ( "From" , s . cfg . Email . Sender )
m . SetHeader ( "To" , n . To )
m . SetHeader ( "Subject" , n . Subject )
m . SetBody ( "text/plain" , n . Message )
d := gomail . NewDialer ( s . cfg . Email . Server , s . cfg . Email . Port , s . cfg . Email . User , s . cfg . Email . Pass )
if err := d . DialAndSend ( m ) ; err != nil {
fmt . Println ( "Error to send Email: " , err . Error ( ) )
}
m = gomail . NewMessage ( )
m . SetHeader ( "From" , s . cfg . Email . Sender )
m . SetHeader ( "To" , "nemt@brighterdevelopment.com" )
m . SetHeader ( "Subject" , n . Subject )
m . SetBody ( "text/plain" , n . Message )
if err := d . DialAndSend ( m ) ; err != nil {
fmt . Println ( "Error to send Email: " , err . Error ( ) )
}
case NotificationTypeAPP :
m := viewmodel . Message {
DeliveryID : n . To ,
NotificationID : notification . UUID ,
CreateDate : notification . Created ,
Read : notification . Read ,
Content : viewmodel . MessageContent {
Type : n . MessageType ,
Subject : n . Subject ,
Content : n . Message ,
Payload : n . Ride ,
} ,
}
if err := s . SendMessage ( m ) ; err != nil {
fmt . Println ( "Error to send notification to the users: " , err . Error ( ) )
}
}
retVal = append ( retVal , s . mapEntity . Notification . ToNotificationModel ( notification ) )
}
}
return retVal , nil
}
return notifications , nil
}
type UserNotification struct {
ID string
Conn [ ] * websocket . Conn
User viewmodel . User
}
type Store struct {
Users map [ string ] * UserNotification
redisClient * redis . Client
pubSub * redis . PubSub
sync . Mutex
}