Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions backend/internal/handlers/websocketHandlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"hopp-backend/internal/models"
"hopp-backend/internal/notifications"
"net/http"
"time"

"github.com/google/uuid"
"github.com/gorilla/websocket"
Expand Down Expand Up @@ -263,6 +264,41 @@ func initiateCall(ctx echo.Context, s *common.ServerState, ws *websocket.Conn, r
rdbCtx := context.Background()
calleeChannelID := common.GetUserChannel(calleeID)

// Check if the caller's team is in trial or paid tier
caller, err := models.GetUserByID(s.DB, callerId)
if err != nil {
ctx.Logger().Error("Error getting caller: ", err)
sendWSErrorMessage(ws, "Failed to get caller information")
return
}

callerWithSub, err := models.GetUserWithSubscription(s.DB, caller)
if err != nil {
ctx.Logger().Error("Error getting caller subscription: ", err)
sendWSErrorMessage(ws, "Failed to check subscription status")
return
}

// Check if caller has access (paid or active trial)
hasAccess := callerWithSub.IsPro
if !hasAccess && callerWithSub.IsTrial && callerWithSub.TrialEndsAt != nil {
// Check if trial is still active
hasAccess = callerWithSub.TrialEndsAt.After(time.Now())
}

if !hasAccess {
ctx.Logger().Warn("Caller does not have active subscription or trial: ", callerId)
msg := messages.NewRejectCallMessage(calleeID, "trial-ended")
msgJSON, err := json.Marshal(msg)
if err != nil {
ctx.Logger().Error("Error marshalling reject message: ", err)
return
}
ws.WriteMessage(websocket.TextMessage, msgJSON)
_ = notifications.SendTelegramNotification(fmt.Sprintf("Unsubscribed user %s tried to call", caller.ID), s.Config)
return
}

// Check first if the callee online
channels, err := s.Redis.PubSubChannels(rdbCtx, calleeChannelID).Result()
if err != nil {
Expand Down
16 changes: 15 additions & 1 deletion backend/internal/messages/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ type RejectCallMessage struct {
Type MessageType `json:"type"`
Payload struct {
CallerID string `json:"caller_id" validate:"required"`
RejectReason string `json:"reject_reason,omitempty" validate:"omitempty,oneof=in-call rejected"`
RejectReason string `json:"reject_reason,omitempty" validate:"omitempty,oneof=in-call rejected trial-ended"`
} `json:"payload"`
}

Expand Down Expand Up @@ -346,3 +346,17 @@ func NewTeammateOnlineMessage(teammateID string) TeammateOnlineMessage {
},
}
}

// NewRejectCallMessage creates a new reject call message
func NewRejectCallMessage(calleeID, reason string) RejectCallMessage {
return RejectCallMessage{
Type: MessageTypeCallReject,
Payload: struct {
CallerID string `json:"caller_id" validate:"required"`
RejectReason string `json:"reject_reason,omitempty" validate:"omitempty,oneof=in-call rejected trial-ended"`
}{
CallerID: calleeID,
RejectReason: reason,
},
}
}
4 changes: 4 additions & 0 deletions tauri/src/components/ui/participant-row-wo-livekit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ export const ParticipantRow = (props: { user: components["schemas"]["BaseUser"]
toast.error(`${props.user.first_name} is already in a call`, {
duration: 2500,
});
} else if (payload.reject_reason === "trial-ended") {
toast.error(`Trial has expired, contact us if you want to extend it`, {
duration: 2500,
});
} else {
toast.error(`${props.user.first_name} rejected your call`, {
duration: 2500,
Expand Down
2 changes: 1 addition & 1 deletion tauri/src/payloads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export const PRejectCallMessage = z.object({
type: z.literal("call_reject"),
payload: z.object({
caller_id: z.string(),
reject_reason: z.enum(["in-call", "rejected"]).optional(),
reject_reason: z.enum(["in-call", "rejected", "trial-ended"]).optional(),
}),
});

Expand Down