Google API is not returning the events created from UI - google-api

I am using googleapis in NodeJS to create & fetch the calendar events. I am using the following method to get the list of events.
const getEvents = async (dateTimeStart, dateTimeEnd,timeZone) => {
console.log("Date Start : " + dateTimeStart + " date end :" + dateTimeEnd + " time zone " + timeZone);
try {
let response = await calendar.events.list({
auth: auth,
calendarId: CALENDER_ID,
timeMin: (new Date(dateTimeStart)).toISOString(),
timeMax: (new Date(dateTimeEnd)).toISOString(),
timeZone: timeZone,
singleEvents: true,
maxResults: 9999,
orderBy: 'startTime
});
let items = response['data']['items'];
console.log(items);
return items;
} catch (error) {
console.log(`Error at getEvents --> ${error}`);
return 0;
}
};
The above method returns only events that are created programmatically via googleapis. If I create the events directly on the calendar from the browser this does not return those events.
Any idea how to fetch all events even if they are created from browser.

Based on what you were explaining about the behavior of the events being created by the service account instead of the actual users I think the problem is that the events created through API are being created under the Calendar ID of the service account, and the ones created by the users through API may have a different Calendar ID, therefore when you try to get the list of events, since you are probably using the Calendar ID from the service account you get only those events created using the API and not the ones created by the users through the web UI.
In this case it may be necessary to make sure that every event is being created under the exact same calendar ID through the web UI and the API so that all the events no matter if they were created through the API or web UI get listed as expected.
Let me know if this is useful, otherwise I can edit the response to add more clarification depending on your specific situation.

Related

Teams bot, transfer a call to another application / voicemail

In our Teams calling bot, we would like to transfer certain calls to specific Teams users, PSTN, but also to an other Teams calling bot and/or voicemail.
For specific Teams users and PSTN we got it working. If we want to transfer a call to another application, we can do so by using its pstn number. But ideally we would also like to transfer using its objectId.
I tried using a transferrequest like this:
var requestBody = new CallTransferRequestBody()
{
TransferTarget = new InvitationParticipantInfo()
{
Identity = new IdentitySet()
{
AdditionalData = new Dictionary<string, object>()
}
}
};
requestBody.TransferTarget.Identity.Application = new Identity { Id = transferTargetId };
//this line does not make any difference
requestBody.TransferTarget.Identity.Application.SetTenantId(tenantId);
But this results in a "Request authorization tenant mismatch." error. Is it possible to directly transfer to another application?
I haven't tried voicemail boxes yet, but if any info on how to transfer to those, is appreciated.
Basically we can transfer an active peer-to-peer call. This is only supported if both the transferee and transfer target are Microsoft Teams users that belong to the same tenant.
However for redirecting call to call queue or auto attendants, you can use the "applicationInstance" identity. The bot is expected to redirect the call before the call times out. The current timeout value is 15 seconds.
const requestBody = {
"targets": [{
"#odata.type": "#microsoft.graph.invitationParticipantInfo",
"identity": {
"#odata.type": "#microsoft.graph.identitySet",
"applicationInstance": {
"#odata.type": "#microsoft.graph.identity",
"displayName": "Call Queue",
"id": queueId
}
}
}],}
Please refer to the documentation here: https://learn.microsoft.com/en-us/graph/api/call-redirect?view=graph-rest-beta&tabs=csharp#request
The redirect API is still having that limitation from my understanding.
But that should work with the new Transfer API:
https://learn.microsoft.com/en-us/graph/api/call-transfer?view=graph-rest-beta&tabs=http

how do I program a slackbot to send a regular message automatically every week

I am building a slackbot that will remind people in my organisation to perform certain admin (hours expenses etc) every week. I know this can be very easily done by each person creating a recurring reminder. What i want is to create a bot that will send a preconfigured message to people every week. I've looked online extensively, and haven't yet found out how slackbot can send a message without an event or being otherwise prompted.
I'm currently testing this on a local ngrok server with the following backend:
const { WebClient } = require('#slack/web-api');
const { createEventAdapter } = require('#slack/events-api');
const slackSigningSecret = process.env.SLACK_SIGNING_SECRET;
const slackToken = process.env.SLACK_TOKEN;
const port = process.env.SLACK_PORT || 3000;
const slackEvents = createEventAdapter(slackSigningSecret);
const slackClient = new WebClient(slackToken);
slackEvents.on('app_mention', (event) => {
console.log(`Got message from user ${event.user}: ${event.text}`);
(async () => {
try {
await slackClient.chat.postMessage({ channel: event.channel, text: `Hello <#${event.user}>! Have you completed your Time sheets for this week yet?` })
} catch (error) {
console.log(error.data)
}
})();
});
slackEvents.on('error', console.error);
slackEvents.start(port).then(() => {
console.log(`Server started on port ${port}`)
});
Once this reminder is done, i intend to build upon it (more features, just need a beginning) so please don't recommend alternative ways my organisation can send reminders to people.
You can try using the chat.scheduleMessage method instead (https://api.slack.com/methods/chat.scheduleMessage). Since you won't rely on an event you may want to store the necessary conversations ids so that they're ready when the app needs to call the method.

Is it possible to programmatic-ally access the list of contacts in outlook using Office Add In

I am building an Add In which is supposed to grab in addition to the list of contacts an account has, the contacts (to, from, cc and bcc) that are used in the current Item (Message).
As per the documentation, the following instruction gave me zero contacts, although I have contacts in the contacts book, and reading a message with a sender email.
var contacts = Office.context.mailbox.item.getEntities().contacts;
I need to grab the list of contacts I manage in my account:
This list is accessible with the open graph APIs, I wonder if it's also accessible locally with the Office object for Office Add-Ins
Office Js does not provide APIs to get the list of contacts in the account.
But you can get an auth token from Outlook using authentication APIs, then use this token to acquire Graph token to interact with Graph APIs and get the list of contacts
Office.context.auth.getAccessTokenAsync(function (result) {
if (result.status === "succeeded") {
// Use this token to call Web API
var ssoToken = result.value;
// Now send this token to your server and acquire a Graph token
// Server can talk to Graph APIs and get contacts to display
} else {
// Handle error
}
});
Create a Node.js Office Add-in that uses single sign-on
It looks you misunderstood the documentation.
A quote:
The following example accesses the contacts entities in the current item's body.
var contacts = Office.context.mailbox.item.getEntities().contacts;
You could get all contacts using the below link:
Microsoft.Office.Interop.Outlook.Items OutlookItems;
Microsoft.Office.Interop.Outlook.Application outlookObj = new Microsoft.Office.Interop.Outlook.Application();
MAPIFolder Folder_Contacts;
Folder_Contacts = (MAPIFolder)outlookObj.Session.GetDefaultFolder(OlDefaultFolders.olFolderContacts);
OutlookItems = Folder_Contacts.Items;
MessageBox.Show("Wykryto kontaktów: " + OutlookItems.Count.ToString());
for (int i = 0; i < OutlookItems.Count; i++)
{
Microsoft.Office.Interop.Outlook.ContactItem contact = (Microsoft.Office.Interop.Outlook.ContactItem)OutlookItems[i+1];
sNazwa = contact.FullName;
sFirma = contact.CompanyName;
sAdress = contact.BusinessAddressStreet;
sMiejscowosc = contact.BusinessAddressPostalCode + " " + contact.BusinessAddressCity;
sEmail = contact.Email1Address;
dataGridView1.Rows.Add(sNazwa, sFirma, sAdress, sMiejscowosc, sEmail);
}
For more information, please refer to the below link:
Get Outlook contacts into C# form-based application

Office365 API access for all network users' calendars using c#

So my main objective is to update network user's outlook calendar from sql server data using office365 api every few minutes. I am stuck at how to get access for other user's outlook calendar? Looked at below link but didnt asnwser much...do i need azure subscription in order to do this? If someone can point me to right direction, that would be great
https://msdn.microsoft.com/en-us/office/office365/howto/common-app-authentication-tasks
I am stuck at how to get access for other user's outlook calendar?
In this case, you can consider using the application permission.
In Azure AD:
register a Web Application in your Azure AD.
add “Read and write calendars in all mail boxes” permission
generate the application secret key
In your application, call Office 365 Graph API - create events by using application token.
http://graph.microsoft.io/en-us/docs/api-reference/v1.0/api/user_post_events
var tmgr = new ApplicationTokenManagement();
var token = tmgr.AcquireToken(Settings.ResourceUrlOfGraph);
var api = new Graph.GraphCalendarAPI(token);
JObject body = new JObject
{
{"subject", "Create from Office 365 API"},
{"start", new JObject { { "DateTime", "2016-03-09T00:00:00"}, { "TimeZone", "China Standard Time" } } },
{"end", new JObject { { "DateTime", "2016-03-10T00:00:00"}, { "TimeZone", "China Standard Time" } } },
{"isAllDay", true }
};
var task = api.CreateEventAsync(body, "user#youcompany.com");
task.Wait();
You can find the complete sample here.

GoogleCalendarAPI accept/decline event

I am working on GoogleCalendar API and using node.js as a platform to build my application.
I am able to create events using authentication procedure and creating the calendar event using the access token generated while authenticating.
My question is that suppose if we have any attendee in the event and I want to accept/decline the event using the calendar API from the attendee's side, how can we do that?
I have tried fetching the calendar event of the attendee and matching it with the iCalUID of the event which was originally created and then modifying the event using update event on the attendee's calendar.
Event creator or owner cannot modify the response of attendees. Only attendees can modify their status.
To update the status on the side of the user, You may use the Event.update API and provide value for 'attendees.responseStatus'. Attendee's response status has 4 (four) possible value (described below).
'needsAction' - has not responded to the invitation.
'declined' - has declined the invitation.
'tentative' - has tentatively accepted the invitation
'accepted' - has accepted the invitation.
In addition to this, You can use the word "primary" as value for the calendar id to represent the currently logged in user
CalendarId: Calendar identifier. To retrieve calendar IDs call the calendarList.list method. If you want to access the primary calendar of the currently logged in user, use the "primary" keyword. (string).
For the id, you need to use the "id" returned by the Events.list API not the "iCalUID". Those two are different as described here.
Other fields that you need to provide are the email (of the attendee), startdate and enddate.
For more information, you may view the official documentation, link below:
https://developers.google.com/google-apps/calendar/v3/reference/events
Here is an example in java, using PATCH. Create an event object with the just the information you want to change, in this case the attendee and the response status. This code is running as the attendee.
final Event event = new Event()
.setAttendees(Arrays.asList(new EventAttendee().setEmail(email)
.setResponseStatus("declined")));
try
getCalendarService(googleAccountCredential).events()
.patch(CALENDAR_PRIMARY, calendarEventId, event)
.setSendNotifications(true)
.setOauthToken(googleAccountCredential.getToken()).execute();
return true;
} catch (final Exception ex) {
...
return false;
}
}
Like Android Enthusiast discussed, only the attendee can update his or her calendar from the attendee's side. You should also check the documentation as he suggested. The answer below is a working example for node.js and python
To update the event, you need to have the eventId and the user email. Get the event from the calendar(with the eventID),
loop through all the attendees, change responseStatus for
that particular attendee and then update the google calendar
For node js using the google api
const { google } = require('googleapis');
const calendar = google.calendar({ version: 'v3', auth: 'YOUR-API-KEY-HERE' });
#get the event to be updated
let theEvent = calendar.events.get({ calendarId: 'primary', eventId: eventId })
#loop through the whole attendee
for (let i = 0, i < theEvent['atendees'].length; i++){
if (theEvent['atendees'][i]['email'] === userEmail){
theEvent['atendees'][i]['responseStatus'] = 'accepted'
}
}
#update the google event
calendar.events.update({ calendarId: 'primary', eventId: theEventId, body: theEvent}, function(err, event) {
  if (err) {
    console.log('there was an error');
    return;
  }
  console.log('Event updated');
});
For python using googleapiclient
from googleapiclient.discovery import build
calendar = build('calendar', 'v3', credentials=credential)
event = calendar.events().get(calendarId='primary', eventId='eventId').execute()
For attendee in event['atendees']:
if atendee['email'] == user_email:
attendee['responseStatus'] = 'accepted'
break
#update the google event
udated_event = calendar.events().update(calendarId='primary', eventId=eventId, body=event).execute()
Lets suppose that you already have the event payload with the attendees key, then you need to get the ID for the created event:
created_event = gcal_service.events().insert(
calendarId='primary', body=event_payload
).execute()
then copy the attendees in a new object
accepted_attendees = {}
accepted_attendees['attendees'] = event_payload['attendees'].copy()
and now what you need to do is submit a patch to the attendees calendar based on the event_id, like this:
for attendee in event_payload['attendees']:
attendee_pos = accepted_attendees['attendees'].index(attendee)
accepted_attendees['attendees'].pop(attendee_pos)
accepted_attendees['attendees'].append({
'email': attendee['email'],
'self': True,
'responseStatus': 'accepted',
'additionalGuests': 0,
})
gcal_service.events().patch(
calendarId='primary',
eventId=created_event['id'],
body=accepted_attendees
)
And that's all, all the other attendees, now have accepted the event, hope it helps.
To respond, you need to get the event with the same event id from the attendee's calendar and then perform a patch or an update operation changing the response status of this attendee from needsAction to accepted / declined.
A bit of documentation on how events are copied between attendees and organizers:
https://developers.google.com/google-apps/calendar/concepts/sharing
Here is an example in python for Google Calendar Api v3. You can either use update or patch. Both of them are working.
all_attendees = event['attendees']
event['attendees'] = [{
'email': 'you#example.com',
'self': True,
'responseStatus': 'accepted',
'additionalGuests': 0,
}]
updated_event = service.events().patch(calendarId=calendar_id, eventId=event_id, body=event).execute()
Have fun

Resources