ListChannels(), GetChannel(), ListUserSubscriptions(), ListChannelSubscriptions(), GetSubscription(), CancelSubscription()
This commit is contained in:
parent
85bfe79115
commit
5c2877bdb8
@ -24,6 +24,8 @@ const (
|
|||||||
|
|
||||||
USER_NOT_FOUND APIError = 1301
|
USER_NOT_FOUND APIError = 1301
|
||||||
CLIENT_NOT_FOUND APIError = 1302
|
CLIENT_NOT_FOUND APIError = 1302
|
||||||
|
CHANNEL_NOT_FOUND APIError = 1303
|
||||||
|
SUBSCRIPTION_NOT_FOUND APIError = 1304
|
||||||
USER_AUTH_FAILED APIError = 1311
|
USER_AUTH_FAILED APIError = 1311
|
||||||
|
|
||||||
NO_DEVICE_LINKED APIError = 1401
|
NO_DEVICE_LINKED APIError = 1401
|
||||||
|
@ -36,7 +36,7 @@ func NewAPIHandler(app *logic.Application) APIHandler {
|
|||||||
// @Failure 400 {object} ginresp.apiError
|
// @Failure 400 {object} ginresp.apiError
|
||||||
// @Failure 500 {object} ginresp.apiError
|
// @Failure 500 {object} ginresp.apiError
|
||||||
//
|
//
|
||||||
// @Router /api-v2/user/ [POST]
|
// @Router /api-v2/users/ [POST]
|
||||||
func (h APIHandler) CreateUser(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) CreateUser(g *gin.Context) ginresp.HTTPResponse {
|
||||||
type body struct {
|
type body struct {
|
||||||
FCMToken string `json:"fcm_token"`
|
FCMToken string `json:"fcm_token"`
|
||||||
@ -116,7 +116,7 @@ func (h APIHandler) CreateUser(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
// @Failure 404 {object} ginresp.apiError
|
// @Failure 404 {object} ginresp.apiError
|
||||||
// @Failure 500 {object} ginresp.apiError
|
// @Failure 500 {object} ginresp.apiError
|
||||||
//
|
//
|
||||||
// @Router /api-v2/user/{uid} [GET]
|
// @Router /api-v2/users/{uid} [GET]
|
||||||
func (h APIHandler) GetUser(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) GetUser(g *gin.Context) ginresp.HTTPResponse {
|
||||||
type uri struct {
|
type uri struct {
|
||||||
UserID int64 `uri:"uid"`
|
UserID int64 `uri:"uid"`
|
||||||
@ -158,7 +158,7 @@ func (h APIHandler) GetUser(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
// @Failure 404 {object} ginresp.apiError
|
// @Failure 404 {object} ginresp.apiError
|
||||||
// @Failure 500 {object} ginresp.apiError
|
// @Failure 500 {object} ginresp.apiError
|
||||||
//
|
//
|
||||||
// @Router /api-v2/user/{uid} [PATCH]
|
// @Router /api-v2/users/{uid} [PATCH]
|
||||||
func (h APIHandler) UpdateUser(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) UpdateUser(g *gin.Context) ginresp.HTTPResponse {
|
||||||
type uri struct {
|
type uri struct {
|
||||||
UserID int64 `uri:"uid"`
|
UserID int64 `uri:"uid"`
|
||||||
@ -228,18 +228,18 @@ func (h APIHandler) UpdateUser(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
//
|
//
|
||||||
// @Param uid path int true "UserID"
|
// @Param uid path int true "UserID"
|
||||||
//
|
//
|
||||||
// @Success 200 {object} handler.ListClients.result
|
// @Success 200 {object} handler.ListClients.response
|
||||||
// @Failure 400 {object} ginresp.apiError
|
// @Failure 400 {object} ginresp.apiError
|
||||||
// @Failure 401 {object} ginresp.apiError
|
// @Failure 401 {object} ginresp.apiError
|
||||||
// @Failure 404 {object} ginresp.apiError
|
// @Failure 404 {object} ginresp.apiError
|
||||||
// @Failure 500 {object} ginresp.apiError
|
// @Failure 500 {object} ginresp.apiError
|
||||||
//
|
//
|
||||||
// @Router /api-v2/user/{uid}/clients [GET]
|
// @Router /api-v2/users/{uid}/clients [GET]
|
||||||
func (h APIHandler) ListClients(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) ListClients(g *gin.Context) ginresp.HTTPResponse {
|
||||||
type uri struct {
|
type uri struct {
|
||||||
UserID int64 `uri:"uid"`
|
UserID int64 `uri:"uid"`
|
||||||
}
|
}
|
||||||
type result struct {
|
type response struct {
|
||||||
Clients []models.ClientJSON `json:"clients"`
|
Clients []models.ClientJSON `json:"clients"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ func (h APIHandler) ListClients(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
|
|
||||||
res := langext.ArrMap(clients, func(v models.Client) models.ClientJSON { return v.JSON() })
|
res := langext.ArrMap(clients, func(v models.Client) models.ClientJSON { return v.JSON() })
|
||||||
|
|
||||||
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, result{Clients: res}))
|
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{Clients: res}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetClient swaggerdoc
|
// GetClient swaggerdoc
|
||||||
@ -278,7 +278,7 @@ func (h APIHandler) ListClients(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
// @Failure 404 {object} ginresp.apiError
|
// @Failure 404 {object} ginresp.apiError
|
||||||
// @Failure 500 {object} ginresp.apiError
|
// @Failure 500 {object} ginresp.apiError
|
||||||
//
|
//
|
||||||
// @Router /api-v2/user/{uid}/clients/{cid} [GET]
|
// @Router /api-v2/users/{uid}/clients/{cid} [GET]
|
||||||
func (h APIHandler) GetClient(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) GetClient(g *gin.Context) ginresp.HTTPResponse {
|
||||||
type uri struct {
|
type uri struct {
|
||||||
UserID int64 `uri:"uid"`
|
UserID int64 `uri:"uid"`
|
||||||
@ -322,7 +322,7 @@ func (h APIHandler) GetClient(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
// @Failure 404 {object} ginresp.apiError
|
// @Failure 404 {object} ginresp.apiError
|
||||||
// @Failure 500 {object} ginresp.apiError
|
// @Failure 500 {object} ginresp.apiError
|
||||||
//
|
//
|
||||||
// @Router /api-v2/user/{uid}/clients [POST]
|
// @Router /api-v2/users/{uid}/clients [POST]
|
||||||
func (h APIHandler) AddClient(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) AddClient(g *gin.Context) ginresp.HTTPResponse {
|
||||||
type uri struct {
|
type uri struct {
|
||||||
UserID int64 `uri:"uid"`
|
UserID int64 `uri:"uid"`
|
||||||
@ -377,7 +377,7 @@ func (h APIHandler) AddClient(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
// @Failure 404 {object} ginresp.apiError
|
// @Failure 404 {object} ginresp.apiError
|
||||||
// @Failure 500 {object} ginresp.apiError
|
// @Failure 500 {object} ginresp.apiError
|
||||||
//
|
//
|
||||||
// @Router /api-v2/user/{uid}/clients [POST]
|
// @Router /api-v2/users/{uid}/clients [POST]
|
||||||
func (h APIHandler) DeleteClient(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) DeleteClient(g *gin.Context) ginresp.HTTPResponse {
|
||||||
type uri struct {
|
type uri struct {
|
||||||
UserID int64 `uri:"uid"`
|
UserID int64 `uri:"uid"`
|
||||||
@ -411,38 +411,299 @@ func (h APIHandler) DeleteClient(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, client.JSON()))
|
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, client.JSON()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListChannels swaggerdoc
|
||||||
|
//
|
||||||
|
// @Summary List all channels of a user
|
||||||
|
// @ID api-channels-list
|
||||||
|
//
|
||||||
|
// @Param uid path int true "UserID"
|
||||||
|
//
|
||||||
|
// @Success 200 {object} handler.ListChannels.response
|
||||||
|
// @Failure 400 {object} ginresp.apiError
|
||||||
|
// @Failure 401 {object} ginresp.apiError
|
||||||
|
// @Failure 404 {object} ginresp.apiError
|
||||||
|
// @Failure 500 {object} ginresp.apiError
|
||||||
|
//
|
||||||
|
// @Router /api-v2/users/{uid}/channels [GET]
|
||||||
func (h APIHandler) ListChannels(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) ListChannels(g *gin.Context) ginresp.HTTPResponse {
|
||||||
return ginresp.NotImplemented()
|
type uri struct {
|
||||||
|
UserID int64 `uri:"uid"`
|
||||||
|
}
|
||||||
|
type response struct {
|
||||||
|
Channels []models.ChannelJSON `json:"channels"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var u uri
|
||||||
|
ctx, errResp := h.app.StartRequest(g, &u, nil, nil)
|
||||||
|
if errResp != nil {
|
||||||
|
return *errResp
|
||||||
|
}
|
||||||
|
defer ctx.Cancel()
|
||||||
|
|
||||||
|
if permResp := ctx.CheckPermissionUserRead(u.UserID); permResp != nil {
|
||||||
|
return *permResp
|
||||||
|
}
|
||||||
|
|
||||||
|
clients, err := h.database.ListChannels(ctx, u.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return ginresp.InternAPIError(500, apierr.DATABASE_ERROR, "Failed to query channels", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := langext.ArrMap(clients, func(v models.Channel) models.ChannelJSON { return v.JSON() })
|
||||||
|
|
||||||
|
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{Channels: res}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChannel swaggerdoc
|
||||||
|
//
|
||||||
|
// @Summary List all channels of a user
|
||||||
|
// @ID api-channels-get
|
||||||
|
//
|
||||||
|
// @Param uid path int true "UserID"
|
||||||
|
// @Param cid path int true "ChannelID"
|
||||||
|
//
|
||||||
|
// @Success 200 {object} models.ChannelJSON
|
||||||
|
// @Failure 400 {object} ginresp.apiError
|
||||||
|
// @Failure 401 {object} ginresp.apiError
|
||||||
|
// @Failure 404 {object} ginresp.apiError
|
||||||
|
// @Failure 500 {object} ginresp.apiError
|
||||||
|
//
|
||||||
|
// @Router /api-v2/users/{uid}/channels/{cid} [GET]
|
||||||
func (h APIHandler) GetChannel(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) GetChannel(g *gin.Context) ginresp.HTTPResponse {
|
||||||
return ginresp.NotImplemented()
|
type uri struct {
|
||||||
|
UserID int64 `uri:"uid"`
|
||||||
|
ChannelID int64 `uri:"cid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var u uri
|
||||||
|
ctx, errResp := h.app.StartRequest(g, &u, nil, nil)
|
||||||
|
if errResp != nil {
|
||||||
|
return *errResp
|
||||||
|
}
|
||||||
|
defer ctx.Cancel()
|
||||||
|
|
||||||
|
if permResp := ctx.CheckPermissionUserRead(u.UserID); permResp != nil {
|
||||||
|
return *permResp
|
||||||
|
}
|
||||||
|
|
||||||
|
channel, err := h.database.GetChannel(ctx, u.UserID, u.ChannelID)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return ginresp.InternAPIError(404, apierr.CLIENT_NOT_FOUND, "Channel not found", err)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return ginresp.InternAPIError(500, apierr.DATABASE_ERROR, "Failed to query channel", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, channel.JSON()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h APIHandler) GetChannelMessages(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) GetChannelMessages(g *gin.Context) ginresp.HTTPResponse {
|
||||||
return ginresp.NotImplemented()
|
return ginresp.NotImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListUserSubscriptions swaggerdoc
|
||||||
|
//
|
||||||
|
// @Summary List all channels of a user
|
||||||
|
// @ID api-user-subscriptions-list
|
||||||
|
//
|
||||||
|
// @Param uid path int true "UserID"
|
||||||
|
//
|
||||||
|
// @Success 200 {object} handler.ListUserSubscriptions.response
|
||||||
|
// @Failure 400 {object} ginresp.apiError
|
||||||
|
// @Failure 401 {object} ginresp.apiError
|
||||||
|
// @Failure 404 {object} ginresp.apiError
|
||||||
|
// @Failure 500 {object} ginresp.apiError
|
||||||
|
//
|
||||||
|
// @Router /api-v2/users/{uid}/subscriptions [GET]
|
||||||
func (h APIHandler) ListUserSubscriptions(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) ListUserSubscriptions(g *gin.Context) ginresp.HTTPResponse {
|
||||||
return ginresp.NotImplemented()
|
type uri struct {
|
||||||
|
UserID int64 `uri:"uid"`
|
||||||
|
}
|
||||||
|
type response struct {
|
||||||
|
Subscriptions []models.SubscriptionJSON `json:"subscriptions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var u uri
|
||||||
|
ctx, errResp := h.app.StartRequest(g, &u, nil, nil)
|
||||||
|
if errResp != nil {
|
||||||
|
return *errResp
|
||||||
|
}
|
||||||
|
defer ctx.Cancel()
|
||||||
|
|
||||||
|
if permResp := ctx.CheckPermissionUserRead(u.UserID); permResp != nil {
|
||||||
|
return *permResp
|
||||||
|
}
|
||||||
|
|
||||||
|
clients, err := h.database.ListSubscriptionsByOwner(ctx, u.UserID)
|
||||||
|
if err != nil {
|
||||||
|
return ginresp.InternAPIError(500, apierr.DATABASE_ERROR, "Failed to query channels", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := langext.ArrMap(clients, func(v models.Subscription) models.SubscriptionJSON { return v.JSON() })
|
||||||
|
|
||||||
|
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{Subscriptions: res}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListChannelSubscriptions swaggerdoc
|
||||||
|
//
|
||||||
|
// @Summary List all subscriptions of a channel
|
||||||
|
// @ID api-chan-subscriptions-list
|
||||||
|
//
|
||||||
|
// @Param uid path int true "UserID"
|
||||||
|
// @Param cid path int true "ChannelID"
|
||||||
|
//
|
||||||
|
// @Success 200 {object} handler.ListChannelSubscriptions.response
|
||||||
|
// @Failure 400 {object} ginresp.apiError
|
||||||
|
// @Failure 401 {object} ginresp.apiError
|
||||||
|
// @Failure 404 {object} ginresp.apiError
|
||||||
|
// @Failure 500 {object} ginresp.apiError
|
||||||
|
//
|
||||||
|
// @Router /api-v2/users/{uid}/channels/{cid}/subscriptions [GET]
|
||||||
func (h APIHandler) ListChannelSubscriptions(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) ListChannelSubscriptions(g *gin.Context) ginresp.HTTPResponse {
|
||||||
return ginresp.NotImplemented()
|
type uri struct {
|
||||||
|
UserID int64 `uri:"uid"`
|
||||||
|
ChannelID int64 `uri:"cid"`
|
||||||
|
}
|
||||||
|
type response struct {
|
||||||
|
Subscriptions []models.SubscriptionJSON `json:"subscriptions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var u uri
|
||||||
|
ctx, errResp := h.app.StartRequest(g, &u, nil, nil)
|
||||||
|
if errResp != nil {
|
||||||
|
return *errResp
|
||||||
|
}
|
||||||
|
defer ctx.Cancel()
|
||||||
|
|
||||||
|
if permResp := ctx.CheckPermissionUserRead(u.UserID); permResp != nil {
|
||||||
|
return *permResp
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := h.database.GetChannel(ctx, u.UserID, u.ChannelID)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return ginresp.InternAPIError(404, apierr.CHANNEL_NOT_FOUND, "Channel not found", err)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return ginresp.InternAPIError(500, apierr.DATABASE_ERROR, "Failed to query channels", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
clients, err := h.database.ListSubscriptionsByChannel(ctx, u.ChannelID)
|
||||||
|
if err != nil {
|
||||||
|
return ginresp.InternAPIError(500, apierr.DATABASE_ERROR, "Failed to query channels", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := langext.ArrMap(clients, func(v models.Subscription) models.SubscriptionJSON { return v.JSON() })
|
||||||
|
|
||||||
|
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{Subscriptions: res}))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSubscription swaggerdoc
|
||||||
|
//
|
||||||
|
// @Summary Get a single subscription
|
||||||
|
// @ID api-subscriptions-get
|
||||||
|
//
|
||||||
|
// @Param uid path int true "UserID"
|
||||||
|
// @Param sid path int true "SubscriptionID"
|
||||||
|
//
|
||||||
|
// @Success 200 {object} models.SubscriptionJSON
|
||||||
|
// @Failure 400 {object} ginresp.apiError
|
||||||
|
// @Failure 401 {object} ginresp.apiError
|
||||||
|
// @Failure 404 {object} ginresp.apiError
|
||||||
|
// @Failure 500 {object} ginresp.apiError
|
||||||
|
//
|
||||||
|
// @Router /api-v2/users/{uid}/subscriptions/{sid} [GET]
|
||||||
func (h APIHandler) GetSubscription(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) GetSubscription(g *gin.Context) ginresp.HTTPResponse {
|
||||||
return ginresp.NotImplemented()
|
type uri struct {
|
||||||
|
UserID int64 `uri:"uid"`
|
||||||
|
SubscriptionID int64 `uri:"sid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var u uri
|
||||||
|
ctx, errResp := h.app.StartRequest(g, &u, nil, nil)
|
||||||
|
if errResp != nil {
|
||||||
|
return *errResp
|
||||||
|
}
|
||||||
|
defer ctx.Cancel()
|
||||||
|
|
||||||
|
if permResp := ctx.CheckPermissionUserRead(u.UserID); permResp != nil {
|
||||||
|
return *permResp
|
||||||
|
}
|
||||||
|
|
||||||
|
subscription, err := h.database.GetSubscription(ctx, u.SubscriptionID)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return ginresp.InternAPIError(404, apierr.SUBSCRIPTION_NOT_FOUND, "Subscription not found", err)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return ginresp.InternAPIError(500, apierr.DATABASE_ERROR, "Failed to query channel", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if subscription.SubscriberUserID != u.UserID {
|
||||||
|
return ginresp.InternAPIError(401, apierr.USER_AUTH_FAILED, "You are not authorized for this action", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, subscription.JSON()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CancelSubscription swaggerdoc
|
||||||
|
//
|
||||||
|
// @Summary Cancel (delete) subscription
|
||||||
|
// @ID api-subscriptions-delete
|
||||||
|
//
|
||||||
|
// @Param uid path int true "UserID"
|
||||||
|
// @Param sid path int true "SubscriptionID"
|
||||||
|
//
|
||||||
|
// @Success 200 {object} models.SubscriptionJSON
|
||||||
|
// @Failure 400 {object} ginresp.apiError
|
||||||
|
// @Failure 401 {object} ginresp.apiError
|
||||||
|
// @Failure 404 {object} ginresp.apiError
|
||||||
|
// @Failure 500 {object} ginresp.apiError
|
||||||
|
//
|
||||||
|
// @Router /api-v2/users/{uid}/subscriptions/{sid} [DELETE]
|
||||||
func (h APIHandler) CancelSubscription(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) CancelSubscription(g *gin.Context) ginresp.HTTPResponse {
|
||||||
return ginresp.NotImplemented()
|
type uri struct {
|
||||||
|
UserID int64 `uri:"uid"`
|
||||||
|
SubscriptionID int64 `uri:"sid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var u uri
|
||||||
|
ctx, errResp := h.app.StartRequest(g, &u, nil, nil)
|
||||||
|
if errResp != nil {
|
||||||
|
return *errResp
|
||||||
|
}
|
||||||
|
defer ctx.Cancel()
|
||||||
|
|
||||||
|
if permResp := ctx.CheckPermissionUserRead(u.UserID); permResp != nil {
|
||||||
|
return *permResp
|
||||||
|
}
|
||||||
|
|
||||||
|
subscription, err := h.database.GetSubscription(ctx, u.SubscriptionID)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return ginresp.InternAPIError(404, apierr.SUBSCRIPTION_NOT_FOUND, "Subscription not found", err)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return ginresp.InternAPIError(500, apierr.DATABASE_ERROR, "Failed to query channel", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if subscription.SubscriberUserID != u.UserID {
|
||||||
|
return ginresp.InternAPIError(401, apierr.USER_AUTH_FAILED, "You are not authorized for this action", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.database.DeleteSubscription(ctx, u.SubscriptionID)
|
||||||
|
if err != nil {
|
||||||
|
return ginresp.InternAPIError(500, apierr.DATABASE_ERROR, "Failed to delete subscription", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, subscription.JSON()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h APIHandler) CreateSubscription(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) CreateSubscription(g *gin.Context) ginresp.HTTPResponse {
|
||||||
return ginresp.NotImplemented()
|
return ginresp.NotImplemented()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h APIHandler) UpdateSubscription(g *gin.Context) ginresp.HTTPResponse {
|
||||||
|
return ginresp.NotImplemented()
|
||||||
|
}
|
||||||
|
|
||||||
func (h APIHandler) ListMessages(g *gin.Context) ginresp.HTTPResponse {
|
func (h APIHandler) ListMessages(g *gin.Context) ginresp.HTTPResponse {
|
||||||
return ginresp.NotImplemented()
|
return ginresp.NotImplemented()
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,6 @@ func (h MessageHandler) SendMessage(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
ErrorHighlight int `json:"errhighlight"`
|
ErrorHighlight int `json:"errhighlight"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
SuppressSend bool `json:"suppress_send"`
|
SuppressSend bool `json:"suppress_send"`
|
||||||
Response string `json:"response"`
|
|
||||||
MessageCount int `json:"messagecount"`
|
MessageCount int `json:"messagecount"`
|
||||||
Quota int `json:"quota"`
|
Quota int `json:"quota"`
|
||||||
IsPro bool `json:"is_pro"`
|
IsPro bool `json:"is_pro"`
|
||||||
@ -145,10 +144,9 @@ func (h MessageHandler) SendMessage(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
return ginresp.JSON(http.StatusOK, response{
|
return ginresp.JSON(http.StatusOK, response{
|
||||||
Success: true,
|
Success: true,
|
||||||
ErrorID: apierr.NO_ERROR,
|
ErrorID: apierr.NO_ERROR,
|
||||||
ErrorHighlight: 0,
|
ErrorHighlight: -1,
|
||||||
Message: "Message already sent",
|
Message: "Message already sent",
|
||||||
SuppressSend: true,
|
SuppressSend: true,
|
||||||
Response: "",
|
|
||||||
MessageCount: user.MessagesSent,
|
MessageCount: user.MessagesSent,
|
||||||
Quota: user.QuotaUsedToday(),
|
Quota: user.QuotaUsedToday(),
|
||||||
IsPro: user.IsPro,
|
IsPro: user.IsPro,
|
||||||
@ -187,7 +185,7 @@ func (h MessageHandler) SendMessage(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
return ginresp.SendAPIError(500, apierr.DATABASE_ERROR, -1, "Failed to create message in db")
|
return ginresp.SendAPIError(500, apierr.DATABASE_ERROR, -1, "Failed to create message in db")
|
||||||
}
|
}
|
||||||
|
|
||||||
subscriptions, err := h.database.ListChannelSubscriptions(ctx, channel.ChannelID)
|
subscriptions, err := h.database.ListSubscriptionsByChannel(ctx, channel.ChannelID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ginresp.SendAPIError(500, apierr.DATABASE_ERROR, -1, "Failed to query subscriptions")
|
return ginresp.SendAPIError(500, apierr.DATABASE_ERROR, -1, "Failed to query subscriptions")
|
||||||
}
|
}
|
||||||
@ -216,7 +214,18 @@ func (h MessageHandler) SendMessage(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ginresp.NotImplemented()
|
return ginresp.JSON(http.StatusOK, response{
|
||||||
|
Success: true,
|
||||||
|
ErrorID: apierr.NO_ERROR,
|
||||||
|
ErrorHighlight: -1,
|
||||||
|
Message: "Message sent",
|
||||||
|
SuppressSend: false,
|
||||||
|
MessageCount: user.MessagesSent,
|
||||||
|
Quota: user.QuotaUsedToday(),
|
||||||
|
IsPro: user.IsPro,
|
||||||
|
QuotaMax: user.QuotaPerDay(),
|
||||||
|
SCNMessageID: msg.SCNMessageID,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h MessageHandler) deliverMessage(ctx *logic.AppContext, client models.Client, msg models.Message) (*string, error) {
|
func (h MessageHandler) deliverMessage(ctx *logic.AppContext, client models.Client, msg models.Message) (*string, error) {
|
||||||
|
@ -94,24 +94,25 @@ func (r *Router) Init(e *gin.Engine) {
|
|||||||
apiv2 := e.Group("/api-v2/")
|
apiv2 := e.Group("/api-v2/")
|
||||||
{
|
{
|
||||||
|
|
||||||
apiv2.POST("/user/", ginresp.Wrap(r.apiHandler.CreateUser))
|
apiv2.POST("/users/", ginresp.Wrap(r.apiHandler.CreateUser))
|
||||||
apiv2.GET("/user/:uid", ginresp.Wrap(r.apiHandler.GetUser))
|
apiv2.GET("/users/:uid", ginresp.Wrap(r.apiHandler.GetUser))
|
||||||
apiv2.PATCH("/user/:uid", ginresp.Wrap(r.apiHandler.UpdateUser))
|
apiv2.PATCH("/users/:uid", ginresp.Wrap(r.apiHandler.UpdateUser))
|
||||||
|
|
||||||
apiv2.GET("/user/:uid/clients", ginresp.Wrap(r.apiHandler.ListClients))
|
apiv2.GET("/users/:uid/clients", ginresp.Wrap(r.apiHandler.ListClients))
|
||||||
apiv2.GET("/user/:uid/clients/:cid", ginresp.Wrap(r.apiHandler.GetClient))
|
apiv2.GET("/users/:uid/clients/:cid", ginresp.Wrap(r.apiHandler.GetClient))
|
||||||
apiv2.POST("/user/:uid/clients", ginresp.Wrap(r.apiHandler.AddClient))
|
apiv2.POST("/users/:uid/clients", ginresp.Wrap(r.apiHandler.AddClient))
|
||||||
apiv2.DELETE("/user/:uid/clients", ginresp.Wrap(r.apiHandler.DeleteClient))
|
apiv2.DELETE("/users/:uid/clients", ginresp.Wrap(r.apiHandler.DeleteClient))
|
||||||
|
|
||||||
apiv2.GET("/user/:uid/channels", ginresp.Wrap(r.apiHandler.ListChannels))
|
apiv2.GET("/users/:uid/channels", ginresp.Wrap(r.apiHandler.ListChannels))
|
||||||
apiv2.GET("/user/:uid/channels/:cid", ginresp.Wrap(r.apiHandler.GetChannel))
|
apiv2.GET("/users/:uid/channels/:cid", ginresp.Wrap(r.apiHandler.GetChannel))
|
||||||
apiv2.GET("/user/:uid/channels/:cid/messages", ginresp.Wrap(r.apiHandler.GetChannelMessages))
|
apiv2.GET("/users/:uid/channels/:cid/messages", ginresp.Wrap(r.apiHandler.GetChannelMessages))
|
||||||
apiv2.GET("/user/:uid/channels/:cid/subscriptions", ginresp.Wrap(r.apiHandler.ListChannelSubscriptions))
|
apiv2.GET("/users/:uid/channels/:cid/subscriptions", ginresp.Wrap(r.apiHandler.ListChannelSubscriptions))
|
||||||
|
|
||||||
apiv2.GET("/user/:uid/subscriptions", ginresp.Wrap(r.apiHandler.ListUserSubscriptions))
|
apiv2.GET("/users/:uid/subscriptions", ginresp.Wrap(r.apiHandler.ListUserSubscriptions))
|
||||||
apiv2.GET("/user/:uid/subscriptions/:sid", ginresp.Wrap(r.apiHandler.GetSubscription))
|
apiv2.GET("/users/:uid/subscriptions/:sid", ginresp.Wrap(r.apiHandler.GetSubscription))
|
||||||
apiv2.DELETE("/user/:uid/subscriptions/:sid", ginresp.Wrap(r.apiHandler.CancelSubscription))
|
apiv2.DELETE("/users/:uid/subscriptions/:sid", ginresp.Wrap(r.apiHandler.CancelSubscription))
|
||||||
apiv2.POST("/user/:uid/subscriptions", ginresp.Wrap(r.apiHandler.CreateSubscription))
|
apiv2.POST("/users/:uid/subscriptions", ginresp.Wrap(r.apiHandler.CreateSubscription))
|
||||||
|
apiv2.PATCH("/users/:uid/subscriptions", ginresp.Wrap(r.apiHandler.UpdateSubscription))
|
||||||
|
|
||||||
apiv2.GET("/messages", ginresp.Wrap(r.apiHandler.ListMessages))
|
apiv2.GET("/messages", ginresp.Wrap(r.apiHandler.ListMessages))
|
||||||
apiv2.GET("/messages/:mid", ginresp.Wrap(r.apiHandler.GetMessage))
|
apiv2.GET("/messages/:mid", ginresp.Wrap(r.apiHandler.GetMessage))
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"blackforestbytes.com/simplecloudnotifier/logic"
|
||||||
"blackforestbytes.com/simplecloudnotifier/models"
|
"blackforestbytes.com/simplecloudnotifier/models"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||||
@ -413,7 +414,7 @@ func (db *Database) CreateMessage(ctx TxContext, senderUserID int64, channel mod
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Database) ListChannelSubscriptions(ctx TxContext, channelID int64) ([]models.Subscription, error) {
|
func (db *Database) ListSubscriptionsByChannel(ctx TxContext, channelID int64) ([]models.Subscription, error) {
|
||||||
tx, err := ctx.GetOrCreateTransaction(db)
|
tx, err := ctx.GetOrCreateTransaction(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -432,6 +433,25 @@ func (db *Database) ListChannelSubscriptions(ctx TxContext, channelID int64) ([]
|
|||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *Database) ListSubscriptionsByOwner(ctx TxContext, ownerUserID int64) ([]models.Subscription, error) {
|
||||||
|
tx, err := ctx.GetOrCreateTransaction(db)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := tx.QueryContext(ctx, "SELECT * FROM subscriptions WHERE channel_owner_user_id = ?", ownerUserID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := models.DecodeSubscriptions(rows)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (db *Database) CreateRetryDelivery(ctx TxContext, client models.Client, msg models.Message) (models.Delivery, error) {
|
func (db *Database) CreateRetryDelivery(ctx TxContext, client models.Client, msg models.Message) (models.Delivery, error) {
|
||||||
tx, err := ctx.GetOrCreateTransaction(db)
|
tx, err := ctx.GetOrCreateTransaction(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -512,3 +532,74 @@ func (db *Database) CreateSuccessDelivery(ctx TxContext, client models.Client, m
|
|||||||
FCMMessageID: langext.Ptr(fcmDelivID),
|
FCMMessageID: langext.Ptr(fcmDelivID),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *Database) ListChannels(ctx *logic.AppContext, userid int64) ([]models.Channel, error) {
|
||||||
|
tx, err := ctx.GetOrCreateTransaction(db)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := tx.QueryContext(ctx, "SELECT * FROM channels WHERE owner_user_id = ?", userid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := models.DecodeChannels(rows)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) GetChannel(ctx TxContext, userid int64, channelid int64) (models.Channel, error) {
|
||||||
|
tx, err := ctx.GetOrCreateTransaction(db)
|
||||||
|
if err != nil {
|
||||||
|
return models.Channel{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := tx.QueryContext(ctx, "SELECT * FROM channels WHERE owner_user_id = ? AND channel_id = ? LIMIT 1", userid, channelid)
|
||||||
|
if err != nil {
|
||||||
|
return models.Channel{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := models.DecodeChannel(rows)
|
||||||
|
if err != nil {
|
||||||
|
return models.Channel{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) GetSubscription(ctx *logic.AppContext, subid int64) (models.Subscription, error) {
|
||||||
|
tx, err := ctx.GetOrCreateTransaction(db)
|
||||||
|
if err != nil {
|
||||||
|
return models.Subscription{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := tx.QueryContext(ctx, "SELECT * FROM subscriptions WHERE subscription_id = ? LIMIT 1", subid)
|
||||||
|
if err != nil {
|
||||||
|
return models.Subscription{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sub, err := models.DecodeSubscription(rows)
|
||||||
|
if err != nil {
|
||||||
|
return models.Subscription{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sub, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *Database) DeleteSubscription(ctx *logic.AppContext, subid int64) error {
|
||||||
|
tx, err := ctx.GetOrCreateTransaction(db)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = tx.ExecContext(ctx, "DELETE FROM subscriptions WHERE subscription_id = ?", subid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -47,11 +47,20 @@ type Notification struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fb App) SendNotification(ctx context.Context, client models.Client, msg models.Message) (string, error) {
|
func (fb App) SendNotification(ctx context.Context, client models.Client, msg models.Message) (string, error) {
|
||||||
|
|
||||||
n := messaging.Message{
|
n := messaging.Message{
|
||||||
Data: map[string]string{"scn_msg_id": strconv.FormatInt(msg.SCNMessageID, 10)},
|
Data: map[string]string{
|
||||||
|
"scn_msg_id": strconv.FormatInt(msg.SCNMessageID, 10),
|
||||||
|
"usr_msg_id": langext.Coalesce(msg.UserMessageID, ""),
|
||||||
|
"timestamp": strconv.FormatInt(msg.Timestamp().Unix(), 10),
|
||||||
|
"priority": strconv.Itoa(msg.Priority),
|
||||||
|
"trimmed": langext.Conditional(msg.NeedsTrim(), "true", "false"),
|
||||||
|
"title": msg.Title,
|
||||||
|
"body": msg.TrimmedBody(),
|
||||||
|
},
|
||||||
Notification: &messaging.Notification{
|
Notification: &messaging.Notification{
|
||||||
Title: msg.Title,
|
Title: msg.Title,
|
||||||
Body: langext.Coalesce(msg.Content, ""),
|
Body: msg.ShortBody(),
|
||||||
},
|
},
|
||||||
Android: nil,
|
Android: nil,
|
||||||
APNS: nil,
|
APNS: nil,
|
||||||
@ -61,12 +70,12 @@ func (fb App) SendNotification(ctx context.Context, client models.Client, msg mo
|
|||||||
Topic: "",
|
Topic: "",
|
||||||
Condition: "",
|
Condition: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
if client.Type == models.ClientTypeIOS {
|
if client.Type == models.ClientTypeIOS {
|
||||||
n.APNS = nil
|
n.APNS = nil
|
||||||
}
|
} else if client.Type == models.ClientTypeAndroid {
|
||||||
|
n.Notification = nil
|
||||||
if client.Type == models.ClientTypeAndroid {
|
n.Android = &messaging.AndroidConfig{Priority: "high"}
|
||||||
n.Android = nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := fb.messaging.Send(ctx, &n)
|
res, err := fb.messaging.Send(ctx, &n)
|
||||||
|
@ -9,7 +9,7 @@ require (
|
|||||||
github.com/mattn/go-sqlite3 v1.14.16
|
github.com/mattn/go-sqlite3 v1.14.16
|
||||||
github.com/rs/zerolog v1.28.0
|
github.com/rs/zerolog v1.28.0
|
||||||
github.com/swaggo/swag v1.8.7
|
github.com/swaggo/swag v1.8.7
|
||||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.20
|
gogs.mikescher.com/BlackForestBytes/goext v0.0.21
|
||||||
google.golang.org/api v0.103.0
|
google.golang.org/api v0.103.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -168,6 +168,8 @@ gogs.mikescher.com/BlackForestBytes/goext v0.0.19 h1:IvCHlIHDviHQXntZFTNdV7qNq5y
|
|||||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.19/go.mod h1:TMBOjo3FRFh/GiTT0z3nwLmgcFJB87oSF2VMs4XUCTQ=
|
gogs.mikescher.com/BlackForestBytes/goext v0.0.19/go.mod h1:TMBOjo3FRFh/GiTT0z3nwLmgcFJB87oSF2VMs4XUCTQ=
|
||||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.20 h1:HxJ0iZ838TQnp/a+/DNajdZjZkV43OsK4VbHarOiHTs=
|
gogs.mikescher.com/BlackForestBytes/goext v0.0.20 h1:HxJ0iZ838TQnp/a+/DNajdZjZkV43OsK4VbHarOiHTs=
|
||||||
gogs.mikescher.com/BlackForestBytes/goext v0.0.20/go.mod h1:TMBOjo3FRFh/GiTT0z3nwLmgcFJB87oSF2VMs4XUCTQ=
|
gogs.mikescher.com/BlackForestBytes/goext v0.0.20/go.mod h1:TMBOjo3FRFh/GiTT0z3nwLmgcFJB87oSF2VMs4XUCTQ=
|
||||||
|
gogs.mikescher.com/BlackForestBytes/goext v0.0.21 h1:OibsssmorZsTdFYRiQFlkXtjUYweQg9SBkWO40ONe0Y=
|
||||||
|
gogs.mikescher.com/BlackForestBytes/goext v0.0.21/go.mod h1:TMBOjo3FRFh/GiTT0z3nwLmgcFJB87oSF2VMs4XUCTQ=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
|
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
|
||||||
|
@ -28,15 +28,39 @@ func (m Message) JSON() MessageJSON {
|
|||||||
OwnerUserID: m.OwnerUserID,
|
OwnerUserID: m.OwnerUserID,
|
||||||
ChannelName: m.ChannelName,
|
ChannelName: m.ChannelName,
|
||||||
ChannelID: m.ChannelID,
|
ChannelID: m.ChannelID,
|
||||||
Timestamp: langext.Coalesce(m.TimestampClient, m.TimestampReal).Format(time.RFC3339Nano),
|
Timestamp: m.Timestamp().Format(time.RFC3339Nano),
|
||||||
Title: m.Title,
|
Title: m.Title,
|
||||||
Content: m.Content,
|
Content: m.Content,
|
||||||
Priority: m.Priority,
|
Priority: m.Priority,
|
||||||
UserMessageID: m.UserMessageID,
|
UserMessageID: m.UserMessageID,
|
||||||
Trimmed: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m Message) Timestamp() time.Time {
|
||||||
|
return langext.Coalesce(m.TimestampClient, m.TimestampReal)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Message) NeedsTrim() bool {
|
||||||
|
return m.Content != nil && len(*m.Content) > 1900
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Message) TrimmedBody() string {
|
||||||
|
if !m.NeedsTrim() {
|
||||||
|
return langext.Coalesce(m.Content, "")
|
||||||
|
}
|
||||||
|
return langext.Coalesce(m.Content, "")[0:1900-3] + "..."
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Message) ShortBody() string {
|
||||||
|
if m.Content == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if len(*m.Content) < 200 {
|
||||||
|
return *m.Content
|
||||||
|
}
|
||||||
|
return (*m.Content)[0:200-3] + "..."
|
||||||
|
}
|
||||||
|
|
||||||
type MessageJSON struct {
|
type MessageJSON struct {
|
||||||
SCNMessageID int64 `json:"scn_message_id"`
|
SCNMessageID int64 `json:"scn_message_id"`
|
||||||
SenderUserID int64 `json:"sender_user_id"`
|
SenderUserID int64 `json:"sender_user_id"`
|
||||||
@ -48,7 +72,6 @@ type MessageJSON struct {
|
|||||||
Content *string `json:"body"`
|
Content *string `json:"body"`
|
||||||
Priority int `json:"priority"`
|
Priority int `json:"priority"`
|
||||||
UserMessageID *string `json:"usr_message_id"`
|
UserMessageID *string `json:"usr_message_id"`
|
||||||
Trimmed bool `json:"trimmed"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type MessageDB struct {
|
type MessageDB struct {
|
||||||
|
@ -91,7 +91,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api-v2/user/": {
|
"/api-v2/users/": {
|
||||||
"post": {
|
"post": {
|
||||||
"summary": "Create a new user",
|
"summary": "Create a new user",
|
||||||
"operationId": "api-user-create",
|
"operationId": "api-user-create",
|
||||||
@ -127,7 +127,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api-v2/user/{uid}": {
|
"/api-v2/users/{uid}": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "Get a user",
|
"summary": "Get a user",
|
||||||
"operationId": "api-user-get",
|
"operationId": "api-user-get",
|
||||||
@ -221,7 +221,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api-v2/user/{uid}/clients": {
|
"/api-v2/users/{uid}/clients": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "List all clients",
|
"summary": "List all clients",
|
||||||
"operationId": "api-clients-list",
|
"operationId": "api-clients-list",
|
||||||
@ -320,7 +320,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api-v2/user/{uid}/clients/{cid}": {
|
"/api-v2/users/{uid}/clients/{cid}": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "Get a single clients",
|
"summary": "Get a single clients",
|
||||||
"operationId": "api-clients-get",
|
"operationId": "api-clients-get",
|
||||||
|
@ -340,7 +340,7 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/ginresp.apiError'
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
summary: Send a new message
|
summary: Send a new message
|
||||||
/api-v2/user/:
|
/api-v2/users/:
|
||||||
post:
|
post:
|
||||||
operationId: api-user-create
|
operationId: api-user-create
|
||||||
parameters:
|
parameters:
|
||||||
@ -363,7 +363,7 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/ginresp.apiError'
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
summary: Create a new user
|
summary: Create a new user
|
||||||
/api-v2/user/{uid}:
|
/api-v2/users/{uid}:
|
||||||
get:
|
get:
|
||||||
operationId: api-user-get
|
operationId: api-user-get
|
||||||
parameters:
|
parameters:
|
||||||
@ -425,7 +425,7 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/ginresp.apiError'
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
summary: (Partially) update a user
|
summary: (Partially) update a user
|
||||||
/api-v2/user/{uid}/clients:
|
/api-v2/users/{uid}/clients:
|
||||||
get:
|
get:
|
||||||
operationId: api-clients-list
|
operationId: api-clients-list
|
||||||
parameters:
|
parameters:
|
||||||
@ -491,7 +491,7 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/ginresp.apiError'
|
$ref: '#/definitions/ginresp.apiError'
|
||||||
summary: Delete a client
|
summary: Delete a client
|
||||||
/api-v2/user/{uid}/clients/{cid}:
|
/api-v2/users/{uid}/clients/{cid}:
|
||||||
get:
|
get:
|
||||||
operationId: api-clients-get
|
operationId: api-clients-get
|
||||||
parameters:
|
parameters:
|
||||||
|
Loading…
Reference in New Issue
Block a user