diff --git a/docs/using-the-sdk/teams-channel-chat-reply.md b/docs/using-the-sdk/teams-channel-chat-reply.md new file mode 100644 index 0000000000..de8a5aa559 --- /dev/null +++ b/docs/using-the-sdk/teams-channel-chat-reply.md @@ -0,0 +1,330 @@ +# Working with a Team Channel Chat message reply + +The Core SDK provides support for working with chat messages within a Teams Channel allowing you to post messages. It is possible using the PnP Core SDK to then reply on these messages. + +[!INCLUDE [Creating Context](fragments/creating-context.md)] + +## Getting Chat Message replies + +The following example will show you how to retrieve all the replies of a message within a channel chat: + +```csharp +// Get the Team +var team = await context.Team.GetAsync(o => o.Channels); + +// Get the channel +var channel = team.Channels.AsRequested().FirstOrDefault(i => i.DisplayName == "General"); + +channel = await channel.GetAsync(o => o.Messages); +var chatMessage = channel.Messages.AsRequested().FirstOrDefault(); + +// Load the replies +chatMessage = await chatMessage.GetAsync(o => o.Replies); + +// Get the replies +var replies = chatMessage.Replies; + +``` + +## Adding Chat Message Replies + +You can post replies to a message within a channel, the following code demonstrates how this can be done: + +```csharp +// Get the Team +var team = await context.Team.GetAsync(o => o.Channels); + +// Get the channel +var channel = team.Channels.AsRequested().FirstOrDefault(i => i.DisplayName == "General"); + +channel = await channel.GetAsync(o => o.Messages); +var chatMessages = channel.Messages; + +// Get the chat message to add a reply to +var chatMessageToAddReply = chatMessages.AsRequested().FirstOrDefault(); + +// Define the body of the reply +var body = "Hello, I'm posting a reply - PnP Rocks!"; + +// Perform the add operation +await chatMessageToAddReply.AddReplyAsync(body); + +``` + +## Add Chat Message Replies with HTML + +You can add chat replies that contain a HTML body, the following code sample will demonstrate how to do this: + +```csharp +// Get the Team +var team = await context.Team.GetAsync(o => o.Channels); + +// Get the channel +var channel = team.Channels.AsRequested().FirstOrDefault(i => i.DisplayName == "General"); + +channel = await channel.GetAsync(o => o.Messages); +var chatMessages = channel.Messages; + +// Get the chat message to add a reply to +var chatMessageToAddReply = chatMessages.AsRequested().FirstOrDefault(); + +// Define the body of the reply +var body = $"

Hello


Example posting a HTML message - PnP Rocks!"; + +// Perform the add operation +await chatMessageToAddReply.AddReplyAsync(body, ChatMessageContentType.Html); + +``` + +## Adding Chat Messages with Attachments + +Chat message replies can support file attachments. + +The following code shows an example of how an attachment is done: + +```csharp +// Get the Team +var team = await context.Team.GetAsync(o => o.Channels); + +// Get the channel +var channel = team.Channels.AsRequested().FirstOrDefault(i => i.DisplayName == "General"); + +channel = await channel.GetAsync(o => o.Messages); +var chatMessages = channel.Messages; + +// Get the chat message to add a reply to +var chatMessageToAddReply = chatMessages.AsRequested().FirstOrDefault(); + +// Upload File to SharePoint Library +IFolder folder = await context.Web.Lists.GetByTitle("Documents").RootFolder.GetAsync(); +IFile existingFile = await folder.Files.GetFirstOrDefaultAsync(o => o.Name == "test_added.docx"); +if(existingFile == default) +{ + existingFile = await folder.Files.AddAsync("test_added.docx", System.IO.File.OpenRead($"test.docx")); +} + +// Prepare the attachment ID +var attachmentId = existingFile.ETag.AsGraphEtag(); ; // Needs to be the documents eTag - just the GUID part - use this extension method + +var body = $"

Hello


Example posting a message with a file attachment - "; + +var fileUri = new Uri(existingFile.LinkingUrl); + +await chatMessageToAddReply.AddReplyAsync(new ChatMessageOptions{ + Content = body, + ContentType = ChatMessageContentType.Html, + Attachments = { + new ChatMessageAttachmentOptions + { + Id = attachmentId, + ContentType = "reference", + // Cannot have the extension with a query graph doesn't recognise and think its part of file extension - include in docs. + ContentUrl = new Uri(fileUri.ToString().Replace(fileUri.Query, "")), + Name = $"{existingFile.Name}", + ThumbnailUrl = null, + Content = null + } + } +}); + +``` + +> [!Note] +> There two areas you should be aware about this feature related to how the Graph works: +> - The Graph produces a eTag reference in the format "{GUID},ID" with quotes, however this has to be stripped down to just the GUID element, without the surrounding braces, comma, quotes and ID for this to be recognised. An extension method has been created to avoid having to write this adaption to the eTag. +> - File used to upload, must not have a query string parameter, this will not be recognised and the Graph treats this as part of the extension and thus will fail if the Name extension is different. + +## Adding Chat Message reply with Cards + +Adding a chat message reply can be done using a Card, see below adaptive card example: + +```csharp +// Get the Team +var team = await context.Team.GetAsync(o => o.Channels); + +// Get the channel +var channel = team.Channels.AsRequested().FirstOrDefault(i => i.DisplayName == "General"); + +channel = await channel.GetAsync(o => o.Messages); +var chatMessages = channel.Messages; + +// Get the chat message to add a reply to +var chatMessageToAddReply = chatMessages.AsRequested().FirstOrDefault(); + +// Attachment ID must be unique, but the same in both body and content properties +var attachmentId = "74d20c7f34aa4a7fb74e2b30004247c5"; +var body = $""; + +await chatMessageToAddReply.AddReplyAsync(new ChatMessageOptions +{ + Content = body, + ContentType = ChatMessageContentType.Html, + Attachments = { + new ChatMessageAttachmentOptions + { + Id = attachmentId, + ContentType = "application/vnd.microsoft.card.adaptive", + // Adaptive Card + Content = "{\"$schema\":\"http://adaptivecards.io/schemas/adaptive-card.json\",\"type\":\"AdaptiveCard\",\"version\":\"1.0\",\"body\":[{\"type\":\"Container\",\"items\":[{\"type\":\"TextBlock\",\"text\":\"Adaptive Card Unit Test\",\"weight\":\"bolder\",\"size\":\"medium\"},{\"type\":\"ColumnSet\",\"columns\":[{\"type\":\"Column\",\"width\":\"auto\",\"items\":[{\"type\":\"Image\",\"url\":\"https://pbs.twimg.com/profile_images/3647943215/d7f12830b3c17a5a9e4afcc370e3a37e_400x400.jpeg\",\"size\":\"small\",\"style\":\"person\"}]},{\"type\":\"Column\",\"width\":\"stretch\",\"items\":[{\"type\":\"TextBlock\",\"text\":\"Matt Hidinger\",\"weight\":\"bolder\",\"wrap\":true},{\"type\":\"TextBlock\",\"spacing\":\"none\",\"text\":\"Created {{DATE(2017-02-14T06:08:39Z,SHORT)}}\",\"isSubtle\":true,\"wrap\":true}]}]}]},{\"type\":\"Container\",\"items\":[{\"type\":\"TextBlock\",\"text\":\"Now that we have defined the main rule sand features of the format ,we need to produce a schema and publish it to GitHub.The schema will be the starting point of our reference documentation.\",\"wrap\":true},{\"type\":\"FactSet\",\"facts\":[{\"title\":\"Board:\",\"value\":\"Adaptive Card\"},{\"title\":\"List:\",\"value\":\"Backlog\"},{\"title\":\"Assigned to:\",\"value\":\"Matt Hidinger\"},{\"title\":\"Duedate:\",\"value\":\"Not set\"}]}]}],\"actions\":[{\"type\":\"Action.ShowCard\",\"title\":\"Set due date\",\"card\":{\"type\":\"AdaptiveCard\",\"body\":[{\"type\":\"Input.Date\",\"id\":\"dueDate\"}],\"actions\":[{\"type\":\"Action.Submit\",\"title\":\"OK\"}]}},{\"type\":\"Action.ShowCard\",\"title\":\"Comment\",\"card\":{\"type\":\"AdaptiveCard\",\"body\":[{\"type\":\"Input.Text\",\"id\":\"comment\",\"isMultiline\":true,\"placeholder\":\"Enter your comment\"}],\"actions\":[{\"type\":\"Action.Submit\",\"title\":\"OK\"}]}}]}", + ContentUrl = null, + Name = null, + ThumbnailUrl = null + } + } +}); + +``` + +## Adding Chat Message reply with Inline Images + +Chat message replies can also include inline images. The following example demonstrates this option: + +```csharp +// Get the Team +var team = await context.Team.GetAsync(o => o.Channels); + +// Get the channel +var channel = team.Channels.AsRequested().FirstOrDefault(i => i.DisplayName == "General"); + +channel = await channel.GetAsync(o => o.Messages); +var chatMessages = channel.Messages; + +// Get the chat message to add a reply to +var chatMessageToAddReply = chatMessages.AsRequested().FirstOrDefault(); + +var body = $"

Hello

Example posting a message with inline image

"; + +await chatMessageToAddReply.AddReplyAsync(new ChatMessageOptions +{ + Content = body, + ContentType = ChatMessageContentType.Html, + HostedContents = + { + new ChatMessageHostedContentOptions + { + Id = "1", + ContentBytes = "", + ContentType = "image/png" + } + } +}); + +``` + +## Adding chat message reply with mentions + +We can use mentions when creating a chat message reply. We can use the following options when mentioning: + +- User +- Conversation (e.g. a team, a channel, ...) +- Team tag + +In this example, a team message will be posted which will tag a channel and a user: + +```csharp +// Get the Team +var team = await context.Team.GetAsync(o => o.Channels); + +// Get the channel +var channel = team.Channels.AsRequested().FirstOrDefault(i => i.DisplayName == "General"); + +channel = await channel.GetAsync(o => o.Messages); +var chatMessages = channel.Messages; + +// Get the chat message to add a reply to +var chatMessageToAddReply = chatMessages.AsRequested().FirstOrDefault(); + +var body = $"Hello, PnP Rocks!
This is a channel and user mention test
Mention 1: Channel
Mention 2: User"; + +await chatMessageToAddReply.AddReplyAsync(new ChatMessageOptions +{ + Content = body, + ContentType = ChatMessageContentType.Html, + Mentions = + { + new ChatMessageMentionOptions + { + Id = 0, + MentionText = "Channel", + Mentioned = new TeamChatMessageMentionedIdentitySet + { + Conversation = new TeamConversationIdentity + { + ConversationIdentityType = TeamConversationIdentityType.Channel, + Id = channel.Id + } + } + }, + new ChatMessageMentionOptions + { + Id = 1, + MentionText = "User", + Mentioned = new TeamChatMessageMentionedIdentitySet + { + User = new Identity + { + DisplayName = userToMention.Title, + Id = graphUser.Id, + UserIdentityType = TeamUserIdentityType.aadUser + } + } + } + } +}); + +``` + +In this example, a reply will be created which will tag an entire team and a team tag. For more information regarding the usage of team tags in the PnP Core SDK, please refer to [Team tags](teams-tags) + +```csharp + +// Get the Team +var team = await context.Team.GetAsync(o => o.Channels, o => o.Tags); + +// Get the channel +var channel = team.Channels.AsRequested().FirstOrDefault(i => i.DisplayName == "General"); + +channel = await channel.GetAsync(o => o.Messages); +var chatMessages = channel.Messages; + +// Get the chat message to add a reply to +var chatMessageToAddReply = chatMessages.AsRequested().FirstOrDefault(); + +var body = $"Hello, PnP Rocks!
This is a team and tag mention test
Mention 1: Team
Mention 2: Tag"; + +await chatMessageToAddReply.AddReplyAsync(new ChatMessageOptions +{ + Content = body, + ContentType = ChatMessageContentType.Html, + Mentions = + { + new ChatMessageMentionOptions + { + Id = 0, + MentionText = "Team", + Mentioned = new TeamChatMessageMentionedIdentitySet + { + Conversation = new TeamConversationIdentity + { + ConversationIdentityType = TeamConversationIdentityType.Team, + Id = team.Id.ToString() + } + } + }, + new ChatMessageMentionOptions + { + Id = 1, + MentionText = "Tag", + Mentioned = new TeamChatMessageMentionedIdentitySet + { + Tag = new TeamTagIdentity + { + DisplayName = team.Tag.First().DisplayName, + Id = team.Tags.First().Id, + } + } + } + } +}); + +``` diff --git a/docs/using-the-sdk/teams-channel-chat.md b/docs/using-the-sdk/teams-channel-chat.md index acbccde065..b675076bd9 100644 --- a/docs/using-the-sdk/teams-channel-chat.md +++ b/docs/using-the-sdk/teams-channel-chat.md @@ -78,7 +78,7 @@ var channel = team.Channels.AsRequested().FirstOrDefault(i => i.DisplayName == " channel = await channel.GetAsync(o => o.Messages); var chatMessages = channel.Messages; - // Upload File to SharePoint Library +// Upload File to SharePoint Library IFolder folder = await context.Web.Lists.GetByTitle("Documents").RootFolder.GetAsync(); IFile existingFile = await folder.Files.GetFirstOrDefaultAsync(o => o.Name == "test_added.docx"); if(existingFile == default) @@ -163,7 +163,6 @@ For advanced information about the specific area of the Graph that handles sendi Additionally, there are different types of cards, such as Adaptive Cards and Thumbnail - these have been tested with unit tests but not all types have yet. For information about the different types of cards, visit: [https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-reference](https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-reference) - ## Adding Chat Messages with Inline Images Chat messages can also include inline images. The following example demonstrates this option: @@ -195,5 +194,120 @@ await chatMessages.AddAsync(new ChatMessageOptions } }); ``` + For advanced information about the specific area of the Graph that handles sending messages with inline images visit: -[https://docs.microsoft.com/en-us/graph/api/chatmessage-post?view=graph-rest-beta&tabs=http#example-5-sending-inline-images-along-with-the-message](https://docs.microsoft.com/en-us/graph/api/chatmessage-post?view=graph-rest-beta&tabs=http#example-5-sending-inline-images-along-with-the-message) \ No newline at end of file +[https://docs.microsoft.com/en-us/graph/api/chatmessage-post?view=graph-rest-beta&tabs=http#example-5-sending-inline-images-along-with-the-message](https://docs.microsoft.com/en-us/graph/api/chatmessage-post?view=graph-rest-beta&tabs=http#example-5-sending-inline-images-along-with-the-message) + +## Adding chat messages with mentions + +We can use mentions when creating a chat message. We can use the following options when mentioning: + +- User +- Conversation (e.g. a team, a channel, ...) +- Team tag + +In this example, a team message will be posted which will tag a channel and a user: + +```csharp +// Get the Team +var team = await context.Team.GetAsync(o => o.Channels); + +// Get the channel +var channel = team.Channels.AsRequested().FirstOrDefault(i => i.DisplayName == "General"); + +channel = await channel.GetAsync(o => o.Messages); +var chatMessages = channel.Messages; + +var body = $"Hello, PnP Rocks!
This is a channel and user mention test
Mention 1: Channel
Mention 2: User"; + +await chatMessages.AddAsync(new ChatMessageOptions +{ + Content = body, + ContentType = ChatMessageContentType.Html, + Mentions = + { + new ChatMessageMentionOptions + { + Id = 0, + MentionText = "Channel", + Mentioned = new TeamChatMessageMentionedIdentitySet + { + Conversation = new TeamConversationIdentity + { + ConversationIdentityType = TeamConversationIdentityType.Channel, + Id = channel.Id + } + } + }, + new ChatMessageMentionOptions + { + Id = 1, + MentionText = "User", + Mentioned = new TeamChatMessageMentionedIdentitySet + { + User = new Identity + { + DisplayName = userToMention.Title, + Id = graphUser.Id, + UserIdentityType = TeamUserIdentityType.aadUser + } + } + } + } +}); + +``` + +In this example, a message will be created which will tag a team and a team tag. For more information regarding the usage of team tags in the PnP Core SDK, please refer to {insert link here} + +```csharp + +// Get the Team +var team = await context.Team.GetAsync(o => o.Channels, o => o.Tags); + +// Get the channel +var channel = team.Channels.AsRequested().FirstOrDefault(i => i.DisplayName == "General"); + +channel = await channel.GetAsync(o => o.Messages); +var chatMessages = channel.Messages; + +var body = $"Hello, PnP Rocks!
This is a team and tag mention test
Mention 1: Team
Mention 2: Tag"; + +await chatMessages.AddAsync(new ChatMessageOptions +{ + Content = body, + ContentType = ChatMessageContentType.Html, + Mentions = + { + new ChatMessageMentionOptions + { + Id = 0, + MentionText = "Team", + Mentioned = new TeamChatMessageMentionedIdentitySet + { + Conversation = new TeamConversationIdentity + { + ConversationIdentityType = TeamConversationIdentityType.Team, + Id = team.Id.ToString() + } + } + }, + new ChatMessageMentionOptions + { + Id = 1, + MentionText = "Tag", + Mentioned = new TeamChatMessageMentionedIdentitySet + { + Tag = new TeamTagIdentity + { + DisplayName = team.Tag.First().DisplayName, + Id = team.Tags.First().Id, + } + } + } + } +}); + +``` + +For advanced information about the specific area of the Graph that handles sending messages with mentions, visit: [https://docs.microsoft.com/en-us/graph/api/chatmessage-post?view=graph-rest-beta&tabs=http#examples](https://docs.microsoft.com/en-us/graph/api/chatmessage-post?view=graph-rest-beta&tabs=http#examples) diff --git a/docs/using-the-sdk/teams-channels.md b/docs/using-the-sdk/teams-channels.md index 2b183cc0b6..6f07f5aab0 100644 --- a/docs/using-the-sdk/teams-channels.md +++ b/docs/using-the-sdk/teams-channels.md @@ -6,7 +6,7 @@ Within Teams, you have one or more channels. This page will show you how you can ## Getting Channels -Channels is a collection part of the ITeam interface, so when you get a team, you can include the channels on the request. +Channels is a collection part of the ITeam interface, so when you get a team, you can include the channels on the request. ```csharp // Get the Team @@ -71,9 +71,9 @@ foreach(var file in folder.Files.AsRequested()) To add a new channel, call the Add method, specifying a name and optionally a description. ```csharp +// Get the Team var team = await context.Team.GetAsync(p => p.Channels); -// Get the Team string channelName = $"My Cool New Channel"; // Check if the channel exists @@ -105,8 +105,8 @@ string channelName = $"My Cool New Channel"; // Get the channel you wish to update var channelToUpdate = team.Channels.Where(p => p.DisplayName == channelName).FirstOrDefault(); -if(channelToUpdate != default){ - +if(channelToUpdate != default +{ string newChannelDescription = $"This cool channel is being updated!"; channelToUpdate.Description = newChannelDescription; @@ -127,8 +127,8 @@ string channelName = $"My Cool New Channel"; // Get the channel you wish to delete var channelToDelete = team.Channels.Where(p => p.DisplayName == channelName).FirstOrDefault(); -if(channelToDelete != default){ - +if(channelToDelete != default) +{ // Perform the delete operation await channelToUpdate.DeleteAsync(); } @@ -136,4 +136,4 @@ if(channelToDelete != default){ > [!Note] > You cannot delete the General Channel, this operation is not supported by the service. -Additionally, channels are soft-deleted for 30 days, before which counts towards the total limit of channels per Team, for further details on the limits, please refer to [Limits and specifications for Microsoft Teams](https://docs.microsoft.com/en-us/microsoftteams/limits-specifications-teams) \ No newline at end of file +Additionally, channels are soft-deleted for 30 days, before which counts towards the total limit of channels per Team, for further details on the limits, please refer to [Limits and specifications for Microsoft Teams](https://docs.microsoft.com/en-us/microsoftteams/limits-specifications-teams) diff --git a/docs/using-the-sdk/teams-events.md b/docs/using-the-sdk/teams-events.md new file mode 100644 index 0000000000..0c4154caaa --- /dev/null +++ b/docs/using-the-sdk/teams-events.md @@ -0,0 +1,289 @@ +# Working with Teams: Events + +Within Teams, you can have team events (meetings). This page will show you how you can Get, Create, Update and Delete events. + +[!INCLUDE [Creating Context](fragments/creating-context.md)] + +## Getting Events + +Events is a collection part of the ITeam interface, so when you get a team, you can include the events on the request. + +```csharp +// Get the Team +var team = await context.Team.GetAsync(o => o.Events); + +// Get the Events +var events = team.Events; +``` + +## Creating Events + +To add a new event, call the Add method, specifying atleast a subject. + +```csharp +// Get the Team +var team = await context.Team.GetAsync(p => p.Events); + +// Get the events +var events = team.Events; + +string eventSubject = $"Test event - PnP Rocks!"; + +await events.AddAsync(new EventCreateOptions +{ + Subject = eventSubject +}); +``` + +## Adding an event with multiple attendees and a start time and end time + +We can create an event using the PnP Core SDK and add multiple attendees to the event. These attendees can either be set _required_, _optional_ or _resource_. + +We can also choose to hide the attendees of an event. This can be done by setting the property _HideAttendees_ to true. It defaults to _false_. + +Next, we will add a start and end time for the event with a timezone. + +The code below will create an event which will last for one hour and will have two attendees. The attendees will be hidden. + +```csharp +// Get the Team +var team = await context.Team.GetAsync(p => p.Events); + +// Get the events +var events = team.Events; + +// Get the users to add to the event +await context.Web.GetAsync(y => y.SiteUsers); + +var firstUser = context.Web.SiteUsers.Where(y => y.PrincipalType == Model.Security.PrincipalType.User).First(); +var secondUser = context.Web.SiteUsers.Where(y => y.PrincipalType == Model.Security.PrincipalType.User).Skip(1).First(); + +await events.AddAsync(new EventCreateOptions +{ + Subject = "Test event - PnP Rocks!", + Attendees = new List + { + new EventAttendeeOptions + { + EmailAddress = firstUser.Mail, + Name = firstUser.Title, + Type = EventAttendeeType.Optional + }, + new EventAttendeeOptions + { + EmailAddress = secondUser.Mail, + Name = secondUser.Title, + Type = EventAttendeeType.Required + } + }, + HideAttendees = true, + Start = new DateTime(2022, 5, 12, 14, 0, 0), + StartTimeZone = EventTimeZone.PacificStandardTime, + End = new DateTime(2022, 5, 12, 15, 0, 0), + EndTimeZone = EventTimeZone.PacificStandardTime, +}); +``` + +## Adding an event that lasts all day + +Using the PnP Core SDK, we can add an event that will last all day. + +```csharp +// Get the Team +var team = await context.Team.GetAsync(p => p.Events); + +// Get the events +var events = team.Events; + +await events.AddAsync(new EventCreateOptions +{ + Subject = "CreateTeamEventThatLastsAllDayAsync", + IsAllDay = true, + Start = DateTime.Now, + End = DateTime.Now.AddDays(1) +}); +``` + +## Adding an event with a location + +We can create an event using the PnP Core SDK and add a location to the event. + +```csharp +// Get the Team +var team = await context.Team.GetAsync(p => p.Events); + +// Get the events +var events = team.Events; + +await events.AddAsync(new EventCreateOptions +{ + Subject = "Test event - PnP Rocks!", + Location = new EventLocationOptions + { + Type = EventLocationType.Default, + DisplayName = "PnP Test location", + Address = new EventAddressOptions + { + City = "Brussels", + State = "Bussels", + PostalCode = "1000", + CountryOrRegion = "BE", + Street = "Wetstraat" + }, + Coordinates = new EventCoordinateOptions + { + Latitude = 20.00, + Longitude = 30.00, + Accuracy = 5, + Altitude = 20, + AltitudeAccuracy = 2.00 + } + } +}); +``` + +## Adding a recurring event + +Using the PnP Core SDK, we can create a recurring event. Below, we will create a recurring event that will occur weekly, on every monday. This event will recur for exactly one year, starting today. + +```csharp + +// Get the Team +var team = await context.Team.GetAsync(p => p.Events); + +// Get the events +var events = team.Events; + +await events.AddAsync(new EventCreateOptions +{ + Subject = "Test event - PnP Rocks!", + Recurrence = new EventRecurrenceOptions + { + Pattern = new EventRecurrencePatternOptions + { + Type = EventRecurrenceType.Weekly, + Interval = 1, + DaysOfWeek = new List + { + DayOfWeek.Monday + } + }, + Range = new EventRecurrenceRangeOptions + { + Type = EventRecurrenceRangeType.EndDate, + EndDate = DateTime.Now.AddYears(1), + StartDate = DateTime.Now + } + } +};) + +``` + +For more information regarding the creation of recurring events, please have a look at the following Graph documentation page: [Recurrence Pattern documentation](https://docs.microsoft.com/en-us/graph/api/resources/patternedrecurrence?view=graph-rest-1.0). This page will list which combinations are possible and which properties are required when e.g. creating a recurrence with a recurrencerange of type 'EndDate' + +You also can always check the tests that have been written starting from line 329 to 447 for more smaples: [Link to tests](https://github.com/pnp/pnpcore/blob/dev/src/sdk/PnP.Core.Test/Teams/TeamEventTests.cs#L329-L447) + +## Adding an online event with some more properties being set + +In the following example we will create a Teams meeting. There will also be other properties being set such as the priority, the sensitivity of the event and the status on how the presence of the user attending the meeting will be shown. + +```csharp +// Get the Team +var team = await context.Team.GetAsync(p => p.Events); + +// Get the events +var events = team.Events; + +await events.AddAsync(new EventCreateOptions +{ + Subject = "Test event - PnP Rocks", + AllowNewTimeProposals = true, + IsOnlineMeeting = true, + OnlineMeetingProvider = EventOnlineMeetingProvider.TeamsForBusiness, + Sensitivity = EventSensitivity.Personal, + ShowAs = EventShowAs.Busy, + Importance = EventImportance.High +}); + +``` + +For all the possible properties that can be set on creating an event, please refer to following page: [Event Create Options](https://pnp.github.io/pnpcore/api/PnP.Core.Model.Teams.EventCreateOptions.html). + +## Updating events + +You can update the events by changing the properties you wish update and call the update method. The events have to be a part of the class [EventUpdateOptions](https://pnp.github.io/pnpcore/api/PnP.Core.Model.Teams.EventUpdateOptions.html). + +The following sample will update the attendees and the subject of an event. + +```csharp + +// Get the Team +var team = await context.Team.GetAsync(p => p.Events); + +// Get the events +var events = team.Events; + +// Create an event to update + +var firstUser = context.Web.SiteUsers.Where(y => y.PrincipalType == Model.Security.PrincipalType.User).First(); + +var eventOptions = new EventCreateOptions +{ + Subject = "Test event - PnP Rocks", + Attendees = new List + { + new EventAttendeeOptions + { + EmailAddress = firstUser.Mail, + Name = firstUser.Title, + Type = EventAttendeeType.Optional + } + } +}; + +// Add the event (which we will update) +var newEvent = await context.Team.Events.AddAsync(eventOptions); + +// Update the event +await newEvent.UpdateAsync(new EventUpdateOptions +{ + Subject = "Test event - PnP Rocks - Updated", + Attendees = new List + { + new EventAttendeeOptions + { + EmailAddress = firstUser.Mail, + Name = firstUser.Title, + Type = EventAttendeeType.Optional + }, + new EventAttendeeOptions + { + EmailAddress = secondUser.Mail, + Name = secondUser.Title, + Type = EventAttendeeType.Required + } + } +}); + +``` + +## Deleting Events + +You can delete the event with the following example: + +```csharp +var team = await context.Team.GetAsync(p => p.Events); + +var event = await team.Events; + +string eventSubject = $"Test event - PnP Rocks"; + +// Get the event you wish to delete +var eventToDelete = team.Events.Where(p => p.DisplayName == eventSubject).FirstOrDefault(); + +if(eventToDelete != default) +{ + // Perform the delete operation + await eventToDelete.DeleteAsync(); +} +``` diff --git a/docs/using-the-sdk/teams-tags.md b/docs/using-the-sdk/teams-tags.md new file mode 100644 index 0000000000..5b4146a630 --- /dev/null +++ b/docs/using-the-sdk/teams-tags.md @@ -0,0 +1,94 @@ +# Working with Teams: Tags + +Within Teams, you are able to use tags. Tags let you quickly reach a group of people all at once. This page will show you how you can Get, Create, Update and Delete tags. + +[!INCLUDE [Creating Context](fragments/creating-context.md)] + +## Getting Tags + +Tags is a collection part of the ITeam interface, so when you get a team, you can include the tags on the request. + +```csharp +// Get the Team + var team = await context.Team.GetAsync(o => o.Tags); + +// Get the Tags + var tags = team.Tags; + +``` + +## Creating Tags + +To add a new tab, call the Add method, specifying a display name and the users to be associated with the tags. + +> [!Note]: +> The user to be associated with the tag has to be a member of the team. + +```csharp + +// Get the Team +var team = await context.Team.GetAsync(x => x.Tags, x => x.Members); + +// Get the user to associate the tag with +var userId = team.Members.AsRequested().First().Id; + +// Perform the add operation +await team.Tags.AddAsync(new TeamTagOptions +{ + DisplayName = "PnP Tag", + Members = new List + { + new TeamTagUserOptions + { + UserId = userId + } + } +}); + +``` + +## Updating Tags + +You can update the tag by changing the properties you wish update and call the update method: + +```csharp + +// Get the Team +var team = await context.Team.GetAsync(p => p.Tags); + +string tagName = "Tag to update"; + +// Get the tag you wish to update +var tagToUpdate = team.Tags.Where(p => p.DisplayName == tagName).FirstOrDefault(); + +if(tagToUpdate != default) +{ + tagToUpdate.DisplayName = "This tag has been updated by the PnP Core SDK!"; + + // Perform the update to the tag + await tagToUpdate.UpdateAsync(); +} + +``` + +## Deleting Tags + +You can delete the tag with the following example: + +```csharp + +/// Get the Team +var team = await context.Team.GetAsync(p => p.Tags); + +string tagName = $"Tag to delete"; + +// Get the tag you wish to delete +var tagToDelete = team.Tags.Where(p => p.DisplayName == tagName).FirstOrDefault(); + +if(tagToDelete != default) +{ + // Perform the delete operation + await tagToDelete.DeleteAsync(); +} + +``` diff --git a/docs/using-the-sdk/toc.yml b/docs/using-the-sdk/toc.yml index 844acc0db4..d8fdeec180 100644 --- a/docs/using-the-sdk/toc.yml +++ b/docs/using-the-sdk/toc.yml @@ -139,6 +139,12 @@ href: teams-channel-tabs.md - name: Chat href: teams-channel-chat.md + - name: Chat replies + href: teams-channel-chat-reply.md + - name: Events + href: teams-events.md + - name: Tags + href: teams-tags.md - name: Archiving href: teams-archiving.md - name: Taxonomy