Get calendars of office365 email without authentication - c#

I want to get list of events of particular users lets say user#company1.com , user#company2.com which uses office365 accounts.
I need to retrive user#company2.com calendar with out login. My application will be like listing my available timings for my clients , so that they can select my free time and will schedule meeting with me. I need to filter the already scheduled events from my list... Is there any example code for getting calendar events without login??
I tried office365 multi-tenant application which will gives sample code for getting calendar events only after login. I need it with out authentication. Please help me on this.

Trying to access the O365 information without authentication is impossible , either user authentication or app authentication will be required . In your scenario ,you may need app authentication . You could try to build Daemon or Service Apps using client credential grant flow as described in this blog, the service app that requires admin consent, but is authorized to access any mailbox/calendar information in your Office 365 tenant.
Another choice is to use EWS Managed API, you could get free/busy information of a user and suggested meeting times by using the EWS Managed API :
https://msdn.microsoft.com/en-us/library/office/dn643673(v=exchg.150).aspx
And an existing Office add-in support on Outlook:
https://findtime.microsoft.com/

Finally I tried to use the free/busy code. My code is as follows... I am following this procedure but I don't know if it is correct or not. I have a Microsoft Office 365 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 some changes to code and am I proceeding in the 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

Querying O365 Calendars With Chilkat

We've been using the Chilkat component with C# for ages to read and send emails. Works great, no problems. Now though we need to be able to extract Calendar data for meetings rooms, all of which have their own mail account setup so that they can all show in Outlook and teams can, in effect, book the room.
Although I've been through the samples online (https://www.example-code.com/dotnet-core/outlook_calendar_list_events.asp) and got it working for our development mail account in terms of permissions etc. it can only see it's 'own' calendars (e.g. Calendar, UK Holidays, Birthdays), and not the calendars for the the meeting rooms (e.g. Room1, Room2, Room3), all of which I've added to the development mail account's list of calendars.
Is this something that's even possible? Have I connected the other calendars up wrong?
I've generated the token using a working set of endpoints (and the scope 'openid profile offline_access user.readwrite calendars.readwrite files.readwrite') and that's validated properly and returned a token. I've then used that with some of the Chilkat sample code but, when run, it outputs 3 calendars rather than the expected/hoped for 7:
http.AuthToken = jsonToken.StringOf("access_token");
Chilkat.HttpResponse resp = http.QuickRequest("GET","https://graph.microsoft.com/v1.0/me/calendars");
if (http.LastMethodSuccess != true)
{
Console.WriteLine(http.LastErrorText);
return;
}
Console.WriteLine("Response status code = " + Convert.ToString(resp.StatusCode));
// The HTTP request succeeded if the response status code = 200.
if (resp.StatusCode != 200)
{
Console.WriteLine(resp.BodyStr);
Console.WriteLine("Failed");
return;
}
Chilkat.JsonObject json = new Chilkat.JsonObject();
json.Load(resp.BodyStr);
json.EmitCompact = false;
Console.WriteLine(json.Emit());
string odata_context = json.StringOf("\"#odata.context\"");
Console.WriteLine(json.SizeOfArray("value"));

Add B2B external user to Azure AD without sending invitation email C#

We are using azure b2b for inviting the external users to access our applications in the Tenant. For inviting
For new users, we are sending the b2b invite(using c# Code with customized mail format), upon acceptance users are able to access the application.
For bulk user without sending email to user, there is an option in the azure, i.e to download the excel template and filling the details in the excel with column [sendEmail] values True or False
Now I want to add the user to the azure ad without sending the email using C# code. Can anyone suggest to achieve the requirement?
You could use the Graph in order to create B2B users without invitation.
Reference : https://learn.microsoft.com/en-us/graph/api/resources/invitation?view=graph-rest-1.0
POST https://graph.microsoft.com/v1.0/invitations
{
"invitedUserEmailAddress": "guestuser#sampledomain.com",
"inviteRedirectUrl": "https://sample.com",
"sendInvitationMessage": false,
}
You could probably experiment the same action and see whether it meets your requirement in the graph explorer :
https://developer.microsoft.com/en-us/graph/graph-explorer
Having said that, Now you can use the GRAPH C# SDK in order to achieve your requirement using the above request
Ref:https://learn.microsoft.com/en-us/graph/sdks/sdks-overview
To add a External user without the email using GraphClient using C# would be like below :
public static void CreateB2BUser()
{
try
{
var invitation = new Invitation
{
SendInvitationMessage = false,
InvitedUserEmailAddress = "user#sample.com",
InvitedUserType = "Member",
InviteRedirectUrl = "https://sampledomain.com",
InvitedUserDisplayName = "Sample User",
};
graphClient.Invitations.Request().AddAsync(invitation);
}
catch (ServiceException ex)
{
Console.WriteLine($"Error Creating User : {ex.Message}")
}
}
This article can help you to get a quickstart with the authentication and creation of the GraphClient.

Edit Exchange appointment of other user

I'm coding a service which should synchronize Outlook appointments with another system. After appointment created I need to add some info to the body. The service is running under some tech account, it's also added as an owner to the organizer's calendar in Outlook. However, the following code doesn't do any changes:
var _exchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP2, TimeZoneInfo.Local)
{
Url = new Uri(someUrl),
Credentials = new NetworkCredential(someUser, somePwd, someDomain)
};
Appointment appointment = Appointment.Bind(_exchangeService, someId, new PropertySet(AppointmentSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End));
string oldSubject = appointment.Subject;
appointment.Subject = appointment.Subject + " moved one hour later and to the day after " + appointment.Start.DayOfWeek + "!";
appointment.Start.AddHours(25);
appointment.End.AddHours(25);
appointment.Update(ConflictResolutionMode.AlwaysOverwrite, SendInvitationsOrCancellationsMode.SendOnlyToAll);
The sample code is taken from MSDN. The code works when Organizer and tech Account is the same user.
Do you have any idea of what could be wrong? Thank you!
The sample code is taken from MSDN. The code works when Organizer and tech Account is the same user.
That's correct because you can only make changes to appointments that the user making the modifications is the owner off (in some case this will require that you use EWS Impersonation https://msdn.microsoft.com/en-us/library/office/dd633680(v=exchg.80).aspx ). For a Meeting object where you have multiple attendees once you make changes in the Organizer mailbox updates then need to be sent out to the attendees who then need to acknowledge those updates for the updates to be applied to the version of the Appointment in the attendee's calendars.
Cheers
Glen

Google Apis v3 in ASP.Net - "Unauthorized client or scope in request"

Maybe I am simply not getting "it", with "it" being the overall setup needed to make this work.
I have a website that scrapes other sites for sporting events. I want to automatically create Google Calendar events from the results, so I want to give my Web Application Read/Write access on a Calendar in my GMail account.
I have been trying to wrap my head around this for a week now, but I can't get it to work and it is crushing my self-esteem as a developer.
The way I "understand" it is that I need a Google API v3 Service Account, because I don't need an API key for a particular user. Or do I need a Simple API key (instead of oAuth)?
Anyways, I went with the Service Account.
In my HomeController I am trying to GET a Calendar so I know it all works.
public void Calendar()
{
string serviceAccountEmail = "...#developer.gserviceaccount.com";
var certificate = new X509Certificate2(
Server.MapPath("~") + #"\App_Data\key.p12",
"notasecret",
X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential =
new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[]
{
CalendarService.Scope.Calendar
},
User = "MY-GMAIL-EMAIL" // Is this correct?
}
.FromCertificate(certificate));
BaseClientService.Initializer initializer = new BaseClientService.Initializer();
initializer.HttpClientInitializer = credential;
initializer.ApplicationName = "CALENDAR NAME"; // Correct?
var service = new CalendarService(initializer);
var list = service.CalendarList.List().Execute().Items; // Exception :-(
}
The error I am getting:
An exception of type 'Google.Apis.Auth.OAuth2.Responses.TokenResponseException' occurred in Google.Apis.dll but was not handled in user code
Additional information: Error:"unauthorized_client", Description:"Unauthorized client or scope in request.", Uri:""
So I tried a bunch of things in Google Calendar, like making it public, adding the service account email as a READ/WRITE user.
What do I need to do to authorize my Web Application so it can create events on my behalf?
I have done this with the service account in a similar post. I changed a bit of my code and got it working to list my calendars by switching a few things around. I can create events as well. I didn't add a user as you have done in the initializer, and under application name, it is the name of the application in the dev console. Make sure you name your application. Make sure your service account is shared with your account.
I slightly changed the list part of your code to this in mine and got back the my list of calendars.
var list = service.CalendarList.List();
var listex = list.Execute();
Check out my example at Google API Calender v3 Event Insert via Service Account using Asp.Net MVC

Quickbooks Online integration c#

My company uses QuickBooks Online, and I would like to write some c# scripts that retrieve very basic information like a list of customers and list of invoices from the QuickBooks Online subscription.
I would also like to submit invoices and payments.
I have created a QuickBooks IPP account (at developer.intuit.com).
I am able to authenticate myself (OAuth) just fine. My questions are:
1) Do I need to authenticate myself every time I wish to connect to QBO IPP (to retrieve a list of customers, submit an invoice, etc.)? Or can my app authenticate itself once & stay 'connected' for months?
2) Is there any sample code to do basic things such as obtain a list of customers, submit an invoice, etc.? I downloaded the sample MVC app from this link
And it was quite helpful - but when I try to get some of the code to work, I just get errors - which leads me to my first question - can I authenticate myself ONCE and use those tokens (appToken, and appTokenSecret) many times in order to perform simple tasks (obtain customer list), or do I have to authenticate myself every time?
Thank you.
Re - 1) Do I need to authenticate myself every time I wish to connect to QBO IPP (to retrieve a list of customers, submit an invoice, etc.)? Or can my app authenticate itself once & stay 'connected' for months?
Please find below steps to get OAuth tokens using which you can make API call against your QBO account. If you create an app in appcenter, you'll get consumerKey and consumerSecret. https://developer.intuit.com/Application/Create/IA
Using the above two tokens, you can generate accessToken and accessSecret from the OAuthPlayground. https://appcenter.intuit.com/Playground/OAuth/IA PN - After completing C2QB(OAuth) flow, you should use 'App Menu API Test.' option which will show you accessToken and accessSecret.
These tokens are valid for 180 days (at max). When these tokens are more than 150 days old (and <180 days), you can make Reconnect API call to revalidate those again.
Ref https://developer.intuit.com/docs/0050_quickbooks_api/0020_authentication_and_authorization/oauth_management_api#Reconnect
So you can always persist these tokens and reuse it.
To let end users connect their QB data with you SaaS app, you need to implement a wizard called 'Connect to Quickbook'. Using 3-legged Oauth your app will be able to capture the acessToken and acessSecret corresponding to the end-user's qbo account.
Ref - https://developer.intuit.com/docs/0100_accounting/0060_authentication_and_authorization/connect_from_within_your_app#7._Add_the_Connect_to_QuickBooks_button
Re - 2) Is there any sample code to do basic things such as obtain a list of customers, submit an invoice, etc.?
Please refer - https://developer.intuit.com/docs/0100_accounting/0500_developer_kits/0150_ipp_.net_devkit_3.0/0002_synchronous_calls#/Data_Services_API
and how to add invoice or sales receipt quickbooks rest api v3.0
This is a sample code to get the Quickbooks data using c#.
You can use OAuth play ground(https://developer.intuit.com/app/developer/playground) to get the access token, realm Id.
Base url is https://sandbox-quickbooks.api.intuit.com/v3/company/realmId/query?minorversion={{minorversion}}.
In here I used 55 as minor version.
using Intuit.Ipp.Core;
using Intuit.Ipp.Data;
using Intuit.Ipp.QueryFilter;
using Intuit.Ipp.Security;
using System;
using System.Collections.Generic;
using System.Linq;
namespace InvoiceTable
{
class Program
{
static void Main(string[] args)
{
try
{
//List<Invoice> InvoiceList = new List<Invoice>();
OAuth2RequestValidator oauthValidator = new OAuth2RequestValidator(Access_Token);
ServiceContext serviceContext = new ServiceContext(realm Id, IntuitServicesType.QBO, oauthValidator);
serviceContext.IppConfiguration.MinorVersion.Qbo = "minorversion";
serviceContext.IppConfiguration.BaseUrl.Qbo = Base URL;
var querySvc = new QueryService<Invoice>(serviceContext);
var InvoiceList = querySvc.ExecuteIdsQuery("Select Balance From Invoice").ToList();
}
catch (Exception ex)
{
throw;
}
}
}
}
IppDotNetSdkForQuickBooksApiV3 version 10.0.0 is the package that you have to install.

Categories