{"id":31848306,"url":"https://github.com/clip-hpc/goslmailer","last_synced_at":"2025-10-12T10:23:21.589Z","repository":{"id":39214674,"uuid":"492814305","full_name":"CLIP-HPC/goslmailer","owner":"CLIP-HPC","description":"GoSlurmMailer - drop in replacement for default slurm MailProg. Delivers slurm job messages to various destinations.","archived":false,"fork":false,"pushed_at":"2024-10-01T11:47:40.000Z","size":1874,"stargazers_count":46,"open_issues_count":6,"forks_count":7,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-09-08T21:43:10.521Z","etag":null,"topics":["discord","hpc","mail","matrix","mattermost","msteams","notifications","slack","slurm","telegram"],"latest_commit_sha":null,"homepage":"","language":"Go","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/CLIP-HPC.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,"zenodo":null}},"created_at":"2022-05-16T11:55:25.000Z","updated_at":"2025-08-06T14:24:29.000Z","dependencies_parsed_at":"2023-12-15T11:27:22.737Z","dependency_job_id":"5f224306-41f8-49cd-96b9-c516446a4144","html_url":"https://github.com/CLIP-HPC/goslmailer","commit_stats":{"total_commits":80,"total_committers":8,"mean_commits":10.0,"dds":0.5125,"last_synced_commit":"d60a3ea6a0d1051bbcf6e2526d77a15904aa6581"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/CLIP-HPC/goslmailer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CLIP-HPC%2Fgoslmailer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CLIP-HPC%2Fgoslmailer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CLIP-HPC%2Fgoslmailer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CLIP-HPC%2Fgoslmailer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CLIP-HPC","download_url":"https://codeload.github.com/CLIP-HPC/goslmailer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CLIP-HPC%2Fgoslmailer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279011061,"owners_count":26084864,"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","status":"online","status_checked_at":"2025-10-12T02:00:06.719Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["discord","hpc","mail","matrix","mattermost","msteams","notifications","slack","slurm","telegram"],"created_at":"2025-10-12T10:23:17.897Z","updated_at":"2025-10-12T10:23:21.574Z","avatar_url":"https://github.com/CLIP-HPC.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# goslmailer\n\n\u003e **News \u0026 Info**\n\u003e\n\u003e### [Discussion forums](https://github.com/CLIP-HPC/goslmailer/discussions) have been enabled for this project, feel free to share your thoughts and ideas there.\n\u003e\n\u003e v2.7.1\n\u003e\n\u003e * In v2.7.0 dumping of configuration at goslmailer/gobler startup was removed.\n\u003e * Now it can be selectively enabled with `debugconfig: true` parameter in [config file](./cmd/goslmailer/goslmailer.conf.annotated_example)\n\u003e \n\u003e\n\u003e v2.7.0\n\u003e\n\u003e * [slack connector](#slack-connector)\n\u003e * [mattermost connector](#mattermost-connector)\n\u003e   * [mattermost section in json sample config](./cmd/goslmailer/goslmailer.conf.annotated_example)\n\u003e   * [mattermost section in toml sample config](./cmd/goslmailer/goslmailer.toml.annotated_example)\n\u003e   * [mattermost bot sample config](./cmd/mattermostbot/mattermost.conf)\n\u003e\n\u003e v2.5.0\n\u003e\n\u003e New: In addition to json, now supports [TOML](https://toml.io/en/) configuration files (.toml file suffix)\n\u003e   * [goslmailer json sample config](./cmd/goslmailer/goslmailer.conf.annotated_example)\n\u003e   * [goslmailer toml sample config](./cmd/goslmailer/goslmailer.toml.annotated_example)\n\u003e   * [gobler toml sample config](./cmd/gobler/gobler.toml)\n\u003e\n\u003e **BREAKING CHANGE**: `qosmap` changed its format from map[int]string to map[string]int.\n\u003e Adopt the [goslmailer config](./cmd/goslmailer/goslmailer.conf.annotated_example) file accordingly.\n\u003e ```\n\u003e  \"qosmap\": {              # map of your sites configured QoSes, with their timelimits (seconds), used for hint generation\n\u003e -   \"3600\": \"RAPID\",\n\u003e -   \"28800\": \"SHORT\",\n\u003e -   \"172800\": \"MEDIUM\",\n\u003e -   \"1209600\": \"LONG\"\n\u003e  \"qosmap\": {              # map of your sites configured QoSes, with their timelimits (seconds), used for hint generation\n\u003e +   \"RAPID\": 3600,\n\u003e +   \"SHORT\": 28800,\n\u003e +   \"MEDIUM\": 172800,\n\u003e +   \"LONG\": 1209600\n\u003e  }\n\u003e ```\n\u003e\n\n## Drop-in notification delivery solution for slurm that can do:\n\n* message delivery to:\n  * [**discord**](https://discord.com/)\n  * [**matrix**](https://matrix.org/)\n  * [**telegram**](https://telegram.org/)\n  * [**msteams**](https://teams.com)\n  * [**slack**](https://slack.com)\n  * [**e-mail**](https://en.wikipedia.org/wiki/Email)\n  * [**mattermost**](https://mattermost.com/)\n* gathering of job **statistics**\n* generating **hints** for users on how to tune their job scripts (see examples below)\n* **templateable** messages ([readme](./templates/README.md))\n* message **spooling** and **throttling**, [details here...](#spooling-and-throttling-of-messages---gobler-service)\n* easy to develop extensions for other protocols, [more here...](./connectors/connectorX/README.md) \n\n---\n\n## Description\n\n**Goslmailer** (GoSlurmMailer) is a drop-in replacement [MailProg](https://slurm.schedmd.com/slurm.conf.html#OPT_MailProg) for [slurm](https://slurm.schedmd.com/).\n\n\nWith goslmailer configured as as the slurm mailer,\n\n```\nMailProg                = /usr/bin/goslmailer\n```\n\nit provides users with the ability to specify a comma-separated list of receivers `[connector:]target` in the sbatch `--mail-user` switch to select where the messages will be sent out (similar to [URI scheme](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax)).\n\ne.g.\n\n```\nsbatch --mail-type=ALL --mail-user=\"mailto:useremailA,msteams:usernameB,telegram:NNNNNNN,usernameC\"\n```\n\nTo support future additional receiver schemes, a [connector package](connectors/) has to be developed and its [configuration block](cmd/goslmailer/goslmailer.conf.annotated_example) present in configuration file.\n\n## Currently available connectors:\n\n* [**discord**](#discord-connector) bot `--mail-user=discord:\u003cchannelId\u003e`\n* [**matrix**](#matrix-connector) bot `--mail-user=matrix:\u003croomId\u003e`\n* [**telegram**](#telegram-connector) bot `--mail-user=telegram:\u003cchatId\u003e`\n* [**mailto**](#mailto-connector) `--mail-user=mailto:\u003cemail-addr\u003e`\n* [**msteams**](#msteams-connector) webhook `--mail-user=msteams:\u003cuserId\u003e`\n* [**slack**](#slack-connector) web API `--mail-user=slack:\u003cuserId\u003e` OR `--mail-user=slack:\u003cchannelId\u003e`\n* [**mattermost**](#mattermost-connector) --mail-user=`mattermost`:channelId\n\nSee each connector details below...\n\n### If you would like to contribute to this project by developing a new connector, [here](./connectors/connectorX/README.md) you can find a heavily annotated connector boilerplate (fully functional) to help you get started.\n\n---\n\n## Building and installing\n\n### Option 1. Download latest precompiled binaries [here](https://github.com/CLIP-HPC/goslmailer/releases/latest)\n\nUnpack, follow [instructions](#install)\n\n### Option 2. Build\n\n#### Quick version, without end to end testing\n\n```\ngit clone https://github.com/CLIP-HPC/goslmailer.git\nmake test\nmake build\nmake install\n```\n\n#### Slightly more involved, with end to end testing:\n\nPrerequisites:\n\n1. generated RSA keypair (passwordless) (`ssh-keygen -t rsa`)\n2. `ssh $USER@localhost` must work without password\n\nKnown caveats:\n\n* redhat/centos: must have lsb_release binary installed, package: `redhat-lsb-core`\n* ubuntu 22: `set enable-bracketed-paste off` present in `~/.inputrc`\n* maybe/maybe not, depends if you see failed tests: `export TERM=dumb` in `~/.bashrc` :)\n* in case of the following error:\n```\nrun_goslmailer: validation *exec.RunRequest failed: target was empty at exec.run  at workflow.run \nrun_loop_over_tests_casestest_00: run_goslmailer: validation *exec.RunRequest failed: target was empty at exec.run  at workflow.run \n```\n\ntry:\n\n```\nmkdir $HOME/.secret\nssh-keygen -b 1024 -t rsa -f id_rsa -P \"\" -f $HOME/.secret/id_rsa\ntouch ~/.ssh/authorized_keys\ncat $HOME/.secret/id_rsa.pub \u003e\u003e  ~/.ssh/authorized_keys \n```\n\n\n```\n# downloads endly binary and runs endly tests\nmake \n```\n\n### Install\n\n#### goslmailer\n\n* place binary in a path to your liking\n* place [goslmailer.conf](cmd/goslmailer/goslmailer.conf.annotated_example) here: `/etc/slurm/goslmailer.conf` (default path)\n  * OR: anywhere else, but then run the binary with `GOSLMAILER_CONF=/path/to/gosl.conf` in environment\n* point slurm `MailProg` to the binary\n\n#### gobler\n\n* place binary in a path to your liking\n* place [gobler.conf](cmd/gobler/gobler.conf) in a path to your liking\n* start the service (with -c switch pointing to config file)\n\n#### tgslurmbot\n\n* place binary in a path to your liking\n* place [tgslurmbot.conf](cmd/goslmailer/goslmailer.conf.annotated_example) in a path to your liking\n  * config file has the same format as [goslmailer](cmd/goslmailer/goslmailer.conf.annotated_example) , so you can use the same one (other connectors configs are not needed)\n* start the service (with -c switch pointing to config file)\n\n#### matrixslurmbot\n\n* place binary in a path to your liking\n* place [matrixslurmbot.conf](cmd/goslmailer/goslmailer.conf.annotated_example) in a path to your liking\n  * config file has the same format as [goslmailer](cmd/goslmailer/goslmailer.conf.annotated_example), so you can use the same one (other connectors configs are not needed)\n* start the service (with -c switch pointing to config file)\n\n#### discoslurmbot\n\n* place binary in a path to your liking\n* place [discoslurmbot.conf](./cmd/discoslurmbot/discoslurmbot.conf) in a path to your liking\n  * config file has the same format as [goslmailer](cmd/goslmailer/goslmailer.conf.annotated_example), so you can use the same one (other connectors configs are not needed)\n* start the service (with -c switch pointing to config file)\n\n\n---\n\n\n## Spooling and throttling of messages - gobler service\n\nIn high-throughput clusters or in situations where job/message spikes are common, it might not be advisable to try to send all of the incoming messages as they arrive.\nFor these environments goslmailer can be configured to spool messages from certain connectors on disk, to be later processed by the **gobler** service.\n\n**gobler** is a daemon program that can be [configured](cmd/gobler/gobler.conf) to monitor specific spool directories for messages, process them and send out using the same connectors as goslmailer.\n\n\nOn startup, gobler reads its config file and spins-up a `connector monitor` for each configured spool directory.\n\n\n`connector monitor` in turn spins up 3 goroutines: `monitor`, `picker` and `numSenders` x `sender`.\n\n* **monitor** :\n  * every `monitorT` seconds (or milliseconds) scans the `spoolDir` for new messages and sends them to the **picker**\n\n* **picker**  :\n  * on receipt of new messages performs *trimming* of excessive messages, limiting the number of users messages in the system to `maxMsgPU`\n  * every `pickerT` seconds (or milliseconds) picks the next message to be delivered and sends it to the **sender** (ordering by time of arrival)\n\n* **sender**  :\n  * `numSenders` goroutines are waiting for messages from the **picker** and try to deliver them. In case of failure, messages are returned to the **picker** for a later retry\n\n\n## Artistic sketch of the system described above\n\n![Sketch of the architecture](./images/archSketch.png)\n\n---\n\n## Connectors\n\n| connector | spooling/throttling capable (gobler) |\n|-----------|---------------------------|\n| mattermost| yes                       |\n| discord   | yes                       |\n| matrix    | no                        |\n| telegram  | yes                       |\n| msteams   | yes                       |\n| mailto    | no                        |\n| slack     | yes                       |\n\n### default connector\n\nSpecifies which receiver scheme is the default one, in case when user didn't specify `--mail-user` and slurm sent a bare username.\n\n```\n\"defaultconnector\": \"msteams\"\n```\n\n---\n\n### mailto connector\n\nMailto covers for original slurm e-mail sending functionality, plus a little bit more.\nWith connector parameters, you can:\n\n* specify your e-mail client (ex slurm: `MailProg`, e.g. /usr/bin/mutt)\n* template mail client command line  (e.g. custom subject line)\n* template message body\n* allowList the recipients\n\n\n#### known caveats\n\n* HTML e-mail and mutt\n  * to make sure mutt sends HTML email with proper content-type header, add following lines to `/etc/Muttrc.local`\n\n```\n# Local configuration for Mutt.\nset content_type=\"text/html\"\n```\n\nSee [annotated configuration example](cmd/goslmailer/goslmailer.conf.annotated_example)\n\n---\n\n### mattermost connector\n\nPrerequisites for the mattermost connector:\n\n1. Create mattermost bot, [instructions here.](https://developers.mattermost.com/integrate/reference/bot-accounts/)\n2. OPTIONAL/CONVENIENT: Start the bot daemon service **mattermostbot** ([example config file](./cmd/mattermostbot/mattermost.conf)).\n    * This is used to deliver `--mail-user=mattermost:chatId` messages, can also be looked up by the user in the Info window\n3. If the bot is running, it will wake up on the configured `triggerString` and send the user a private message with slurm job submission instructions\n4. Put `mattermost` block in [goslmailer.conf](./cmd/goslmailer/goslmailer.conf.annotated_example) (and optionally [gobler.conf](./cmd/gobler/gobler.conf) if spooling is used)\n\n![Mattermost card](./images/mattermost.png)\n\nAdditional helpful sources:\n\n* [message markdown](https://docs.mattermost.com/channels/format-messages.html#:~:text=Use%20Markdown,%2C%20tables%2C%20and%20math%20formulas.)\n\n---\n\n### discord connector\n\nPrerequisites for the discord connector:\n\n1. a discord bot must be created and\n2. the bot daemon service **discoslurmbot** must be running ([example config file](./cmd/discoslurmbot/discoslurmbot.conf)).\n3. once the bot is running, it will wake up on the configured `triggerString` and send the user a private message with slurm job submission instructions\n\n\n#### Discord Bot setup\n\n1. User settings -\u003e Advanced -\u003e Developer mode ON\n2. [Discord developer portal](https://discord.com/developers/applications) -\u003e New Application -\u003e Fill out BotName\n3. Once the application is saved, select *Bot* from left menu -\u003e Add Bot -\u003e message: \"A wild bot has appeared!\"\n4. Left menu: OAuth2 -\u003e Copy Client ID\n5. Modify this url with the Client ID from 4. and open in browser: `https://discord.com/api/oauth2/authorize?client_id=\u003cCLIENT-ID\u003e\u0026permissions=8\u0026scope=bot`\n6. \"An external application BotName wants to access your Discord Account\" message -\u003e Select server -\u003e Continue\n7. Grant Administrator permissions -\u003e yes/no/maybe ? -\u003e Authorize\n8. [Discord developer portal](https://discord.com/developers/applications) -\u003e Select BotName -\u003e Bot menu -\u003e Reset Token -\u003e Copy and Save, to be used in discoslurmbot.conf\n\nOr follow this [tutorial](https://discordpy.readthedocs.io/en/stable/discord.html)\n\n![Discord card](./images/discord.png)\n\n* discord bot and packaged developed using [discordgo](https://github.com/bwmarrin/discordgo) and with the help of _Discord Gophers_\n\n---\n\n### telegram connector\n\nSends **1on1** or **group chat** messages about jobs via [telegram messenger app](https://telegram.org/)\n\n![Telegram card](./images/telegram.png)\n\nPrerequisites for the telegram connector:\n\n1. a telegram bot must be created and\n2. the bot daemon service **tgslumbot** must be running.\n\nSite admins can [create a telegram bot](https://core.telegram.org/bots#6-botfather) by messaging [botfather](https://t.me/botfather).\n\nOnce the bot is created, you will receive a bot `token`. Place the bot `token` in the goslmailer/gobler config file in the `telegram` connector section (see example below).\n\nStart the tgslurmbot binary that serves as the bot.\n\nWhen the chat/group chat with the bot is initiated and/or the bot receives a `/start` command, he will reply with a chat-specific `--mail-user=telegram:nnn` message which the user can use in his slurm job scripts to get the job messages.\n\nSee [annotated configuration example](cmd/goslmailer/goslmailer.conf.annotated_example)\n\n---\n\n### matrix connector\n\nSends messages to user-defined Matrix rooms.\n\n![Matrix](./images/matrix.png)\n\nThe Matrix connector can send messages through a pre-defined user that you\nmanually join into channels. In addition, you can setup matrixslurmbot to\ncontrol this pre-defined user and have him join rooms upon invitation.\n\nThe first thing you need is to add the proper parameters to the\nconnectors/matrix section of the config file.\n\nTo obtain the access token, you can run this command using curl:\n\n```bash\ncurl -XPOST -d '{\"type\":\"m.login.password\", \"user\":\"@myuser:matrix.org\", \"password\":\"mypassword\"}' \"https://matrix.org/_matrix/client/r0/login\"\n```\n\nWhich should get you a response akin to this one, containing the token:\n\n```json\n{\n    \"user_id\": \"@myuser:matrix.org\",\n    \"access_token\": \"syt_dGRpZG9ib3QXXXXXXXEyQMBEmvOVp_10Jm93\",\n    \"home_server\": \"matrix.org\",\n    \"device_id\": \"DMIIOMEYBK\",\n    \"well_known\": {\n        \"m.homeserver\": {\n            \"base_url\": \"https://matrix-client.matrix.org/\"\n        }\n    }\n}\n```\n\nOnce you've done this, goslmailer will be able to send messages to any channel\nthe configured user is a member of with a command like this:\n\n```bash\nsbatch --mail-type=ALL --mail-user='matrix:!VEbreVXXXkmLWjeGPi:matrix.org' --wrap \"ls\"\n```\n\nWhere `!VEbreVXXXkmLWjeGPi:matrix.org` is the ID of the channel you want to send\nthe message to. You can obtain this ID from the `Settings\u003eAdvanced` section of\nthe room.\n\n#### Using the bot\n\nInstead of manually having the pre-defined user join certain rooms, you can use\n`matrixslurmbot` to control this user and have it join rooms automatically upon invitation.\nFor this you just need to start the `matrixslurmbot`, pointing it to a config file identical to the one before using\n(you could strip it down to contain only the 'matrix' section).\n\nWhile the bot is running, any user can invite it to join a channel (e.g. `/invite\n@mybotuser:matrix.org`). The bot will join the channel and post the\n`--mail-user:...` argument to be used when submitting jobs in order to receive a message in that\nchannel.\n\nIn the event that the pre-defined user is alone in a channel (i.e. all normal\nusers left), the bot will make the pre-defined user leave and forget the\nchannel.\n\n---\n\n### msteams connector\n\nSends a message to a preconfigured ms teams channel webhook.\n\n![MS Teams card](./images/msteams.png)\n\nSince MS Teams does not provide with the option to send messages to users directly, only to channel webhooks, we have devised a way using MS Power Automate framework to pick up messages from this one configured *sink* channel and deliver them via private 1on1 chats to the recipient user.\n\nUsers listed in the `--mail-user=msteams:userA,msteams:userB` will be sent as adaptive card [mention](https://github.com/CLIP-HPC/goslmailer/blob/main/templates/adaptive_card_template.json#L225) entity.\nA [MS Power Automate workflow](https://powerautomate.microsoft.com/en-us/) monitors the configured *sink* channel, parses the received adaptive card jsons, locates the `mention` entity and delivers to it the copy of the message via private chat.\n\nSee [annotated configuration example](cmd/goslmailer/goslmailer.conf.annotated_example)\n\n---\n\n### slack connector\n\nSends messages to direct messages or channels in Slack using its Web API and [slack-go](https://github.com/slack-go/slack).\n\nPrerequisite for the slack connector:\n\n1. A Slack App must be created\n\n\n#### Slack App setup\n\n1. Go to the [Slack App portal](https://api.slack.com/apps?new_app=1). Give your app a name (such as \"SlurmBot\"), and choose the workspace you want to use the app in. ***You must be allowed to add apps to this workspace.***\n2. Click on **OAuth \u0026 Permissions** on the sidebar. Scroll down to **Scopes** and click on **Add an OAuth Scope.** Add `chat:write` and `im:write`.\n3. Scroll back up to **OAuth Tokens for Your Workspace** and copy the **Bot User OAuth Token**. It should look something like `xoxb-5555555555555-5555555555555-XXXXXXXXXXXXXXXXXXXXXXX`. This will be used in your goslmailer config (`goslmailer.conf` or `goslmailer.toml`), and gobler config if used.\n\n![Slack card](./images/slack.png)\n\n#### Notes\n\nThe bot will be able to send to any channel it's in. Make sure it is not added to channels it shouldn't send messages in (such as an announcments channel). You can add the bot to a channel by pinging it (send a message with just @SlurmBot, for example) and then click on **Add to Channel**.\n\n* [slack-go](https://github.com/slack-go/slack) used in this connector.\n\n---\n\n## Gotchas\n\n### msteams\n\n* using adaptive card schema version 1.5 doesn't work with our adaptive card, check if some element changed in designer\n    * tested: 1.0, 1.2 - work\n\n\n## references\n\n### msteams\n\n* [Adaptive cards](https://adaptivecards.io/)\n* [Adaptive cards - Designer](https://adaptivecards.io/designer/)\n* [Rate limiting for connectors](https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using?tabs=cURL#rate-limiting-for-connectors)\n* [Bot optimizing for rate limiting](https://docs.microsoft.com/en-us/microsoftteams/platform/bots/how-to/rate-limit#)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclip-hpc%2Fgoslmailer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclip-hpc%2Fgoslmailer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclip-hpc%2Fgoslmailer/lists"}