feat(live): add handler endpoints for Go Live (me, key, regenerate, update)
This commit is contained in:
parent
083fe2e50d
commit
8062ec685c
2 changed files with 113 additions and 3 deletions
|
|
@ -16,14 +16,19 @@ func (r *APIRouter) setupLiveRoutes(router *gin.RouterGroup) {
|
|||
|
||||
live := router.Group("/live")
|
||||
{
|
||||
live.GET("/streams", liveStreamHandler.ListLiveStreams)
|
||||
live.GET("/streams/:id", liveStreamHandler.GetLiveStream)
|
||||
|
||||
// Protected routes (me/* MUST come before :id)
|
||||
if r.config != nil && r.config.AuthMiddleware != nil {
|
||||
protected := live.Group("")
|
||||
protected.Use(r.config.AuthMiddleware.RequireAuth())
|
||||
r.applyCSRFProtection(protected)
|
||||
protected.GET("/streams/me", liveStreamHandler.GetMyStreams)
|
||||
protected.GET("/streams/me/key", liveStreamHandler.GetMyStreamKey)
|
||||
protected.POST("/streams/me/key/regenerate", liveStreamHandler.RegenerateStreamKey)
|
||||
protected.POST("/streams", liveStreamHandler.CreateLiveStream)
|
||||
protected.PUT("/streams/:id", liveStreamHandler.UpdateLiveStream)
|
||||
}
|
||||
// Public routes (after protected)
|
||||
live.GET("/streams", liveStreamHandler.ListLiveStreams)
|
||||
live.GET("/streams/:id", liveStreamHandler.GetLiveStream)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,3 +95,108 @@ func (h *LiveStreamHandler) CreateLiveStream(c *gin.Context) {
|
|||
}
|
||||
RespondSuccess(c, http.StatusCreated, gin.H{"stream": created})
|
||||
}
|
||||
|
||||
// GetMyStreams returns the authenticated user's streams (including stream_key)
|
||||
func (h *LiveStreamHandler) GetMyStreams(c *gin.Context) {
|
||||
userID, ok := GetUserIDUUID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
streams, err := h.service.ListByUser(c.Request.Context(), userID)
|
||||
if err != nil {
|
||||
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to list streams", err))
|
||||
return
|
||||
}
|
||||
type streamWithKey struct {
|
||||
*models.LiveStream
|
||||
StreamKey string `json:"stream_key"`
|
||||
}
|
||||
result := make([]streamWithKey, len(streams))
|
||||
for i, s := range streams {
|
||||
result[i] = streamWithKey{LiveStream: s, StreamKey: s.StreamKey}
|
||||
}
|
||||
RespondSuccess(c, http.StatusOK, gin.H{"streams": result})
|
||||
}
|
||||
|
||||
// GetMyStreamKey returns the user's stream key (creates draft if none exist)
|
||||
func (h *LiveStreamHandler) GetMyStreamKey(c *gin.Context) {
|
||||
userID, ok := GetUserIDUUID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
streams, err := h.service.ListByUser(c.Request.Context(), userID)
|
||||
if err != nil {
|
||||
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to get streams", err))
|
||||
return
|
||||
}
|
||||
var streamKey string
|
||||
if len(streams) > 0 {
|
||||
streamKey = streams[0].StreamKey
|
||||
} else {
|
||||
draft := &models.LiveStream{Title: "My Stream"}
|
||||
created, createErr := h.service.Create(c.Request.Context(), userID, draft)
|
||||
if createErr != nil {
|
||||
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to create stream", createErr))
|
||||
return
|
||||
}
|
||||
streamKey = created.StreamKey
|
||||
}
|
||||
RespondSuccess(c, http.StatusOK, gin.H{
|
||||
"stream_key": streamKey,
|
||||
"rtmp_url": "rtmp://stream.veza.app/live",
|
||||
})
|
||||
}
|
||||
|
||||
// RegenerateStreamKey generates a new stream key for the user's first stream
|
||||
func (h *LiveStreamHandler) RegenerateStreamKey(c *gin.Context) {
|
||||
userID, ok := GetUserIDUUID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
streams, err := h.service.ListByUser(c.Request.Context(), userID)
|
||||
if err != nil || len(streams) == 0 {
|
||||
RespondWithAppError(c, apperrors.NewNotFoundError("no stream found"))
|
||||
return
|
||||
}
|
||||
newKey, err := h.service.RegenerateStreamKey(c.Request.Context(), streams[0].ID, userID)
|
||||
if err != nil {
|
||||
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to regenerate key", err))
|
||||
return
|
||||
}
|
||||
RespondSuccess(c, http.StatusOK, gin.H{
|
||||
"stream_key": newKey,
|
||||
"rtmp_url": "rtmp://stream.veza.app/live",
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateLiveStream updates a live stream's metadata (ownership check)
|
||||
func (h *LiveStreamHandler) UpdateLiveStream(c *gin.Context) {
|
||||
userID, ok := GetUserIDUUID(c)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
id, err := uuid.Parse(c.Param("id"))
|
||||
if err != nil {
|
||||
RespondWithAppError(c, apperrors.NewValidationError("invalid stream ID"))
|
||||
return
|
||||
}
|
||||
var req CreateLiveStreamRequest
|
||||
if appErr := NewCommonHandler(h.logger).BindAndValidateJSON(c, &req); appErr != nil {
|
||||
RespondWithAppError(c, appErr)
|
||||
return
|
||||
}
|
||||
stream := &models.LiveStream{
|
||||
Title: req.Title,
|
||||
Description: req.Description,
|
||||
Category: req.Category,
|
||||
ThumbnailURL: req.ThumbnailURL,
|
||||
StreamerName: req.StreamerName,
|
||||
Tags: req.Tags,
|
||||
}
|
||||
updated, updateErr := h.service.Update(c.Request.Context(), id, userID, stream)
|
||||
if updateErr != nil {
|
||||
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to update stream", updateErr))
|
||||
return
|
||||
}
|
||||
RespondSuccess(c, http.StatusOK, gin.H{"stream": updated})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue