예제 #1
0
func Create(u *url.URL, h http.Header, reply *models.ChannelMessage, c *models.Context) (int, http.Header, interface{}, error) {
	parentId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	// fetch the parent message
	parent, err := models.Cache.Message.ById(parentId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	parentChannel, err := models.Cache.Channel.ById(parent.InitialChannelId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	canOpen, err := parentChannel.CanOpen(c.Client.Account.Id)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !canOpen {
		return response.NewAccessDenied(models.ErrCannotOpenChannel)
	}

	// first create reply as a message
	reply.TypeConstant = models.ChannelMessage_TYPE_REPLY

	// set initial channel id for message creation
	reply.InitialChannelId = parent.InitialChannelId

	reply.AccountId = c.Client.Account.Id

	if err := reply.Create(); err != nil {
		// todo this should be internal server error
		return response.NewBadRequest(err)
	}

	// then add this message as a reply to a parent message
	mr := models.NewMessageReply()
	mr.MessageId = parentId
	mr.ReplyId = reply.Id
	mr.CreatedAt = reply.CreatedAt
	mr.ClientRequestId = reply.ClientRequestId
	if err := mr.Create(); err != nil {
		// todo this should be internal server error
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(
		reply.BuildEmptyMessageContainer(),
	)
}
예제 #2
0
func Create(u *url.URL, h http.Header, req *models.ChannelMessage, c *models.Context) (int, http.Header, interface{}, error) {

	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrAccessDenied)
	}

	channelId, err := fetchInitialChannelId(u, c)
	if err != nil {
		return response.NewBadRequest(err)
	}

	ch := models.NewChannel()
	if err := ch.ById(channelId); err != nil {
		return response.NewBadRequest(models.ErrChannelNotFound)
	}

	canOpen, err := ch.CanOpen(c.Client.Account.Id)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !canOpen {
		return response.NewBadRequest(models.ErrCannotOpenChannel)
	}

	// override message type
	// all of the messages coming from client-side
	// should be marked as POST
	req.TypeConstant = models.ChannelMessage_TYPE_POST

	req.InitialChannelId = channelId

	req.AccountId = c.Client.Account.Id

	if req.Payload == nil {
		req.Payload = gorm.Hstore{}
	}

	if c.Client.Account.IsShareLocationEnabled() {
		// gets the IP of the Client
		// and adds it to the payload of the ChannelMessage
		location := parseLocation(c)
		req.Payload["location"] = location
	}

	if err := checkThrottle(channelId, req.AccountId); err != nil {
		return response.NewBadRequest(err)
	}

	if err := req.Create(); err != nil {
		// todo this should be internal server error
		return response.NewBadRequest(err)
	}

	cml := models.NewChannelMessageList()
	// override channel id
	cml.ChannelId = channelId
	cml.MessageId = req.Id
	cml.ClientRequestId = req.ClientRequestId
	if err := cml.Create(); err != nil && !models.IsUniqueConstraintError(err) {
		// todo this should be internal server error
		return response.NewBadRequest(err)
	}

	cmc := models.NewChannelMessageContainer()
	err = cmc.Fetch(req.Id, request.GetQuery(u))
	if err != nil {
		return response.NewBadRequest(err)
	}

	// assign client request id back to message response because
	// client uses it for latency compansation
	cmc.Message.ClientRequestId = req.ClientRequestId
	return response.HandleResultAndError(cmc, err)
}