So, I'm working on Discord.Net and want to get if user has certain role
I wrote this code:
public bool IsAlreadyHasAffiliation(SocketGuildUser user)
{
IReadOnlyCollection<SocketRole> roles = user.Roles;
foreach(SocketRole role in roles)
{
if (SpecifiedRoles.ContainsValue(role.Id)) return true;
}
return false;
}
It works fine but has some problem: Don't get the role that added by bot after bot started.
For example after I added "Role1" via bot and execute above function, it work like user don't have Role1.
How can I get live update of role in bot?
If you're noticing strange behaviour in relation to users, which you are, then it's most likely down to the recent Privileged Intents update. Discord.NET caches (downloads) users and uses events such as GuildUserUpdated to keep this cache up to date in the background. Without the Guild Members intent Discord.NET can not keep its user cache up to date, causing problems such as this.
To fix the problem enable the Guild Members privileged intent on the Bot tab of your bot's page on the Discord developer's portal.
If that doesn't work then use the nightly versions of Discord.NET and specify all of the intents that you need in the DiscordSocketConfig. To use the nightly versions, add https://www.myget.org/F/discord-net/api/v3/index.json as a package source on NuGet package manager.
Here's a DiscordSocketConfig which specifies gateway intents (only available on nightly):
new DiscordSocketConfig
{
GatewayIntents =
GatewayIntents.Guilds |
GatewayIntents.GuildMembers |
GatewayIntents.GuildMessageReactions |
GatewayIntents.GuildMessages |
GatewayIntents.GuildVoiceStates,
...
});
Related
I'm trying to get all the messages from Microsoft Teams in my tenant, I have registered the application to Azure, set the correct permissions and grated admin privileges.
What I am getting confused about is creating a GraphServiceClient.
My app is more of an Daemon Application.
I would really appreciate if someone could give me an example of how to create the client correctly.
this is my code so far:
string[] graphScopes = { "https://graph.microsoft.com/.default" };
IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
.Create("x")
.WithTenantId("x")
.WithClientSecret("x")
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(app);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
try
{
var messages = await graphClient.Teams["x"].Channels["x#thread.skype"].Messages.Request().GetAsync();
Console.ReadLine();
foreach(var item in messages)
{
Console.WriteLine(item.Body);
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
Console.Read();
}
I'm getting the following error no matter what I'm trying to get
Code: UnknownError Inner error: AdditionalData: request-id: x date: 2020-05-27T14:22:37 ClientRequestId:x
update: I was able to get something from the API, I had wrong permissions.
still can't get the messages though,
I have all these permission:
ChannelMessage.Read.All, Group.Read.All, Group.ReadWrite.All
I'm probably missing the "ChannelMessage.Read.Group (RSC)" permission but I can't find it in the permissions page.
May this is the solution or the problem ;-)
Microsoft Teams APIs in Microsoft Graph that access sensitive data are considered protected APIs. These APIs require that you have additional validation, beyond permissions and consent, before you can use them.
https://learn.microsoft.com/en-us/graph/teams-protected-apis
Your problem is you are accessing a "beta" api but using the production base url path.
The permission you need is ANY of the following (i.e. or not and):
ChannelMessage.Read.Group (RSC) OR
ChannelMessage.Read.All OR
Group.Read.All OR
Group.ReadWrite.All
Since you have Group.Read.All, that is ALL you need for permissions.
What you need to do is change the base URL to the beta api:
graphClient.BaseUrl = "https://graph.microsoft.com/beta";
UPDATED:
Since now you are saying that you are getting a "Forbidden" error, I think you also have a consent problem.
My guess is that you created & consented you app on one tenant but you are trying to access the data in another tenant. This will give you a forbidden errors. i.e. you created and consented on a dev azure account tenant and are trying to access your work tenant.
If this is the situation you need to:
* Make sure that the setup you azure app to be multi-tenanted
* You have to get your app consented by the target tenant
If you do that and use the beta endpoint I would expect that your example code will start working.
Update2:
Finally got around to trying to do the message list with a application context like you above and I get the same Forbidden error as well from the beta api. From a user context it works fine. So your answer will be to use a user context and not an application context to access this API.
It looks like what you are hitting is a Protected API. So if you want to use this API from an application context, you will have to submit a request to be allowed access to it.
I was looking into Microsoft Graph Postman Collections but could not locate the tenantID, serviceURL or userID?
Is there a way to fetch userID, tenantID and serviceURL from MSTeams?
As the other answer mentions, you can get this via the "context" object, which in turn means you need to create a Teams application, and it must include a Tab. There is another similar option, which is to create a Bot for Teams, and when the user installs the bot, either 1-1, or into a channel or group chat, you get the chance to retrieve that information. You can see more about that here, including some options based on the type of bot and when you want to retrieve the information.
If it's ok to have an app, then simply go ahead with this approach. If you really don't -want the user to interact with an app, then you could consider the following:
create the application (e.g. a bot) in order to get the context you need
Auto-install the bot, as per this Graph call
Retrieve and save the information in the conversationUpdate, which is fired when you bot is installed by the user / team / chat
Auto uninstall the app using this Graph call
However, you haven't explained why you need those bits of information. That set is often used to send a proactive message from a bot, and if that's what you're trying to do, you'll need the bot anyway.
Please take a look at Get context using Microsoft Teams javascript library.
// Call the initialize API first
microsoftTeams.initialize();
// Check the initial theme user chose and respect it
microsoftTeams.getContext(function (context) {
if (context) {
console.log(context);
}
});
I am trying to create an app using firebase auth and firestore where new users can be invited via email to work on a project. The problem is, I do not know the best way to store the temporary user project permissions before they have a uid. I want the user that got invited via email to get access to the project upon opening the link sent to them.
I had tried two different ways
Having a sub collection doc for every user in the project
/project/{projectId}/users/{userId}
When a new user is invited, the userId was set to their email, having a cloud function that triggered when a new user was created to send the invite email to the user. Once the user opened the link, it deleted their user document and a cloud function ran that created a new doc with the users id now that they had once since they were authenticated.
This worked, but left a 10 second period where the user can't interact with the project because the cloud function for making the new user doc is running. Also it just seemed like a bad way to do it.
Having a single document with all of the user information
/project/{projectId}/users/users
users:{
roles: {
users_id: 'admin',
new_user_email: 'admin',
}
}
This one I was not able to get to work as firestore does not let you create a key with a period in it, but if there was a way around this, it would work as well. I had also set up firestore security rules which made it so they could only edit fields where the key was there uid or their email if they were not an editor/admin.
Consider creating an anonymous account in Firebase Authentication first, which requires no input from the user. It will receive a UID that you can use to store data for that account. Then, you can convert that account to a normal account after the signup or login succeeds.
Since you didn't say which mobile platform you're using, I linked you to the web docs, but the procedure is generally the same for each one.
When a user registers at my website I also need to create a quickblox user. I got this procedure to work:
Get a session token from API route "api.quickblox.com/session.json". But to do so I need a user. So I use my own login to quickblox dashboard.
Create the user by hitting API route "/users.json". Fair eanough, it works!
Questions
It feels strange using my own dashboard login as the token generator account. Is there not some other way?
The newly created user can create more users! That is, I created a new token with the details from the just created user, whom in turn was allowed to create further users. This cant be right? What am I doing wrong?
Quickblox chat example available here: http://quickblox.github.io/quickblox-javascript-sdk/samples/chat/# serves the keys and secret in the open, like this:
QBApp = { appId: 46126, authKey: 'Nyc2fwgg8QeFJpS', authSecret: SUv3grsaDMx5'}; Is that the way to do it? Then atleast I would like to control the creation of new users..
Thanks!
Hope you doing well !!
For Quickblox must have manage session for each and every users,you have to download and integrate quickblox SDK into your web app.
You have to follow this steps:
1) Create a app on Quickblox and add credentials into your javascript SDK or configure your javascript SDK.
2) Whenever user is logged-in to you app you must have to login quickblox as well and get session for logged-in user.
3) Do whatever operation with user created session like (chat,viedo call, audio call)
4) When user log-out from your, you have to manage like user also logout form quickblox and destroy previously created sessions.
5) When registering new user you have to also register that user into your quickblox app.
this way you have to manage user management.
hope this will help you.
To create a user with an arbetary session/token this function can be used (for JS SDK)
var params = {login: 'test3', password: '12345678'};
function createUser(params) {
QB.createSession(function(err, result) {
QB.users.create(params, function(err, user) {
if (user) {
// user - JS obejct with QB user
alert("successfully created a user!");
} else {
alert("error!");
}
});
});
}
"The newly created user can create more users!"
After further research I have concuded this is a part of the design and not to worry about. I will add a job to clean up any users created by spammers.
I am working on an application using Firebase as the backend. I have a working implementation of GitHub authentication using Firebase. However, I want to limit my complete application (all read/write operations) to people in a specific GitHub organization.
From what I gather, it is to be done via adding Security Rules in Forge. However, the organization of a user is not part of the "basic auth data" that GitHub provides to Firebase for use. Is there any way for me to make the app available to members of a particular organization only?
Current Code:
var FB = new Firebase('https://XXXXX.firebaseio.com');
var auth = new FirebaseSimpleLogin(FB, function(error, user){
if(user==null){
auth.login('github',{rememberMe:true});
}
else{
//We are logged in
$.getJSON("https://api.github.com/user/orgs?access_token="+user.accessToken+"&callback=?", function(data){
var orgs = data.data.map(function(org){return org.login});
if(orgs.indexOf(config.github_org)>-1){
//Public Member of Chosen Github Org
//Now we fetch the data and render it
}
else{
//Throw them out
alert("Join the group "+config.github_org+" on GitHub to get access to Eon");
document.location="https://github.com/"+config.github_org;
}
})
}
});
To use FB Security Rules you'll need to compare the auth data with something in the Firebase (like a list of organizations), but it looks like you are trying to get those on the fly every time. Instead I'd recommend keeping a collection of users in your Firebase organized by their auth.uid that have organization lists you can check against:
users
uid1
...
uidX
orgs
org1
...
orgX
So when a user tries to access a given orgX you can check to see if root.child('users').child(auth.uid).child('orgs/orgX') exists in your Security Rules.