var mongoose = require('mongoose') var findOrCreate = require('mongoose-findorcreate') var _ = require('lodash') var db, PushToken, Notification, Channel mongoose.Promise = require('bluebird') function init (config) { db = mongoose.connect(config.mongodbUrl) mongoose.connection.on('error', errorHandler) var pushTokenSchema = new db.Schema({ platform: { type: 'String', required: true, lowercase: true, enum: ['ios', 'android'], }, token: { type: 'String', required: true, unique: true, }, channel: { type: 'String', required: true, }, }) var channelSchema = new db.Schema({ channel: { type: 'String', required: true, lowercase: true, }, last_push: { type: 'Date', required: true, } }) channelSchema.plugin(findOrCreate); var notificationSchema = new db.Schema({ channel: { type: 'String', required: true, lowercase: true, }, date: { type: 'Date', required: true, } }) module.exports.PushToken = PushToken = db.model('PushToken', pushTokenSchema) module.exports.Notification = Notification = db.model('Notification', notificationSchema) module.exports.Channel = Channel = db.model('Channel', channelSchema) } function errorHandler (error) { console.error('ERROR: ' + error) } /* devices / tokens */ function addToken (data) { return new PushToken(data).save() } function getAllIOSTokens (channel, cb) { PushToken.distinct("token", { channel: channel, platform: 'ios' }, function (err, tokens) { if (err) return cb(err, []) return cb(null, tokens) }) } function getAllAndroidTokens (channel, cb) { PushToken.distinct("token", { channel: channel, platform: 'android' }, function (err, tokens) { if (err) return cb(err, []) return cb(null, tokens) }) } function getAllTokens (channel, cb) { PushToken.find({ channel: channel }, function (err, items) { if (err) return cb(err, []) var items = items.map(function (item) { return { platform: item.get('platform'), token: item.get('token') } }) return cb(null, items) }) } function removeToken (data) { PushToken.find(data).remove().exec() } function getDeviceCount (channels, cb) { var countz = {} get_next() function get_next() { var channel = channels.pop() PushToken.distinct("token", { channel: channel }, function(err, tokens){ countz[channel] = tokens.length if (channels.length) { return get_next() } else { cb(countz) } }) } } /* notifications */ function addNotification (channel, cb) { var now = new Date Channel.findOrCreate({channel: channel}, {last_push: now}, function(err, note, created) { if (err) { console.error("Error finding/creating notification", err) cb(err, false) return } else if (! created) { note.last_push = now note.save() } cb(null, note) }) new Notification ({ channel: channel, date: now, }).save() } function getNotifications (cb) { Notification.find(function (err, items) { if (err) return cb(err, null) var items = _.map(items, function (item) { return _.pick(item, ['channel', 'last_push']) }) return cb(null, items) }) } /* wrap functions for some reason */ module.exports = { init: init, addToken: addToken, removeToken: removeToken, getAllTokens: getAllTokens, getAllIOSTokens: getAllIOSTokens, getAllAndroidTokens: getAllAndroidTokens, getDeviceCount: getDeviceCount, addNotification: addNotification, getNotifications: getNotifications, }