Exemplo n.º 1
0
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
}