Skip to content

Conversation

Donnyp751
Copy link

Hello, I have some changes which allow publishing of a users Teams Status to a MQTT topic of choice. I have tested this with mosquito, which I run on my home assistant server.

The purpose of this for me, is to automate the changing of my office status light from green to red when I become busy, and red to green when I am available.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @Donnyp751, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements a new MQTT integration for the application, enabling it to publish a user's Microsoft Teams status to an MQTT broker. This feature is designed to facilitate home automation scenarios, such as controlling smart lights based on presence. The changes include adding new configuration options, implementing a robust MQTT client, and integrating browser-side status detection to capture real-time Teams presence updates.

Highlights

  • MQTT Integration: This pull request introduces a new MQTT integration feature, allowing the application to publish a user's Microsoft Teams presence status to a configurable MQTT broker. This enables seamless integration with home automation systems and other IoT devices.
  • Configurability: New configuration options have been added under an mqtt section, allowing users to enable/disable the feature and specify broker details, authentication credentials, client ID, and topic prefixes.
  • Teams Status Monitoring: The application now actively monitors the Teams web interface for status changes (e.g., Available, Busy, Do Not Disturb) using DOM observation and polling. These changes are then mapped to standardized status codes and published as JSON payloads to the MQTT topic.
  • Documentation: Comprehensive documentation has been added and updated, including a new README.md for the MQTT module and an updated configuration.md with detailed setup instructions and examples for Home Assistant integration.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a great new feature for MQTT integration, allowing users to publish their Teams status for home automation. The implementation is comprehensive, with new configuration options, a dedicated MQTT client, and extensive documentation.

My review focuses on a few key areas for improvement:

  • There appears to be some code duplication and a potential bug where two status monitors are initialized. Consolidating this logic will improve maintainability.
  • The MQTT client implementation can be simplified by leveraging the promise-based API of the mqtt library.
  • Some of the new browser-injected code could be refined by removing debug logs and magic numbers.

Overall, this is a solid contribution. Addressing these points will make the feature more robust and easier to maintain.

Comment on lines 72 to 75
if (config.mqtt && config.mqtt.enabled) {
console.debug("MQTT status monitoring enabled");
require("./tools/statusMonitor").init(config, ipcRenderer);
}

Choose a reason for hiding this comment

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

high

It seems that two separate status monitors are being initialized. One here via require("./tools/statusMonitor"), and another one via injectBrowserLogic() in app/mainAppWindow/index.js which injects app/browser/injectedBrowser.js. This will lead to duplicated status checks and IPC calls, which is inefficient and may cause unexpected behavior.

The logic in statusMonitor.js and injectedBrowser.js is also nearly identical, which creates a maintenance burden.

Please consolidate the status monitoring logic into a single place and ensure it's only initialized once. Given that injectedBrowser.js is being injected separately, perhaps the initialization here should be removed.

Copy link
Owner

Choose a reason for hiding this comment

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

On this one, I don't think you need to add the complexity of checking the UI status, and you can just get the status by listening to the ipc event. I will see if I can find the place you should put it.

Copy link
Author

Choose a reason for hiding this comment

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

Does the updated implementation look correct using the IPC event?

document.addEventListener('DOMContentLoaded', startMonitoring);
} else {
// DOM is already ready
setTimeout(startMonitoring, 3000); // Give Teams time to load

Choose a reason for hiding this comment

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

medium

The setTimeout with a hardcoded value of 3000ms is not a reliable way to wait for the Teams application to finish loading, as loading times can vary. This could lead to the status monitor failing to start if Teams takes longer to load.

Consider a more robust approach, like using a MutationObserver to wait for a key element of the Teams UI to be present before starting the monitor. A simpler improvement would be to make this timeout configurable.

Comment on lines +97 to +105
await new Promise((resolve, reject) => {
this.client.publish(topic, payload, { retain: true }, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});

Choose a reason for hiding this comment

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

medium

The mqtt.js v5+ library's publish method returns a Promise when no callback is provided. You can simplify this code by removing the new Promise wrapper and awaiting the publish call directly.

            await this.client.publish(topic, payload, { retain: true });

Copy link
Owner

Choose a reason for hiding this comment

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

what the bot says.

Comment on lines +121 to +123
await new Promise((resolve) => {
this.client.end(false, resolve);
});

Choose a reason for hiding this comment

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

medium

Similar to publishStatus, the client.end() method also returns a promise. You can simplify this by directly awaiting the result and removing the new Promise wrapper.

            await this.client.end(false);

Copy link
Owner

Choose a reason for hiding this comment

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

this shoudl be correct. Just trust the bot ;)

@IsmaelMartinez
Copy link
Owner

Hello, I have some changes which allow publishing of a users Teams Status to a MQTT topic of choice. I have tested this with mosquito, which I run on my home assistant server.

The purpose of this for me, is to automate the changing of my office status light from green to red when I become busy, and red to green when I am available.

Hi @Donnyp751 , Thanks a lot for your contribution. I will try to review the changes later today. The AIs will have give you a bit of a check of the code. They normally do decent code reviews, but feel free to challenge some of the decisions. Thanks a lot!

Copy link
Owner

@IsmaelMartinez IsmaelMartinez left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the contribution. Can you check if this work without all the 3 UI files (2 that I don't think are in use)? it should only need to consume the event, and that will be more reliable than checking UI changes that are out of our control. I only go down that route when there is no other option. Thanks!

Comment on lines 72 to 75
if (config.mqtt && config.mqtt.enabled) {
console.debug("MQTT status monitoring enabled");
require("./tools/statusMonitor").init(config, ipcRenderer);
}
Copy link
Owner

Choose a reason for hiding this comment

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

On this one, I don't think you need to add the complexity of checking the UI status, and you can just get the status by listening to the ipc event. I will see if I can find the place you should put it.

Copy link
Owner

Choose a reason for hiding this comment

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

this file seems to be duplicated or an older version of the statusMonitor and injectedBrowser ones.

Copy link
Owner

Choose a reason for hiding this comment

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

also, I think it will work without neither of the 3 files. Can you try it?

Copy link
Author

Choose a reason for hiding this comment

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

Got rid of the unused files, still using the statusMonitor, I think there is still some improvements to be made.

Comment on lines +97 to +105
await new Promise((resolve, reject) => {
this.client.publish(topic, payload, { retain: true }, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
Copy link
Owner

Choose a reason for hiding this comment

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

what the bot says.

Comment on lines +121 to +123
await new Promise((resolve) => {
this.client.end(false, resolve);
});
Copy link
Owner

Choose a reason for hiding this comment

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

this shoudl be correct. Just trust the bot ;)

Copy link
Owner

Choose a reason for hiding this comment

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

As with the other browser files, I don't think we need them. The event we intercept from Microsoft does the job and will be more reliable than checking the UI changes.

@@ -276,6 +276,7 @@ function onDidFinishLoad() {
// Inject browser functionality
injectScreenSharingLogic();
injectNotificationLogic();
injectBrowserLogic();
Copy link
Owner

Choose a reason for hiding this comment

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

I don't think we need this as mention in the other files. Can you check without it and see if it does work realiable?

Copy link
Author

Choose a reason for hiding this comment

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

So far I have not been able to get it to work reliably, I will continue doing some more testing and see what I can figure out.

@@ -316,6 +317,23 @@ function injectNotificationLogic() {
}
}

function injectBrowserLogic() {
Copy link
Owner

Choose a reason for hiding this comment

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

same as the previous comment. I don't think we need this

…ndlers, still working on trying to get working without injectBrowserLogic
Simplify object creation

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Copy link

@Donnyp751
Copy link
Author

I still have some work to do on this, I will try to address the remaining feedback you had provided and resolve the issues with the current implementation, as well as try to get it working reliably without the injectBrowserLogic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants