func (f *Controller) sendChannelEvent(cml *models.ChannelMessageList, cm *models.ChannelMessage, eventName string) error { cmc, err := cm.BuildEmptyMessageContainer() if err != nil { return err } return f.publishToChannel(cml.ChannelId, eventName, cmc) }
// MessageUpdated controls message updated status // if an error occurred , returns error otherwise returns nil func (f *Controller) MessageUpdated(cm *models.ChannelMessage) error { if len(cm.Token) == 0 { if err := cm.ById(cm.Id); err != nil { return err } } if err := f.sendInstanceEvent(cm, cm, UpdateInstanceEventName); err != nil { f.log.Error(err.Error()) return err } return nil }
func UpdateInstance(m *models.ChannelMessage, eventName string, body interface{}) error { // While sending message instance updates, instead of creating new PubNub channel for each message // we are sending the events to parent channels. For this reason, we need channel tokens. // For public messages we are sending instance events to each message's group channel c, err := m.FetchParentChannel() if err != nil { return err } request := map[string]interface{}{ "token": m.Token, "eventName": eventName, "body": body, "messageId": m.Id, "channelToken": c.Token, } return bongo.B.Emit("dispatcher_message_updated", request) }
func UpdatePost(cm *models.ChannelMessage, token string) (*models.ChannelMessage, error) { cm.Body = "after update" url := fmt.Sprintf("/message/%d", cm.Id) cmI, err := sendModelWithAuth("POST", url, cm, token) if err != nil { return nil, err } return cmI.(*models.ChannelMessage), nil }
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(), ) }
func Update(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) } id, err := request.GetURIInt64(u, "id") if err != nil { return response.NewBadRequest(err) } body := req.Body payload := req.Payload if err := req.ById(id); err != nil { if err == bongo.RecordNotFound { return response.NewNotFound() } return response.NewBadRequest(err) } if req.AccountId != c.Client.Account.Id { isAdmin, err := modelhelper.IsAdmin(c.Client.Account.Nick, c.GroupName) if err != nil { return response.NewBadRequest(err) } if !isAdmin { return response.NewBadRequest(models.ErrAccessDenied) } } if req.Id == 0 { return response.NewBadRequest(err) } req.Body = body req.Payload = payload if err := req.Update(); err != nil { return response.NewBadRequest(err) } cmc := models.NewChannelMessageContainer() return response.HandleResultAndError(cmc, cmc.Fetch(id, request.GetQuery(u))) }
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) }