GithubHelp home page GithubHelp logo

jackcuthbert / slack-fm Goto Github PK

View Code? Open in Web Editor NEW
14.0 1.0 1.0 2.42 MB

A tiny self-hosted service that automatically updates your Slack status from your Last.fm profile.

License: MIT License

TypeScript 93.30% Dockerfile 2.36% JavaScript 3.60% Shell 0.73%
slack-api lastfm-api status-updates music self-hosted

slack-fm's Introduction

slack-fm
Travis CI Docker Pulls
slack-fm - Self-hosted service to sync Last.fm with your Slack status | Product Hunt Embed

Introduction

Slack-fm is a tiny self-hosted service that automatically updates your Slack status from your Last.fm profile. It updates your Slack status when all the following conditions are met:

  • the user is not set to "away"
  • a custom status hasn't been set
  • something is now playing on Last.fm
  • the time is between 9am and 5pm (configurable)
  • it's not a weekend (configurable)

To clear the status it will search Last.fm for the now playing tracks duration and use that as the status expiration time. If there is no duration information it defaults to a 10 minute expiration (configurable).

It looks like this:

Slack Preview

Prerequisites

  1. Last.fm API key (get one here)
  2. Last.fm username (this is probably your own username!)
  3. Slack "legacy" token (get one here)

Configuration

All configuration is available via environment variables. Values without defaults are required.

Variable Default Description
LAST_FM_KEY Access to Last.fm data
LAST_FM_USERNAME Which user to get track info for
SLACK_TOKEN Personal "legacy" token for updating your Slack status
SLACK_EMOJI :headphones: Specify which emoji to use in the status
SLACK_SEPARATOR โ€ข Specify which character to use as a separator between the track name and artist
TZ UTC Set the timezone
ACTIVE_HOURS_START 8 The hour of the day to start updating your Slack status
ACTIVE_HOURS_END 18 The hour of the day to stop updating your Slack status
UPDATE_INTERVAL 1 The time in minutes to wait until updating your Slack Status
UPDATE_WEEKENDS undefined Provide any value to enable status updates during the weekend
UPDATE_EXPIRATION 10 The time in minutes to use as a default status expiration length
SENTRY_DSN undefined Optionally provide a Sentry DSN to enable error reporting
ENABLE_LOGGING undefined Enable verbose console output

Hosting

I designed this to be easily self hosted, just use the Docker image! It's automatically built and versioned on Docker Hub based on GitHub activity.

Docker run

docker run \
  -e SLACK_TOKEN=<YOUR_SLACK_TOKEN> \
  -e LAST_FM_KEY=<YOUR_LAST_FM_KEY> \
  -e LAST_FM_USERNAME=<LAST_FM_USERNAME> \
  -e TZ=<YOUR_TIMEZONE> \
  jckcthbrt/slack-fm:latest

Docker compose

version: '3.7'
services:
  slack_fm:
    image: jckcthbrt/slack-fm:latest
    container_name: slack_fm
    restart: unless-stopped
    environment:
      TZ: <YOUR_TIMEZONE>
      SLACK_TOKEN: <YOUR_SLACK_TOKEN>
      LAST_FM_KEY: <YOUR_LAST_FM_KEY>
      LAST_FM_USERNAME: <LAST_FM_USERNAME>
docker-compose up

Contributing

This should be relatively simple to set up and run, all that's required is Node v12 and some environment variables.

  1. Fork this repository and clone your version
  2. Install dependencies with npm install
  3. Run the tests with npm test
  4. Set up your environment variables as above (direnv is great for this)
  5. Start the app locally with npm start
  6. Commit and push your changes then submit a PR back to this repository

slack-fm's People

Contributors

dependabot-preview[bot] avatar ellsclytn avatar jackcuthbert avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

olavs73

slack-fm's Issues

Slack API issues?

Slack seems to have killed off the legacy API?

at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (<anonymous>),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),

[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),
[Slack] Getting user presence,
Error: internal_error,
at Object.getSlackPresence (/app/dist/utils/slack.js:74:19),
at runMicrotasks (),
at processTicksAndRejections (internal/process/task_queues.js:94:5),
at async main (/app/dist/index.js:42:29),

Set up semantic-release tagging

At the moment all releases are manual which means I have to git tag and version bump package.json every time a new image is to be built in DockerHub.

Best Practice for updating multiple Slack accounts?

I have both personal and work Slack accounts and running this wonderful program allows me to update my status on one of them, but I'm curious if there's a best practice for updating multiple? I could run another image with a different Slack API Key but then it would double the calls to last.fm, right?

Thanks

Slack App version

Slack has finally retired the creation of new legacy tokens making this project a non-starter for people who haven't already created a token. For slack-fm to continue working it needs to be refactored to use the Slack App method rather than a legacy token.

If you already have a legacy token you can still use that or re-issue it and slack-fm will continue to work.

This issue will track any progress made towards making sure slack-fm continues to work into the future.

Clear status after hours

Mechanism to remove any status set by the app outside running hours. Perhaps detect the unique combination of the middle dot and the :headphones: emoji so it doesn't remove anything set by the user.

Use status expiration to clear statuses

Instead of manually clearing statuses and checking for previously set statuses slack-fm should be able to rely on slacks status expiration feature and a configurable "typical song length" (or actual duration value from the track.getinfo API).

This should save a couple API requests to clear a status when:

  • the current time is outside the configured active hours
  • nothing is playing

Unhandled promise rejecting getting LastFM track list

Seems intermittent, trace:

(node:24) UnhandledPromiseRejectionWarning: Error: Operation failed - Most likely the backend service failed. Please try again.
    at getLastFmTrack (/app/dist/index.js:42:19)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:24) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 90)

Really long song titles fail to be set

Really long titles like Bring me the Horizon's new "One Day the Only Butterflies Left Will Be in Your Chest as You March Towards Your Death" definitely don't fit. These titles should probably be truncated to fit so at least the start of the names can be seen on Slack.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.