Posts posted throught Feed Dialog are not increasing monthly active user count (MAU) - fbdialogs

I'm posting posts to Facebook using Feed Dialog:
function gogogo() {
var bitLyUrl = getQueryVariable('bitLyUrl');
var hashTag = getQueryVariable('hashTag');
var message = getQueryVariable('message');
FB.init({ appId: 452707668140903, status: false });
var obj = {
method: 'feed',
link: bitLyUrl,
name: bitLyUrl,
caption: 'Test'
description: message + ' ' + bitLyUrl + ' ' + hashTag
};
function callback(response) {
if (response && response.post_id) {
alert('success');
}
else{
alert('failure');
}
}
FB.ui(obj, callback);
};
I had four different users post using my app (they logged in using their credentials) however when I checked my app settings, monthly active user count is still = 1
Does anyone know if user has to authorize my app in order to count as active user?
Thanks,
Marta

Related

Getting notification twice for same event in chat messages

I am using the below code for the notifications in a chat messaging, it is executing successfully, but it is executing notification twice for the same event, which should happen only for once for a single event. May I know what wrong I am doing in the code below for the firebase cloud function implemented with firestore database in flutter application
exports.sendNotification = functions.firestore.document("messageRoom/{message_room_id}/messages/{messageID}").onWrite((change, context) => {
const idTo = context.params.idTo;
const message_room_id = context.params.message_room_id;
const messageID = context.params.messageID;
return admin.firestore().collection('messageRoom').doc(message_room_id).collection('messages').doc(messageID).get().then(queryResult => {
const idFrom = queryResult.data().idFrom;
const to_token_id = queryResult.data().to_token_id;
const idTo = queryResult.data().idTo;
console.log("User id " + idTo + " | Notification id " + "notification_id" + " | Token ID is : " + to_token_id + " | from user id " + idFrom);
var payload = {
notification: {
title: 'Chat Message',
body: "New Message",
icon: 'default',
sound: 'default'
},
data: {
click_action: 'FLUTTER_NOTIFICATION_CLICK',
groupChatId: messageID,
category: 'default'
}
};
return admin.messaging().sendToDevice(to_token_id, payload).then(result => {
console.log("Notification Sent chat notification");
return null;
});
}
);
});
I just thought that this is worth an answer creation basing on Sanzio and Johnny convesation.
In such situation first thought is that onWrite listener is getting called twice. So first to make sure writing to messageRoom/{message_room_id}/messages/{messageID} is done once, whether it be from a device or another cloud function.
Actually, in this case it appeared that writing has been done from two different locations.
I hope it will help anyone who will face it in future :)

How to get mail id of twitter account through nodejs

I am trying to get mail id from twitter user through nodejs at the result I only got tweets and other details of users but I don't get mail id. I attach my code anyone tell me whether my code is write way to get mail id
// twitter api script
var config = require("./config");
// In config file I have my consumer_key, consumer_secret, access_token_key,access_token_secret
var fs = require('fs');
var Twitter = require('twitter');
var client = new Twitter(config.twitter);
var writer = fs.createWriteStream('tweets.json')
var start_time = 0;
var handles = "";
fs.readFile('./t_handle.csv', 'utf8', function(err, contents) {
var params = {
'include_email' : true
};
handles = contents.split("\n");
writer.write("[");
handles.forEach(function(handle){
handle = handle.split("/")[3];
if(typeof handle !== 'undefined' && handle){
handle = handle.split("?")[0];
get_handle_tweets(handle,params);
}
});
});
function get_handle_tweets(handle){
client.get('statuses/user_timeline', { screen_name: handle }, function(error, tweets,params,response) {
if(error){
console.log(error);
}else{
tweets.forEach(function(tweet){
writer.write(JSON.stringify(tweet)+",\n");
});
}
});
}
First check if when you Authorize for your app in the Will be able to see field, "see your email address" is there , if not check if you have valid privacy policy and TOS URL since white listing the app is no longer required, also in php I had to Change 'include_email' : true to 'include_email' : 'true' sometime ago when I tried this, so that could be the issue.

Bot Response based on user session using botframework (NodeJS)

How to send bot response based on user session in NodeJS.
I have created a sample NodeJS application using botframework and connecting to IBM watson to process the user query to get the appropriate response and sending back the response with 10secs delay.
I have generate the ngrok URL and configured it bot framework for web channel. When i test this in mutipl browsers simulataneously , i am getting the same response for all , not based on the user session and user request.
It's giving the latest request processed response to everyuser. I have copied the sample nodejs code below.
Can someone please look into my code and suggest me on how to send the response based on user session/conversationID?
NodeJS sample code :
'use strict';
var restify = require('restify');
var builder = require('botbuilder');
var Conversation = require('watson-developer-cloud/conversation/v1');
require('dotenv').config({silent: true});
var server = restify.createServer();
var contexts = { CandidateID : "89798" , Location : "USA" }
var workspace= 'XXXXXXXXXXXXXXXX';
let name,id,message,addr,watson;
var savedAddress;
server.listen(process.env.port || process.env.PORT || 3000, function () {
console.log('%s listening to %s', server.name, server.url);
});
// Create the service wrapper
var conversation = new Conversation({
username: 'XXXXXXXXXXXXXXXX',
password: 'XXXXXXXXXXXXXXXX',
url: 'https://gateway.watsonplatform.net/conversation/api',
version_date: 'XXXXXXXXXXXXXXXX'
});
// setup bot credentials
var connector = new builder.ChatConnector({
appId: 'XXXXXXXXXXXXXXXX',
appPassword: 'XXXXXXXXXXXXXXXX'
});
var bot = new builder.UniversalBot(connector,);
server.post('/api/messages', connector.listen());
// root dialog
bot.dialog('/', function (session, args) {
name = session.message.user.name;
id = session.message.user.id;
message = session.message.text;
savedAddress = session.message.address;
var payload = {
workspace_id: workspace,
context: contexts,
input: {
text: session.message.text
}
};
var conversationContext = {
workspaceId: workspace,
watsonContext: contexts
};
if (!conversationContext) {
conversationContext = {};
}
payload.context = conversationContext.watsonContext;
conversation.message(payload, function(err, response) {
if (err) {
console.log(err);
session.send(err);
} else {
console.log(JSON.stringify(response, null, 2));
conversationContext.watsonContext = response.context;
watson = response.output.text;
}
});
console.log(message);
setTimeout(() => {
startProactiveDialog(savedAddress);
}, 10000);
});
// handle the proactive initiated dialog
bot.dialog('/survey', function (session, args, next) {
if (session.message.text === "done") {
session.send("Great, back to the original conversation");
session.endDialog();
} else {
session.send(id + ' ' + watson);
}
});
// initiate a dialog proactively
function startProactiveDialog(address) {
bot.beginDialog(address, "*:/survey");
}
You need to make sure it passes back and forth all of the system context for that user's session. Our botkit middleware essentially does this for you.
https://github.com/watson-developer-cloud/botkit-middleware
It looks like that you are leveraging the sample at https://github.com/Microsoft/BotBuilder-Samples/tree/master/Node/core-proactiveMessages/startNewDialog Sending a dialog-based proactive message to specific user.
The sample is just for reference, it only saves the latest conversion at it only declare one variable savedAddress, each time the new user comes in, the new seession address will assign to savedAddress and cover the old value.
You can try to define an object to save user addresses for quick test:
var savedAddress = {};
bot.dialog('/', function (session, args) {
savedAddress[session.message.address.id] = session.message.address;
var message = 'Hey there, I\'m going to interrupt our conversation and start a survey in a few seconds.';
session.send(message);
message = 'You can also make me send a message by accessing: ';
message += 'http://localhost:' + server.address().port + '/api/CustomWebApi';
session.send(message);
setTimeout(() => {
startProactiveDialog(savedAddress[session.message.address.id]);
}, 5000);
});
For production stage, you can leverage Redis or some other cache storage to store this address list.
Hope it helps.

How to retrieve from Firebase based on current user

Here is the deal.
I am using VueFire and would like to retrieve data from a Firebase database I have set up. In there I have a node with users and each one is defined by a unique id. Also for every user I have an array with a cart full of items they would to purchase. To make it dynamic I am calling the reference in the firebase hook like so:
export default {
firebase:{
cart: app.database().ref('users')
}, //and so on and so on
}
Instead of .ref('users') I want to retrieve the current user, using his unique id like so: .ref('users/' + user.uid + '/cart')
To get the current user uid I do the observer that is firebase.auth().onAuthStataChanged(user=>{//code here})
Problem is, since this is asynchronous, the firebase hook activates before the current user is retrieved. I have tried to simply call firebase.auth().currentUser, but this is also slow and unreliable to use.
I am open to any kinds of suggestions!
I made a solution that worked for my case and might work for yours.
What I did is attach value listeners when the user gets authenticated and then I turn them off when the user loses authentication. With this method I'm only asking to retrieve user data if the user is actually authenticated. Here's how I did it:
this.$root.firebase.auth().onAuthStateChanged(user => {
if (user) {
this.$store.dispatch('setUserUID', user.uid)
// Listen for User Data
let dataRef = this.$root.db.ref('/userdata/' + user.uid)
let self = this
dataRef.on('value', function(snap) {
let value = snap.val()
self.$store.dispatch('setUserData', value)
})
}
else {
// Stop Listening for User Data
this.$root.db.ref('/userdata/' + this.$store.state.user.uid).off()
this.$store.dispatch('setUserUID', null)
}
})
Okay I got it. Thanks to #Daniel D for his tip on binding as an array or object. So as it turns out I don't have to do it in the firebase reference hook, I just have to bind it as array in the mounted() hook for example. I just declare an empty cart: [] in data and then fill it like so:
<script>
import changeColorMixin from '../mixins/changeColorMixin'
import animateFunction from '../mixins/animationMixin'
import Firebase from 'firebase'
import app from '../firebaseApp'
export default {
data(){
return{
isLoggedIn: '',
cart: []
}
},
methods:{
changeColor: changeColorMixin,
animateEntrance: animateFunction,
promptLogin: function(){
console.log('you need to login!');
},
chooseSize: function($event){
$($event.target).parents().eq(2).addClass('chosen');
},
closeOrder: function($event) {
$($event.target).parents().eq(2).removeClass('chosen');
},
makeOrder: function($event){
var $this = this;
Firebase.auth().onAuthStateChanged(function(user){
if(user){
var cartRef = app.database().ref('users/' + user.uid + '/cart');
var currentCart;
cartRef.once('value', function(result) {
currentCart = result.val();
var size = $($event.target).html();
var name = $($event.target).parents().eq(2).attr('id');
app.database().ref('users/' + user.uid + '/cart/' + name + '/count').once('value', function(snap){
var count = snap.val();
if(count > 0){
count = count + 1;
}else{
count = 1;
}
cartRef.child(name).set({
size: size,
count: count,
name: name
});
});
});
}else{
console.log('gotta login mate');
}
});
}
},
mounted(){
Firebase.auth().onAuthStateChanged(user => {
if(user){
this.isLoggedIn = true;
var cartRef = app.database().ref('users/' + user.uid + '/cart');
this.$bindAsArray('cart', cartRef);
}else{
this.isLoggedIn = false;
}
});
this.animateEntrance();
this.changeColor();
}
}
</script>
As I said big thanks to #Daniel D

MongoDB Query takes too long

Problem: When creating the first document for a user, query takes too long
I'm creating some report, of the schema Report. I also have a UserSchema. I create a document in my UI and pass that data to a post request which is this:
exports.addSubReport = function(req,res) {
var id = req.body.masterform;
var subform = new Report();
var myDate = Date();
subform.title = req.body.title;
subform.date = req.body.date;
subform.date = myDate;
subform.owner = req.user;
subform.body = req.body.body;
subform.save();
Report.findById(id, function (err, report) {
if(err) {
res.redirect('/404NotFound');
}
else {
report.subreport.push(subform);
subform.parentReport = report;
report.save();
}
});
User.findById(req.body.id, function (err, user) {
user.forms_created.push(subform);
subform.owner = req.user;
subform.authors[0] = user.profile.firstName + " " + user.profile.lastName;
subform.author = user;
subform.save();
});
res.json(req.body);
};
this works fine and creates the object the way I want it to, however after creating the document, I set the state in my UI to 'Wait' until I can recieve the JSON with this new Report I just created. This is the GET request code:
exports.allMyReports = function(req, res) {
var id = req.user._id;
var totalproc = 0;
var dupe = [];
Report.find({"author" : id}, function (err, form) {
dupe = form;
dupe.forEach(function (person) {
User.findById(person.author, function (err, user) {
if (!err) {
person.authors[0] = user.profile.firstName + " " + user.profile.lastName;
person.save();
totalproc = totalproc + 1;
}
if (totalproc == dupe.length) {
res.json(dupe);
}
}
);
});
});
};
However the problem is that on every first report I create for a user, it takes an extremely long time. It's most likely the query of searching for it by author but than I thought well.... if the user has 15 documents already how does it even find all those documents instaneously? I have no idea why it takes so long in this case though and I haven't been able to come up with a solution yet but I think it has to do with how I'm querying.
Here is a sample of how i do it in the UI:
_onCreateReport = () => {
const title = React.findDOMNode(this.refs.title).value;
const date = React.findDOMNode(this.refs.date).value;
const body = React.findDOMNode(this.refs.body).value;
ReportsActions.addNewReport({
title: title,
date: date,
body: body
});
ReportsActions.getMyReports();
}
I perform the action of adding a new report ('post' request to API), and then getMyReport 'get' request to api for all reports belonging to me, once that returns it shows a new render of 3 buttons, one to view that document, one to view all my documents, one to create another report.
All I did, was request all the documents, and figure it out in the front-end. It reduced the time of the ajax call and I just filtered it out in my front-end which performs quick and doesn't hold the server up.

Resources