Office365 Calendar Events For Team Meeting - c#

I am developing one application in ASP.NET with office365 REST API. I need to schedule a team event in office365 but before scheduling that event i need to check the available time of all team members. If a slot is free then only i need to setup a event for the team.
Lets assume i have 3 members team like , user1#someone.com , user2#someone.com, user3#clientone.com . I need to check the available times of all members on team and needs to show only compatable times. Lets assume user1 have a schedule meeting at 9:00am - 9:30 am then i need to hide that time why because user1 is not having free time.
How can i do this? Any idea?

Find Meeting Times (=Exchange FreeBusy) is in preview https://msdn.microsoft.com/en-us/office/office365/api/calendar-rest-operations#Findmeetingtimespreview but you should be able to use it via https://outlook.office.com/api/beta
Cheers
Glen

Finally i tried to use the free/busy code . My code as follows... I am following this procedure but i don't know either it is correct or not. I have office365 account and by passing credentials silently i am creating exchange server service. After that i am passing different domain attendee information as ORGANIZER and REQUIRED as follows. But it is returning all values not skipping any scheduled meetings for those users.
Lets assume user1#domain.com is ORGANIZER and user2#anotherdomain.com is REQUIRED for meeting . User1 have meeting scheduled at 7:00-7:30pm on daily basis but when i executed the following script it shows me 7:00-7:30pm as available for meeting. It supposed to block that time. Can you suggest somechanges to code and am i proceeding in correct way??
private static void GetSuggestedMeetingTimes(ExchangeService service)
{
List<AttendeeInfo> attendees = new List<AttendeeInfo>();
attendees.Add(new AttendeeInfo()
{
SmtpAddress = "user1#mydomain.com",
AttendeeType = MeetingAttendeeType.Organizer
});
attendees.Add(new AttendeeInfo()
{
SmtpAddress = "user2#anotherdomain.com",
AttendeeType = MeetingAttendeeType.Required
});
// Specify options to request free/busy information and suggested meeting times.
AvailabilityOptions availabilityOptions = new AvailabilityOptions();
availabilityOptions.GoodSuggestionThreshold = 49;
availabilityOptions.MaximumNonWorkHoursSuggestionsPerDay = 0;
availabilityOptions.MaximumSuggestionsPerDay = 40;
// Note that 60 minutes is the default value for MeetingDuration, but setting it explicitly for demonstration purposes.
availabilityOptions.MeetingDuration = 30;
availabilityOptions.MinimumSuggestionQuality = SuggestionQuality.Good;
availabilityOptions.DetailedSuggestionsWindow = new TimeWindow(DateTime.Now.AddDays(1), DateTime.Now.AddDays(2));
availabilityOptions.RequestedFreeBusyView = FreeBusyViewType.FreeBusy;
// Return free/busy information and a set of suggested meeting times.
// This method results in a GetUserAvailabilityRequest call to EWS.
GetUserAvailabilityResults results = service.GetUserAvailability(attendees,
availabilityOptions.DetailedSuggestionsWindow,
AvailabilityData.FreeBusyAndSuggestions,
availabilityOptions);
// Display suggested meeting times.
Console.WriteLine("Availability for {0} and {1}", attendees[0].SmtpAddress, attendees[1].SmtpAddress);
Console.WriteLine();
foreach (Suggestion suggestion in results.Suggestions)
{
Console.WriteLine("Suggested date: {0}\n", suggestion.Date.ToShortDateString());
Console.WriteLine("Suggested meeting times:\n");
foreach (TimeSuggestion timeSuggestion in suggestion.TimeSuggestions)
{
Console.WriteLine("\t{0} - {1}\n",
timeSuggestion.MeetingTime.ToShortTimeString(),
timeSuggestion.MeetingTime.Add(TimeSpan.FromMinutes(availabilityOptions.MeetingDuration)).ToShortTimeString());
}
}
int i = 0;
// Display free/busy times.
foreach (AttendeeAvailability availability in results.AttendeesAvailability)
{
Console.WriteLine("Availability information for {0}:\n", attendees[i].SmtpAddress);
foreach (CalendarEvent calEvent in availability.CalendarEvents)
{
Console.WriteLine("\tBusy from {0} to {1} \n", calEvent.StartTime.ToString(), calEvent.EndTime.ToString());
}
i++;
}

Related

List all Shifts Graph API

I'm using Graph API SDK in a C# Console Application and I'd like to list all the shift data from Microsoft Teams. But I'm unable to retrieve such information. Here is what I have done so far.
According to the documentation to list all shift, you have to provide the team ID in order to retrieve the shift, however, in my case, I have to retrieve all the shift from all the teams. So, I have to retrieve the list of the team first. The documentation says that to retrieve all team you have to retrieve the list of groups first. I've followed the same approach and the following is the code that I've used.
var groups = await graphClient
.Groups.Request()
.Filter("resourceProvisioningOptions/Any(x:x eq 'Team')")
.GetAsync();
foreach (var group in groups)
{
Console.WriteLine(group.DisplayName);
var shifts = await graphClient
.Teams[group.Id]
.Schedule
.Shifts
.Request()
.GetAsync();
}
I'm able to retrieve the Group list, however, I'm not able to retrieve the Shift list. When it tries to retrieve the Shift list the following error occurs:
Code: NotFound
Message: {
"error":{
"code":"NotFound",
"message":"Sorry, the team was not found, or you may not have access to it.",
"details":[],
"innererror":{"code":"TeamNotFound"}
}
}
Inner error:
AdditionalData:
request-id: c5ab5f5c-ec3d-463b-9b1f-0798734e94ce
date: 11/11/2019 7:50:42 AM
ClientRequestId: c5ab5f5c-ec3d-463b-9b1f-0798734e94ce
Would appreciate any help that can help me to list all the shift list from Microsoft Teams. Thank you.
This error most likely occurs since schedule object is not provisioned. The point is List shifts endpoint expects schedule object to be provisioned. From Get schedule documentation:
During schedule provisioning, clients can use the GET method to get
the schedule and look at the provisionStatus property for the current
state of the provisioning. If the provisioning failed, clients can get
additional information from the provisionStatusCode property.
In msgraph-sdk-dotnet whether schedule provisioned could be determined like this:
var schedule = await graphClient.Teams[group.Id].Schedule.Request().GetAsync();
if (schedule.ProvisionStatus == OperationStatus.Completed)
{
//...
}
Here is an updated example (which demonstrates how to retrieve shifts for provisioned schedule):
var groups = await graphClient.Groups.Request()
.Filter("resourceProvisioningOptions/Any(x:x eq 'Team')")
.GetAsync();
foreach (var group in groups)
{
var schedule = await graphClient.Teams[group.Id].Schedule.Request().GetAsync();
if (schedule.ProvisionStatus == OperationStatus.Completed)
{
var shifts = await graphClient.Teams[group.Id].Schedule.Shifts.Request().GetAsync();
//...
}
}

Google play error when making a purchase while implementing Soomla Unity3d plugin

I am creating an app that implements the Soomla Unity IAP plugin. In my effort to get the IAP to work, I have gotten to a point where I can make a purchase when in the editor. (Not a real purchase, it just updates the virtual currency that the user can buy/spend in game).
When I launch this on an Android device, I get this error: Authentication is required. You need to sign into your Google Account.
Now I have read multiple different articles where people have had this issue and nothing seems to be helping me.
Here is list of what I have tried so far:
1) Make sure app is published either to alpha or beta for testing.(in alpha now)
2) Make sure prices match for game and in developer console.
3) Use a device that is logged in as a user that is not using the developer email.
4) Make sure the email on the test device is listed as a tester in the developer console.
5) Make sure the necessary permissions are listed in the Android Manifest.
6) Confirm merchant account is set up correctly and verified.
7) Make sure to build as release and not development (not sure if this even matters, but I tried both ways).
8) Completely removed all of the Soomla plugin from the project and then added it back in while following the tutorial very closely just to makes sure nothing small was missed. Still no dice.
I have the core and store components added to the scene that they are necessary in. Please let me know if you have any other ideas of what I should do to fix this problem. In the mean time, here is the StoreAssets.cs code I use for setting up Soomla:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Soomla.Store;
public class StoreAssets : IStoreAssets
{
public static bool purchased = false;
public int GetVersion()
{
return 0;
}
public void onItemPurchased(PurchasableVirtualItem pvi, string payload)
{
purchased = true;
}
public VirtualCurrency[] GetCurrencies()
{
return new VirtualCurrency[]{TOKEN_CURRENCY};
}
public VirtualGood[] GetGoods()
{
return new VirtualGood[] {BACKUP_FORCEFIELD, IMMUNITY, EMP, MULTIPLIER};
}
public VirtualCurrencyPack[] GetCurrencyPacks()
{
return new VirtualCurrencyPack[] {FIVE_TOKEN_PACK, TEN_TOKEN_PACK, FIFTY_TOKEN_PACK};
}
public VirtualCategory[] GetCategories()
{
return new VirtualCategory[]{};
}
/** Virtual Currencies **/
public static VirtualCurrency TOKEN_CURRENCY = new VirtualCurrency
(
"Token", // Name
"Token currency", // Description
"token_currency_ID" // Item ID
);
/** Virtual Currency Packs **/
public static VirtualCurrencyPack FIVE_TOKEN_PACK = new VirtualCurrencyPack
(
"5 Tokens", // Name
"5 token currency units", // Description
"5_tokens_id", // Item ID
5, // Number of currencies in the pack
"token_currency_ID", // ID of the currency associated with this pack
new PurchaseWithMarket
( // Purchase type (with real money $)
"tokens_5_PROD_ID", // Product ID
0.99 // Price (in real money $)
)
);
public static VirtualCurrencyPack TEN_TOKEN_PACK = new VirtualCurrencyPack
(
"10 Tokens", // Name
"10 token currency units", // Description
"10_tokens_id", // Item ID
10, // Number of currencies in the pack
"token_currency_ID", // ID of the currency associated with this pack
new PurchaseWithMarket
( // Purchase type (with real money $)
"tokens_10_PROD_ID", // Product ID
1.99 // Price (in real money $)
)
);
public static VirtualCurrencyPack FIFTY_TOKEN_PACK = new VirtualCurrencyPack
(
"50 Tokens", // Name
"50 token currency units", // Description
"50_tokens_id", // Item ID
50, // Number of currencies in the pack
"token_currency_ID", // ID of the currency associated with this pack
new PurchaseWithMarket
( // Purchase type (with real money $)
"tokens_50_PROD_ID", // Product ID
4.99 // Price (in real money $)
)
);
/** Virtual Goods **/
public static VirtualGood BACKUP_FORCEFIELD = new SingleUseVG
(
"BackupForcefield", // Name
"Secondary forcefield for extra protection.", // Description
"bff_ID", // Item ID
new PurchaseWithVirtualItem
( // Purchase type (with virtual currency)
"token_currency_ID", // ID of the item used to pay with
1 // Price (amount of coins)
)
);
public static VirtualGood EMP = new SingleUseVG
(
"Emp", // Name
"Clear the surrounding space of all lasers.", // Description
"emp_ID", // Item ID
new PurchaseWithVirtualItem
( // Purchase type (with virtual currency)
"token_currency_ID", // ID of the item used to pay with
5 // Price (amount of coins)
)
);
public static VirtualGood IMMUNITY = new SingleUseVG
(
"Immunity", // Name
"Immune to damage.", // Description
"immunity_ID", // Item ID
new PurchaseWithVirtualItem
( // Purchase type (with virtual currency)
"token_currency_ID", // ID of the item used to pay with
10 // Price (amount of coins)
)
);
public static VirtualGood MULTIPLIER = new SingleUseVG
(
"Multiplier", // Name
"Double your score per deflected laser.", // Description
"multiplier_ID", // Item ID
new PurchaseWithVirtualItem
( // Purchase type (with virtual currency)
"token_currency_ID", // ID of the item used to pay with
15 // Price (amount of coins)
)
);
}
In order to purchase Items, I call:
StoreInventory.BuyItem("the id of my item");
To use an item that has been purchased, I call:
StoreInventory.TakeItem("the id of my item");
StoreInventory is a class that is included in Soomla when it is imported into Unity.
Here is the code where buying and item consumption is done:
public class Purchase : MonoBehaviour
{
public Text tokens;
public static bool bffFilled = false,
immFilled = false, empFilled = false,
multFilled = false, init = false;
void Start()
{
if (!init)
{
init = true;
SoomlaStore.Initialize(new StoreAssets());
}
Token.updateTokens (tokens);
}
void Update()
{
if (StoreEvents.balanceChanged)
{
StoreEvents.balanceChanged = false;
Token.updateTokens(tokens);
}
}
public void BuyItem (int item)
{
if (item == 1)
{
StoreInventory.BuyItem (StoreAssets.FIVE_TOKEN_PACK.ItemId);
}
else if (item == 2)
{
StoreInventory.BuyItem (StoreAssets.TEN_TOKEN_PACK.ItemId);
}
else if (item == 3)
{
StoreInventory.BuyItem (StoreAssets.FIFTY_TOKEN_PACK.ItemId);
}
Token.updateTokens(tokens);
}
public void getUpgrade(int upgrade)
{
if (upgrade == 1)
{
bool bffNotBought = PlayerPrefs.GetInt("Bff Available", 0) == 0;
if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 1 && bffNotBought)
{
PlayerPrefs.SetInt("Bff Available", 1);
PlayerPrefs.Save();
bffFilled = true;
StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 1);
}
}
else if (upgrade == 2)
{
bool empNotBought = PlayerPrefs.GetInt("Emp Available", 0) == 0;
if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 5 && empNotBought)
{
PlayerPrefs.SetInt("Emp Available", 1);
PlayerPrefs.Save();
empFilled = true;
StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 5);
}
}
else if (upgrade == 3)
{
bool immNotBought = PlayerPrefs.GetInt("Imm Available", 0) == 0;
if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 10 && immNotBought)
{
PlayerPrefs.SetInt("Imm Available", 1);
PlayerPrefs.Save();
immFilled = true;
StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 10);
}
}
else if (upgrade == 4)
{
bool multNotBought = PlayerPrefs.GetInt("Mult Available", 0) == 0;
if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 15 && multNotBought)
{
PlayerPrefs.SetInt("Mult Available", 1);
PlayerPrefs.Save();
multFilled = true;
StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 15);
}
}
Token.updateTokens (tokens);
}
}
8/26/15
I have now created both a google group and a google community for testing this app. I added the email for my other android device to the both of these and I used the link provided to download the app. Doing all of this still resulted in the same error as before.
8/27/15
I just noticed that my credit card on my merchant account had expired. One of the articles I read mentioned having issues like this if there were issues with the merchant account. I have updated the information and now I have to wait the deposit they will put in my account to make sure it is working. Once that is done I will update whether or not this fixed my current problem.
8/31/15
After finally verifying my merchant account on Google Play, I still seem to have the same problem. Fixing my merchant account did not change anything that I couldn't tell.
I just updated my post to include my whole StoreAssets.cs script and what I use to make purchases and consume items when a player uses them. I added this since I have no idea what else the issue could be.
9/7/15
Still no luck so far. Issue persists in android. The editor itself makes test purchases but purchases cannot be make from an android device without getting the same error as listed above.
9/9/15
Just as a quick update, I have tried building the project without the development build selected in the build settings and I send the link to all of the people in my Google community in order to give it a shot. Everyone still has the same error as my testing device does.
9/11/15
After trying a few things that Tony pointed out, I have noticed that the onBillingSupported() function is not called when I use this: StoreEvents.OnBillingSupported += onBillingSupported; I'm not sure why just yet.
9/12/15
After going through the tutorial on the soomla site, I have done everything it said except starting the Iab in the background and the fraud protection since they aren't required. the onBillingSupported method is still not called and I am still getting the same error as before on android devices.
9/12/15
I just removed everything for the Soomla plugin and imported the newest version and followed the instructions again and I still get the same error.
9/16/15
Really no idea what I am missing here. After removing all of the Soomla plugin and then adding it again and still getting the same error after multiple tries. I have followed everything as the tutorial says and I have all of the code above.
I have never had the problem you describe. I created a private Google+ community though, and added the community as testers. Shifted my App to Beta. And invited people to my private community where there was a link to download the app and test it. It was easy.
The second point, is your code above. You are fetching 4 goods and 3 currency packs but the code does not reflect that. Maybe you you only pasted half the class.
Finally, see if this thread will help: http://answers.soom.la/t/solved-some-clarification-about-iab-testing/2067/8
By the way, SOOMLA have a dedicated site answers.soom.la for SOOMLA related issues.
Did you try buying goods from another device?
I have had this issue before, but do not recall how I fixed it.
From what I remember when it failed for me, it was working on the different co-worker's device.
Try testing it on a different device.
also, do you have multiple google accounts on your device?
I remember that one of the things that I tried was removing all google account from my device and just left my main account registered. Unfortunately, I don't remember if that worked, but I hope it will help you.
if you find out how to fix it please post an update here. good luck
In my case, I didn't realize that what I was using for my item ID and my product ID were mixed up. The item ID is just to identify the item within soomla, the product ID is the actual I'd you,set in google play.
From the brief discussion in the comments it sounds like you may not have everything implemented.
Check out this link:
http://know.soom.la/unity/store/store_gettingstarted/
In the Getting Started section it states..
Create your own implementation of IStoreAssets in order to describe your game's specific assets.
Initialize SoomlaStore with the class you just created:
SoomlaStore.Initialize(new YourStoreAssetsImplementation());
Initialize SoomlaStore in the Start function of MonoBehaviour and NOT
in the Awake function. SOOMLA has its own MonoBehaviour and it needs
to be "Awakened" before you initialize.
Initialize SoomlaStore ONLY ONCE when your application loads.
The initialization is confirmed on this page as well.
http://know.soom.la/unity/store/store_istoreassets/
This says it is not mandatory but looks helpful
If you have your own storefront implemented inside your game, it's
recommended that you open the IAB Service in the background when the
store opens and close it when the store is closed.
// Start Iab Service SoomlaStore.StartIabServiceInBg();
// Stop Iab Service SoomlaStore.StopIabServiceInBg();
This is not mandatory, your game will work without this, but we do recommend it
because it enhances performance. The idea here is to preemptively
start the in-app billing setup process with Google's (or Amazon's)
servers.
You could try adding logging to the initialize event to make sure it is initializing. Here is a list of events you can try logging from..
http://know.soom.la/unity/store/store_events/
NOTE: One thing you need to notice is that if you want to listen to
OnSoomlaStoreInitialized event you have to set up the listener before
you initialize SoomlaStore. So you'll need to do:
StoreEvents.OnSoomlaStoreInitialized += onSoomlaStoreInitialized;
before
Soomla.SoomlaStore.Initialize(new Soomla.Example.MuffinRushAssets());
You can also setup the OnBillingSetup event with some logging to make sure it is initializing your billing correctly.
StoreEvents.OnBillingSupported += onBillingSupported;
public void onBillingSupported() {
// ... your game specific implementation here ... }

Office 365 API MVC Authentification

I am using the MVC Office 365 API libraries and I would like to archieve the following thing: Logging into User-Accounts where I know the username / password and then get there calendar entries.
What I have so far is code that makes this redirect and ask the user to enter credentials. But how can I log in for them wihtout asking? The idea is to get the calendar entries for every user (lets say 20 of them) automatically every few minutes.
public static async Task<IEvent[]> GetCalendarEvents()
{
var client = await EnsureClientCreated();
// Obtain calendar event data
var eventsResults = await (from i in client.Me.Events
where i.End >= DateTimeOffset.UtcNow
select i).Take(10).ExecuteAsync();
var events = eventsResults.CurrentPage.OrderBy(e => e.Start).ToArray();
return events;
}
public static async Task<ExchangeClient> EnsureClientCreated()
{
var _discoveryContext = await CacheHelper.GetDiscoveryContext();
var dcr = await _discoveryContext.DiscoverResourceAsync(ServiceResourceId);
return new ExchangeClient(ServiceEndpointUri, async () =>
{
return (await _discoveryContext.AuthenticationContext.AcquireTokenByRefreshTokenAsync(new SessionCache().Read("RefreshToken"),
new Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential(_discoveryContext.AppIdentity.ClientId, _discoveryContext.AppIdentity.ClientSecret),
ServiceResourceId))
.AccessToken;
});
}
Late answer I know. But if your still looking for this, or anyone else, this blog may be what your looking for.
http://blogs.msdn.com/b/exchangedev/archive/2015/01/22/building-demon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow.aspx
A daemon/service app will get calendar events on behalf of a user, proving the user and the app are registered under the same tennat/organisation.

Twilio Gather/Play Recordings in loop

I am building a Twilio IVR using WebAPI and hit a bit of a snag. I am trying to loop through the recordings and at the end of each one offer the option to press 1 to delete the recording.
I can't find any examples anywhere of this in a C# WebAPI implementation and the following won't work and I am not sure how to go about this.
What I know;
Need to GATHER the digits entered
Somehow pass back the recording sid to the api to know which recording to delete.
Here is the code I've written so far:
public HttpResponseMessage Messages() {
string baseUrl = Url.Request.RequestUri.GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped);
var twilio = new TwilioRestClient(_accountSid, _authToken);
var recordings = twilio.ListRecordings(null, DateTime.Today, null, null);
var twilioResponse = new TwilioResponse();
if (recordings != null && recordings.Recordings.Count > 0)
{
var msgCount = 1;
var msgTotal = recordings.Recordings.Count();
foreach (var recording in recordings.Recordings)
{
var caller = twilio.GetCall(recording.CallSid);
var callerNumber = Regex.Replace(caller.From, #"([0-9]{1})", "$1,");
var callDate = recording.DateCreated.ToString("dddd MMMM d");
var callTime = recording.DateCreated.ToString("h m t");
twilioResponse.Say(string.Format("Playing message {0} of {1}, from {2} on {3} at {4} M.", msgCount, msgTotal, callerNumber, callDate, callTime),
new { voice = "woman" });
var voiceFile = string.Format("{0}2010-04-01/Accounts/{1}/Recordings/{2}.mp3", twilio.BaseUrl, _accountSid, recording.Sid);
twilioResponse.Play(voiceFile);
//twilioResponse.BeginGather(new
// {
// action = baseUrl + "/api/Recording/Delete",
// numDigits = 1,
// });
//twilioResponse.Say("TO DELETE THIS MESSAGE PRESS 1");
//twilioResponse.EndGather();
msgCount++;
}
}
return Request.CreateResponse(HttpStatusCode.OK, twilioResponse.Element, Configuration.Formatters.XmlFormatter);
}
I've worked with Twilio's API before but this is a new one for me and I can't really see if this is possible. The PHP example they have is doing it though so maybe I am simply missing the mark because I should be going a different way about this.
Twilio evangelist here.
What you have looks really close. Lets look at passing back the Recording SID in scenarios where the user presses one since thats relatively easy to do by using the action URL your setting on the Gather verb to hold some state for you:
action = baseUrl + "/api/Recording/Delete?recordingSid=" + recording.Sid;
Now when the user presses one, Twilio will make a request to the Action URL which includes the recordingSid parameter.
Once you've deleted the Recording, you can just redirect back to your Messages endpoint to continue to listen to more recordings. In order to keep track of which recordings you've listened to already, you might need to pass some additional parameters in the action URL that can you can pass through your delete workflow and back into the listen workflow.
Hope that helps.

Getting a list of all users via Valence

I am trying to get a list of all users in our instance of Desire2Learn using a looping structure through the bookmarks however for some reason it continuously loops and doesn't return. When I debug it it is showing massive amounts of users (far more than we have in the system as shown by the User Management Tool. A portion of my code is here:
public async Task<List<UserData>> GetAllUsers(int pages = 0)
{
//List<UserData> users = new List<UserData>();
HashSet<UserData> users = new HashSet<UserData>();
int pageCount = 0;
bool getMorePages = true;
var response = await Get<PagedResultSet<UserData>>("/d2l/api/lp/1.4/users/");
var qParams = new Dictionary<string, string>();
do
{
qParams["bookmark"] = response.PagingInfo.Bookmark;
//users = users.Concat(response.Items).ToList<UserData>();
users.UnionWith(response.Items);
response = await Get<PagedResultSet<UserData>>("/d2l/api/lp/1.4/users/", qParams);
if (pages != 0)
{
pageCount++;
if (pageCount >= pages)
{
getMorePages = false;
}
}
}
while (response.PagingInfo.HasMoreItems && getMorePages);
return users.ToList();
}
I originally was using the List container that is commented out but just switched to the HashSet to see if I could notice if duplicates where being added.
It's fairly simple, but for whatever reason it's not working. The Get<PagedResultSet<UserData>>() method simply wraps the HTTP request logic. We set the bookmark each time and send it on.
The User Management Tool indicates there are 39,695 users in the system. After running for just a couple of minutes and breaking on the UnionWith in the loop I'm showing that my set has 211,800 users.
What am I missing?
It appears that you’ve encountered a defect in this API. The next course of action is for you to have your institution’s Approved Support Contact open an Incident through the Desire2Learn Helpdesk. Please make mention in the Incident report that Sarah-Beth Bianchi is aware of the issue, and I will work with our Support team to direct this issue appropriately.

Categories