Python-slack-sdk: How connect to Slack through proxy?

Created on 26 Feb 2021  路  3Comments  路  Source: slackapi/python-slack-sdk

I'm trying to connect to Slack bot, but i'm getting error, probably because i'm behind a proxy-server. There is a SLACK_BOT_TOKEN in my environment variables.
How can i connect using the following code?

import os
import time
import re
from slackclient import SlackClient

slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
starterbot_id = None
RTM_READ_DELAY = 1 

if __name__ == "__main__":
    if slack_client.rtm_connect(with_team_state=False):
        print("Starter Bot connected and running!")
        starterbot_id = slack_client.api_call("auth.test")["user_id"]
        while True:
            command, channel = parse_bot_commands(slack_client.rtm_read())
            if command:
                handle_command(command, channel)
            time.sleep(RTM_READ_DELAY)
    else:
        print("Connection failed. Exception traceback printed above.")

Below you can see an error that i get when i launch the script above:

Failed RTM connect
Traceback (most recent call last):
  File "C:\slack\env\lib\site-packages\urllib3\connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "C:\slack\env\lib\site-packages\urllib3\connectionpool.py", line 382, in _make_request
    self._validate_conn(conn)
  File "C:\slack\env\lib\site-packages\urllib3\connectionpool.py", line 1010, in _validate_conn
    conn.connect()
  File "C:\slack\env\lib\site-packages\urllib3\connection.py", line 411, in connect
    self.sock = ssl_wrap_socket(
  File "C:\slack\env\lib\site-packages\urllib3\util\ssl_.py", line 428, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(
  File "C:\slack\env\lib\site-packages\urllib3\util\ssl_.py", line 472, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
  File "C:\Users\vvgrink1\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Users\vvgrink1\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1040, in _create
    self.do_handshake()
  File "C:\Users\vvgrink1\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLEOFError: EOF occurred in violation of protocol (_ssl.c:1123)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\slack\env\lib\site-packages\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "C:\slack\env\lib\site-packages\urllib3\connectionpool.py", line 755, in urlopen
    retries = retries.increment(
  File "C:\slack\env\lib\site-packages\urllib3\util\retry.py", line 573, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='slack.com', port=443): Max retries exceeded with url: /api/rtm.connect (Caused by SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol (_ssl.c:1123)')))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\slack\env\lib\site-packages\slackclient\client.py", line 140, in rtm_connect
    self.server.rtm_connect(use_rtm_start=with_team_state, **kwargs)
  File "C:\slack\env\lib\site-packages\slackclient\server.py", line 137, in rtm_connect
    reply = self.api_requester.do(
  File "C:\slack\env\lib\site-packages\slackclient\slackrequest.py", line 84, in do
    return self.post_http_request(token, request, post_data, files, timeout, domain)
  File "C:\slack\env\lib\site-packages\slackclient\slackrequest.py", line 110, in post_http_request
    res = requests.post(
  File "C:\slack\env\lib\site-packages\requests\api.py", line 119, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "C:\slack\env\lib\site-packages\requests\api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\slack\env\lib\site-packages\requests\sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\slack\env\lib\site-packages\requests\sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "C:\slack\env\lib\site-packages\requests\adapters.py", line 514, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='slack.com', port=443): Max retries exceeded with url: /api/rtm.connect (Caused by SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol (_ssl.c:1123)')))
Connection failed. Exception traceback printed above.
1x 3x question rtm-client web-client

All 3 comments

Hi @vv-grinko, thanks for asking the question! Before answering the way to set proxy in your code, we highly recommend using newer version of the SDK. Your code should depend on slackclient v1, which is no longer maintained. The current recommendation is to use v3, which is available in a bit different PyPI project name - slack_sdk (slack-sdk also works).

Here is the up-to-date document to use the latest RTMClient (please use slack_sdk.rtm.v2 as it's more stable): https://slack.dev/python-slack-sdk/real_time_messaging.html

The way to configure proxy is not in the document (I will update the document later). You can use proxy argument in the constructor as below. Also, HTTPS_PROXY / HTTP_PROXY env variables work for you.

import os
from slack_sdk.rtm.v2 import RTMClient

rtm = RTMClient(
    token=os.environ.get("SLACK_CLASSIC_BOT_TOKEN"),
    proxy="http://your-proxy-domain:9000/", # or "http://user:pass@your-proxy-domain:9000/"
)

I know some developers may have particular reasons to use RTM API but our current recommendation is to use Socket Mode along with Events API. Socket Mode offers more functionalities like handling interactive components and modals and more granular permissions (which is crucial for apps for business operations). Here is the document for Socket Mode client: https://slack.dev/python-slack-sdk/socket-mode/index.html In the same way with RTMClient, you case pass proxy argument (or env variable).

I hope this was helpful to you 馃憢

Hi @vv-grinko, thanks for asking the question! Before answering the way to set proxy in your code, we highly recommend using newer version of the SDK. Your code should depend on slackclient v1, which is no longer maintained. The current recommendation is to use v3, which is available in a bit different PyPI project name - slack_sdk (slack-sdk also works).

Here is the up-to-date document to use the latest RTMClient (please use slack_sdk.rtm.v2 as it's more stable): https://slack.dev/python-slack-sdk/real_time_messaging.html

The way to configure proxy is not in the document (I will update the document later). You can use proxy argument in the constructor as below. Also, HTTPS_PROXY / HTTP_PROXY env variables work for you.

import os
from slack_sdk.rtm.v2 import RTMClient

rtm = RTMClient(
    token=os.environ.get("SLACK_CLASSIC_BOT_TOKEN"),
    proxy="http://your-proxy-domain:9000/", # or "http://user:pass@your-proxy-domain:9000/"
)

I know some developers may have particular reasons to use RTM API but our current recommendation is to use Socket Mode along with Events API. Socket Mode offers more functionalities like handling interactive components and modals and more granular permissions (which is crucial for apps for business operations). Here is the document for Socket Mode client: https://slack.dev/python-slack-sdk/socket-mode/index.html In the same way with RTMClient, you case pass proxy argument (or env variable).

I hope this was helpful to you 馃憢

Thanks! I'm starting use Socket Mode. But i get stucked and can't understand how retrieve data that i get from slack when some event occurs, can you help with that pls?
For example, from Slack i get this string:

"Unhandled request ({'token': '2oXzB3W1OY2m7ZSHjxUyauVU', 'team_id': 'T01KL149WNB', 'api_app_id': 'A01LC1RAMGA', 'event': {'client_msg_id': '770acd47-249c-4a06-bf06-a7614d9bb841', 'type': 'message', 'text': 'TEST TEXT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!', 'user': 'U01L10HG1NF', 'ts': '1614519507.002800', 'team': 'T01KL149WNB', 'blocks': [{'type': 'rich_text', 'block_id': '+PBV', 'elements': [{'type': 'rich_text_section', 'elements': [{'type': 'text', 'text': 'TEST TEXT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!'}]}]}], 'channel': 'C01L8TGMNMT', 'event_ts': '1614519507.002800', 'channel_type': 'channel'}, 'type': 'event_callback', 'event_id': 'Ev01P6KVMN6B', 'event_time': 1614519507, 'authorizations': [{'enterprise_id': None, 'team_id': 'T01KL149WNB', 'user_id': 'U01L10HG1NF', 'is_bot': False, 'is_enterprise_install': False}], 'is_ext_shared_channel': False, 'event_context': '1-message-T01KL149WNB-C01L8TGMNMT'})"

@vv-grinko

Unhandled request

Probably, you're using Bolt for Python. You can handle this message in either of the following ways. Unlike other app listeners, Bolt automatically calls ack() method under the hood.

@app.message("TEST")
def handle_test_message(body, logger):
    logger.info(body)

@app.event("message")
def handle_all_message_events(body, logger):
    logger.info(body)

Also, you can find many examples under the examples directory. Any app listeners in the code snippets work for Socket Mode without any changes. Search by app.event or app.message in the directory for more examples.

I don't think you prefer this way but if you would like to use the underlying SocketModeClient, acknowledging requests would be like this: https://github.com/slackapi/python-slack-sdk/blob/v3.4.0/integration_tests/samples/socket_mode/builtin_proxy_example.py#L34-L35

As I've provided an answer to the proxy question here, let me close this issue now. If you have further questions about Socket Mode or Bolt in general, more folks can help you at the community Slack workspace. If you are not in the workspace, you can join from this URL.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

schlegelp picture schlegelp  路  3Comments

naveenjafer picture naveenjafer  路  4Comments

divyatman picture divyatman  路  4Comments

seratch picture seratch  路  3Comments

sushiparlour picture sushiparlour  路  5Comments