Exchange web service set organizer of the appointment - exchangewebservices

When I use Service account to add a new appointment, the organizer always the user of Credentials to Exchange service, I want to set the organizer to another user, but the organizer property is readonly, how can I achieve that?
var appointment = new Appointment(_service.ExchangeService);
if (exchangeAppointment.Participants.Any() && exchangeAppointment.Participants != null)
{
foreach (var participant in exchangeAppointment.Participants)
{
appointment.RequiredAttendees.Add(participant);
}
}
appointment.Resources.Add(exchangeAppointment.RoomAdIdentityEmail);
appointment.Location = string.Join(",", appointment.Resources);
appointment.Subject = exchangeAppointment.Subject;
appointment.Body = exchangeAppointment.Body;
appointment.Start = exchangeAppointment.StartTime;
appointment.End = exchangeAppointment.EndTime;
appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy);

The Organizer is going to be set based on the Calendar your saving the Appointment to, when you using a Service Account your creating the Appointment OnBehalf of the Organizer so you would need set the Save location to the calendar of the Organizer you want eg
Save(new FolderId(WellKnownFolderName.Calendar, "user#ddomain.com"), SendInvitationsMode.SendToAllAndSaveCopy);
The other option is to use EWS Impersonation and then Impersonate the Organizer http://msdn.microsoft.com/en-us/library/office/dd633680%28v=exchg.80%29.aspx
Cheers
Glen

Related

Getting error when try to create meeting on exchange calendar through exchange api

I am using EWS Managed exchange api in c#
I am getting below error when i am try to create meeting on default calendar (Calendar).
Cannot create a calendar item in a non-calendar folder.
here is my code :
Appointment appointment = new Appointment(service);
appointment.Subject = "Test meeting";
appointment.Body = "Test Connection meeting";
appointment.Start = meetingStartTime;
appointment.End = meetingEndTime;
appointment.Sensitivity = Sensitivity.Normal;
appointment.Save(calendarId, SendInvitationsMode.SendToNone);
Note : I am fetching the calendar by calendar name.
As below
SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "Calendar");
Please revert as soon as possible.
Most certainly the error is where you fetch the SearchResult.
A workaround would be to just call
appointment.Save(WellKnownFolderName.Calendar, SendInvitationsMode.SendToNone);
This calls for the default calendar folder without the need to search it first.

Script to validate if value exists in a list

I have a google spreadsheet which will be used for collaboration and I was able to create a UI interface which will fetch and update data from a table to make it easier for users.
For the work I need to restrict users to only be able to update rows if they are assigned to them and I am able to do it. But along with that, I also need to allow administrator to assign or update rows which are not assigned to them.
I have a table with all employee's email address and an admin flag for those who are admin.
Name____________Email________________Is Admin
Employee 1_______emp1#domain.com_____Admin
Employee 2_______emp2#domain.com_____
Employee 3_______emp3#domain.com_____
Employee 4_______emp4#domain.com_____Admin
Employee 5_______emp5#domain.com_____
Employee 6_______emp6#domain.com_____
How can I write a something in my script that will allow me to if the user who is triggering a function has admin right or not.
I user Session.getActiveUser().getEmail() to pull out the users email address. I am creating the tool to be used within google apps domain.
Code that checks if the user is the owner of the row, this part works fine but what I want to do is if a user is admin they basically will skip this check.
if (s.getRange("E4").getValue() != usr()){
msg("Once a Task is assigned to an employee, only assigned employee can make any changes to the Task. Thank you");
return;
}
s = sheet
usr() = function calling to check active user email
If I can do something like countifs where I can check count based on the email address and Admin criteria and if its >= 1 proceed if its 0 show error that you can not make changes.
Please let me know.
Really appreciate the help.
Thank you.
Zooooon
Are you looking for something like this?
function myFunction() {
var s = SpreadsheetApp.getActiveSheet();
var usr = Session.getActiveUser().getEmail();
var emails = s.getRange("E2:F").getValues();
for (var i=0;i<emails.length;i++) {
if (emails[i][0] === usr){
if (emails[i][1] === "Admin") {
//Do something when Admin
return;
} else {
//Do something when not admin
return;
}
} else {
//Do something when email not in the list
}
}
}
I am assuming your data is in the range "D:F"

Returning a users directory profile with the Admin SDK on Google Apps Script

Need some GAS help..
I am trying to return a list of users and their department using the ADMIN SDK
Using Google Apps Script and the Directory API in the Admin SDK.
if (users) {
for (var i = 0; i < users.length; i++) {
var user = users[i];
values.push([users[i].primaryEmail, users[i].orgUnitPath, users[i].organizations.department]);
}
I cannot figure out the syntax to return the department in the organizations.department
If I use
users[i].organizations
Then it returns every available entry in organization for that user.
Ex.
[{title=Student, location=3, customType=work, department=School, primary=true, name=School District}]
I need to return just 'department'
Thank you in advance!
As per my understanding, there is no way to get department directly. You need iterate each organization entry to get department. see here in fields text-field, you can select fields that you want to see in output(response)

How do I getGivenName() of getActiveUser()

Each user on the domain initiates a simple script we run for leave entitlements but we want the welcome message to be "Hi First Name," however the script doesn't seem to be able to fetch getGivenName() from getActiveUser() for a standard user.
Is there a way?
As noted in comments, and in Documentation, the UserManager Service is only accessible by Domain Administrators.
Here's an alternative. Domain Users may have themselves in their own contacts, so how about a best-effort attempt at finding themselves there?
/**
* Get current user's name, by accessing their contacts.
*
* #returns {String} First name (GivenName) if available,
* else FullName, or login ID (userName)
* if record not found in contacts.
*/
function getOwnName(){
var email = Session.getEffectiveUser().getEmail();
var self = ContactsApp.getContact(email);
// If user has themselves in their contacts, return their name
if (self) {
// Prefer given name, if that's available
var name = self.getGivenName();
// But we will settle for the full name
if (!name) name = self.getFullName();
return name;
}
// If they don't have themselves in Contacts, return the bald userName.
else {
var userName = Session.getEffectiveUser().getUsername();
return userName;
}
}
In Apps Script, I was able to get this information using the About REST API: https://developers.google.com/drive/v2/reference/about/get
var aboutData = DriveApp.About.get();
var userEmail = aboutData["user"]["emailAddress"];
var userDisplayName = aboutData["user"]["displayName"];
You can get a user name but first you have to create a domain user using the provisioning api. You can enable the API by logging in to your admin account, and select Domain settings and the User settings tab to select the checkbox enabling the Provisioning API. Read more about it here
You can then use
user = user.getgivenName()
Since the UserManager Service is only available to a Domain Administrator, you could publish a service as the administrator, that serves user's Given Names, and invoke that from the user-run script using the UrlFetchApp.
The UserName Service
Refer to the Content Service Documentation for the background information this is based upon.
The service accepts a parameter, userName, which it uses to perform a lookup as the administrator.
Paste the following code into a script, then deploy the script as a web service. This must be done by a Domain Administrator, as the service access the UserManager Service, but the script must be made accessible by all users in the domain. (Since I'm not an admin in my domain, I cannot access the UserManager, so I've included a domain-user-invokable line for testing, calling the getOwnName() function I described in my first answer.)
Remember to invoke doGet() from the debugger to go through the authorization before accessing the published service.
/**
* When invoked as a Web Service running as Domain Administrator,
* returns the GivenName of the requested user.
*
* #param {String} userName= Should be set to Session.getEffectiveUser().getUsername().
*/
function doGet(request) {
//return ContentService.createTextOutput(getOwnName()); // for testing by non-admin user
var userName = request.parameters.userName;
var givenName = UserManager.getUser(userName).getGivenName();
return ContentService.createTextOutput(givenName);
}
Invoke service using UrlFetch
Refer to Using External APIs for an explanation of how to make use of the service written in the previous section. I'll show how to access the service from another script, but remember that you can also do this from web pages within your domain.
We will use UrlFetchApp.fetch() to get our service to return the user's first name as a String.
The service was written to accept one parameter, userName, and we append this to the url, in the form userName=<string>.
With the URL built, we fetch(), then retrieve the name from the response. While this example returns just the name, you may choose to change the service to return the complete "Hello User" string.
function testService() {
var domain = "my-google-domain.com";
var scriptId = "Script ID of service";
var url = "https://script.google.com/a/macros/"+domain+"/s/"+scriptId+"/exec?"
+ "userName="+Session.getEffectiveUser().getUsername();
var response = UrlFetchApp.fetch(url);
var myName = response.getContentText();
debugger; // pause in debugger
}
Another potential way of getting the display name on a gmail account is to find a Draft email in the GmailApp, and get the From header, which may have the full name. Some drafts might be setup with no display name in gmail, in which case the From header will only be the email address, but typically the From header is in the format:
Firstname Lastname <email#domain.com>
This code should get you the string above from the first gmail Draft: (note this will probably throw an exception if there are no drafts, so check that first.)
GmailApp.getDrafts()[0].getMessage().getHeader("From")
Ref: https://developers.google.com/apps-script/reference/gmail/gmail-message#getHeader(String)
Ref: https://www.ietf.org/rfc/rfc2822.txt

How to add the contact using EWS

I have 2 questions
I want to add the email Contact to Exchange server.I have seen the sample code using EWS.But that code used to add the contact for user specific.How to add the contact domain specific.
I want to get the domain contacts from Exchange server.I dont want all the contact i need only the today's added or modified contacts.
How can i acheive this .Can any one help me?
Regards
Vairamuthu.G.S
I did not understand "contact domain specific" but I will share you my code. It may help
Adding contact
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
// you should set the credentials of the user and
//call AutoDiscover to get the service URL before executing the code
Contact newcontact = new Contact(service);
newcontact.DisplayName = "data";
newcontact.EmailAddresses[EmailAddressKey.EmailAddress1] = new EmailAddress();
newcontact.EmailAddresses[EmailAddressKey.EmailAddress1].Address = "data";
newcontact.EmailAddresses[EmailAddressKey.EmailAddress1].Name = newcontact.DisplayName;
newcontact.FileAs = newcontact.DisplayName;
newcontact.Save();
Note that the new contact is saved in the contacts folder in the mailbox of the logging in user.
Filtering the retrieved contacts
SearchFilter filter = new SearchFilter.IsGreaterThan(ItemSchema.DateTimeCreated, DateTime.Now.AddDays(-1));
FindItemsResults<Item> contactCreatedToday = service.FindItems(WellKnownFolderName.Contacts, filter, new ItemView(int.MaxValue));
foreach (Item t in contactCreatedToday)
{
try
{
Contact c = (Contact) t;
//do processing
}
catch (InvalidCastException)
{
throw;
}
}