Skip to content

Commit

Permalink
204: Handle proxies when using Slack WebClient (#205)
Browse files Browse the repository at this point in the history
  • Loading branch information
raihle authored Jun 1, 2023
1 parent 599e66b commit c70e795
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 2 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,23 @@ Incoming Webhooks conform to the same rules and functionality as any of Slack's
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
```

### HTTPS Proxy

If you need to use a proxy to connect with Slack, you can use the `HTTPS_PROXY` (or `https_proxy`) environment variable. In this example we use the Slack App technique, but configuring a proxy works the same way for all of them:

```yaml
- name: Post to a Slack channel via a proxy
id: slack
uses: slackapi/slack-github-action@v1.24.0
with:
channel-id: 'CHANNEL_ID'
slack-message: 'This message was sent through a proxy'
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
# Set the HTTPS_PROXY environment variable to whatever your policy requires
HTTPS_PROXY: 'http://proxy.example.org:8080'
```

## Contributing

See [CONTRIBUTING](.github/contributing.md).
Expand Down
6 changes: 4 additions & 2 deletions src/slack-send.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const github = require('@actions/github');
const { WebClient } = require('@slack/web-api');
const flatten = require('flat');
const axios = require('axios');
const { promises: fs } = require('fs');
Expand All @@ -8,6 +7,8 @@ const markup = require('markup-js');
const HttpsProxyAgent = require('https-proxy-agent');
const { parseURL } = require('whatwg-url');

const { createWebClient } = require('./web-client');

const SLACK_WEBHOOK_TYPES = {
WORKFLOW_TRIGGER: 'WORKFLOW_TRIGGER',
INCOMING_WEBHOOK: 'INCOMING_WEBHOOK',
Expand Down Expand Up @@ -63,7 +64,8 @@ module.exports = async function slackSend(core) {
if (typeof botToken !== 'undefined' && botToken.length > 0) {
const message = core.getInput('slack-message') || '';
const channelIds = core.getInput('channel-id') || '';
const web = new WebClient(botToken);
const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy || '';
const web = createWebClient(botToken, httpsProxy);

if (channelIds.length <= 0) {
console.log('Channel ID is required to run this action. An empty one has been provided');
Expand Down
20 changes: 20 additions & 0 deletions src/web-client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const { WebClient } = require('@slack/web-api');
const HttpsProxyAgent = require('https-proxy-agent');

/**
*
* @param {string} botToken token used to authenticate as the Slack Bot user
* @param {string?} httpsProxy (optional) URL for the proxy to use for HTTPS requests
* @returns { WebClient } a WebClient configured with the bot token and proxy agent (if needed)
*/
function createWebClient(botToken, httpsProxy) {
if (httpsProxy) {
const httpsProxyAgent = new HttpsProxyAgent(httpsProxy);
return new WebClient(botToken, { agent: httpsProxyAgent });
}
return new WebClient(botToken);
}

module.exports = {
createWebClient,
};
1 change: 1 addition & 0 deletions test/slack-send-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ describe('slack-send', () => {
});
describe('proxy config', () => {
beforeEach(() => {
delete process.env.https_proxy;
delete process.env.HTTPS_PROXY;
});
it('should use https proxy agent when proxy uses HTTP', async () => {
Expand Down
33 changes: 33 additions & 0 deletions test/web-client-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const { assert } = require('chai');
const sinon = require('sinon');
const rewiremock = require('rewiremock/node');

/* eslint-disable-next-line global-require */
rewiremock(() => require('@slack/web-api')).with({
WebClient: class {
constructor(token, options) {
this.token = token;
this.options = options || {};
}
},
});
rewiremock.enable();
const { createWebClient } = require('../src/web-client');

rewiremock.disable();

describe('web-client', () => {
beforeEach(() => {
sinon.reset();
});

it('should create WebClient with an https proxy agent if given a proxy URL', async () => {
const web = createWebClient('xoxb-xxxxx', 'http://test.proxy:8080/');
assert.equal(typeof web.options.agent, 'object');
});

it('should create WebClient with default settings if not given a proxy URL', async () => {
const web = createWebClient('xoxb-xxxxx');
assert.equal(web.options.agent, undefined);
});
});

0 comments on commit c70e795

Please sign in to comment.