Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

204: Handle proxies when using Slack WebClient #205

Merged
merged 2 commits into from
Jun 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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');
hello-ashleyintech marked this conversation as resolved.
Show resolved Hide resolved
assert.equal(web.options.agent, undefined);
});
});