04-06-2021 16:11 PM - last edited 01-22-2022 07:53 AM
Hey guys
Think of tinder for virtual coffee breaks. That's more or less what it is.
As a user, you need to register yourself to be in the pool of "registered users". Once you're registered, you're eligible to search for a possible coffee-match AND others can be matched with YOU. It's as easy as clicking on a button. The app will then filter out registered users that are not eligible for a match. It will then present you with a matched user and will also suggest timeslots for a coffee. You can even see if the user is available on suggested timeslots. If not, just let it generate new timeslots for you.
Not eligible users could be:
I'm planning to improve the conditions even further so users can choose, perhaps, their department to be matched with, their preferred timings, etc. For now, it's just what I stated above.
Coffee Flex needs the following connections:
Apart from that, it's also using two tables:
In the App.OnStart property, you can change the gblInvitationMessage variable to any HTML text you like. This is the one that is being used when an invitation will be sent (to the matched user).
To change the colors, simply adjust the colors in the colStyles library. The most important ones are primaryAccent.Fill, light.BorderColor, background.Fill, background.BorderColor, gradient, darkGradient, and lightGradient
I hope you like it.
If you have feedback, bugs, just want to say thank you or anything in between, please let me know and drop a comment.
Brilliant @FabianAckeret thank you, fingers crossed they can get it running! Such a great tool!
Cheers!
@RobertRatcliffe , yes my colleague did, in the btnSendInvitation section he changed it to: -
Set(gblShowLoading,true);
// create teams meeting invitation
UpdateContext(
{
lclCreatedTeamsMeeting:
MicrosoftTeams.CreateTeamsMeeting(
gblMyCalendar,
"Coffee Flex Match",
{content: gblInvitationMessage, contentType: "html"},
"GMT Standard Time",
{dateTime: Text(gblMeetingStart, DateTimeFormat.UTC)},
{dateTime: Text(gblMeetingEnd, DateTimeFormat.UTC)},
true,
"teamsForBusiness",
{requiredAttendees: gblMatchedUser.Email}
)
}
);
Patch(
Matches,
Defaults(Matches),
{
'User 1': LookUp('Registered Users', 'Azure AD Object ID' = gblUser.id),
'User 2': LookUp('Registered Users', 'Azure AD Object ID' = gblMatchedUser.'Azure AD Object ID'),
'Coffee Date': gblMeetingStart
}
);
// no teams meeting
/* Office365Outlook.V4CalendarPostItem(
gblMyCalendar,
"Coffee Flex Match",
gblMeetingStart,
gblMeetingEnd,
"GMT Standard Time",
{
importance: "Normal",
body: gblUser.displayName & " has been matched with you in the coffee flex game. Would you like to drink a virtual-coffee?",
location: "test",
showAs: "busy",
requiredAttendees: gblMatchedUser.Email
}
);
*/
UpdateContext({lclShowMatch: false});
UpdateContext({lclShowSuccess: true});
Set(gblShowLoading,false);
Worked perfectly Sir. Many thanks for your help and support.
Hey Guys,
I was wondering if you guys can help me with the following errors. The errors occurs once a match has been made and selected. Once the send confirmation portion goes through, the screen shows that the meeting invitation has been sent, but it errors out. We dont get the meeting invitation email, although we accepted the permissions at first when registering. Please help. The errors are in the pictures below. Thank you in advance.
Hi @mendiolaa12 , I think the next part my colleague changed was the btnFindMatch to the below. Give that a try, if not I'll have to contact him to find out more
Set(gblShowLoading,true);
///////////////////////////////////////////////////////////
// filter users that current user can be matched with
// this is the logic that defines who is NOT a match
ClearCollect(
colNonMatches,
AddColumns(
Filter(
Matches,
With(
{
coffeeCondition:
'Coffee Date' = Today() ||
DateAdd('Coffee Date',1,Days) = Today() ||
DateAdd('Coffee Date',-1,Days) = Today()
},
//'User 1'.'Azure AD Object ID' = gblUser.id ||
coffeeCondition || (coffeeCondition && 'User 1'.'Azure AD Object ID' = gblUser.id)
)
),
"User",
'User 2'.'Azure AD Object ID'
)
);
// add user 1 column to that no-match collection
Collect(
colNonMatches,
AddColumns(
Filter(
Matches,
With(
{
coffeeCondition:
'Coffee Date' = Today() ||
DateAdd('Coffee Date',1,Days) = Today() ||
DateAdd('Coffee Date',-1,Days) = Today()
},
//'User 1'.'Azure AD Object ID' = gblUser.id ||
coffeeCondition || (coffeeCondition && 'User 2'.'Azure AD Object ID' = gblUser.id)
)
),
"User",
'User 1'.'Azure AD Object ID'
)
);
///////////////////////////////////////////////////////////
// get random user from above selection
// this is the logic that defines who IS a match
UpdateContext(
{
lclRegisteredUsers:
Filter(
'Registered Users',
Registered &&
'Azure AD Object ID' <> gblUser.id &&
Not('Azure AD Object ID' in colNonMatches.User)
)
}
);
// check whether there is or is not a match
If(
CountRows(lclRegisteredUsers) >= 1,
UpdateContext({lclIsMatch: true});
UpdateContext({lclRandMatch: RoundUp(Rand() * CountRows(lclRegisteredUsers),0)});
// get random of user in data source and assign to variable
Set(
gblMatchedUser,
Last(
FirstN(
lclRegisteredUsers,
lclRandMatch
)
)
);
// get the whole record of the matched user and save it to a variable
Set(gblMatchedUser, LookUp('Registered Users', cr466_registeredusersid = gblMatchedUser.cr466_registeredusersid));
///////////////////////////////////////////////////////////
// find meeting times and suggest them on the popup
Set(gblNow, Now());
Clear(colMeetingTimes);
ClearCollect(
colMeetingTimes,
AddColumns(
Office365Outlook.FindMeetingTimesV2(
{
MinimumAttendeePercentage: "0",
MeetingDuration: 20,
Start: gblNow,
End: DateAdd(gblNow,5,Days),
OptionalAttendees: gblMatchedUser.Email
}
).meetingTimeSuggestions,
"StartTime",
meetingTimeSlot.start.dateTime,
"EndTime",
meetingTimeSlot.end.dateTime
)
);
// Set(gblMyCalendar, First(Office365Outlook.CalendarGetTables().value).Name), ;
Set(gblMyCalendar,
LookUp(Office365Outlook.CalendarGetTables().value, DisplayName="Calendar").Name);
// set the meeting start and end time to the first item in the timeslots (in case the user doesn't select another in the next step, this is going to be the default one)
Set(gblMeetingStart,DateAdd(DateTimeValue(First(colMeetingTimes).StartTime), -TimeZoneOffset(DateTimeValue(First(colMeetingTimes).StartTime)), Minutes));
Set(gblMeetingEnd,DateAdd(DateTimeValue(First(colMeetingTimes).EndTime), -TimeZoneOffset(DateTimeValue(First(colMeetingTimes).EndTime)), Minutes));
// show match
UpdateContext({lclShowMatch: true, lclShowBalloons: true}),
// if there is no match
UpdateContext({lclShowNoMatch: true})
);
Set(gblShowLoading,false);
Hi KenEddie,
Did you have to also resolve issues where the time between matches was not being enforced??
Was working fine until today (1st of the month) and now proposing multiple matches on the same day, despite many already being booked.
how did you solve this? I am getting the same error.
Thanks for this. I got an denied access error, though, apparently because of a language issue (we're using Outlook in German). I replaced the following line:
Set(gblMyCalendar,
LookUp(Office365Outlook.CalendarGetTables().value, DisplayName="Calendar").Name);
With this:
Set(gblMyCalendar,
LookUp(Office365Outlook.CalendarGetTables().value, DisplayName="Calendar" || DisplayName="Kalender").Name);
This works for now. But is there an option where I don't have to specify the exact name in every language?