Search code examples
javascriptfetch-apislack-api

slack chat.postMessage API endpoint is not allowing the authorization header


I have this code running in the browser

<html>

    <script type="module">
        console.log("working");

        var url = "https://slack.com/api/chat.postMessage";
        var auth_token = "xoxb-2B"; //Your Bot's auth token
        var body = {channel: "ses", text: "testing app"}

        async function postData(url = '', data = {}) {
            // Default options are marked with *
            const response = await fetch(url, {
                method: 'POST', // *GET, POST, PUT, DELETE, etc.
                headers: {
                    "Authorization": "Bearer " + auth_token,
                    "Content-Type" : "application/json"
                },
                body: JSON.stringify(data) // body data type must match "Content-Type" header
            });
            return response.json(); // parses JSON response into native JavaScript objects
        }

        postData('https://slack.com/api/chat.postMessage', body)
        .then(data => {
            console.log(data); // JSON data parsed by `data.json()` call
        });
    </script>
</html>

I'm getting

Access to fetch at 'https://slack.com/api/chat.postMessage' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

I don't understand, I need to specify the bearer token somehow, even in the docs it says to put it in the Authorization header, why aren't they allowing it?


Solution

  • I don't understand, I need to specify the bearer token somehow, even in the docs it says to put it in the Authorization header, why aren't they allowing it?

    This is a different problem, is not related to the Bearer token at all. From the error you're getting, it means, the origin you're using to fetch the Slack API, is not trusted (http://127.0.0.1:5500), there is nothing you can do from the browser since this is a policy that comes from the server which defines the authorized origins. (Learn more about CORS here) Since I don't think this is supported by Slack, you will need to fetch the Slack API from the server.

    One way to solve this, is by exposing a backend API, for example:

    Post a message to Slack                                                                                 Run in Fusebit
    router.post('/api/tenant/:tenantId/test', async (ctx) => {
      // Create a Slack client pre-configured with credentials necessary to communicate with your tenant's Slack workspace.
      // For the Slack SDK documentation, see https://slack.dev/node-slack-sdk/web-api.
      const slackClient = await integration.tenant.getSdkByTenant(ctx, connectorName, ctx.params.tenantId);
    
      // Get the Slack user ID associated with your tenant
      const slackUserId = slackClient.fusebit.credentials.authed_user.id;
    
      // Send a Direct Message to the Slack user
      const result = await slackClient.chat.postMessage({
        text: 'Hello world!',
        channel: slackUserId,
      });
    
      console.log('message response', result.message);
      ctx.body = { message: `Successfully sent a message to Slack user ${slackUserId}!` };
    });