create calendar on office 365 outlook - outlook

I am an administrator of Microsoft office 365 in a mid-sized company.
All employees want to see all other's schedules. They, of course, know they can add other's calendar on their own outlook and see schedule, though They want to see see all other's schedules. It is somehow cumbersome for them to add all employees on their own outlook. They want admin to manage calendar group on outlook in company-wide.
I did not find any powershell cmdlet to manage calendar group, but found graph API Create Calendar https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/user_post_calendars.
For example, if I were A#example.com and wanted to see B's calendar. When I run create calendar API on graph explorer with owner:{"address":"b#example.com", "name":"B"} and it ends with success and shows result that owner:{"address":"a#example.com", "name":"A"}. Of course I cannot see B's schedule on my outlook.
this is post request body:
{
"name": "b",
"color": "auto",
"owner": {"address":"b#example.com", "name":"b"}
}
This is result:
{
"#odata.context": ....
"name": "b",
"color": "auto",
"changeKey": "......",
"canShare": true,
"canViewPrivateItems": true,
"canEdit": true,
"owner": {
"name": "a",
"address": "a#example.com"
}
}
How can I satisfy my employees' request?
Thank you,

Related

Dynamic typeahead in Adaptive Card Task flow

I'm trying to implement the dynamic typeahead search as was shown on the below resources:
https://learn.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/dynamic-search?tabs=desktop%2Ccsharp
https://github.com/OfficeDev/Microsoft-Teams-Samples/tree/main/samples/bot-type-ahead-search-adaptive-cards/csharp
I'm having the following Adaptive Card returned from the OnTeamsMessagingExtensionFetchTaskAsync (from message action):
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"id": "choiceSelect",
"type": "Input.ChoiceSet",
"choices": [
{
"title": "Choice 1",
"value": "Choice 1"
},
{
"title": "Choice 2",
"value": "Choice 2"
}
],
"placeholder": "Placeholder text",
"style": "filtered",
"choices.data": {
"type": "Data.Query",
"dataset": "cases"
}
}
]
}
Card is rendered correctly, but when I start typing, I'm getting the following results:
No request is being made. I was trying to debug the JS, but it is troublesome for me - I couldn't pinpoint the exact place it fails, but got these symbols to lookup: executeSearchInvoke, enableAppPermissionEnforcement and enableTenantSettingsForBots in 3.2-app.min.js.
Can anyone point me in the right direction? Is there some kind of dependency or permission I should add to the bot? Some setting in Teams Admin Center? I can add that static typeahead works flawlessly, but I need the dynamic one (big data collection to query).
EDIT:
I have confirmed that the app is added to the team (it is visible on the list of apps in team settings); I've removed and added it again just in case. I am still getting the same results.
List of permissions visible from the App details page:
This app will have permission to:
Receive messages and data that I provide to it.
Send me messages and notifications.
Access my profile information such as my name, email address, company name, and preferred language.
Receive messages and data that team members provide to it in a channel.
Send messages and notifications in a channel.
Access this team's information such as team name, channel list and roster (including team member's names and email addresses) - and use this to contact them​.

How to get team id when the bot is installed in personal scope(MS Teams)?

I have a use case where I need to show following information in my personal application.
List of channels in teams where bot is installed.
List of users in teams where bot is installed.
I was exploring connector client for the same and came up with following code:-
const credentials = new MicrosoftAppCredentials(appId, appPassword);
const connectorClient = new ConnectorClient(credentials, {
baseUri: serviceUrl
});
const token = await credentials.getToken();
axios.defaults.headers.common.Authorization = `Bearer ${ token }`;
# To get channels
const response = await axios.get(
'https://smba.trafficmanager.net/in/v3/teams/{teamId}/conversations'
);
# To get members
const users = await connectorClient.conversations.getConversationPagedMembers(teamId);
This works perfect as long as I have the teamId.
But the issue I am facing here is with respect to finding teamId in personal scope. I install my bot application as follows by choosing the Add option.
As far as I understand, the above installs the bot in the personal scope of the user. Now, in this scenario the team id information is not present in conversationUpdate event at all. Please note that this is the first time I am installing the bot in the team, so the data should be available as per Microsoft documentation, but the only information available in channel object is tenant.
{
"membersAdded": [
{
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0"
}
],
"type": "conversationUpdate",
"timestamp": "2017-02-23T19:38:35.312Z",
"localTimestamp": "2017-02-23T12:38:35.312-07:00",
"id": "f:5f85c2ad",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
"from": {
"id": "29:1I9Is_Sx0OIy2rQ7Xz1lcaPKlO9eqmBRTBuW6XzkFtcjqxTjPaCMij8BVMdBcL9L_RwWNJyAHFQb0TRzXgyQvA"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"id": "19:efa9296d959346209fea44151c742e73#thread.skype"
},
"recipient": {
"id": "28:f5d48856-5b42-41a0-8c3a-c5f944b679b0",
"name": "SongsuggesterBot"
},
"channelData": {
// for me this object is empty
"team": {
"id": "19:efa9296d959346209fea44151c742e73#thread.skype"
},
"eventType": "teamMemberAdded",
"tenant": {
"id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
}
}
Next, I also tried to install the bot in the team scope by using Add To Teams option. In this case it prompts me to select a channel to install, in which I choose general.
Now, I do get the team object inside channelData in onConversationUpdate and this flow works perfectly fine.
{
"membersAdded": [
{
"id": "28:64564f44-dd7c-441a-b427-efcd662f21b5"
}
],
"type": "conversationUpdate",
"timestamp": "2021-10-14T13:22:01.6072361Z",
"id": "f:4ebc9a41-5140-7621-33f5-31d97275ce00",
"channelId": "msteams",
"serviceUrl": "https://smba.trafficmanager.net/in/",
"from": {
"id": "29:17ZGff4Pvqz_zSNqEexg-86uBFcB6vnOBZzCwu4_puGdDsrYWCW_DdlB15PrcjC--nLlqD5CwtLMJyzXPY5OSsg",
"aadObjectId": "eac26e98-104a-4785-87aa-bcf77ea1d7c1"
},
"conversation": {
"isGroup": true,
"conversationType": "channel",
"tenantId": "c8fef0de-e240-4456-b523-3285ecc62087",
"id": "19:y7qDBfGH2jE_Ze6G8mJS_CiWiqCaRFfH77jFZvJ1xgU1#thread.tacv2"
},
"recipient": {
"id": "28:64564f44-dd7c-441a-b427-efcd662f21b5",
"name": "Trick"
},
"channelData": {
"team": {
"aadGroupId": "5bc77aa9-9487-49ae-958f-b37b2191e64d",
"name": "test 5",
"id": "19:y7qDBfGH2jE_Ze6G8mJS_CiWiqCaRFfH77jFZvJ1xgU1#thread.tacv2"
},
"eventType": "teamMemberAdded",
"tenant": {
"id": "c8fef0de-e240-4456-b523-3285ecc62087"
}
}
}
So what I am trying to understand here is that, why is the information not coming in case the bot is installed in personal scope?
I am asking this mainly because without personal scope added for bot(i.e if I keep scope only as team), the application does not show for user, inside Apps. But if I allow the scope to be extended to personal the user might select that while installing the application and my teamId information will not be available to fetch the data, that I need.
This brings to my next question, which is, is there any way in which the default add button on the add app screen installs the bot in such a way that I get team object inside channelData, in conversationUpdate in every scenario, i.e whether I choose add or add to team?
Is this how it is supposed to behave or am I missing something. Would love to hear some thoughts on this. Thanks in advance.
It might be that you're over thinking this - here's a more simple view:
if you install a bot into a Team, you'll get a Team Id (and any related channel where it is installed).
if you have "personal" scope set up for the bot, then the user also has the option to install the bot into "personal" scope. As this implies, they are NOT installing the bot INTO an actual Team - that's why you're not receiving a Team Id. It's not broken - it's entirely correct.
If you don't WANT your bot to be able to be installed in personal scope, simply remove that option in your manifest (the "personal" scope) - you have the ability to choose because it depends what you're wanting the user to be able to do with your bot. Some bots only make sense inside a Team, others only in Personal Scope, others only in Group Chat or in a Meeting - you can allow your bot to installed in any/all of these are relevant.

How can I disable waiting room in Google Meets created with calendar api?

In the Google Calendar api there's the ability to request that a conferencing link be created when an event is created.
My current setup is that I have an account that is creating google calendar events whenever someone schedules a meeting on my app. The problem is that when someone outside of my organization tries to join the meeting it says "ask to join" which isn't possible since nobody from my organization will be in the meeing. Are there are parameters to let me turn off the waiting room feature or at least have a list of approved emails that are allowed to enter the meeting. The request body looks like this right now:
{
"end": {
"dateTime": "2020-08-30T05:27:35.206Z"
},
"start": {
"dateTime": "2020-08-29T05:27:35.206Z"
},
"conferenceData": {
"createRequest": {
"conferenceSolutionKey": {
"type": "hangoutsMeet"
},
"requestId": "12345"
}
},
"summary": "Test event with meets 2",
"attendees": [
{
"email": "****#gmail.com"
}
]
}
The attendee I added still has to request to join the meeting.
This appears to be a bug!
I have taken the liberty of reporting this on Google's Issue Tracker for you, detailing the behaviour:
User from outside of G Suite domain required to ask to join a Meeting from a Calendar event they are invited to
You can hit the ☆ next to the issue number in the top left on the page which lets Google know more people are encountering this and so it is more likely to be seen to faster.

How do I create an all day event in the Google Classroom API Method: courses.courseWork.create?

I would like to add an all-day event to my Google Classroom Course as an assignment with the Classroom API found here: Method: courses.courseWork.create documentation
Here is the json request I've been using in their API explorer:
{
"title": "Lesson 1.1",
"workType": "assignment",
"state": "published",
"description": "This is a test assignment.",
"dueDate": {
"year": 2017,
"month": 9,
"day": 2
},
"dueTime": {
"hours": null,
"minutes": null
}
}
I've tried many variations, but it always posts the assignment due at 8:00 PM by default, never an allDay or all-day event. Removing the dueTime isn't allowed per the documentation. Yet, when I manually create a lesson it's an optional field. I inspected the post data and couldn't find out how this is happening.
It doesn't appear to mention how to create an all-day event in the Google Classroom API documentation and the Google Calendar API docs didn't give me any usable hints.
Any ideas?

Pull public event data from Google Calendar

I may be over thinking this a bit. On my web site, I would like to user certain data from my public google calendar. My plan is to pull it on the server side so I can do things like process it, cache it and format it the way I want.
I've been looking at using the Google Api libraries, but I can't get past any of the authorization hurdles. A service account sounds like what I really want, but I'm having trouble wrapping my head around how that works in this situation.
The old GDATA apis would be ok, but I'm not very keen on using them because they look fairly deprecated at this point by the newer libraries.
Since it is all public data, I'm hoping there is a simpler way to get to the event data that I'm looking for.
In case it matters, my site is Asp.Net (MVC).
Update
Ok, I was definitely way over thinking it. See my answer.
Now that RSS has been removed from Google Calendar, I've been in search of an easy replacement. I dug around and found the following in the Google Calendar API that seems to do the trick: calendar.events.list
Calendar Events List in Google API Explorer is a good place to get started with the different parameters and options - and it'll build you an example request string. You can see that I specified a minimum time of 2/5/2016, sort it by the start time, and show deleted events.
GET https://www.googleapis.com/calendar/v3/calendars/[CALENDAR ID HERE]/events?
orderBy=startTime&showDeleted=true&singleEvents=true&
timeMin=2016-02-05T00%3A00%3A00Z&key={YOUR_API_KEY}
Results are in JSON so you can parse it in your favorite programming language, ASP.NET or whatever. Result looks like:
{
"kind": "calendar#events",
"etag": "\"123456789123456\"",
"summary": "My Public Calendar",
"updated": "2016-01-29T14:38:29.392Z",
"timeZone": "America/New_York",
"accessRole": "reader",
"defaultReminders": [ ],
"items": [ {
"kind": "calendar#event",
"etag": "\"9876543210987654\"",
"id": "sfdljgsdkjgheakrht4sfdjfscd",
"status": "confirmed",
"htmlLink": "https://www.google.com/calendar/event?eid=sdgtukhysrih489759sdkjfhwseihty7934hyt94hdorujt3q95uy689u9yhfdgnbiwe5hy",
"created": "2015-07-06T16:21:59.000Z",
"updated": "2015-07-06T16:21:59.329Z",
"summary": "In-Service Day",
"location": "Maui, HI",
"creator": {
"email": "abra#cadabra.com",
"displayName": "Joe Abra"
},
"organizer": {
"email": "cadabra.com_sejhrgtuiwerghwi4hruh#group.calendar.google.com",
"displayName": "My Public Calendar",
"self": true
},
"start": {
"date": "2016-02-08"
},
"end": {
"date": "2016-02-09"
},
"transparency": "transparent",
"iCalUID": "isdt56y784g78ty86tgsfdgh#google.com",
"sequence": 0
},
{
...
}]
}
One good answer to this (the one I'm going with) is to simply use the calendar's public address to get the data. This is an option that I had forgotten about and it works fine for this particular situation.
You can find the url for the data if you go to the settings for a particular calendar and pick the format you want (I went with xml for this situation.)
The data that you get out of this service is very human-reader optimized, but I can make it work for what I'm doing.

Resources