I have to subscribe to cometD Salesforce channel and hence building cometD client in python. I am using the below python library.
https://github.com/dkmadigan/python-bayeux-client
And below is the handshake response I am getting
{'Host': ['xxxxx.my.salesforce.com/cometd/42.0/'], 'Content-Type': ['application/x-www-form-urlencoded'], 'Authorization': ['admin@123Pi6s9Y2QVergfergregpqqY']} message={"channel":"/meta/handshake","id":"1",
"supportedConnectionTypes":["callback-polling", "long-polling"],
"version":"1.0","minimumVersion":"1.0"} Headers({'host': ['xxxxx.my.salesforce.com/cometd/42.0/'], 'content-type': ['application/x-www-form-urlencoded'], 'authorization': ['admin@123Pi6s9Y2QVergfergregpqqY']}) {u'successful': False, u'advice': {u'reconnect': u'none'}, u'ext': {u'replay': True, u'sfdc': {u'failureReason': u'401::Request requires authentication'}, u'payload.format': True}, u'error': u'403::Handshake denied', u'id': u'1', u'channel': u'/meta/handshake'}
And I am getting 401::Request requires authentication.
In the Authorization key, I have concatenated password and Access token i.e. admin@123Pi6s9Y2QVergfergregpqqY where admin@123 is the password I use to login to Salesforce.
I have been banging my head since 2 days but not able to figure out why handshake is failing. Any suggestions?
I believe that the authorization key is incorrect. It is not your password that is expected but an OAuth access token or session id that you receive after you log into salesforce. See the different OAuth flows, if you are testing you can use the username password flow.
The following method u can use to get the session id when needed
import requests
import json
LOGIN_INSTANCE_URL = 'https://test.salesforce.com/services/oauth2/token'
LOGIN_USER_NAME = 'username_here'
CLIENT_ID = 'connected app consumer key'
CLIENT_SECRET = 'connected app consumer secret'
PASSWORD = 'password token'
def connect(authUrl, clientId, secret, username, password):
headers = {
}
postBody = {
'grant_type': 'password',
'client_id': clientId,
'client_secret':secret,
'username': username,
'password': password
}
try:
response = requests.post(authUrl, data = postBody, headers = headers)
#response.raise_for_status()
if (response.status_code == 200):
authResponse = response.json()
return authResponse['access_token']
else: #if not 200 see what the problem was
print response.text
except requests.exceptions.RequestException as e:
print e
print(connect(LOGIN_INSTANCE_URL, CLIENT_ID, CLIENT_SECRET, LOGIN_USER_NAME, PASSWORD))
This is just sample code that should work, but you need to create a connected app first. for stand alone app without user intervention JWT flow is better.