Have public channels visible to all non admin users and forbid user from creating channels - rocket.chat

How can I have the existing public channels visible to all users ?
How can I forbid users (non admin) from creating channels ?
Version: 0.49.0

The way I handled this was to create two main channels (Lobby and Announcements) for all of my employees.
I then used the REST API to add all users to those two channels. This won't prevent them from leaving the channels, but you could simply call the API every so often to add people back in that left (or new users, if setting the Default channel to True under Rooms in Administration doesn't seem to be working).
Here's the steps to do this, using curl:
Get your authentication Token and UserId [1]
Use your Token and Id from step 1 to get the full channel list [2]
Take the desired roomId from step 2 and (as well as using your Token and Id from step 1) use the addAll API [3] to add literally all users to the channel.
For the second one, you can use the Permissions [4] tab under Administration, it is "create-c" for public or "create-p" for private.
I can't post more than two links, so..
[1] httpx://rocket.chat/docs/developer-guides/rest-api/authentication/login
[2] httpx://rocket.chat/docs/developer-guides/rest-api/channels/list
[3] https://rocket.chat/docs/developer-guides/rest-api/channels/addall
[4] https://rocket.chat/docs/administrator-guides/permissions/

Related

Stripe differentiate between payment Intent and payment link

I'm trying to read the webhook response from both a payment intent (in which a user in the website press pay to pay for an item) and a payment link (where he receives a link which then he can pay through) I'm trying to find how can I differentiate between them but I can't find a difference. Is there a flag or something to distinguish which one was paid
PaymentLinks[1] are a way to accept payment without building a storefront. It uses PaymentIntents[2] behind in order to accept payment.
Actually, when you create a PaymentLink, Stripe creates a Checkout Session[3] and a PaymentIntent for each payment attempt.
In order to track payments issued from PaymentLinks[4] using webhooks,you should listen to one of these events depending on your exact need:
checkout.session.completed [5] to track when customers completed a payment.
payment_intent.succeeded [6] to track when a Payment was done successfully.In order to distinguish between PaymentIntent that you’ve created by your own and from the ones are created by PaymentLinks, you can add metadata[7] when you create PaymentIntent from your website.
[1] https://stripe.com/docs/payments/payment-links
[2] https://stripe.com/docs/payments/payment-intents
[3] https://stripe.com/docs/payments/checkout
[4] https://stripe.com/docs/payments/payment-links/api#tracking-payments
[5] https://stripe.com/docs/api/events/types#event_types-checkout.session.completed
[6] https://stripe.com/docs/api/events/types#event_types-payment_intent.succeeded
[7] https://stripe.com/docs/api/payment_intents/create#create_payment_intent-metadata

Best practice for subscribe and publish architecture for chat-like app

I'd like to know what best practices exist around subscribing to changes and publishing them to the user. This is a pretty broad and vaguely worded question. Therefore, allow me to elaborate on this using an example.
Imagine the following (simplified) chat-like application:
The user opens the app and sees the home screen.
On this home screen a list of chat-groups is fetched and displayed.
Each chat-group has a list of users (members).
The user can view this list of members.
Each user/member has at least a first name available.
The user can change its name in the settings.
And now the important part: When this name is changed, every user that is viewing the list of members, should see the name change in real-time.
My question concerns the very last point.
Let's create some very naive pseudo-code to simulate such a thing.
The client should at least subscribe to something. So we could write something like this:
subscribeToEvent("userChanged")
The backend should on its part, publish to this event with the right data. So something like this:
publishDataForEvent("userChanged", { userId: "9", name: "newname" } )
Of course there is a problem with this code. The subscribed user now gets all events for every user. Instead it should only receive events for users it is interested in (namely the list of members it is currently viewing).
Now that is the issue I want to know more about. I could think of a few solutions:
Method 1
The client subscribes to the event, and sends with it, the id of the group he is currently viewing. Like so for example:
subscribeToEvent("userChanged", { groupId: "abc" })
Consequently, on the backend, when a user changes its name, the following should happen:
Fetch all group ids of the user
Send out the event using those group ids
Something like this:
publishDataForEvent("userChanged", { userId: "9", name: "newname" }, { groupIds: ["abc", "def" })
Since the user is subscribed to a group with id "abc" and the backend publishes to several groups, including "abc", the user will receive the event.
A drawback of this method is that the backend should always fetch all group ids of the user that is being changed.
Method 2
Same as method 1. But instead of using groupIds, we will use userIds.
subscribeToEvent("userChanged", { myUserId: "1" })
Consequently, on the backend, when a user changes its name, the following should happen:
Fetch all the user ids that relate to the user (so e.g. friendIds based on the users he shares a group with)
Send out the event using those friendIds
Something like this:
publishDataForEvent("userChanged", { userId: "xyz", name: "newname" }, { friendIds: ["1", "2" })
An advantage of this is that the subscription can be somewhat more easily reused. Ergo the user does not need to start a separate subscription for each group he opens, since he is using his own userId instead of the groupId.
Drawback of this method is that it (like with method 1 but probably even worse) potentially requires a lot of ids to publish the event to.
Method 3
This one is just a little different.
In this method the client subscribes on multiple ids.
An example:
On the client side the application gathers all users that are relevant to the current user. For example, that can be done by gathering all the user ids of the currently viewed group.
subscribeToEvent("userChanged", { friendIds: ["9", "10"] })
At the backend the publish method can be fairly simple like so:
publishDataForEvent("userChanged", { userId: "9", name: "newname" }, { userId: "9" } )
Since the client is subscribed to user with userId "9", amongst several users, the client will receive this event.
Advantage of this method is that the backend publish method can be held fairly simple.
Drawback of this is that the client needs quite some logic to subscribe to the right users.
I hope that the examples made the question more clear. I have the feeling I am missing something here. Like, major chat-app companies, can't be doing it one of these ways right? I'd love to hear your opinion about this.
On a side note, I am using graphql as a backend. But I think this question is general enough to not let that play a role.
The user can change its name in the settings.
And now the important part: When this name is changed, every user that is viewing the list of members, should see the name change in real-time.
I assume the user can change his name via a FORM. The contents of that form will be send with a HTTP-Reuqest to a backand script that will do the change in a DB like
update <table> set field=? where userid=?
Preferred
This would be the point where that backend script would connect to your web socket server and send a message like.
{ opcode:'broadcast', task:'namechange', newname='otto' ,userid='47111' }
The server will the broadcast to all connected clients
{task:'namechange', newname='otto' ,userid='4711' }
All clients that have a relationship to userid='4711' can now take action.
Alternative 1
If you cant connect your backend script to the web socket server the client might send { opcode:'broadcast', task:'namechange', newname='otto' ,userid='47111' }
right before the FORM is trasnmitted to the backend script.
This is shaky because if anything goes wrong in the backend, the false message is already delivered, or the client might die before the message goes out, then no one will notice the change.

Role Based Notification, Along with Groups using Signalr in MVC 5

i am a beginner in signalR and Need to make an application where there are many users having many roles, and there should be three channels of sending notification to clients
1. Public (Used For All)
2. Private (Sending Notification to Single Person)
3. Group and Sub Group (Sending Notification to the persons who are member of some group or sub-group)
Problem is i am unable to understand the user differentiation in SignalR and not getting the concept of groups.
Anyone please Guide me
First of all, you can start to read the Microsoft documentation about the groups. Then you can read the authorization documentation so you would be able to create groups and manage users for each role.
What you can do is, when the client connects to the Hub, and assuming you know the users role (using the context and the authorization) you will add them to those 3 groups.
Then it is easy to send message to those groups, you have such examples everywhere in the stackOverflow and the internet.
Hope this helps you.
Code example:
/// <summary>
/// Called when a new connection is established with the hub.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task OnConnectedAsync()
{
// 1. Add the use to the public group
await this.Groups.AddToGroupAsync( this.Context.ConnectionId, "PublicGroup");
// 2. Add user to the private channel, single person
await this.Groups.AddToGroupAsync(this.Context.ConnectionId, this.Context.User.Identity.Name);
if (this.Context.User.IsInRole("Admin"))
{
// 3. Add the user to the Admin group
await this.Groups.AddToGroupAsync(this.Context.ConnectionId, "Admin");
}
// add to other groups...
await base.OnConnectedAsync();
}

Put a user on hold with Amazon Lex

We are using Amazon Connect, Lex and Lambda to create a phone bot. One use case we have is that we need to put the user on hold while we find information in other systems. So the conversation will be something like this:
- bot: hi, what can I do for you?
- user: i want to make a reservation
- bot: wait a minute while I fetch information about available rooms
... after 5 seconds ...
- bot: I found a free room blah blah
I don't see a way to send the wait a minute... message and keep control of the conversation. How can we achieve that?
You can accomplish this inside a single Lex bot by setting the intent to be fulfilled by a lambda function, the response of the function would play a message saying “please wait” and then chain another internet to perform the search using the data from the original intent.
See this link for information about sharing data between intents.
You can chain or switch to the next intent by passing the confirmIntent dialog action back in the lambda response. See this link for more information on the lambda input and response format.
You can use wait block in aws connect https://docs.aws.amazon.com/connect/latest/adminguide/flow-control-actions-wait.html
By using this block you can set time to 5 secs . after time expired you can play prompt.
This is a very common problem typically when we want to do backend lookups in an IVR. The problem is lex does not provide any means to just play prompts.
One way to do it is:
Create a dummy slot in your intent (the reservation intent from your example above) with any type (e.g. AMAZON.NUMBER), we don't really care what the value is in this slot
From the lex code-hook for the intent, return ElicitSlot for this dummy slot with prompt as "Wait a minute while I fetch available rooms... "
If you do only this much, the problem you will face is that Lex will expect input from caller and will wait for around 4 seconds before passing control back to the Init and Validation Lambda, so there will be unnecessary delay. To overcome this, you need to set timeout properties as session attribute in "Get Customer Input" block from connect.
Property1:
Lex V2 Property name: x-amz-lex:audio:start-timeout-ms:[intentName]:[slotToElicit]
Lex Classic Property name x-amz-lex:start-silence-threshold-ms:[intentName]:[slotToElicit]
value: 10 (or any small number, this is in millseconds)
Property2:
Only available in Lex Classic, to disable barge-in on Lex V2, you can do it for required slot from lex console
Property name: x-amz-lex:barge-in-enabled:[intentName]:[slotToElicit]
Value: false
If barge-in is not disabled, there is a chance user may speak in middle of your "Please wait..." prompt and it will not be played completely.
Official documentation for these properties:
https://docs.aws.amazon.com/connect/latest/adminguide/get-customer-input.html
https://docs.aws.amazon.com/lexv2/latest/dg/session-attribs-speech.html
Another way:
Whenever such a prompt needs to be played, store the lex context temporarily either as a contact attribute after serialization, or if too big in size to be stored as contact attribute in a store like dynamodb.
Return control back to connect, play the prompt using 'Play prompt' module in connect. To give control back to bot, you will need invoke a lambda to re-initialize Lex with the full lex context again- using PostText API and then again passing control to same bot using 'Get Customer Input'
I have implemented option1 and it works well. You can even create cover-prompt which gets played if the backend lookup takes longer than expected. The actual lookup could be delegated to another lambda so that the code-hook lambda can continue doing customer interaction ever x (say 5) seconds to keep them informed that you are still looking up information.

RingCentral Main Company Number SMS `Phone number doesn't belong to extension` error

I tried to send SMS and listed the from as our Main Company Number but it would not go out. Said Phone number doesn't belong to extension per the error below. The RC account I am using for running my API calls does not have a phone line/number assigned.
Do I have to be logged in with the account that matches the from phone number?
{
"errorCode": "FeatureNotAvailable",
"message": "Phone number doesn't belong to extension",
"errors": [
{
"errorCode": "MSG-304",
"message": "Phone number doesn't belong to extension"
}
]
}
You can send SMS from the Main Company Number for a single user or multiple users using the following approaches:
Scenario 1: Send and Respond using a single user
In-order to send SMS from the main company number:
Set the Operator Extension
Authorize using the Operator Extension
Send SMS using the Main Company Number
Operator Extension: When a caller presses 0 (zero) or does not enter an extension number, the system connects the call to the designated operator extension by default. An Administrator can configure the operator extension
to have different call handling rules.
Scenario 2: Send and Respond using Multiple Users
In-order to send and SMS from Main Company Number and respond to it using multiple users, set up a call-queue and configure the operator extension to point to the Call Queue.
Create a Call-Queue and assign a password to it.
Set the Operator Extension to point to Call Queue.
Authorize using the Operator Extension ( Call Queue )
Send SMS using the Main Company Number
More info is available here:
https://devcommunity.ringcentral.com/ringcentraldev/topics/how-to-send-sms-from-the-main-company-number
To verify the numbers your user extension can send SMS from, call the following endpoint:
GET /restapi/v1.0/account/{accountId}/extension/{extensionId}/phone-number
This will return an array of phone numbers. Check the features property. The ones that can be used will have the SMSSender and/or MMSSender features. More info on this is available in the Developer Guide:
http://ringcentral-api-docs.readthedocs.io/en/latest/messages_sms-and-pager/#listing-valid-sms-sending-numbers

Resources