diff --git a/controllers/kapistir.js b/controllers/kapistir.js index ba0c67c..88d9c38 100644 --- a/controllers/kapistir.js +++ b/controllers/kapistir.js @@ -28,7 +28,9 @@ KapistirController.prototype.all = function(request, reply) { reply(Boom.notFound(e.message)); } }; - +KapistirController.prototype.ref = function(request, reply) { + reply.view('ref',null); +}; diff --git a/controllers/question.js b/controllers/question.js index 14ea95f..86b0f90 100644 --- a/controllers/question.js +++ b/controllers/question.js @@ -2,17 +2,19 @@ var Boom = require('boom'); var QuestionModel = require('../models/question'); +var UserModel = require('../models/user'); var cloudinary = require('cloudinary'); var fs = require('fs'); -var config_params = require(__dirname + '/../config/config.json'); +var config_params = require(__dirname + '/../config/config.json'); var async = require('async'); function QuestionController(db) { this.questionModel = new QuestionModel(db); + this.userModel = new UserModel(db); }; -QuestionController.prototype.addQuestion = function(request, reply) { +QuestionController.prototype.addQuestion = function (request, reply) { try { var newQuestion = { "user_id": request.payload.user_id, @@ -29,21 +31,56 @@ QuestionController.prototype.addQuestion = function(request, reply) { newQuestion.question_image = request.payload.question_image; newQuestion.option_b = 'hayir'; newQuestion.option_a = 'evet'; - } + newQuestion.is_private = request.payload.is_private == null ? false : request.payload.is_private; + newQuestion.private_url = request.payload.private_url == null ? "" : request.payload.private_url; - this.questionModel.insertQuestion(newQuestion, function(createdQuestion) { + } + var self = this; + async.waterfall([ + function (callback) { + self.questionModel.insertQuestion(newQuestion, function (createdQuestion) { + callback(null, createdQuestion); + }); + }, + function (createdQuestion, callback) { + if (!request.payload.notify_friend) { + callback(null, createdQuestion); + } else { + var friendsArray = []; + self.userModel.getUserFriends(newQuestion.user_id, newQuestion.app, function (users) { + if (users.length == 0) { + callback(null, createdQuestion); + } + else { + for (var i = 0; i < users.length; i++) { + var mUser = users[i]; + if (mUser.reg_id != null || mUser.reg_id != "") { + friendsArray.push(mUser.reg_id); + } + } + self.userModel.findUserById(newQuestion.user_id, function (userinfo) { + createdQuestion.asker_name=userinfo.name; + self.questionModel.notifyFriends(createdQuestion, friendsArray, function (err, info) { + callback(null, createdQuestion); + }); + }); + + } + }); + } + } + ], function (err, createdQuestion) { reply({ data: createdQuestion }); }); - } catch (e) { reply(Boom.badRequest(e.message)); } }; -QuestionController.prototype.editQuestion = function(request, reply) { +QuestionController.prototype.editQuestion = function (request, reply) { try { - var newQuestion = { + var newQuestion = { "id": request.params.id }; @@ -59,7 +96,7 @@ QuestionController.prototype.editQuestion = function(request, reply) { newQuestion.option_a = 'evet'; } - this.questionModel.editQuestion(newQuestion, function(editedQuestion) { + this.questionModel.editQuestion(newQuestion, function (editedQuestion) { reply({ data: editedQuestion }); }); @@ -71,10 +108,10 @@ QuestionController.prototype.editQuestion = function(request, reply) { // [GET] /tasks/{id} -QuestionController.prototype.all = function(request, reply) { +QuestionController.prototype.all = function (request, reply) { try { - this.questionModel.showAllQuestions(function(data) { + this.questionModel.showAllQuestions(function (data) { reply(data); }); @@ -83,25 +120,25 @@ QuestionController.prototype.all = function(request, reply) { } }; -QuestionController.prototype.userQuestions = function(request, reply) { +QuestionController.prototype.userQuestions = function (request, reply) { - this.questionModel.userQuestions(request.params.app, request.query.user_id, request.query.limit,function(data) { - reply({ - data: { - "count": data.length, - "rows": data - } - }); + this.questionModel.userQuestions(request.params.app, request.query.user_id, request.query.limit, function (data) { + reply({ + data: { + "count": data.length, + "rows": data + } }); + }); }; -QuestionController.prototype.fetch = function(request, reply) { +QuestionController.prototype.fetch = function (request, reply) { try { var uId = (request.query.user_id || request.query.user_id.length > 0) ? request.query.user_id : null; - this.questionModel.fetchQuestions(request.params.app, request.query.limit, uId, request.headers['x-voter-installation'],request.query.debug, function(data) { + this.questionModel.fetchQuestions(request.params.app, request.query.limit, uId, request.headers['x-voter-installation'], request.query.debug, function (data) { reply({ data: { "count": data.length, @@ -115,16 +152,16 @@ QuestionController.prototype.fetch = function(request, reply) { } }; -QuestionController.prototype.getOne = function(request, reply) { +QuestionController.prototype.getOne = function (request, reply) { try { var uId = request.query.user_id; var qId = request.params.id; var app = request.query.app; - this.questionModel.getQuestion(uId, qId, app, function(data) { + this.questionModel.getQuestion(uId, qId, app, function (data) { reply({ - data: { + data: { "rows": data } }); @@ -135,10 +172,10 @@ QuestionController.prototype.getOne = function(request, reply) { } }; -QuestionController.prototype.delete = function(request, reply) { +QuestionController.prototype.delete = function (request, reply) { try { - this.questionModel.deleteQuestion(request.params.id, function(data) { + this.questionModel.deleteQuestion(request.params.id, function (data) { reply({ data: null }); @@ -152,7 +189,7 @@ QuestionController.prototype.delete = function(request, reply) { -QuestionController.prototype.upload = function(request, reply) { +QuestionController.prototype.upload = function (request, reply) { try { cloudinary.config(config_params["cloudinary"]); @@ -168,15 +205,15 @@ QuestionController.prototype.upload = function(request, reply) { var path = __dirname + "/../uploads/" + name; var file = fs.createWriteStream(path); - file.on('error', function(err) { + file.on('error', function (err) { console.error(err); }); data.file.pipe(file); - data.file.on('end', function(err) { + data.file.on('end', function (err) { - cloudinary.uploader.upload(path, function(result) { + cloudinary.uploader.upload(path, function (result) { fs.unlink(path, (err) => { if (err) throw err; reply({ data: result.url }); diff --git a/controllers/user.js b/controllers/user.js index b80a515..1328a84 100644 --- a/controllers/user.js +++ b/controllers/user.js @@ -41,6 +41,7 @@ UserController.prototype.signup = function(request, reply) { data.imei = request.headers['x-voter-installation']; data.app = parseInt(request.headers['x-voter-client-id']); data.last_fb_token = request.payload.token; + data.reg_id=request.payload.reg_id==null?'':request.payload.reg_id; for (var i = 0; i < res.friends.data.length; i++) { diff --git a/db_schemas/question.js b/db_schemas/question.js index ec1420c..3ae600a 100644 --- a/db_schemas/question.js +++ b/db_schemas/question.js @@ -2,7 +2,7 @@ var Sequelize = require('sequelize'); -module.exports = function(sequelize, DataTypes) { +module.exports = function (sequelize, DataTypes) { var question = sequelize.define("question", { id: { type: Sequelize.UUID, @@ -22,15 +22,17 @@ module.exports = function(sequelize, DataTypes) { updated_at: { type: DataTypes.DATE, defaultValue: DataTypes.NOW }, is_deleted: { type: DataTypes.BOOLEAN, defaultValue: false }, abuse_count: { type: DataTypes.INTEGER, defaultValue: 0 }, - favorite_count: { type: DataTypes.INTEGER, defaultValue: 0 } + favorite_count: { type: DataTypes.INTEGER, defaultValue: 0 }, + is_private: { type: DataTypes.BOOLEAN, defaultValue: false }, + private_url: DataTypes.STRING, }, { - tableName: 'question', - schema: 'public', - freezeTableName: true, - timestamps: false, - hasTrigger: true - }); + tableName: 'question', + schema: 'public', + freezeTableName: true, + timestamps: false, + hasTrigger: true + }); return question; }; diff --git a/db_schemas/user.js b/db_schemas/user.js index ff1b313..4aba687 100644 --- a/db_schemas/user.js +++ b/db_schemas/user.js @@ -18,7 +18,8 @@ module.exports = function(sequelize, DataTypes) { is_deleted: { type: DataTypes.BOOLEAN, defaultValue: false }, friends: { type: DataTypes.ARRAY(DataTypes.STRING), defaultValue: null }, app: DataTypes.INTEGER, - last_fb_token: DataTypes.STRING + last_fb_token: DataTypes.STRING, + reg_id: DataTypes.STRING, }, { diff --git a/index.js b/index.js index 0d716d8..698f7ed 100644 --- a/index.js +++ b/index.js @@ -12,9 +12,9 @@ var server = new Hapi.Server({ debug: { request: ['info', 'error'], log: ['info' server.connection({ - host: '0.0.0.0', + host: '0.0.0.0', - // host: 'localhost', + //host: 'localhost', port: process.env.PORT || 8000 }); diff --git a/models/question.js b/models/question.js index 8fe4cdd..f64c0d4 100644 --- a/models/question.js +++ b/models/question.js @@ -2,33 +2,34 @@ var crypto = require('crypto'); var Sequelize = require('sequelize'); +var request = require('request'); function QuestionModel(db) { this.questionSchema = db.question; this.sequelize = db.sequelize; }; -QuestionModel.prototype.insertQuestion = function(question, cb) { +QuestionModel.prototype.insertQuestion = function (question, cb) { - this.questionSchema.create(question).then(function(createdQuestion) { + this.questionSchema.create(question).then(function (createdQuestion) { cb(createdQuestion); }); }; -QuestionModel.prototype.editQuestion = function(question, cb) { +QuestionModel.prototype.editQuestion = function (question, cb) { this.questionSchema.findOne({ where: { id: question.id } - }).then(function(db_question) { + }).then(function (db_question) { db_question.option_a = question.option_a; db_question.option_b = question.option_b; db_question.question_text = question.question_text; db_question.question_image = question.question_image; - db_question.save({ fields: ['option_a', 'option_b', 'question_text', 'question_image'] }).then(function() { + db_question.save({ fields: ['option_a', 'option_b', 'question_text', 'question_image'] }).then(function () { cb(db_question); }); @@ -36,31 +37,31 @@ QuestionModel.prototype.editQuestion = function(question, cb) { }; -QuestionModel.prototype.getQuestion = function(user_id,q_id,app, cb) { +QuestionModel.prototype.getQuestion = function (user_id, q_id, app, cb) { - var rawQuery = ""; + var rawQuery = ""; var _replacements = [user_id, q_id, app]; rawQuery = 'select * from proc_get_question_by_id(cast(? as UUID),cast(? as UUID),?)'; this.sequelize.query(rawQuery, { - replacements: _replacements, - type: this.sequelize.QueryTypes.SELECT, - }) - .then(function(questions) { + replacements: _replacements, + type: this.sequelize.QueryTypes.SELECT, + }) + .then(function (questions) { cb(questions); }); }; -QuestionModel.prototype.showAllQuestions = function(cb) { +QuestionModel.prototype.showAllQuestions = function (cb) { - this.questionSchema.findAll().then(function(questions) { + this.questionSchema.findAll().then(function (questions) { cb(questions); }); }; -QuestionModel.prototype.userQuestions = function(user_id, app, limit, cb) { +QuestionModel.prototype.userQuestions = function (user_id, app, limit, cb) { var rawQuery = ""; @@ -69,14 +70,14 @@ QuestionModel.prototype.userQuestions = function(user_id, app, limit, cb) { rawQuery = 'select * from proc_fetch_user_questions(cast(? as UUID),?,?)'; this.sequelize.query(rawQuery, { - replacements: _replacements, - type: this.sequelize.QueryTypes.SELECT, - }) - .then(function(questions) { + replacements: _replacements, + type: this.sequelize.QueryTypes.SELECT, + }) + .then(function (questions) { cb(questions); }); -//TESTING + //TESTING // this.questionSchema.findAll({ // where: { // user_id: user_id, @@ -89,7 +90,7 @@ QuestionModel.prototype.userQuestions = function(user_id, app, limit, cb) { // }); }; -QuestionModel.prototype.userFavorites = function(user_id, app, limit, cb) { +QuestionModel.prototype.userFavorites = function (user_id, app, limit, cb) { @@ -100,10 +101,10 @@ QuestionModel.prototype.userFavorites = function(user_id, app, limit, cb) { rawQuery = 'select * from proc_fetch_user_favorites(cast(? as UUID),?,?)'; this.sequelize.query(rawQuery, { - replacements: _replacements, - type: this.sequelize.QueryTypes.SELECT, - }) - .then(function(questions) { + replacements: _replacements, + type: this.sequelize.QueryTypes.SELECT, + }) + .then(function (questions) { cb(questions); }); @@ -112,7 +113,7 @@ QuestionModel.prototype.userFavorites = function(user_id, app, limit, cb) { }; -QuestionModel.prototype.fetchQuestions = function(app, limit, user_id, installation_id, debug, cb) { +QuestionModel.prototype.fetchQuestions = function (app, limit, user_id, installation_id, debug, cb) { var debugMode = debug ? debug : 0; var rawQuery = ""; @@ -129,11 +130,11 @@ QuestionModel.prototype.fetchQuestions = function(app, limit, user_id, installat this.sequelize.query(rawQuery, { - replacements: _replacements, - type: this.sequelize.QueryTypes.SELECT, - // model: this.questionSchema - }) - .then(function(questions) { + replacements: _replacements, + type: this.sequelize.QueryTypes.SELECT, + // model: this.questionSchema + }) + .then(function (questions) { cb(questions); }); @@ -176,17 +177,17 @@ QuestionModel.prototype.fetchQuestions = function(app, limit, user_id, installat -QuestionModel.prototype.getAllKapistirForWeb = function(cb) { +QuestionModel.prototype.getAllKapistirForWeb = function (cb) { var rawQuery = 'select tu.*,u.profile_img as asker_profile_img,u.facebook_id, u.name as asker_name from question as tu inner JOIN "user" as u on u.id=tu.user_id where tu.app=1 ORDER BY created_at desc'; this.sequelize.query(rawQuery, { - //replacements: [app, (user_id) ? user_id : installation_id, limit], - type: this.sequelize.QueryTypes.SELECT, - // model: this.questionSchema - }) - .then(function(questions) { + //replacements: [app, (user_id) ? user_id : installation_id, limit], + type: this.sequelize.QueryTypes.SELECT, + // model: this.questionSchema + }) + .then(function (questions) { cb(questions); }); @@ -194,17 +195,17 @@ QuestionModel.prototype.getAllKapistirForWeb = function(cb) { }; -QuestionModel.prototype.deleteQuestion = function(id, cb) { +QuestionModel.prototype.deleteQuestion = function (id, cb) { this.questionSchema.update({ is_deleted: "true" }, { where: { id: id } - }).then(function() { + }).then(function () { cb('OK'); }); }; -QuestionModel.prototype.increaseStats = function(answer, cb) { +QuestionModel.prototype.increaseStats = function (answer, cb) { var incrementField = { skip_count: Sequelize.literal('skip_count+1') } @@ -225,26 +226,26 @@ QuestionModel.prototype.increaseStats = function(answer, cb) { this.questionSchema.update(incrementField, { where: { id: answer.question_id } - }).then(function() { + }).then(function () { cb('OK'); }); }; -QuestionModel.prototype.increaseAbuse = function(answer, cb) { +QuestionModel.prototype.increaseAbuse = function (answer, cb) { var incrementField = { abuse_count: Sequelize.literal('abuse_count+1') } this.questionSchema.update(incrementField, { where: { id: answer.question_id } - }).then(function() { + }).then(function () { cb('OK'); }); }; -QuestionModel.prototype.increaseFavorite = function(answer, cb) { +QuestionModel.prototype.increaseFavorite = function (answer, cb) { var incrementField = { favorite_count: Sequelize.literal('favorite_count+1') } if (answer.unfavorite === true) { incrementField = { favorite_count: Sequelize.literal('favorite_count-1') } @@ -253,11 +254,59 @@ QuestionModel.prototype.increaseFavorite = function(answer, cb) { this.questionSchema.update(incrementField, { where: { id: answer.question_id } - }).then(function() { + }).then(function () { cb('OK'); }); }; +QuestionModel.prototype.notifyFriends = function (question, user_friends_id_arrays, cb) { + + var options = { + url: 'https://fcm.googleapis.com/fcm/send', + headers: { + 'Content-Type': 'application/json', + 'Authorization':'key= AAAA613GGxs:APA91bE9644felnHXGqefx_H2UgEylMJLLjXqW9C9amUWiJIR7DLzlfURanPG_1PzIEJDT6vxi8c-gNge0IDZdigJgY9Fxj7rhYc3ZPNNVSzeSQY3cli-lk-mprQDCqwLmk1YdmUunJP' + }, + method: 'POST', + json: { + "data": { + "PushAction": "ActionFriendAskQuestion", + "NotifTitle": question.asker_name + " bir soruya cevap arıyor.", + "NotifContent": "Cevaplamak için hemen tıkla!", + "NotifSubContent": "Referandum", + "NotifNoClear": false, + "ShowNotif": true, + "PayloadQuestionId": question.id, + "PayloadUserId": question.user_id + }, + "notification": { + "title": question.asker_name + " bir soruya cevap arıyor.", + "body": "Cevaplamak için hemen tıkla!", + "icon": "myicon", + "sound": "mySound", + "color": "#345678", + "click_action": "ACTION_OPEN_FRIEND_QUESTION" + }, + "priority": "high", + "registration_ids": user_friends_id_arrays + } + }; + + function callback(error, response, body) { + if (!error && response.statusCode == 200) { + + return cb(null, response.statusMessage) + + } + cb(error, null); + + } + + request(options, callback); + +}; + + module.exports = QuestionModel; diff --git a/models/user.js b/models/user.js index bcb5462..5aaa4c3 100644 --- a/models/user.js +++ b/models/user.js @@ -4,10 +4,10 @@ var crypto = require('crypto'); function UserModel(db) { this.userSchema = db.user; - this.sequelize = db.sequelize; + this.sequelize = db.sequelize; }; -UserModel.prototype.upsert = function(user, cb) { +UserModel.prototype.upsert = function (user, cb) { //Upsert olacak var self = this; @@ -15,10 +15,10 @@ UserModel.prototype.upsert = function(user, cb) { where: { facebook_id: user.facebook_id } - }).then(function(userList) { + }).then(function (userList) { if (userList.length == 0) { - self.userSchema.create(user).then(function(createdUser) { + self.userSchema.create(user).then(function (createdUser) { //empty cb(createdUser); }); @@ -28,8 +28,9 @@ UserModel.prototype.upsert = function(user, cb) { app: user.app, last_fb_token: user.last_fb_token, imei: user.imei, - friends: user.friends - }).then(function() { + friends: user.friends, + reg_id: user.reg_id + }).then(function () { cb(mUser); }) @@ -39,7 +40,7 @@ UserModel.prototype.upsert = function(user, cb) { }); }; -UserModel.prototype.ban = function(user_id, banned_user_id, app, cb) { +UserModel.prototype.ban = function (user_id, banned_user_id, app, cb) { //Upsert olacak var self = this; @@ -50,14 +51,45 @@ UserModel.prototype.ban = function(user_id, banned_user_id, app, cb) { this.sequelize.query(rawQuery, { - replacements: _replacements - }) - .then(function() { + replacements: _replacements + }) + .then(function () { cb(); }); }; +UserModel.prototype.findUserById = function (user_id, cb) { + //Upsert olacak + + var self = this; + this.userSchema.findById(user_id).then(function (userinfo) { + cb(userinfo) + }); + + +}; + +UserModel.prototype.getUserFriends = function (user_id, app, cb) { + //Upsert olacak + + var self = this; + + + var rawQuery = 'select * from "user" u where u.facebook_id in(select unnest(friends) from "user" where id=? and app=?)'; + + + this.sequelize.query(rawQuery, { + replacements: [user_id, app], + type: this.sequelize.QueryTypes.SELECT, + // model: this.questionSchema + }) + .then(function (users) { + cb(users); + }); + +}; + module.exports = UserModel; diff --git a/package.json b/package.json index 1592845..bb006ff 100644 --- a/package.json +++ b/package.json @@ -26,14 +26,15 @@ "hapi-swagger": "^4.2.1", "inert": "^3.2.0", "joi": "^5.0.1", - "pg": "^4.4.6", + "pg": "^6.1.5", "pg-hstore": "^2.3.2", - "sequelize": "^3.19.3", + "sequelize": "^3.30.4", "vision": "^4.0.1", "wreck": "^7.0.0", "fbgraph":"1.3.0", "cloudinary":"1.3.1", - "jade":"1.11.0" + "jade":"1.11.0", + "request":"2.81.0" }, "devDependencies": { "lab": "^5.0.2", diff --git a/public/views/ref.jade b/public/views/ref.jade new file mode 100644 index 0000000..3f451e8 --- /dev/null +++ b/public/views/ref.jade @@ -0,0 +1,15 @@ +doctype html +html + head + + title Test sorular + body + a(onclick='javascript:try_to_open_app();',href="eferhatg://test") referandum + script(type='text/javascript'). + function open_appstore() { + window.location='https://play.google.com'; + } + + function try_to_open_app() { + setTimeout('open_appstore()', 300); + } \ No newline at end of file diff --git a/routes/v1/kapistir.js b/routes/v1/kapistir.js index ede3032..a8ab6d5 100644 --- a/routes/v1/kapistir.js +++ b/routes/v1/kapistir.js @@ -19,6 +19,12 @@ exports.register = function(server, options, next) { handler: kapistirController.all } }, { + method: 'GET', + path: '/v1/ref', + config: { + handler: kapistirController.ref + } + },{ method: 'GET', path: '/public/{path*}', handler: { diff --git a/routes/v1/question.js b/routes/v1/question.js index bf8f45b..1774fa7 100644 --- a/routes/v1/question.js +++ b/routes/v1/question.js @@ -155,6 +155,9 @@ exports.register = function(server, options, next) { app: Joi.number().min(0).max(1).required().description('App referandum için 0, kapistir için 1'), option_a: Joi.when('app', { is: 1, then: Joi.required() }).description('A şıkkı metni ya da resim linki'), option_b: Joi.when('app', { is: 1, then: Joi.required() }).description('B şıkkı metni ya da resim linki'), + notify_friend: Joi.boolean().description("friend notification"), + is_private:Joi.boolean().description("is private"), + private_url:Joi.string().description("private url") }), headers: Joi.object({ 'x-voter-client-id': Joi.string().required().description('Her app için farklı olacak.'), diff --git a/routes/v1/user.js b/routes/v1/user.js index 83b351e..073d8d4 100644 --- a/routes/v1/user.js +++ b/routes/v1/user.js @@ -24,7 +24,8 @@ exports.register = function(server, options, next) { handler: userController.signup, validate: { payload: Joi.object().keys({ - token: Joi.string().required().description('Facebook api token') + token: Joi.string().required().description('Facebook api token'), + reg_id: Joi.string().description('Registration_id'), }), headers: Joi.object({ 'x-voter-client-id': Joi.string().required().description('Her app için farklı olacak.'),