Filtering socket.io subscriptions - socket.io

Imagine I have a User model and also a Message model. User has many messages.
Then in the client I do a:
io.socket.get('/user/2/messages'....
I get all my user messages and there is no problem trying to get someones else messages because I have a policy for that. Good.
I want to listen if the user has new messages, if I do a:
io.socket.on('message')
I get every message created, mine or not mine.
So: Can I listen just for MY messages? AKA listen for associated messages but not all of them.
Maybe using a policy or something for just that. Because even if there is a way to listen to them, anyone can modify the client to listen to what he wants to, I need to filter all of that.

Yes, you can. The trick is to listen for user events with the "addedTo" verb, rather than listening directly for message creation. The code would be something like:
io.socket.on('user', function(msg) {
if (msg.verb == 'addedTo' && msg.attribute == 'messages') {
// A new message was added to the user's "messages" collection
var messageId = msg.addedId
// From here you can request /message/[messageId] to get the
// message details if you need them
}
});
More info on the .publishAdd() doc page.
Note that only the ID of the added message is given; you may find you want the whole thing. You can handle that by either making a separate request for the new message, or overriding publishAdd as is suggested in this answer.
The only catch here is to make sure you're limiting who gets subscribed to those user events. It sounds like you have a policy in place that prevents users from accessing /user/:id/messages for other users. You'll want want preventing them from accessing /user/:id for other users as well (at least via sockets), since they will be subscribed to any user they access that way.
If this is undesirable--that is, if you'd like people to be able to hit those routes--then an alternative would be to use the autoSubscribe model property to restrict the automatic subscription that blueprints normally do. autoSubscribe is normally set to true, which means that any time a socket request is made for a model, the requesting socket will be subscribed to all events for that model instance. You can instead set it to an array of contexts that should be subscribed to. Contexts are specific events you're interested in, like update or destroy (more about contexts in the docs). Finally, you can set autoSubscribe to false to restrict subscription to that model entirely. Then you can just subscribe manually with .subscribe() whenever you want to listen for events.
You can see some examples of contexts and autoSubscribe in action in the sailsChat sample app.

Related

Slack `member_joined_channel` - how to check if my bot was invited?

I want to send a message to any public channel that my bot gets added to. I notice there's the member_joined_channel event as documentated here, however I'm not sure how to figure out when to determine if my bot was the invited member. I know there's the user property, but I don't want to hardcode my bot's user ID.
I'm not familiar with the slack API, but i found this endpoint :
https://api.slack.com/types/conversation
In the response, you have a flag is_member which contains what you need I think :
is_member indicates whether the user, bot user or Slack app associated
with the token making the API call is itself a member of the
conversation.
EDIT:
then, you can retreive the list of public channel and have this flag on every channel accessible :
https://api.slack.com/methods/conversations.list
If you are writing a WebSocket-based "RTM" bot, you can listen for the channel_joined event, which is sent only for your own user/bot.
For the more typical Webhook-based bot, the best choice is to listen for the member_joined_channel event and compare the user field if you want an event-based implementation. Hardcoding or otherwise storing your bot's user id is a necessity.
Otherwise, as suggested in the previous answer, you can periodically query all conversations with the conversations.list method and check if you have become a member using the is_member field.
In case one of these methods does not provide the is_private field that you need to determine whether a channel is public, you can use the conversations.info method, which returns a channel object with the is_private field.
Coversation info is your friend https://api.slack.com/methods/conversations.info

Can you wait for user response message with bwmarrin/discordgo?

Is there any option to wait for user response message in discordgo? I'm looking for something similar to discord.js awaitMessages.
No, but you can make a collection that holds message and event information and checking news messages.
Simply
Make a collection/array
Add message information
Check if the incoming message in the message event handler is in the collection
Handle event
Remove from collection
Don't forget set a timeout and clear expired data from collection.
according the docs: awaitMessages
time: Amount of time in milliseconds the collector should run for
max: Number of messages to successfully pass the filter
In Go, you can easily use a routine with just one keyword go, so implementing asynchronous (async) is very simple.
solving ideas:
Create a message storage center: It has the following features:
store all sent messages
Have a garbage collection mechanism: Since we are constantly collecting messages, we need a mechanism to eliminate old messages.
Need a mutex: Considering that the messages may generate race conditions, this lock is added to ensure security
It can generate filters: to communicate with each filter, we need to provide a chan for each filter.
Whenever a new message is created, we add the message to the message center, and it also notifies each filter.
Define your filter function: The message will be collected whenever this criterion is true. for example
Define the callback function: This is the result of the filter function. You can do something based on this result. for example
Full code
I put the full code on the replit and gist.
If you want to run it, you can copy the code from replit and set your token and channel ID (or user ID) in the environment variables to test it.

Order of wl_display_dispatch and wl_display_roundtrip call

I am trying to make sense of which one should be called before and which one later between wl_display_dispatch and wl_display_roundtrip. I have seen both order so wondering which one is correct.
1st order:
wl_display_get_registry(display); wl_registry_add_listener() // this call is just informational
wl_display_dispatch();
wl_display_roundtrip();
what i think : wl_display_dispatch() will read and dispatch events from display fd, whatever is sent by server but in between server might be still processing requests and for brief time fd might be empty.
wl_display_dispatch returns assuming all events are dispatched. Then wl_display_roundtrip() is called and will block until server has processed all request and put then in event queue. So after this, event queue still has pending events, but there is no call to wl_display_dispatch(). How those pending events will be dispatched ? Is that wl_display_dispatch() wait for server to process all events and then dispatch all events?
2nd order:
wl_display_get_registry(display); wl_registry_add_listener() // this call is just informational
wl_display_roundtrip();
wl_display_dispatch();
In this case, wl_display_roundtrip() wait for server to process all events and put them in event queue, So once this return we can assume all events sent from server are available in queue. Then wl_display_dispatch() is called which will dispatch all pending events.
Order 2nd looks correct and logical to me, as there is no chance of leftover pending events in queue. but I have seen Order 1st in may places including in weston client examples code so I am confused whats the correct order of calling.
It would be great if someone could clarify here.
Thanks in advance
2nd order is correct.
client can't do much without getting proxy(handle for global object). what i mean is client can send request by binding to the global object advertised by server so for this client has to block until all global object are bind in registry listener callback.
for example for client to create surface you need to bind wl_compositor interface then to shell interface to give role and then shm(for share memory) and so on.wl_display_dispatch cannot guaranty all the events are processed if your lucky it may dispatch all events too but cannot guarantee every-time. so you should use wl_display_roundtrip for registry at-least.

Validation within a asynchronous SAGA pattern - CQRS & DDD

Let's consider the flow below:
API client calls [POST] /api/v1/invitation/:InvitationId/confirm
Confirm the invitation within a SAGA
Eventually raise an InvitationConfirmed event to indicate success
We are some troubles finding a good place to validate the "event" we pass to the SAGA. For instance, we want to make sure that:
- The specified InvitationId exists
- The corresponding invitation is not expired or already processed
We tried a couple of things:
Fire a command:
Fire a command RequestInvitationConfirmation
Handle synchronously this command and return an error if the command is not valid OR otherwise raise the InvitationConfirmationRequested event.
The rest of the flow is the same
CONS:
- Requires us to follow a "request/response" pattern (synchronous within the HTTP request lifetime)
Raise an event:
Raise an event InvitationConfirmationRequested
Within the SAGA, query the Invitation service and perform the validations. If the command is not valid, we publish an event InvitationConfirmationFailed
(...)
CONS:
- As far as I understand SAGA should be used to orchestrate the flow. Here we are introducing the concept of "validation". I'm not sure it's the recommended approach.
Validation is a very common concept. How would you handle it in a distributed fully asynchronous system?
Important point in the design of this system is: "Who is the client of this API?".
If this client is an internal Service or Application that's one thing (as in a distributed app, microservices etc.).
If the API is used by third party client's, that's another thing.
Short answer
If the API is used internally between Services, sending a command with invalid Id in the system is a fault, so it should be logged and examined by the system developers. Also cases like these should be accounted for by having a manual way of fixing them (by some administrative backend). Log these kinds of stuff and notify developers.
If the API is used from third party apps, then it matters how responsibilities are separated between the API and the other part of the system that it uses. Make the API responsible for validation and don't send commands with invalid id's. Treat command with invalid ID's like fault, as in the first case. In this case if you use asynchronous flow, you will need a way to communicate with the third party app to notify it. You can use something like WebHooks.
For the second part of the validations check these series of blog posts and the original paper.
Long answer
If you search around you will see a lot of discussions on errors and validations, so here's my take on that.
Since we do separation of other parts of our systems, it's seems natural to separate the types of error that we have. You can check this paper on that topic.
Let's define some error types.
Domain Errors
Application Errors
Technical Errors (database connections lost etc.)
Because we have different types of errors, the validation should be performed from different parts of our systems.
Also the communication of these errors can be accomplished by different mechanisms depending on:
the requester of the operation and the receiver
the communication channel used
the communication type: synchronous or asynchronous
Now the validations that you have are:
Validate that an Invitation with the specified Id exists
Validate that the Invitation has not expired
Validate that the Invitation is not already processed (accepted, rejected etc.)
How this is handled will depend on how we separate the responsibilities in our application. Let's use the DesignByContract principle and define clear rules what each layer (Domain, Application etc.) should expect from the other ones.
Let's define a rule that a Command containing an InvitationId that doesn't correspond to an existing Invitation should not be created and dispatched.
NOTE the terminology used here can vary vastly depending of what type of architecture is used on the project (Layered Architecture, Hexagonal etc.)
This forces the CommandCreator to validate that an Invitation exists with the specified Id before dispatching the command.
In the case with the API, the RouteHandler (App controller etc.) that will accept the request will have to:
perform this validation himself
delegate to someone else to do the validation
Let's further define that this is part of our ApplicationLayer (or module, components etc. doesn't matter how it's called, so I'll use Layer) and make this an ApplicationError. From here we can do it in many different ways.
One way is to have a DispatchConfirmInvitationCommandApplicationService that will ask the DomainLayer if an Invitation with the requested Id exists and raise an error (throw exception for example) if it doesn't. This error will be handled by the RouteHandler and will be send back to the requester.
You can use both a sync and async communication. If it's async you will need to create a mechanism for that. You can refer to EnterpriseIntegrationPatterns for more information on this.
The main point here is: It's not part of the Domain
From here on, everyone else in our system should consider that the invitation with the specified Id in the ConfirmInvitationCommand exists. If it doesn't, it's treated like a fault in the system and should be checked by developers and/or administrators. There should be a manual way (an administrative backend) to cancel such invalid commands, so this must be taken into account when developing the system, bu treated like a fault in the system.
The other two validations are part of the Domain.
So let's say you have a
Invitation aggregate
InvitationConfirmationSaga
Let's make them these aggregates communicate with messages. Let's define these types of messages:
RequestConfirmInvitation
InvitationExpired
InvitationAlreadyProcessed
Here's the basic flow:
ConfirmInvitationCommand starts a InvitationConfirmationSaga
InvitationConfirmationSaga send RequestConfirmInvitation message to Invitation
And then:
If the Invitation is expired it sends InvitationExpired message to InvitationConfirmationSaga
If the Invitation is processed it sends InvitationAlreadyProcessed message to InvitationConfirmationSaga
If the Invitation is not expired it, it's accepted and it sends InvitationAccepted message to InvitationConfirmationSaga
Then:
InvitationConfirmationSaga will receive these messages and raise events accordingly.
This way you keep the domain logic in the Domain, in this case the Invitation Aggregate.
You have a command ConfirmInvitation containing InvitationId. You send it to your Invitation domain from InvaitationAppService. Your Invitation domain should look like this
...
public void ConfirmInvitation()
{
if (this.Status == InvitationStatus.Confirmed)
throw new InvalidInvitationException("Requested invitation has already been confirmed");
//check more business logic here
this.Status = InvitationStatus.Confirmed;
Publish(new InviationConfirmedEvent(...));
}
...
Your InvitationAppService should have something like below:
...
public void ConfirmInvitation(Guid invitationId)
{
// rehydrate your domain from eventstore
var invitation = repo.GetById<Invitation>(invitationId);
if (invitation == null)
throw new InvalidInvitationException("Invalid Invitation requested");
invitation.ConfirmInvitation(new ConfirmInvitation(...));
}
You don't need to introduce a new event InvitationConfirmationRequested. DDD is an approach in which your domain/business validation should reside inside domains. Don't try to fit other patterns or technologies in your domain. Validating your domain inside saga(which is used to orchestrate distribute transactions across the services) might create complexities and chaos

Why use event listeners over function calls?

I've been studying event listeners lately and I think I've finally gotten them down. Basically, they are functions that are called on another object's method. My question is, why create an event listener when calling the function will work just fine?
Example, I want to call player.display_health(), and when this is fired, the method player.get_health() should be fired and stored so that display_health() has access to it. Why should I use an event listener over simply calling the function? Even if display_health() were in another object, this still doesn't appear to be a problem to me.
If you have another example that fits the usage better, please let me know. Perhaps particular languages don't benefit from it as much? (Javascript, PHP, ASP?)
You might not always be in control of the code that's doing the calling. Or even if you are, you don't want to introduce dependencies into that code. In cases like that, it's better for the code to fire an event and allow the code you do control, or the code that should have the dependency, to listen for the event and act accordingly.
For example, perhaps you're creating a library that will be used by other people. They don't have the source code or in some way can't/shouldn't be able to modify it (or shouldn't have to). Your documentation states that specific events are raised under specific circumstances. They can then, in turn, respond to those events.
Or perhaps you have some domain libraries in your enterprise. You do control them and can modify them, but architecturally they're generally considered to be working as they currently are coded and shouldn't be changed. (Don't want to incur a round of QA to re-validate the updated code, the code belongs to another department and they don't want you to change it, etc.) And you're in the position where you want that code to be able to do different things in different circumstances/environments. If that code raises and event where relevant, you can hook your code into it (and/or swap out accordingly) without having to mess with that code.
Just a couple quick examples, I'm sure others have more.
My question is, why create an event listener when calling the function will work just fine?
What if you don't know what function you want to call?
Take the classic example, a Button that the user can click on. Whoever writes the library has no idea what function you want called when the button is clicked. It would also be pretty prohibitive if every Button could only call the same function when it is clicked.
So instead, you can attach an event handler to the event. Then when the event is triggered, the Button can do what it needs to, without having to know at compile-time exactly what function it's supposed to be calling.
In Brief, you can write the code without event listener, but using event listener help other to use the same code as library.
Even with the detailed answers above, I was still having trouble understanding what the actual difference was between using a controller / functions OR an event listener.
One of the things that has been left out in all of these answers is that the use of Events and Event Listeners comes in handy when you do not want to couple your code so closely. Each function, class, etc, should have singleness of purpose.
So say you are getting hit with an API request from an outsider. In my case, my exact problem understanding this concept was when I am receiving API calls from Stripe Webhooks.
The purpose of Stripe Webhooks is: say a customer spends $10,000 on your website. Your standard procedure is to Auth and Capture. Update DB to reflect their new membership status. In a perfect world, and in our company's case, 999/1000 times, this goes perfectly. Either their card is declined on the spot, or the payment goes through. In both cases, we send them an email letting them know.
But what about the 1/1000 time when the user pays and Stripe returns a Card Failure error (which can be a number of different things)? In our case, we email them and tell them the billing has failed. The problem we've encountered is that some BANKS are investigating large charges, which comes back as an Error, but then a few minutes later the bank authorizes the charges and the payment is captured.
So what is there to do? Enter Stripe Webhooks. Stripe Webhooks will hit an API endpoint if something like this occurs. Actually, Stripe Webhooks can hit your API any and every time a payment isn't instantly Authed, Captured, or if the customer asks for a refund.
This is where an Event Listener comes in handy. Stripe shoots over a POST with the customer info, as well as the Webhook type. We will now process that, update the database, and shoot them a success email.
But why not just use a standard route and controller?
The reason we don't just use a standard route and controller is because we would either need to modify the already defined functions, classes, etc, or create a new series of classes that are coupled together, such as -> Stripe API Calls Received, Update DB, Send Email. Instead of coupling these closely together, we use an Event Listener to first accept the API Call, then hit each of those Classes, Functions, etc., leaving everything uncoupled.
I looked everywhere, and I think the Laravel documentation explains it best. I finally understood when given a concrete example, and what the purpose of an Event Listener is:
Events serve as a great way to decouple various aspects of your application, since a single event can have multiple listeners that do not depend on each other. For example, you may wish to send a Slack notification to your user each time an order has shipped. Instead of coupling your order processing code to your Slack notification code, you can raise an OrderShipped event, which a listener can receive and transform into a Slack notification.
https://laravel.com/docs/5.6/events
I think the main reason for events vs function calls is that events are 'listened to' while calls are 'made'. So a function call is always made to another object whereas listeners 'choose' to listen for an event to be broadcast from your object.
The observer pattern is a good study for this capability. Here is a brief node.js example which illustrates the concept:
var events = require('events');
var Person = function(pname) {
var name = pname;
};
var james = new Person('james');
var mary = new Person('mary');
var loudmouth = new Person('blabberer');
loudmouth.mouth = new events.EventEmitter();
//jame's observer.
james.read_lips = function(msg){
console.log("james found out: " + msg);
};
//james adds his event to the emitter's event listener.
james.enter_elevator = function(){
console.log('james is in the elevator');
//NOTE: james adds HIMSELF as a listener for the events that may
//transpire while he is in the elevator.
loudmouth.mouth.on('elevator gossip', james.read_lips)
};
//james removes his event from the emitter when he leaves the elevator.
james.leave_elevator = function(){
// read lips is how james responds to the event.
loudmouth.mouth.removeListener('elevator gossip', james.read_lips);
console.log('james has left the elevator');
};
//mary's observer
mary.overhear = function(msg){
console.log("mary heard: " + msg);
};
//mary adds her observer event to the emitter's event listeners
mary.enter_elevator = function(){
// overhear is how mary responds to the event.
console.log('mary is in the elevator');
//NOTE: now mary adds HERSELF to the listeners in the elevator and
//she observes using a different method than james which suits her.
loudmouth.mouth.on('elevator gossip', mary.overhear);
};
loudmouth.speaks = function(what_is_said){
console.log('loudmouth: ' + what_is_said);
this.mouth.emit('elevator gossip', what_is_said);
};
james.enter_elevator();
mary.enter_elevator();
loudmouth.speaks('boss is having an affair');
james.leave_elevator();
loudmouth.speaks('just kidding');
console.log('james did not hear the last line because he was not listening anymore =)');
so in this 'story' the actors choose to listen or when to not listen for events from a third party. I hope this helps.

Resources