{"id":19796948,"url":"https://github.com/mercurytechnologies/slacklinker","last_synced_at":"2025-05-01T03:31:15.308Z","repository":{"id":110976324,"uuid":"540073238","full_name":"MercuryTechnologies/slacklinker","owner":"MercuryTechnologies","description":"Slack backlink bot","archived":false,"fork":false,"pushed_at":"2025-04-14T22:34:59.000Z","size":344,"stargazers_count":10,"open_issues_count":1,"forks_count":2,"subscribers_count":48,"default_branch":"main","last_synced_at":"2025-04-30T22:58:54.152Z","etag":null,"topics":["slack","slack-bot","slack-web"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MercuryTechnologies.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-22T16:33:44.000Z","updated_at":"2025-04-14T22:35:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"b1d197e9-c60d-4b01-8c3c-18a2223c0014","html_url":"https://github.com/MercuryTechnologies/slacklinker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MercuryTechnologies%2Fslacklinker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MercuryTechnologies%2Fslacklinker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MercuryTechnologies%2Fslacklinker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MercuryTechnologies%2Fslacklinker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MercuryTechnologies","download_url":"https://codeload.github.com/MercuryTechnologies/slacklinker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251818013,"owners_count":21648849,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["slack","slack-bot","slack-web"],"created_at":"2024-11-12T07:23:06.822Z","updated_at":"2025-05-01T03:31:15.301Z","avatar_url":"https://github.com/MercuryTechnologies.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Slacklinker: a Slack backlink bot\n\n![screenshot of slacklinker replying to a message \"I just pushed a PR that\ndefinitely works, for sure\" with a link to a message linking to it saying \"Oh\nno, prod is on fire\"](doc/slacklinker-demo.png)\n\nThis is a Slack bot that creates backlinks when you link messages. It's written\nusing the Servant web framework for Haskell, and the [slack-web] Slack library.\n\n[slack-web]: https://github.com/MercuryTechnologies/slack-web\n\nIt also supports backlinking Linear tickets when they are mentioned on Slack by adding an attached Slack message to the tickets.\n\n## Configuration\n\n### Slack setup\n\nHere is the app manifest you can use to set up the Slack app on the [Slack API\nsite]:\n\n[Slack API site]: https://api.slack.com/apps\n\n```yaml\ndisplay_information:\n  name: Slacklinker\nfeatures:\n  app_home:\n    home_tab_enabled: true\n    messages_tab_enabled: true\n    messages_tab_read_only_enabled: false\n  bot_user:\n    display_name: Slacklinker\n    always_online: true\noauth_config:\n  redirect_urls:\n    - https://YOUR_SERVICE/oauth_redirect\n  scopes:\n    bot:\n      # read chat messages\n      - channels:history\n      # join itself to channels\n      - channels:join\n      # find public channels\n      - channels:read\n      # send messages\n      - chat:write\n      # send reactions to messages\n      - reactions:write\n      # read the team URL\n      - team:read\n      # take commands via IM\n      - im:history\n      # know which IMs it is in (?!)\n      - im:read\n      # read files sent in DMs for updating user emoji\n      - files:read\n      # find users by email\n      - users:read\n      # find users by email\n      - users:read.email\nsettings:\n  event_subscriptions:\n    request_url: https://YOUR_SERVICE/webhook\n    bot_events:\n      - app_home_opened\n      - channel_created\n      - channel_left\n      - file_shared\n      - message.channels\n      - message.im\n  org_deploy_enabled: false\n  socket_mode_enabled: false\n  token_rotation_enabled: false\n```\n\nAdditionally, on the \"App Home\" panel, you have to enable \"Messages tab\" and\n\"Allow users to send Slash commands and messages from the messages tab\" as well\nas \"Home Tab\".\n\n### App setup\n\nThis app is developed and deployed using Nix. You can get a development shell\nwith haskell-language-server and all the tools you need with `nix develop`.\n\nTo deploy it, you can equivalently use the `packages.${system}.default`\nattribute from `flake.nix` or the `build` attribute of `release.nix` (which are\nidentical). Before starting the application (`result/bin/slacklinker`), your\nservice manager should run `result/db/migrate.sh` to run the database\nmigrations.\n\nSome basic configuration is done via environment variables:\n\nCorresponding to the values in the \"Basic Information\" pane of the [Slack API site]:\n- `SLACK_CLIENT_SECRET`\n- `SLACK_SIGNING_SECRET`\n- `SLACK_CLIENT_ID`\n\nCorresponding to your database:\n- `POSTGRES_CONNECTION_STRING` is a Postgres connection string like\n  `postgresql://slacklinker:yourpassword@localhost:5432/slacklinker`\n\nCorresponding to your OpenTelemetry tracing service (this is the recommended\nway to debug and monitor Slacklinker):\n- `OTEL_SERVICE_NAME=slacklinker`\n- `OTEL_EXPORTER_OTLP_ENDPOINT` (for Honeycomb, `https://api.honeycomb.io`)\n- `OTEL_EXPORTER_OTLP_HEADERS` (for Honeycomb, `x-honeycomb-team=YOUR-API-KEY`)\n\nYou can set some runtime configuration settings in the database using\n`one-off-task set-setting`. A full list of these is in\n[`src/Slacklinker/Settings/Types.hs`](src/Slacklinker/Settings/Types.hs).\n\nMake Slacklinker not backlink to posts by these apps. This is helpful in making\nsure that Slacklinker won't backlink to itself. It is recommended to put\nSlacklinker's own app id here.\n\n- `BLOCKED_APP_IDS=appid1,appid2`\n\n### Linear setup\n\nLinear integration is optional and is not visible if not configured.\n\nFor Linear integration (backlinking Linear tickets with Slack message attachments on the tickets), create a [Linear app].\nThe redirect URL should be given as `https://YOUR-SLACKLINKER/linear/oauth_redirect`.\n\n[Linear app]: https://developers.linear.app/docs/oauth/authentication\n\nConfigure the following settings in Slacklinker's environment variables:\n\n- `LINEAR_CLIENT_ID` is the Client ID from the Linear App page.\n- `LINEAR_CLIENT_SECRET` is the Signing Secret from the Linear App page.\n- `SLACKLINKER_HOST` is the unqualified Slacklinker domain, i.e.\n  `slacklinker.example.com`.\n\n  This is required to make redirect URLs for Linear OAuth2.\n\nThen, you can link Linear by visiting App Home (the DMs with Slacklinker, on the home tab).\nIf it's not visible, make sure it's enabled in the Slack app API settings.\n\nSlacklinker will try linking any Linear ticket identifiers matching a known Linear Team for any given Slack workspace.\nHowever, the list of teams is not updated automatically.\nTo update them, you can run `one-off-task update-all-linear-teams` (which should be put in a cron job in a real deployment) or the IM command `update_linear_teams`.\n\n### Usage\n\nOnce you have the application running at some public URL, you need to authorize\nit with OAuth2.\n\nTo do this, go to `https://YOUR_SERVICE/authorize`. You will be redirected to\nSlack to authorize the application.\n\nAfter authorizing Slacklinker on your workspace, unless you intend to run a\npublic instance, you should immediately disable `AllowRegistration`:\n\n```\nbin/one-off-task set-setting --settingName AllowRegistration --value false\n```\n\n(note that one-off-task needs to have the same environment variables as the\nservice)\n\nOnce Slacklinker is authorized, you can send the bot a private message\n`join_all`, which will have the bot join all existing public non-shared Slack\nchannels.\n\nThe bot will automatically join any newly created public channels, so no\nfurther action is needed.\n\n## Development notes\n\nSince [slack-web] does not (currently) support Slack's [Socket Mode], you\n*need* a public request URL to run Slacklinker. This is most easily achieved\nwith something like [ngrok] in development and your preferred infrastructure in\nproduction.\n\n[Socket Mode]: https://api.slack.com/apis/connections/socket\n[ngrok]: https://ngrok.com/\n\nWe recommend using [`direnv`][direnv] and [`nix-direnv`][nix-direnv] to get a\nworking environment for working on slacklinker. You can see a sample for\n`.envrc` at [./.envrc.sample](./.envrc.sample).\n\n[nix-direnv]: https://github.com/nix-community/nix-direnv\n[direnv]: https://direnv.net/\n\n### Schema changes \u0026 Migrations\n\nIf you do a database schema change, you will need to generate a migration.\nThese use the [Refinery] CLI, which basically just runs SQL. You can get\nPersistent to generate the outline of the migration like so:\n\n```\n$ cabal run one-off-task -- suggest-migrations --migrationName your_migration_name\n```\n\n[Refinery]: https://github.com/rust-db/refinery\n\n### Golden tests\n\nUse `scripts/update-golden.sh SOME_GOLDEN_DIR` to update golden snapshot test\nfiles.\n\n### Logging\n\nSet log level with `LOG_LEVEL=debug` and SQL log level with `LOG_SQL=debug`\nenvironment variables.\n\n### Updating dependencies\n\nSome Haskell dependencies (such as tmp-postgress and slack-web) are overriden from source in [./nix/deps](https://github.com/MercuryTechnologies/slacklinker/tree/main/nix/deps). To update, use `cabal2nix` (available in your dev shell via nix develop).\n\n```\ncabal2nix \"${GITHUB_URI}\" \u003e \"./nix/deps/${PACKAGE_NAME}.nix\"\n```\n\nThat command will grab the latest git head from the repo. To get a specific version you can use `--revision`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmercurytechnologies%2Fslacklinker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmercurytechnologies%2Fslacklinker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmercurytechnologies%2Fslacklinker/lists"}