Issue with watch request on gmail api - gmail-api

I am using the below code to send a watch request to gmail. But it is sending push notifications for every action on the mailbox. I need google to send notifications if there is a new email received only. Otherwise I don't want google to send notifications. I am using google-api nodejs client. Can anyone please assist me on this?
watch (cb) {
const params = {
userId: 'me',
resource: {
labelIds: ['INBOX'],
labelFilterAction: 'include',
topicName: configure.Google.TopicName
}
};
this.gmail.users.watch(params, cb);
}

You can do labelIds: ['UNREAD']
When you go to request history.list with the historyId, there is an option to limit the messages returned to messagesAdded, though you will continue to get extraneous push notifications.

labelIds expects the id of the label, not the display name of it.

Related

I use user_ref which get from checkbox plugin opt-in webhook to send a message to a user, I cannot receive prior_message after the user replying us

I write a demo web page which contains Checkbox plugin. I set user_ref for the plugin during every rendering.
An user click the checkbox and submit subscribe request. Then a opt-in webhook has been sent to me with a unique user_ref.
I send a message to the user_ref (set it as recipient) successfully.
After the user replied my message, I get a webhook in this format:
"sender":{ "id":"PSID" }, "recipient":{ "id":"PAGE-ID" }, "timestamp":XXXXX, "message":{ "mid":"mid.145...", "text":"XXXXX" } According to the official document: https://developers.facebook.com/docs/messenger-platform/discovery/checkbox-plugin#implementation The webhook I expected to receive should be in this format: "sender":{ "id":"PSID" }, "recipient":{ "id":"PAGE-ID" }, "timestamp":XXXXXXX, "message":{ "mid":"mid.145...", "text":"XXXX" }, "prior_message": { "source":"checkbox_plugin", "identifier":"USER-REF" }
The parameter "prior_message" is missing
I hope to get the identifier in the prior_message and use the identifier to distinguish the user that replying to us

SendGrid suppression/bounces provides no results []

When trying to retrieve suppression or bounces using SendGrid API 3, I get no results.
I did contact SendGrid support and they confirmed that the API key is logging in successfully
I was able to send email using the same API key
When you login into the account on the web site, you can see suppression and bounces (global)
I also tried this route "suppression/unsubscribes" and get the same result []
I am only interested in downloading all global bounces or unsubscribes.
string queryParamsBounce = #"{
'end_time': 1,
'start_time': 1
}";
var responseBounce = await client.RequestAsync(method: BaseClient.Method.GET, urlPath: "suppression/bounces", queryParams: queryParamsBounce);
Console.WriteLine(responseBounce.StatusCode);
Console.WriteLine(responseBounce.Body.ReadAsStringAsync().Result);
Console.WriteLine(responseBounce.Headers.ToString());
Just delete the queryParams from the api request as below:
var response = await client.RequestAsync(method: SendGridClient.Method.GET, urlPath: "suppression/blocks");
Or change the endtime parameter to a time in future. e.g. 'end_time':2212920280

What is the best way to handle real time chat & messaging system?

I am using node.js for backend and angular for frontend...
I thought to use socket.io but I am not sure how how to handle comunication between users...
For example how can I push message message to specific user after message is saved to database?
ex.
router.post('/message', function(req, res) {
Message.create({
text: req.body.text,
fromUser: req.fromToken.id,
toUser: req.body.toUser
}, function(err,message) {
//FROM HERE WHAT IS THE BEST WAY TO PUSH MESSAGE TO USER
})
});

AppEngine channel API: duplicate messages client side

I am trying to use the Channel API to push updates from server to the client. The flow is the user presses a button which triggers a server side action that generates a lot of logs. I want to display the logs to the user "in real time".
When I first load the page it I get all the messages, no problem. If I trigger the action a second time without refreshing the page in my browser, then all messages appear twice. Here is the set up portion of the channel that is tied to the page onLoad event. With resulting console logs I gathered that the onMessage() method is being invoked more than once when the page is not refreshed. Looks like I need to "kill" earlier sockets in some way, but could not find a way in the official documentation. Can someone point me in the right direction to get rid of the spurious messages?
// First fetch a token for the async communication channel and
// create the socket
$.post("/app/channels", {'op':'fetch', 'id' : nonce},
function (data, status, xhr) {
if (status == "success") {
data = JSON.parse(data);
token = data["token"];
console.log("Cookie: " + get_mp_did() + "; token: " + token);
var channel = new goog.appengine.Channel(token);
var handler = {
'onopen': onOpened,
'onmessage': onMessage,
'onerror': function() {
$("#cmd_output").append('Channel error.<br/>');
},
'onclose': function() {
$("#cmd_output").append('The end.<br/>');
$.post("/app/channels", {'op':'clear'});
}
};
var socket = channel.open(handler);
socket.onopen = onOpened;
socket.onmessage = onMessage;
}
});
onOpened = function() {
$("#cmd_output").empty();
};
onMessage = function(data) {
message = JSON.parse(data.data)['message'];
$("#cmd_output").append(message);
console.log('Got this sucker: ' + message);
}
If I understand your post and code correctly, the user clicks on a button which calls the $.post() function. The server code is responsible to create the channel in GAE as response to a /app/channels request. I think that your server in fact creates a new channel client ID / token with every subsequent request. Since the page is not reloaded, any subsequent request would add a new channel to this client. And all these channels would be still connected (hence, no page refresh).
I assume your server code has all channels associated to a user, and you send the message to a user utilizing all channels? Such pattern would result in this behavior. You can verify my assumption by clicking 3 or four times on the button with-out page refresh. The log output would be multiplied by the factor of 3 or 4.
I suggest, that you store the token in the client and on the server. Then make a modification to your client JS. If a channel is already created store the token value and provide it to any subsequent request to /app/channels. Modify the server so it will not create a new channel, if a token is provided with the request. If the token links to an existing valid channel, re-use the channel and return the same token in the response. You may need to add some more details for disconnected or expired channels, maybe also a cron-job to delete all expired channels after a while.

How do I send user specific data with socket.io and laravel?

I am not sure how to word this question right, but here I go. I have laravel, angular, node w/socket.io and I am also using JWT for authentication. My end goal is to be able to send real time update notifications to specific users. For the life of me, I cannot seem to get how the workflow would be.
My initial though was to send the jwt within the handshake and then use then in node to do http requests to get data, and then return said data. In another words, when a specific event is fired, node will already have the token, send request to laravel for specific information.
Can someone please explain to me how sending user specific data via socket.io in this architecture?
I found this great article : https://www.ukietech.com/blog/programming/step-by-step-instruction-of-setting-up-real-time-secure-broadcasting-with-laravel-5-1-socket-io-and-redis/
This set me on the right track.
First I need to pass in my JWT into the socket:
var socket = io('http://192.168.10.10:3000', {query: "Authorization="+$rootScope.$storage.satellizer_token});
Next I actually verify the token.. again. I know this may be overkill, but I want to know that what hits the socket is legit.
io.use(function(socket, next){
if (socket.handshake.query.Authorization) {
var config = {
url:'http://192.168.10.10/api/auth',
headers:{
Authorization:'Bearer '+socket.handshake.query.Authorization
}
};
request.get(config,function(error,response,body){
socket.userId = JSON.parse(body).id;
next();
});
}
// call next() with an Error if you need to reject the connection.
next(new Error('Authentication error'));
});
The request in this block of code returns a user object based on the authenticated token. Refer to JWTAuth for more.
Then on connection I will assign the user to a unique channel.
io.on('connection',function(socket){
socket.join('userNotifications.'+socket.userId);
console.log('user joined room: userNotifications.'+socket.userId);
});
Then broadcast the event:
notifications.on('pmessage', function(subscribed, channel, message) {
var m = JSON.parse(message);
io.emit(channel+":"+m.event, message);
});
Back on the client side I listen for the channel. the var user is the user id.
socket.on('userNotifications.'+ user+':App\\Events\\notifications', function(message){
console.log(message);
});

Resources