func MyActiveOrg(orgIdHex string) (activeOrg *ws.ActiveOrg, err error) { mu.Lock() defer mu.Unlock() // Validation: The org id should be valid orgId, err := utils.ToObjectId(orgIdHex) if err != nil { utils.PrintStackAndError(err) return } // Already running in the map activeOrg, exist := activeOrgMap[orgIdHex] if exist { return } // Should init the org and put into map for further use org, err := organizations.FindById(orgId) if err != nil { utils.PrintStackAndError(err) return } // Find and maintain all dbs for handling shared groups allDBs := []*mgodb.Database{org.Database} embedOrgs, err := organizations.FindByIds(org.EmbededOrgIds) if err != nil { utils.PrintStackAndError(err) return } for _, embedOrg := range embedOrgs { allDBs = append(allDBs, embedOrg.Database) } // Init the activeOrg and put it into the map activeOrg = &ws.ActiveOrg{ OrgId: orgIdHex, Organization: org, OnlineUsers: make(map[bson.ObjectId]*ws.OnlineUser), Broadcast: make(chan ws.GenericPushingMessage), CloseSign: make(chan bool), AllDBs: allDBs, } go runActiveOrg(activeOrg) activeOrgMap[orgIdHex] = activeOrg return }
func SendEntryNotification(entryTopicData *nsqproducers.EntryTopicData) (err error) { serv, err := MakeWsService(entryTopicData.OrgId, entryTopicData.UserId) if err != nil { utils.PrintStackAndError(err) return } apiEntry := entryTopicData.ApiEntry currentOrg := serv.CurrentOrg currentUser := serv.LoggedInUser // TODO: the db should be group db, not current org db db := currentOrg.Database entry, err := entries.FindById(db, bson.ObjectIdHex(apiEntry.Id)) if err != nil { utils.PrintStackAndError(err) return } var entity notifications.Entity switch entryTopicData.Status { case nsqproducers.TOPIC_STATUS_CREATE, nsqproducers.TOPIC_STATUS_DELETE, nsqproducers.TOPIC_STATUS_UPDATE: entity = notifications.MakeEntryEntity(db, currentOrg, currentUser, entry) case nsqproducers.TOPIC_STATUS_LIKE, nsqproducers.TOPIC_STATUS_REMOVE_LIKE: hasLiked := (entryTopicData.Status == nsqproducers.TOPIC_STATUS_LIKE) entity = notifications.NewLikeEntity(currentOrg, currentUser, entry, hasLiked) } // currentTime := time.Now() causedEntry := entity.CausedEntry() causedEntries := entity.CausedEntries() eventMap := entity.Events(db) // Save or delete notification items if err := entity.HandleNotificationItems(db, eventMap); err != nil { utils.PrintStackAndError(err) // dont' return } orgIds := entity.GetToNotifyOrgIds() // Build organization map for shared group user orgMap := make(map[string]*organizations.Organization) orgs, err := organizations.FindByIds(utils.TurnPlainIdsToObjectIds(orgIds)) if err == nil { for _, org := range orgs { orgMap[org.Id.Hex()] = org } } onlineUsers := GetOnlineUsersByOrgIds(orgIds) emailToUserMap := make(map[string]bool) // Handle event for each user for toUserId, event := range eventMap { // If it is Qortex Support, then the key of the eventMap is "userId-organizationId", // which is used to differentiate same user in different organizations toUserId = strings.Split(toUserId, "-")[0] toUserObjectId := bson.ObjectIdHex(toUserId) orgId := bson.ObjectIdHex(event.ToUser.OriginalOrgId) // don't notify anything to sender if currentUser.Id == toUserObjectId && entity.NotNotifySelf() { continue } if entity.NeedResetUserCount() { if causedEntries != nil { for _, causedEntry := range causedEntries { notifications.ResetCount(db, toUserObjectId, causedEntry.GroupId, orgId) } } else { // Reset user mycount for event user notifications.ResetCount(db, toUserObjectId, causedEntry.GroupId, orgId) } } onlineUser := pickOnlineUser(toUserObjectId, onlineUsers) if onlineUser == nil { // Don't send mail multi times to the same member when posting a Qortex Support _, exist := emailToUserMap[toUserId] if !exist && event.NeedToSendNotificationMail() { // Send Mail if user offline, only work in Dev and Production // serv.SendNotificationMail(event, apiEntry, currentTime, orgMap) } } else if entity.NeetToSendRealtimeNotification(onlineUser.User) { makeAndPushEventReply(currentUser, event, entity, onlineUser) } emailToUserMap[toUserId] = true } return }