Sync your Spotify playback to Microsoft Teams status automatically.
A solo-dev, vibe-coded desktop app for Windows and macOS.
I had a weekend, some caffeine, and a vague memory of MSN Messenger's "Now Playing" feature. This is the result. Fully vibe-coded.
| Feature | Description |
|---|---|
| π΅ Spotify Polling | Real-time track detection via Spotify Web API |
| π Teams Status | Sets your Teams custom status message with track info |
| β±οΈ Smart Polling | Sleeps until track ends + buffer β no wasted API calls |
| ποΈ Auto-Clear | Automatically clears status when Spotify pauses/stops |
| π Secure Auth | PKCE OAuth for Spotify, Device Code flow for Teams |
| βοΈ Configurable | Custom status format, emoji, polling interval |
| π₯οΈ System Tray | Runs silently in the background |
| π Launch at Login | Optional auto-start on Windows boot |
| π‘οΈ Profanity Filter | Auto-detects and replaces profane track names with safe placeholder |
Spotify Web API β PresenceJam (polling) β Microsoft Graph API β Teams Status
β β β
"Artist - Format with "π΅ Artist -
Track" template Track π§"
The app polls Spotify every few seconds while a track is playing. When the track changes, it formats a message using your custom template and pushes it to Teams via Microsoft Graph.
Want to add screenshots? PRs welcome! See CONTRIBUTING.md.
| View | Description |
|---|---|
| Dashboard | Shows currently playing track, Teams connection status, and sync controls |
| Onboarding | 3-step wizard: Spotify credentials β Microsoft auth β Customize settings |
| Settings | Adjust status format, polling interval, profanity filter, launch-at-login |
| Log Viewer | Scroll through the daily rotating log files |
Download the latest release from GitHub Releases:
PresenceJam-2.3.0.msi β Windows 10/11 installer (64-bit)PresenceJam-2.3.0-macos.dmg β macOS installer (Apple Silicon)# 1. Install dependencies
npm install
# 2. Start development mode
npm run tauri dev
# 3. Build for release
npm run tauri build
For full setup instructions (Spotify app registration, Teams auth flow), see CONTRIBUTING.md.
Customize how your Teams status looks using these placeholders:
| Placeholder | Output |
|---|---|
{artist} |
Artist name |
{track} |
Track name |
{album} |
Album name |
{emoji} |
π΅ (playing) or βΈοΈ (paused) |
Default: π΅ {artist} - {track} π§
Example output: π΅ Daft Punk - One More Time π§
If a track or artist name contains profanity, PresenceJam replaces the entire status with a safe placeholder rather than displaying the profane content.
| Setting | Default | Description |
|---|---|---|
profanity_filter |
true |
Enable/disable the filter |
profanity_placeholder |
Currently Listening to Spotify |
Placeholder text shown when content is filtered. Supports {emoji} (π΅ playing / βΈοΈ paused) |
How detection works:
1βi, 3βe, $βs, @βa, 0βo, 5βs, 7βt, !βi, |βishiiit β shiit (but not excessive repeats)class, cocktail, assassin)cocktail without blocking cockNote: The filter currently operates on the formatted status string. A future refactor may filter raw Spotify metadata before formatting to prevent placeholder injection via custom templates. See ARCHITECTURE.md for details.
| What | Where | How |
|---|---|---|
| Spotify tokens | tauri-plugin-store |
Stored locally in credentials.json with atomic writes |
| Teams tokens | tauri-plugin-store |
Stored locally in credentials.json with atomic writes |
| App config | %APPDATA%\PresenceJam\config.json |
Plain JSON |
| Credentials | %APPDATA%\PresenceJam\credentials.json |
Plain JSON |
| App logs | %APPDATA%\PresenceJam\logs\ |
Daily rotating, 30-day retention |
Having issues? Check the TROUBLESHOOTING guide for common problems and solutions.
The app minimizes to the system tray β this is by design. Right-click the tray icon β Quit to fully exit.
presencejam://callbackContributions welcome! See CONTRIBUTING.md for development setup, coding standards, and submission guidelines.
AI-generated contributions are encouraged. Use whatever tools help you build the best code β just make sure it compiles and follows the project patterns.
Curious how it all works? See ARCHITECTURE.md for deep-dive diagrams and explanation.
See CHANGELOG.md for version history.
See ACKNOWLEDGEMENTS.md for the open-source dependencies that make this project possible.
MIT License β see LICENSE for details.