Getting channels and looping through them discord.net - c#

I am trying to create a commands using discord.net that will get a guild by id and then loop through the channels roles and users allowing me to list the names or permission each role or channel has. However, I've run into a few issues. The way I am currently getting my guild is using
var guild = BotStuff._client.GetGuild(Global.guildid);
After I get the guild I was able to get the number of channels, roles, or users using
var channels = guild.Channels;
and then
Console.WriteLine(channles.Count);
However, my main issue is that I want to be able to loop through the channels or roles and change the permissions or log the name of them, but I am unsure of how to accomplish this. I wasn't able to find documentation for this. Any help is appreciated!

I'll provide you with some examples that would already work with your current variables.
You need to gather the current channels in a guild, however since a Category is still considered a channel, you need to filter it out using the Where method in LINQ. This way, we will only have text and voice channels in our enumerable, which we then just loop through using the foreach keyword.
In the code examples below, you can modify the channel (name, positon, category) and add the permissions for both users and roles as you wanted.
In case you simply want to type their names into the console, just display the Name property in the foreach:
Console.WriteLine(channel.Name)
Change the name of each channel in a guild:
var guild = BotStuff._client.GetGuild(Global.guildid);
var channels = guild.Channels.Where(x => !(x is ICategoryChannel));
foreach (var channel in channels)
{
await channel.ModifyAsync(x =>
{
x.Name = "new name";
});
}
Add a permission overwrite for a user:
var guild = BotStuff._client.GetGuild(Global.guildid);
var channels = guild.Channels.Where(x => !(x is ICategoryChannel));
foreach (var channel in channels)
{
var guilduser = guild.GetUser(554240045800882181);
await channel.AddPermissionOverwriteAsync(guilduser, new OverwritePermissions(sendMessages: PermValue.Allow, manageChannel: PermValue.Allow));
}
This way we will let the user of ID 554240045800882181 send messages and manage the channel. You are able to choose between Allow, Inherit, Deny.
The permission adding method is overloaded and also accepts a role as an argument, so with a small modification we can change the channel permissions for a whole group of people.
var guildrole = guild.GetRole(202853174959144960);
await channel.AddPermissionOverwriteAsync(guildrole, new OverwritePermissions(manageMessages: PermValue.Allow, attachFiles: PermValue.Allow));
The IDs/variables used are just examples, you should understand and modify the code before using it.

For listing channel : (with a bot, else just replace Context.Guild.Channel per u'r getguild variable)
foreach (var channel in Context.Guild.Channels)
{
Console.WriteLine(channel.Name);
}

Related

Remove user from folder permission using MS Graph

We have a C# application that is using the Microsoft Graph API to display the contents of SharePoint folder to users in a Syncfusion FileManager control. We need to grant permissions to those folders for certain users in order that they can collaborate on files.
We can add specific users using the sharing invitation to add a permission (see https://learn.microsoft.com/en-us/graph/api/driveitem-invite?view=graph-rest-1.0&tabs=http). We also need to be able to remove a user from this permission without deleting the whole link (and therefore any other users using it). I cannot see a way of doing this!
I have also tried using CreateLink (see https://learn.microsoft.com/en-us/graph/api/driveitem-createlink?view=graph-rest-1.0&tabs=http) but get an ‘Invalid Request’ error when trying to ‘Grant’ permission to a user and therefore never get as far as trying to remove an individual user!. The code I am using to try and 'Grant' permission is as follows (the last line produces the error):
public object CreateSharingLink(string itemId, List<string> recipientList, List<string> roles)
{
if (itemId == null) return null;
var type = "edit";
var scope = "organization";
Permission p = GraphClient.Drives[documentLibrary.Id].Items[itemId].CreateLink(type, scope).Request().PostAsync().Result;
return GrantAccessToSharingLink(p.Link.WebUrl, recipientList, roles);
}
public object GrantAccessToSharingLink(string sharingUrl, List<string> recipientList, List<string> roles)
{
List<DriveRecipient> recipients = (recipientList.Select(r => new DriveRecipient { Email = r })).ToList();
string base64Value = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(sharingUrl));
string encodedUrl = "u!" + base64Value.TrimEnd('=').Replace('/', '_').Replace('+', '-');
return GraphClient.Shares[encodedUrl].Permission.Grant(roles, recipients).Request().PostAsync().Result;
}
Any assistance would be much appreciated.
A similar question was asked a while ago but without an answer. Remove GrantedTo user from Permission using Graph API
You can delete only not inherited permissions. Only sharing permissions that are not inherited can be deleted. Here's the related doc.

Firebase-realtime-database how to return the data within a nested child node as a list

I'm building a mood logging app using Xamarin forms for a university project but i've hit a wall when trying to return the data contained within a nested child node. Please see my firebase schema below:
BrainBreakApp
MoodLog #1
unique MoodLog id assigned by firebase
Mood Rating
Note
Location
Activities
Unique activity id assigned by firebase
activity logged by user (e.g. Shopping)
Unique activity id assigned by firebase
activity logged by user (e.g. Working)
MoodLog #2
MoodLog #3
etc.
I'm easily able to return all of the data within each mood log, except the data within the 'Activities' child node. I have placed 'shopping' and 'working' in bold because that is the data I need to return.
In my 'MoodLog' model, I have declared the 'Activities' attribute as a list of type 'Activity'; which is a separate model just containing an 'ActivityName' attribute. As my current code stands I need to return all of the activities for that particular log in a list that I can assign to the MoodLog 'Activities' attribute.
I've tried a number of approaches including adding the statement to return the list within the 'Activity' assignment and generating a list of the activities for each emotion log separately and assigning the returned list to 'Activity'; but clearly no luck. The issue i'm continually running into when trying to create a separate list of activities for that emotion log, is being able to access the firebase generated key for that particular log each time, and also being able to return a List<> type rather than a Task List<> type that I can't assign to the 'Activity' attribute.
I appreciate that much of the documentation states to make the schema as flat as possible, and if you can think of a flatter schema that will serve the same purpose that would also be fantastic.
I'm a complete Firebase newbie so any help at all would be very much appreciated!
I'll place my current code below and you will see where I need to add the list of activities:
public async Task<List<EmotionLog>> GetAllLogsForPerson()
{
var allPersons = await GetAllLogs();
await Firebase
.Child(LogChildName)
.OnceAsync<EmotionLog>();
return allPersons.Where(a => a.UserId == personId).ToList();
}
public async Task<List<EmotionLog>> GetAllLogs()
{
return (await Firebase
.Child(LogChildName)
.OnceAsync<EmotionLog>()).Select(item => new EmotionLog
{
UserId = item.Object.UserId,
DateTime = item.Object.DateTime,
Note = item.Object.Note,
Location = item.Object.Location,
MoodRating = item.Object.MoodRating,
NoActivities = item.Object.NoActivities,
Activity =
{
// Need to add list of activities here
}
}).ToList();
}
EDIT:
Please see the code below used to post the emotion log data to the firebase db. I add all of the other log data first in the 'AddLog' method, and then iterate separately through the activities using the 'AddActivity' method, which is called within the 'Add Log' method.
public async Task AddLog(string Id, string Note, string Location, DateTime DateTime, int MoodRating, List<string> ActivityList)
{
await Firebase
.Child(LogChildName)
.PostAsync(new EmotionLog() { UserId = Id, Note = Note, Location = Location, DateTime = DateTime, MoodRating = MoodRating});
await AddActivity(Id, ActivityList);
}
public async Task AddActivity(string Id, List<string> ActivityList)
{
var toAddUserActivities = (await Firebase
.Child(LogChildName)
.OnceAsync<EmotionLog>()).Last(a => a.Object.UserId == Id);
foreach (string item in ActivityList)
{
await Firebase
.Child(LogChildName)
.Child(toAddUserActivities.Key)
.Child(ActivityChildName)
.PostAsync(new Activity() { ActivityName = item });
}
}
The solution was to remove the unique Id assigned to each activity within the database. These were being generating because rather than just adding my activity list to the emotion log as one whole list, i was iterating through the list and adding each of them to the emotion log individually.
Once i removed the code that iterated through the activity list and changed my list to type List, everything worked perfectly :)

MS Graph API C# Add user to group

I've been investigating how to add (and later remove) a user from an Azure AD group using the Microsoft Graph API (the dotnet/C# library available on nuget).
Nuget MS Graph API
Ignoring all else around getting a connected GraphServiceClient etc. I'm trying code very similar to the sample below, not getting any exception (suggesting things are fine) but when I get the group once again via the API, it's not got any members still!
Interestingly (as an aside), when I ask for memberOf property on the user object and tell it to expand it, it comes back null still.
var user = await client.Users[userPrincipalName]
.Request()
.Select("id,memberOf")
.Expand("memberOf")
.GetAsync();
var group = await client.Groups[groupId]
.Request()
.Select("members")
.Expand("members")
.GetAsync();
group.Members.Add(user);
await client.Groups[groupId].Request().UpdateAsync(group);
// userPrincipalName => "test.user#mytenant.com"
// groupId => the object GUID for the group
Does anyone know what I'm doing wrong here? The docs I used to come up with this code were based on the links to the following documents:
API doc for 'group'
Adding a member to a group
Also, I tried to style the approach on the solution suggested here to setting licenses for users:
Assign user license via Graph API
As usual, thanks for any help.
Peter
Additional
I've also tried poking around in the graph API looking at potentially updating the .Members property/resource rather than the group itself:
await client.Groups[groupId].Members.Request(). // <-- Only has GetAsync()
But it only has the GetAync() method available to it.
Updated based on answer
var usersGroups = await client.Users[userPrincipalName].MemberOf.Request().GetAsync();
if (!usersGroups.Any(g => g is Group && g.Id == groupId))
{
// User is not a member of the group, add them.
var user = await client.Users[userPrincipalName].Request().Select("id").GetAsync();
await client.Groups[groupId].Members.References.Request().AddAsync(user);
}
I've added the code snippet above based on the answer, as I think it succinctly answers the issue regarding adding members.
Thanks to Nan Yu for the answer.
To add user to Group ,you could use :
User userToAdd = await graphClient.Users["objectID"].Request().GetAsync();
await graphClient.Groups["groupObjectID"].Members.References.Request().AddAsync(userToAdd);
To get members of a group :
List<ResultsItem> items = new List<ResultsItem>();
// Get group members.
IGroupMembersCollectionWithReferencesPage members = await graphClient.Groups[id].Members.Request().GetAsync();
if (members?.Count > 0)
{
foreach (User user in members)
{
// Get member properties.
items.Add(new ResultsItem
{
Properties = new Dictionary<string, object>
{
{ Resource.Prop_Upn, user.UserPrincipalName },
{ Resource.Prop_Id, user.Id }
}
});
}
}
Get groups the current user is a direct member of ,you could try :
IUserMemberOfCollectionWithReferencesPage memberOfGroups = await graphClient.Users["testnanyu#testbasic1.onmicrosoft.com"].MemberOf.Request().GetAsync();
if (memberOfGroups?.Count > 0)
{
foreach (var directoryObject in memberOfGroups)
{
// We only want groups, so ignore DirectoryRole objects.
if (directoryObject is Group)
{
Group group = directoryObject as Group;
items.Add(new ResultsItem
{
Display = group.DisplayName,
Id = group.Id
});
}
}
}

How to get all installations when using Azure Notification Hubs installation model?

Using NotificationHubClient I can get all registered devices using GetAllRegistrationsAsync(). But if I do not use the registration model but the installation model instead, how can I get all installations? There are methods to retrieve a specific installation but none to get everything.
You're correct, as of July 2016 there's no way to get all installations for a hub. In the future, the product team is planning to add this feature to the installations model, but it will work in a different way. Instead of making it a runtime operation, you'll provide your storage connection string and you'll get a blob with everything associated with the hub.
Sorry for visiting an old thread... but in theory you could use the GetAllRegistrationsAsyc to get all the installations. I guess this will return everything without an installation id as well, but you could just ignore those if you choose.
Could look something like this
var allRegistrations = await _hub.GetAllRegistrationsAsync(0);
var continuationToken = allRegistrations.ContinuationToken;
var registrationDescriptionsList = new List<RegistrationDescription>(allRegistrations);
while (!string.IsNullOrWhiteSpace(continuationToken))
{
var otherRegistrations = await _hub.GetAllRegistrationsAsync(continuationToken, 0);
registrationDescriptionsList.AddRange(otherRegistrations);
continuationToken = otherRegistrations.ContinuationToken;
}
// Put into DeviceInstallation object
var deviceInstallationList = new List<DeviceInstallation>();
foreach (var registration in registrationDescriptionsList)
{
var deviceInstallation = new DeviceInstallation();
var tags = registration.Tags;
foreach(var tag in tags)
{
if (tag.Contains("InstallationId:"))
{
deviceInstallation.InstallationId = new Guid(tag.Substring(tag.IndexOf(":")+1));
}
}
deviceInstallation.PushHandle = registration.PnsHandle;
deviceInstallation.Tags = new List<string>(registration.Tags);
deviceInstallationList.Add(deviceInstallation);
}
I am not suggesting this to be the cleanest chunk of code written, but it does the trick for us. We only use this for debugging type purposes anyways

How to get multiple keyword based steaming data using twitter streaming API

i am using tweetinvi 0.9.7 to fetch data from filtered stream against multiple keywords. i am fetching data against 10 keywords at the same time by using multiple threads.
The problem is only two keywords are fetching the data and rest other threads exited without fetching any data. what are the possible reasons? and how to tackle it. kindly guide me.
you cannot start multiple streams at the same time. In theory you are limited to one but usually you can get 2 running simultaneously.
Here is an example showing how to add multiple tracks to a single stream:
var myKeywordsToFollow = new List<string>
{
"tweetinvi",
"twitter",
".net",
"c#"
// ...
};
var fs = Stream.CreateFilteredStream();
foreach (var track in myKeywordsToFollow)
{
// The second param is optional but give you an easy way to
// configure what you want to do for this specific track
fs.AddTrack(track, tweet =>
{
// Do what you do with the tweet matching your track
});
}
// Now the stream has 4 tracks!
fs.MatchingTweetReceived += (sender, args) =>
{
var matchingTracksReceived = args.MatchingTracks;
var tweet = args.Tweet;
};
fs.StartStreamMatchingAnyCondition();

Categories

Resources