{"id":16696990,"url":"https://github.com/seratch/slack-remote-functions-on-cloudflare","last_synced_at":"2026-04-09T20:45:05.307Z","repository":{"id":208786290,"uuid":"722485641","full_name":"seratch/slack-remote-functions-on-cloudflare","owner":"seratch","description":"Build a remote function for Slack's automation platform on Cloudflare Workers","archived":false,"fork":false,"pushed_at":"2024-04-25T20:56:38.000Z","size":74,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-10T12:12:38.084Z","etag":null,"topics":["automation","bun","cloudflare","cloudflare-workers","slack","slack-api","slack-platform","typescript"],"latest_commit_sha":null,"homepage":"https://dev.to/seratch/slacks-remote-functions-on-cloudflare-workers-1dg0","language":"TypeScript","has_issues":false,"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/seratch.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-11-23T08:54:35.000Z","updated_at":"2024-10-02T20:31:32.000Z","dependencies_parsed_at":"2023-11-23T09:49:03.965Z","dependency_job_id":null,"html_url":"https://github.com/seratch/slack-remote-functions-on-cloudflare","commit_stats":null,"previous_names":["seratch/slack-remote-functions-on-cloudflare"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seratch%2Fslack-remote-functions-on-cloudflare","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seratch%2Fslack-remote-functions-on-cloudflare/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seratch%2Fslack-remote-functions-on-cloudflare/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seratch%2Fslack-remote-functions-on-cloudflare/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seratch","download_url":"https://codeload.github.com/seratch/slack-remote-functions-on-cloudflare/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247284918,"owners_count":20913691,"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":["automation","bun","cloudflare","cloudflare-workers","slack","slack-api","slack-platform","typescript"],"created_at":"2024-10-12T17:45:39.843Z","updated_at":"2026-04-09T20:45:05.269Z","avatar_url":"https://github.com/seratch.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Slack Remote Functions on Cloudflare Workers\n\nThis repository demonstrates how to build a remote function for [Slack's automation platform](https://api.slack.com/automation) on the [Cloudflare Workers](https://workers.cloudflare.com/) platform. The [slack-cloudflare-workers](https://github.com/seratch/slack-cloudflare-workers) library provides the toolset for swiftly creating such an app in TypeScript.\n\n## Clone this repo\n\n```bash\ngit clone git@github.com:seratch/slack-remote-functions-on-cloudflare.git\ncd slack-remote-functions-on-cloudflare/\n```\n\n## Create a new remote-funtion app\n\nAs of November 2023, you need to utilize either [Slack CLI](https://api.slack.com/automation/cli/install) commands or [`apps.manifest.create` API](https://api.slack.com/methods/apps.manifest.create) when initiating the development of a new Slack app that provides remote functions. This guide shows how to perform the API call without installing Slack CLI.\n\n### Create Cloudflare Tunnel for local development\n\nIn this guide, you will first confirm whether the app functions as anticipated on your local machine, before deploying the app on Cloudflare Workers. To accomplish this smoothly, you'll need to amend the app's manifest data to utilize the public URLs of the local app.\n\nStart by initiating a new tunnel for local development. You can do this by executing the following command:\n\n```bash\n# For other platforms: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/\nbrew install cloudflare/cloudflare/cloudflared\ncloudflared tunnel --url http://localhost:3000\n```\n\nThen, you will see the outputs like this:\n```\n$ cloudflared tunnel --url http://localhost:3000\n2023-11-23T08:33:52Z INF Thank you for trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee. If you intend to use Tunnels in production you should use a pre-created named tunnel by following: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps\n2023-11-23T08:33:52Z INF Requesting new quick Tunnel on trycloudflare.com...\n2023-11-23T08:33:53Z INF +--------------------------------------------------------------------------------------------+\n2023-11-23T08:33:53Z INF |  Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):  |\n2023-11-23T08:33:53Z INF |  https://maps-victim-warm-registration.trycloudflare.com                                   |\n2023-11-23T08:33:53Z INF +--------------------------------------------------------------------------------------------+\n2023-11-23T08:33:53Z INF Cannot determine default configuration path. No file [config.yml config.yaml] in [~/.cloudflared ~/.cloudflare-warp ~/cloudflare-warp /etc/cloudflared /usr/local/etc/cloudflared]\n2023-11-23T08:33:53Z INF Version 2023.8.2\n2023-11-23T08:33:53Z INF GOOS: darwin, GOVersion: go1.20.7, GoArch: amd64\n2023-11-23T08:33:53Z INF Settings: map[ha-connections:1 protocol:quic url:http://localhost:3000]\n2023-11-23T08:33:53Z INF cloudflared will not automatically update when run from the shell. To enable auto-updates, run cloudflared as a service: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/run-tunnel/as-a-service/\n2023-11-23T08:33:53Z INF Generated Connector ID: 65df45f4-8ab7-48fd-ad0b-4e52847c5924\n2023-11-23T08:33:53Z INF Initial protocol quic\n2023-11-23T08:33:53Z INF ICMP proxy will use 192.168.68.112 as source for IPv4\n2023-11-23T08:33:53Z INF ICMP proxy will use fe80::10a5:5e5a:9e14:f080 in zone en0 as source for IPv6\n2023-11-23T08:33:53Z INF Created ICMP proxy listening on 192.168.68.112:0\n2023-11-23T08:33:53Z INF Created ICMP proxy listening on [fe80::10a5:5e5a:9e14:f080%en0]:0\n2023-11-23T08:33:53Z INF Starting metrics server on 127.0.0.1:61237/metrics\n2023-11-23T08:33:53Z WRN Your version 2023.8.2 is outdated. We recommend upgrading it to 2023.10.0\n2023-11-23T08:33:54Z INF Registered tunnel connection connIndex=0 connection=d6531124-06de-4034-9f30-058c7a14e8a7 event=0 ip=198.41.200.23 location=kix04 protocol=quic\n```\n\nIn this case, `https://maps-victim-warm-registration.trycloudflare.com/` is the public URL receiving requests from Slack. Open `src/manifest.ts` and replace the two `request_url: \"https://TODO.trycloudflare.com/\"` parts in the code with this string.\n\n### Perform an apps.manifest.create API call\n\nAlright, the manifest data is now prepared, so let's proceed to make the API call.\n\nHead to https://api.slack.com/reference/manifests#config-tokens and grab your refresh token:\n\n\u003cimg width=\"500\" src=\"https://user-images.githubusercontent.com/19658/285134796-0f4669b0-ccc5-4fae-917c-78e2f3238346.png\"\u003e\n\nYou will use `.env` file located in the root directory of this project.\n\n```bash\necho 'SLACK_TOOLING_REFRESH_TOKEN=xoxe-1-...' \u003e .env\n```\n\nLet's use [Bun](https://bun.sh/docs/installation) for quickly running `src/manifest.ts`. If you're on macOS, the following commands set up the `bun` command for you:\n```bash\nbrew install bun\nbun add -d bun-types\n```\n\nEverything is set! Execute the command provided below to create a new Slack app with remote functions:\n\n```bash\nbun run src/manifest.ts\n```\n\nIf everything goes well, you will see a mesage like `!!! Visit https://api.slack.com/apps/{app_id} to install the app !!!` on the terminal. Click the URL and install the app into your Slack workspace.\n\n## Configure secrets\n\nTo configure your app, copy the following two secrets:\n\n* SLACK_SIGNING_SECRET: Settings \u003e Basic Information \u003e App Credentials \u003e Signing Secret\n* SLACK_BOT_TOKEN: Settings \u003e Install App \u003e Bot User OAuth Token\n\nTo run the app locally, create `.dev.vars` file with the following content:\n```\nSLACK_SIGNING_SECRET=...\nSLACK_BOT_TOKEN=xoxb-...\nSLACK_LOGGING_LEVEL=DEBUG\n```\n\n## Run the app on your local machine\n\nWhen you hit `npm start` on the termimnal, you will see the outputs like this:\n\n```\n$ npm start\n\n\u003e my-remote-func@0.0.0 start\n\u003e wrangler dev --port 3000\n\n ⛅️ wrangler 3.17.1\n-------------------\nUsing vars defined in .dev.vars\nYour worker has access to the following bindings:\n- Vars:\n  - SLACK_SIGNING_SECRET: \"(hidden)\"\n  - SLACK_BOT_TOKEN: \"(hidden)\"\n  - SLACK_LOGGING_LEVEL: \"(hidden)\"\n⎔ Starting local server...\n[mf:inf] Ready on http://*:3000\n[mf:inf] - http://127.0.0.1:3000\n[mf:inf] - http://192.168.68.112:3000\n[mf:inf] - http://localhost:3000\n[mf:inf] - http://[::1]:3000\n╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮\n│ [b] open a browser, [d] open Devtools, [l] turn off local mode, [c] clear console, [x] to exit                                         │\n╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\n```\n\nOnce your remote function has been installed to your Slack workspace or organization, you can utilize the custom step in the Workflow Builder as follows:\n\n\u003cimg src=\"https://user-images.githubusercontent.com/19658/285131373-3d6dab00-4f8b-45f3-b488-8e3e412c40ab.gif\" width=500\u003e\n\nShare the trigger URL for the workflow either in a channel or a canvas document. Clicking the link button initiates the workflow. The execution of your custom step within this workflow triggers a 'function_executed' event in your Cloudflare Workers app.\n\n\u003cimg src=\"https://user-images.githubusercontent.com/19658/285131111-b0d02f9c-c0fb-4604-aae0-5233dbd4d315.gif\" width=500\u003e\n\n## Deploy the app\n\nNow that the app is working, you can deploy this app onto Cloudflare Workers as a service ready for production. To do so, execute the commands mentioned below. You can go with the secrets that are already available in the `dev.vars` file.\n\n```bash\nwrangler deploy\nwrangler secret put SLACK_SIGNING_SECRET\nwrangler secret put SLACK_BOT_TOKEN\n```\n\nLastly, head to `https://api.slack.com/apps/{app_id}` and finalize the two request URLs (Interactivity \u0026 Shortcuts, Event Subcriptions) to use the Cloudflware Workers URL like `https://slack-remote-functions-on-cloudflare.{your account here}.workers.dev`.\n\n## Build your own remote function\n\nThe examples contained in this repo illustrate the use of buttons and modal views. Yet, if such engagement is not required for your use case, you can simply consolidate all neccessary logic into the `app.function(callbackId)` listener and remove other `app.action`/`app.view` listeners.\n\nPlease note, it is necessary to call either `functions.completeSuccess` or `functions.completeError` API. This action is required to instruct Slack's workflow to proceed to the subsequent step, or abort the workflow execution respectively. You can refer to `src/index.ts` for guidance on how to implement these API calls within the code.\n\nEnjoy!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseratch%2Fslack-remote-functions-on-cloudflare","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseratch%2Fslack-remote-functions-on-cloudflare","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseratch%2Fslack-remote-functions-on-cloudflare/lists"}