Sails.js sails.io.js, blueprints not getting events from .publish(), how to subscribe to all events? - socket.io

I don't know why I'm not getting notification events from sails models from model.publish().
In pre-1.x sailsjs, similar client-side code had worked and I would get every event when records are created, updated or deleted. So, I must be misunderstanding something.
How do I subscribe to all events for any records from CRUD operations?
On the server side, I have Job.js and JobController.js.
In Job.js model, this test just creates a new record every 10 secs:
test: async function(dataset) {
let count = 0;
setInterval(async function() {
count++;
let newjob = {
dataset: dataset,
state: 'delayed',
name: "job name "+count
};
let job = await Job.create(newjob).fetch()
sails.log.info('created test job: ',JSON.stringify(job));
Job.publish([job.id],job);
},10000);
}
In JobController.js, called by the client and starts the test rolling:
submittest: async function(req,res) {
let dataset = await Dataset.Get({});
await Job.test(dataset[0].id);
return res.ok({status:'ok'});
}
In the client test.html, io.socket.get operations are successful, but I never see an event:
...
<script>
io.socket.get('/job', function(body, JWR) {
console.log('and with status code: ', JWR.statusCode);
setTimeout(function() {
io.socket.get('/job/submittest', function (body,JWR) {
io.socket.on('job', function(msg) {
console.log("job event",msg); // not getting here. why?
});
});
},2000)
});
</script>
This all runs fine but the problem is, no events are seen from the client side. Why? Am I not subscribed to events with the initial io.socket.get('/job')?

Essentially, what is happening here, is you are shouting into an empty box about a new record in your model, but no one is listening to you in that empty box.
In other words, you need to subscribe the socket connection to the model updates.
See: https://sailsjs.com/documentation/reference/web-sockets/resourceful-pub-sub/subscribe
Also, checkout the answer to this question for a quick how to.

Related

how do I program a slackbot to send a regular message automatically every week

I am building a slackbot that will remind people in my organisation to perform certain admin (hours expenses etc) every week. I know this can be very easily done by each person creating a recurring reminder. What i want is to create a bot that will send a preconfigured message to people every week. I've looked online extensively, and haven't yet found out how slackbot can send a message without an event or being otherwise prompted.
I'm currently testing this on a local ngrok server with the following backend:
const { WebClient } = require('#slack/web-api');
const { createEventAdapter } = require('#slack/events-api');
const slackSigningSecret = process.env.SLACK_SIGNING_SECRET;
const slackToken = process.env.SLACK_TOKEN;
const port = process.env.SLACK_PORT || 3000;
const slackEvents = createEventAdapter(slackSigningSecret);
const slackClient = new WebClient(slackToken);
slackEvents.on('app_mention', (event) => {
console.log(`Got message from user ${event.user}: ${event.text}`);
(async () => {
try {
await slackClient.chat.postMessage({ channel: event.channel, text: `Hello <#${event.user}>! Have you completed your Time sheets for this week yet?` })
} catch (error) {
console.log(error.data)
}
})();
});
slackEvents.on('error', console.error);
slackEvents.start(port).then(() => {
console.log(`Server started on port ${port}`)
});
Once this reminder is done, i intend to build upon it (more features, just need a beginning) so please don't recommend alternative ways my organisation can send reminders to people.
You can try using the chat.scheduleMessage method instead (https://api.slack.com/methods/chat.scheduleMessage). Since you won't rely on an event you may want to store the necessary conversations ids so that they're ready when the app needs to call the method.

Why does it appear I am receiving an event twice

I have the following code that is logging receiving an event twice. Any ideas why? The received event message together with the event itself appear twice for every event received:
listen() {
LOG.info('Awaiting events');
this.bizNetworkConnection.on('event', (event) => {
LOG.info('************Received Event**************');
LOG.info(event);
let options = {
properties: { key:'value'}
};
});
}
static async listen(args) {
let cr = new CommodityRegistry('commodityRegistry');
await cr.init();
let results = await cr.listen();
LOG.info('Listened for events');
}
Composer currently listens for events from all peers (check your connection.json for the number of peers getting events). A client application will receive all of the events emitted by the business network, and it's up to the application to choose which/to what extent those events are integrated.

How to manage user inputs in a short time interval?

i would like to implement a way of managing a user sending many messages in a time interval (for example 3 seconds), so that the chatbot only responds to the last one.
Example of inputs (in a gap of 3 seconds):
-Hi
-Hi
-Hi
-Help
Result: The chatbot only responds to the Help message.
Thanks in advance.
You can leverage Middleware feature to intercept every message, with which you can store every user's every message in cache, when your bot receive a new message, you can compaire with those info in cache, then dicide whether the flow needs to go forward.
Npde.js code snippet for quick test:
const moment = require('moment');
let lastMessage = null;
let lastMessageTime = null;
bot.use({
receive: (session, next) => {
let currentMessage = session
if (currentMessage.text !== lastMessage) {
lastMessage = currentMessage.text;
lastMessageTime = currentMessage.timestamp;
next();
} else {
if (moment(currentMessage.timestamp) - moment(lastMessageTime) >= 3000) {
lastMessageTime = currentMessage.timestamp;
next();
}
}
}
})
What needs you paying attention is that, in production env, you need to store the message with session/user id. E.G. Using session/user id as prefix of message and timesamp key in cache.
Please refer to https://learn.microsoft.com/en-us/bot-framework/dotnet/bot-builder-dotnet-middleware for how to intercept messages in C#,
and refer to https://learn.microsoft.com/en-us/bot-framework/nodejs/bot-builder-nodejs-intercept-messages for Node.js version.
Hope it helps.

parse.com background job triggering timeouts with cloud code function

I have written a cloud code function called approveDish that works within the timeout limits set by Parse.com when I call the function directly once from a client button.
However, I need to migrate some old database records to this and am wondering why when I run the background job with larger than say 3 results returned in the query I get timeouts in that cloud code function. Shouldn't this in a background job not timeout ever as we're calling things seriously?
Parse.Cloud.job("migrateDishesToChains", function(request, status){
Parse.Cloud.useMasterKey();
var Dishes = Parse.Object.extend("Dishes");
var query = new Parse.Query(Dishes);
query.notEqualTo("approved", true);
//dishes.equalTo("user", "JQd58QhOCO");
query.limit(1);
query.find().then(function(results) {
// Create a trivial resolved promise as a base case.
var promise = Parse.Promise.as();
_.each(results, function(result) {
// For each item, extend the promise with a function to delete it.
promise = promise.then(function() {
// Return a promise that will be resolved when the delete is finished.
return Parse.Cloud.run("approveDish", {dishID: result.id});
});
});
return promise;
}).then(function() {
status.success();
});
});

Sailsjs Session access during custom onConnect in socket.io

I'm trying to group all my socket.io connection into groups.
I want 1 group for each sails.js session.
My first goal is authentificate all tabs in a same time.
So I tried to do this with onConnect in config/sockets.js like that :
onConnect: function(session, socket) {
// By default: do nothing
// This is a good place to subscribe a new socket to a room, inform other users that
// someone new has come online, or any other custom socket.io logic
if (typeof session.socket == 'undefined'){
session.socket = [];
}
session.socket.push(socket.id);
session.save();
console.log(session, socket);
},
// This custom onDisconnect function will be run each time a socket disconnects
onDisconnect: function(session, socket) {
// By default: do nothing
// This is a good place to broadcast a disconnect message, or any other custom socket.io logic
if(Array.isArray(session.socket)){
var i = session.socket.indexOf(socket.id);
if(i != -1) {
session.socket.splice(i, 1);
session.save();
}
}
console.log(session, socket);
},
But I realize that session doesn't save my modifications.
I tried a session.save but sailsjs doesn't know req !
Session.set(sessionKey, req.session, function (err) {
I want to access to sails.js sesion but I don't know how to do it.
I tried to search a solution but now, after 6 hours of search I think it's time to requiered some help !
Thanks and sorry for my poor english (I'm french).
There appears to be a bug in the implementation of onConnect and onDisconnect in Sails v0.9.x. You can work around it for now by adding the following line before a call to session.save in those methods:
global.req = {}; global.req.session = session;
then changing session.save() to:
session.save(function(){delete global.req;});
That will provide the missing req var as a global, and then delete the global (for safety) after the session is saved.
Note that this issue only affects sessions in the onConnect and onDisconnect methods; inside of controller code session.save should work fine.
Thanks for pointing this out!

Resources