Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GitHub Issue #170 - Update status when starting/ending a zoom meeting #171

Closed
wants to merge 17 commits into from

Conversation

cvhariharan
Copy link

Summary

This PR adds ability to the mattermost-zoom-plugin to automatically update the status of the user starting/ending a zoom meeting. When the meeting is started by a user, their status is set to DND and when they end the meeting, the status is set to ONLINE.

Ticket Link

Fixes #170

@mattermod
Copy link
Contributor

Hello @cvhariharan,

Thanks for your pull request! A Core Committer will review your pull request soon. For code contributions, you can learn more about the review process here.

@jasonblais jasonblais added the 2: Dev Review Requires review by a core committer label Oct 4, 2020
@jasonblais
Copy link
Contributor

@cvhariharan thanks for the contribution! Are you open to help review the build failure and let us know if you have any questions on how to resolve?

@codecov
Copy link

codecov bot commented Oct 4, 2020

Codecov Report

Merging #171 (52060a2) into master (45747e2) will decrease coverage by 1.08%.
The diff coverage is 14.72%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #171      +/-   ##
==========================================
- Coverage   20.85%   19.76%   -1.09%     
==========================================
  Files           7        7              
  Lines         729      855     +126     
==========================================
+ Hits          152      169      +17     
- Misses        536      633      +97     
- Partials       41       53      +12     
Impacted Files Coverage Δ
server/http.go 24.15% <8.57%> (-1.78%) ⬇️
server/plugin.go 20.12% <16.00%> (-3.48%) ⬇️
server/command.go 14.50% <21.05%> (+0.46%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 45747e2...52060a2. Read the comment docs.

@jasonblais
Copy link
Contributor

Thanks @cvhariharan 🚀

@larkox
Copy link
Contributor

larkox commented Oct 5, 2020

@cvhariharan Thank you for the contribution. The current implementation seems nice, but I am not 100% sure about the use, because of edge cases. For example:

  • If I have manually set my status as away or offline, and I create a meeting, I will be set to DnD, and when the meeting finish, I will be set as Online. Is this expected?
  • If the webhooks are not set up, I will always get put to DnD, but never back to Online.

@aaronrothschild any thoughts on this? It is a similar problem as the one we had on Microsoft Calendar. Also, should we add a setting to set this on or off?

@cvhariharan
Copy link
Author

Hi @larkox, to solve the first issue, could we do something like only update the status to dnd iff the status is online already or maybe save the old status before changing to dnd and reverting back when the meeting ends?

For the second issue, I do agree that the status won't go back to online if the webhooks are not setup unless we have some background job that checks the meeting status.

@mickmister
Copy link
Contributor

mickmister commented Oct 5, 2020

to solve the first issue, could we do something like only update the status to dnd iff the status is online already or maybe save the old status before changing to dnd and reverting back when the meeting ends?

@cvhariharan To handle the "which status should we set the user back to" issue, we used the status.Manual property to determine whether the user's current status was manually set: https://github.com/mattermost/mattermost-plugin-mscalendar/blob/c751170a9ab789526782266d76ce970fad220a83/server/mscalendar/availability.go#L231

If the most recent status was manually set, meaning status.Manual is currently true:

  • Store the status in the kv store to be used later
  • When it comes time to set their status back, set it to the stored status

If the most recent status was not manually set:

  • Store a blank status in the kv store, signaling that it was not manually set
  • When it comes time to set their status back, set it to Online. This allows the system to go back into its own cycle of automating the user's status.

For the second issue, I do agree that the status won't go back to online if the webhooks are not setup unless we have some background job that checks the meeting status.

I think this can be put into a follow up ticket

@aaronrothschild
Copy link
Contributor

I think we should ask the user what they would like us to do the first time we are about to set their status to Away/Dnd.

Frankly, you should probably just copy the behavior from the MS Calendar plugin that asks the user about their preference. Not sure how much scope that might add to this ticket (or not).

For the second issue, I do agree that the status won't go back to online if the webhooks are not setup unless we have some background job that checks the meeting status.

I think this can be put into a follow up ticket

Agreed, hopefully most should have webhooks setup. The important aspect is that we tell the user that we've switched their status (add some text to the Zoom message saying it started the meeting AND "We've set your Mattermost status to "Away/Dnd""

@cvhariharan
Copy link
Author

cvhariharan commented Oct 6, 2020

From what I understand, for the first meeting that the user creates with this feature on, the plugin asks their preference on allowing automatic status updates. Their preference is persisted for future use.

I will go through the MS Calendar plugin and try to see how I can replicate the behavior here.
Is there any code sample or documentation that I can refer to understand how prompts in plugins work?

@larkox
Copy link
Contributor

larkox commented Oct 6, 2020

@cvhariharan What you want to use for prompting the user are Slack Attachments. You could try to use the experimental flow (or wizard, I plan to change the name eventually), but probably it is an overkill.

You should also add a slash command to change this setting. Something simple as /zoom settings updateStatus on.

Finally, for the status change, you may want to check this PR: mattermost/mattermost-plugin-mscalendar#140

@cvhariharan
Copy link
Author

Thanks @larkox, I was beginning to experiment with slack attachments. The PR is also very helpful. I will see what I can do.

@jasonblais jasonblais added 3: QA Review Requires review by a QA tester hacktoberfest-accepted labels Oct 6, 2020
@cvhariharan
Copy link
Author

cvhariharan commented Oct 8, 2020

Hello, from the previous discussions I have made the following changes

  1. When the user starts their first zoom call, they get a direct message from zoom bot asking if they want to allow automatic status change.
  2. Added a /zoom status command which takes yes/no as an argument which can be used to change the status change preference

Let me know if something should be changed. 😄

Copy link
Contributor

@larkox larkox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general it looks good. Just some minor improvements.

server/command.go Outdated Show resolved Hide resolved
server/http.go Outdated Show resolved Hide resolved
server/http.go Outdated Show resolved Hide resolved
server/plugin.go Show resolved Hide resolved
server/plugin.go Outdated Show resolved Hide resolved
@larkox
Copy link
Contributor

larkox commented Oct 13, 2020

@cvhariharan Could you also post screenshots with all possible outcomes so @aaronrothschild can check from a UX perspective the messages and look of the feature?

@aaronrothschild
Copy link
Contributor

Thanks for your work @cvhariharan , looking forward to checking this out!

@aaronrothschild
Copy link
Contributor

@cvhariharan Thanks for the screenshots!

@abhijit-singh @levb or @hanzei thoughts on the "settings" as part of the /zoom slash command?

Perhaps we should add a /zoom settings status off which is a similar pattern to the /jitsi settings options approach?

@levb
Copy link
Contributor

levb commented Oct 28, 2020

0/5 the idea is awesome, the UX needs some work - sorry late to the discussion. Either way, we can ship with the feature off by default while we work out the kinks of managing the setting.

@mattermod
Copy link
Contributor

This PR has been automatically labelled "stale" because it hasn't had recent activity.
A core team member will check in on the status of the PR to help with questions.
Thank you for your contribution!

/cc @jasonblais @jfrerich @emilyacook

@hanzei
Copy link
Collaborator

hanzei commented Nov 3, 2020

/zoom settings status off seems like a good idea. We can disable my default.

Copy link
Contributor

@larkox larkox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my side it looks good. Thanks for the contribution!

@hanzei hanzei added the Awaiting Submitter Action Blocked on the author label Nov 3, 2020
@hanzei
Copy link
Collaborator

hanzei commented Nov 3, 2020

@cvhariharan Heads up that there is a merge conflict to resolve

@hanzei hanzei added this to the v2.0.0 milestone Nov 3, 2020
@cvhariharan
Copy link
Author

The merge conflicts are now resolved @hanzei.

@hanzei hanzei removed the Awaiting Submitter Action Blocked on the author label Nov 3, 2020
Copy link
Contributor

@mickmister mickmister left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work @cvhariharan! I just have some requests regarding error handling

@@ -19,6 +19,8 @@ const oAuthHelpText = `* |/zoom connect| - Connect to zoom

const alreadyConnectedString = "Already connected"

const statusHelpText = `* |/zoom status yes/no| - Change automatic status change setting, yes/no`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we describe what this means a bit here? Maybe something like "With this activated, your status will automatically change based on if you are in a meeting"

p.API.LogDebug("Could not save status change preference ", appErr)
return "Could not save status preference", appErr
}
return "Status preference updated successfully", nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this message convey the fact of "Your status will be updated" or "Your status will not be updated"?

appErr := p.API.KVSet(key, []byte(changeStatus))
if appErr != nil {
p.API.LogDebug("failed to set status change preference", "error", appErr.Error())
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should return here instead of proceeding after the if statement. Maybe have this function return an error, and call this function with a smaller function that handles the error. Any error that occurs in this function should cause the function to return early.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mickmister Here if we don't return early, the next call is to setUserStatus which would automatically send another slack attachment for user confirmation on automatic status change. Won't that be more convenient?

Also, if I understand this correctly, you are suggesting we remove the KVSet and setUserStatus snippets and put it in a separate function and return early if that function throws any error?

Comment on lines +90 to +93
err := p.setUserStatus(userID, int(meetingID), false)
if appErr != nil {
p.API.LogDebug("failed to change user status", "error", err)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
err := p.setUserStatus(userID, int(meetingID), false)
if appErr != nil {
p.API.LogDebug("failed to change user status", "error", err)
}
err := p.setUserStatus(userID, int(meetingID), false)
if err != nil {
p.API.LogDebug("failed to change user status", "error", err)
}

@@ -283,12 +329,17 @@ func (p *Plugin) handleMeetingEnded(w http.ResponseWriter, r *http.Request, webh
return
}

err := p.setUserStatus(post.UserId, int(meetingID), true)
if err != nil {
p.API.LogDebug("failed to change user status", "error", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we return the error, and handle it on the caller's side? I think we will need to make a separate small function to do so.

Comment on lines +233 to +237
statusVal, err := p.API.KVGet(statusKey)
if err != nil {
p.API.LogDebug("Could not get old status from KVStore", "err", appErr.Error())
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
statusVal, err := p.API.KVGet(statusKey)
if err != nil {
p.API.LogDebug("Could not get old status from KVStore", "err", appErr.Error())
return err
}
statusVal, appErr := p.API.KVGet(statusKey)
if appErr != nil {
p.API.LogDebug("Could not get old status from KVStore", "err", appErr.Error())
return appErr
}

Comment on lines +321 to +322
p.API.LogDebug("Create Attachment: ", appErr)
return appErr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
p.API.LogDebug("Create Attachment: ", appErr)
return appErr
return errors.Wrap(appErr, "Failed to create status change attachment post")

Comment on lines +313 to +314
p.API.LogDebug("Create Attachment: ", appErr)
return appErr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
p.API.LogDebug("Create Attachment: ", appErr)
return appErr
return errors.Wrap(appErr, "Failed to get bot DM channel")

Comment on lines +272 to +273
p.API.LogDebug("Failed to update user status", "err", appErr)
return appErr
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use errors.Wrap to decorate errors with relevant error messages in this function and have the parent log, instead of logging here?

Comment on lines +216 to +218
if appErr != nil {
p.API.LogDebug("Could not get stored status preference from KV ", appErr)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we return here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should.

@cvhariharan
Copy link
Author

@mickmister Hi, sorry I have been caught up with work, I will take a look into this over the weekend.

@mickmister
Copy link
Contributor

@mickmister Hi, sorry I have been caught up with work, I will take a look into this over the weekend.

No problem, thanks @cvhariharan 🙂

@mattermod
Copy link
Contributor

This PR has been automatically labelled "stale" because it hasn't had recent activity.
A core team member will check in on the status of the PR to help with questions.
Thank you for your contribution!

/cc @jasonblais @jfrerich @emilyacook

@jfrerich
Copy link
Contributor

Hi @cvhariharan! Have you had a chance to address the PR feedback? Do you need any assistance? Thanks!

@cvhariharan
Copy link
Author

Hi @jfrerich, I haven't been able to look into this yet. I have been caught up with work for sometime. I will get back to this as soon as possible.

@lindy65
Copy link

lindy65 commented May 26, 2021

Hi @cvhariharan - I'm helping to review stale PRs and will be closing this one for now as it's been standing for 6 months. Please feel free to re-open it if you're able to prioritize the work :)

I've re-added the "Up for Grabs" label on #170

//cc @larkox @mickmister

@lindy65 lindy65 closed this May 26, 2021
@hanzei hanzei added Lifecycle/3:orphaned and removed 2: Dev Review Requires review by a core committer 3: QA Review Requires review by a QA tester Lifecycle/1:stale labels May 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Synch Status: When on a Zoom call, show as “Busy”
10 participants