salespyforce 1.4.0.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- salespyforce/__init__.py +53 -0
- salespyforce/api.py +129 -0
- salespyforce/chatter.py +167 -0
- salespyforce/core.py +872 -0
- salespyforce/errors/__init__.py +12 -0
- salespyforce/errors/exceptions.py +389 -0
- salespyforce/errors/handlers.py +15 -0
- salespyforce/knowledge.py +531 -0
- salespyforce/utils/__init__.py +10 -0
- salespyforce/utils/core_utils.py +152 -0
- salespyforce/utils/helper.py +140 -0
- salespyforce/utils/log_utils.py +264 -0
- salespyforce/utils/tests/__init__.py +8 -0
- salespyforce/utils/tests/resources.py +157 -0
- salespyforce/utils/tests/test_instantiate_object.py +49 -0
- salespyforce/utils/tests/test_sobjects.py +58 -0
- salespyforce/utils/tests/test_soql.py +23 -0
- salespyforce/utils/tests/test_sosl.py +29 -0
- salespyforce/utils/version.py +52 -0
- salespyforce-1.4.0.dev0.dist-info/LICENSE +21 -0
- salespyforce-1.4.0.dev0.dist-info/METADATA +253 -0
- salespyforce-1.4.0.dev0.dist-info/RECORD +23 -0
- salespyforce-1.4.0.dev0.dist-info/WHEEL +4 -0
salespyforce/core.py
ADDED
|
@@ -0,0 +1,872 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
:Module: salespyforce.core
|
|
4
|
+
:Synopsis: This module performs the core Salesforce-related operations
|
|
5
|
+
:Usage: ``from salespyforce import Salesforce``
|
|
6
|
+
:Example: ``sfdc = Salesforce(helper=helper_file_path)``
|
|
7
|
+
:Created By: Jeff Shurtliff
|
|
8
|
+
:Last Modified: Jeff Shurtliff
|
|
9
|
+
:Modified Date: 17 Nov 2025
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import re
|
|
13
|
+
|
|
14
|
+
import requests
|
|
15
|
+
|
|
16
|
+
from . import api, errors
|
|
17
|
+
from . import chatter as chatter_module
|
|
18
|
+
from . import knowledge as knowledge_module
|
|
19
|
+
from .utils import core_utils, log_utils
|
|
20
|
+
from .utils.helper import get_helper_settings
|
|
21
|
+
|
|
22
|
+
# Define constants
|
|
23
|
+
FALLBACK_SFDC_API_VERSION = '65.0' # Used if querying the org for the version fails
|
|
24
|
+
|
|
25
|
+
# Initialize logging
|
|
26
|
+
logger = log_utils.initialize_logging(__name__)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class Salesforce(object):
|
|
30
|
+
"""This is the class for the core object leveraged in this module."""
|
|
31
|
+
# Define the function that initializes the object instance (i.e. instantiates the object)
|
|
32
|
+
def __init__(self, connection_info=None, version=None, base_url=None, org_id=None, username=None,
|
|
33
|
+
password=None, endpoint_url=None, client_id=None, client_secret=None, security_token=None, helper=None):
|
|
34
|
+
"""This method instantiates the core Salesforce object.
|
|
35
|
+
|
|
36
|
+
.. version-changed:: 1.4.0
|
|
37
|
+
The authorized Salesforce org is now queried to determine the latest API version to leverage unless
|
|
38
|
+
explicitly defined with the ``version`` parameter when instantiating the object.
|
|
39
|
+
|
|
40
|
+
:param connection_info: The information for connecting to the Salesforce instance
|
|
41
|
+
:type connection_info: dict, None
|
|
42
|
+
:param version: The Salesforce API version to utilize (uses latest version from org if not explicitly defined)
|
|
43
|
+
:type version: str, None
|
|
44
|
+
:param base_url: The base URL of the Salesforce instance
|
|
45
|
+
:type base_url: str, None
|
|
46
|
+
:param org_id: The Org ID of the Salesforce instance
|
|
47
|
+
:type org_id: str, None
|
|
48
|
+
:param username: The username of the API user
|
|
49
|
+
:type username: str, None
|
|
50
|
+
:param password: The password of the API user
|
|
51
|
+
:type password: str, None
|
|
52
|
+
:param endpoint_url: The endpoint URL for the Salesforce instance
|
|
53
|
+
:type endpoint_url: str, None
|
|
54
|
+
:param client_id: The Client ID for the Salesforce instance
|
|
55
|
+
:type client_id: str, None
|
|
56
|
+
:param client_secret: The Client Secret for the Salesforce instance
|
|
57
|
+
:type client_secret: str, None
|
|
58
|
+
:param security_token: The Security Token for the Salesforce instance
|
|
59
|
+
:type security_token: str, None
|
|
60
|
+
:param helper: The file path of a helper file
|
|
61
|
+
:type helper: str, None
|
|
62
|
+
:returns: The instantiated object
|
|
63
|
+
:raises: :py:exc:`TypeError`
|
|
64
|
+
"""
|
|
65
|
+
# Define the default settings
|
|
66
|
+
self._helper_settings = {}
|
|
67
|
+
|
|
68
|
+
# Check for provided connection info
|
|
69
|
+
if connection_info is None:
|
|
70
|
+
# Check for a supplied helper file
|
|
71
|
+
if helper:
|
|
72
|
+
# Parse the helper file contents
|
|
73
|
+
self.helper_path = helper
|
|
74
|
+
if any((isinstance(helper, tuple), isinstance(helper, list), isinstance(helper, set))):
|
|
75
|
+
helper_file_path, helper_file_type = helper
|
|
76
|
+
elif isinstance(helper, str):
|
|
77
|
+
helper_file_path, helper_file_type = (helper, 'yaml')
|
|
78
|
+
elif isinstance(helper, dict):
|
|
79
|
+
helper_file_path, helper_file_type = helper.values()
|
|
80
|
+
else:
|
|
81
|
+
error_msg = "The 'helper' argument can only be supplied as tuple, string, list, set or dict."
|
|
82
|
+
logger.error(error_msg)
|
|
83
|
+
raise TypeError(error_msg)
|
|
84
|
+
self._helper_settings = get_helper_settings(helper_file_path, helper_file_type)
|
|
85
|
+
connection_info = self._parse_helper_connection_info()
|
|
86
|
+
elif not any((base_url, org_id, username, password, endpoint_url, client_id, client_secret, security_token)):
|
|
87
|
+
# Prompt for the connection info if not defined
|
|
88
|
+
connection_info = define_connection_info()
|
|
89
|
+
else:
|
|
90
|
+
# Compile the connection info from the provided parameters
|
|
91
|
+
connection_info = compile_connection_info(base_url, org_id, username, password, endpoint_url,
|
|
92
|
+
client_id, client_secret, security_token)
|
|
93
|
+
|
|
94
|
+
# Get the connection information used to connect to the instance
|
|
95
|
+
self.connection_info = connection_info if connection_info is not None else self._get_empty_connection_info()
|
|
96
|
+
|
|
97
|
+
# Define the base URL value
|
|
98
|
+
self.base_url = self.connection_info.get('base_url')
|
|
99
|
+
|
|
100
|
+
# Define the connection response data variables
|
|
101
|
+
auth_response = self.connect()
|
|
102
|
+
self.access_token = auth_response.get('access_token')
|
|
103
|
+
self.instance_url = auth_response.get('instance_url')
|
|
104
|
+
self.signature = auth_response.get('signature')
|
|
105
|
+
|
|
106
|
+
# Define the version with explicitly provided version or by querying the Salesforce org
|
|
107
|
+
self.version = f'v{version}' if version else f'v{self.get_latest_api_version()}'
|
|
108
|
+
|
|
109
|
+
# Import inner object classes so their methods can be called from the primary object
|
|
110
|
+
self.chatter = self._import_chatter_class()
|
|
111
|
+
self.knowledge = self._import_knowledge_class()
|
|
112
|
+
|
|
113
|
+
def _import_chatter_class(self):
|
|
114
|
+
"""This method allows the :py:class:`salespyforce.core.Salesforce.Chatter` class to be utilized in the core object."""
|
|
115
|
+
return Salesforce.Chatter(self)
|
|
116
|
+
|
|
117
|
+
def _import_knowledge_class(self):
|
|
118
|
+
"""This method allows the :py:class:`salespyforce.core.Salesforce.Knowledge` class to be utilized in the core object."""
|
|
119
|
+
return Salesforce.Knowledge(self)
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
def _get_empty_connection_info():
|
|
123
|
+
"""This method returns an empty connection_info dictionary with all blank values."""
|
|
124
|
+
_connection_info = {}
|
|
125
|
+
_fields = ['username', 'password', 'base_url', 'endpoint_url',
|
|
126
|
+
'client_key', 'client_secret', 'org_id', 'security_token']
|
|
127
|
+
for _field in _fields:
|
|
128
|
+
_connection_info[_field] = ''
|
|
129
|
+
return _connection_info
|
|
130
|
+
|
|
131
|
+
def _parse_helper_connection_info(self):
|
|
132
|
+
"""This method parses the helper content to populate the connection info."""
|
|
133
|
+
_connection_info = {}
|
|
134
|
+
_fields = ['username', 'password', 'base_url', 'endpoint_url',
|
|
135
|
+
'client_key', 'client_secret', 'org_id', 'security_token']
|
|
136
|
+
for _field in _fields:
|
|
137
|
+
if _field in self._helper_settings['connection']:
|
|
138
|
+
_connection_info[_field] = self._helper_settings['connection'][_field]
|
|
139
|
+
return _connection_info
|
|
140
|
+
|
|
141
|
+
def _get_headers(self, _header_type='default'):
|
|
142
|
+
"""This method returns the appropriate HTTP headers to use for different types of API calls."""
|
|
143
|
+
return api._get_headers(_access_token=self.access_token, _header_type=_header_type)
|
|
144
|
+
|
|
145
|
+
def connect(self):
|
|
146
|
+
"""This method connects to the Salesforce instance to obtain the access token.
|
|
147
|
+
(`Reference <https://jereze.com/code/authentification-salesforce-rest-api-python/>`_)
|
|
148
|
+
|
|
149
|
+
:returns: The API call response with the authorization information
|
|
150
|
+
"""
|
|
151
|
+
params = {
|
|
152
|
+
'grant_type': 'password',
|
|
153
|
+
'client_id': self.connection_info.get('client_key'),
|
|
154
|
+
'client_secret': self.connection_info.get('client_secret'),
|
|
155
|
+
'username': self.connection_info.get('username'),
|
|
156
|
+
'password': f'{self.connection_info.get("password")}{self.connection_info.get("security_token")}'
|
|
157
|
+
}
|
|
158
|
+
response = requests.post(self.connection_info.get('endpoint_url'), params=params)
|
|
159
|
+
if response.status_code != 200:
|
|
160
|
+
raise RuntimeError(f'Failed to connect to the Salesforce instance.\n{response.text}')
|
|
161
|
+
return response.json()
|
|
162
|
+
|
|
163
|
+
def get(self, endpoint, params=None, headers=None, timeout=30, show_full_error=True, return_json=True):
|
|
164
|
+
"""This method performs a GET request against the Salesforce instance.
|
|
165
|
+
(`Reference <https://jereze.com/code/authentification-salesforce-rest-api-python/>`_)
|
|
166
|
+
|
|
167
|
+
:param endpoint: The API endpoint to query
|
|
168
|
+
:type endpoint: str
|
|
169
|
+
:param params: The query parameters (where applicable)
|
|
170
|
+
:type params: dict, None
|
|
171
|
+
:param headers: Specific API headers to use when performing the API call
|
|
172
|
+
:type headers: dict, None
|
|
173
|
+
:param timeout: The timeout period in seconds (defaults to ``30``)
|
|
174
|
+
:type timeout: int, str, None
|
|
175
|
+
:param show_full_error: Determines if the full error message should be displayed (defaults to ``True``)
|
|
176
|
+
:type show_full_error: bool
|
|
177
|
+
:param return_json: Determines if the response should be returned in JSON format (defaults to ``True``)
|
|
178
|
+
:returns: The API response in JSON format or as a ``requests`` object
|
|
179
|
+
"""
|
|
180
|
+
return api.get(self, endpoint=endpoint, params=params, headers=headers, timeout=timeout,
|
|
181
|
+
show_full_error=show_full_error, return_json=return_json)
|
|
182
|
+
|
|
183
|
+
def api_call_with_payload(self, method, endpoint, payload, params=None, headers=None, timeout=30,
|
|
184
|
+
show_full_error=True, return_json=True):
|
|
185
|
+
"""This method performs a POST call against the Salesforce instance.
|
|
186
|
+
(`Reference <https://jereze.com/code/authentification-salesforce-rest-api-python/>`_)
|
|
187
|
+
|
|
188
|
+
:param method: The API method (``post``, ``put``, or ``patch``)
|
|
189
|
+
:type method: str
|
|
190
|
+
:param endpoint: The API endpoint to query
|
|
191
|
+
:type endpoint: str
|
|
192
|
+
:param payload: The payload to leverage in the API call
|
|
193
|
+
:type payload: dict
|
|
194
|
+
:param params: The query parameters (where applicable)
|
|
195
|
+
:type params: dict, None
|
|
196
|
+
:param headers: Specific API headers to use when performing the API call
|
|
197
|
+
:type headers: dict, None
|
|
198
|
+
:param timeout: The timeout period in seconds (defaults to ``30``)
|
|
199
|
+
:type timeout: int, str, None
|
|
200
|
+
:param show_full_error: Determines if the full error message should be displayed (defaults to ``True``)
|
|
201
|
+
:type show_full_error: bool
|
|
202
|
+
:param return_json: Determines if the response should be returned in JSON format (defaults to ``True``)
|
|
203
|
+
:returns: The API response in JSON format or as a ``requests`` object
|
|
204
|
+
"""
|
|
205
|
+
return api.api_call_with_payload(self, method=method, endpoint=endpoint, payload=payload, params=params,
|
|
206
|
+
headers=headers, timeout=timeout, show_full_error=show_full_error,
|
|
207
|
+
return_json=return_json)
|
|
208
|
+
|
|
209
|
+
def post(self, endpoint, payload, params=None, headers=None, timeout=30, show_full_error=True, return_json=True):
|
|
210
|
+
"""This method performs a POST call against the Salesforce instance.
|
|
211
|
+
(`Reference <https://jereze.com/code/authentification-salesforce-rest-api-python/>`_)
|
|
212
|
+
|
|
213
|
+
:param endpoint: The API endpoint to query
|
|
214
|
+
:type endpoint: str
|
|
215
|
+
:param payload: The payload to leverage in the API call
|
|
216
|
+
:type payload: dict
|
|
217
|
+
:param params: The query parameters (where applicable)
|
|
218
|
+
:type params: dict, None
|
|
219
|
+
:param headers: Specific API headers to use when performing the API call
|
|
220
|
+
:type headers: dict, None
|
|
221
|
+
:param timeout: The timeout period in seconds (defaults to ``30``)
|
|
222
|
+
:type timeout: int, str, None
|
|
223
|
+
:param show_full_error: Determines if the full error message should be displayed (defaults to ``True``)
|
|
224
|
+
:type show_full_error: bool
|
|
225
|
+
:param return_json: Determines if the response should be returned in JSON format (defaults to ``True``)
|
|
226
|
+
:returns: The API response in JSON format or as a ``requests`` object
|
|
227
|
+
"""
|
|
228
|
+
return api.api_call_with_payload(self, 'post', endpoint=endpoint, payload=payload, params=params,
|
|
229
|
+
headers=headers, timeout=timeout, show_full_error=show_full_error,
|
|
230
|
+
return_json=return_json)
|
|
231
|
+
|
|
232
|
+
def patch(self, endpoint, payload, params=None, headers=None, timeout=30, show_full_error=True, return_json=False):
|
|
233
|
+
"""This method performs a PATCH call against the Salesforce instance.
|
|
234
|
+
(`Reference <https://jereze.com/code/authentification-salesforce-rest-api-python/>`_)
|
|
235
|
+
|
|
236
|
+
:param endpoint: The API endpoint to query
|
|
237
|
+
:type endpoint: str
|
|
238
|
+
:param payload: The payload to leverage in the API call
|
|
239
|
+
:type payload: dict
|
|
240
|
+
:param params: The query parameters (where applicable)
|
|
241
|
+
:type params: dict, None
|
|
242
|
+
:param headers: Specific API headers to use when performing the API call
|
|
243
|
+
:type headers: dict, None
|
|
244
|
+
:param timeout: The timeout period in seconds (defaults to ``30``)
|
|
245
|
+
:type timeout: int, str, None
|
|
246
|
+
:param show_full_error: Determines if the full error message should be displayed (defaults to ``True``)
|
|
247
|
+
:type show_full_error: bool
|
|
248
|
+
:param return_json: Determines if the response should be returned in JSON format (defaults to ``True``)
|
|
249
|
+
:returns: The API response in JSON format or as a ``requests`` object
|
|
250
|
+
"""
|
|
251
|
+
return api.api_call_with_payload(self, 'patch', endpoint=endpoint, payload=payload, params=params,
|
|
252
|
+
headers=headers, timeout=timeout, show_full_error=show_full_error,
|
|
253
|
+
return_json=return_json)
|
|
254
|
+
|
|
255
|
+
def put(self, endpoint, payload, params=None, headers=None, timeout=30, show_full_error=True, return_json=True):
|
|
256
|
+
"""This method performs a PUT call against the Salesforce instance.
|
|
257
|
+
(`Reference <https://jereze.com/code/authentification-salesforce-rest-api-python/>`_)
|
|
258
|
+
|
|
259
|
+
:param endpoint: The API endpoint to query
|
|
260
|
+
:type endpoint: str
|
|
261
|
+
:param payload: The payload to leverage in the API call
|
|
262
|
+
:type payload: dict
|
|
263
|
+
:param params: The query parameters (where applicable)
|
|
264
|
+
:type params: dict, None
|
|
265
|
+
:param headers: Specific API headers to use when performing the API call
|
|
266
|
+
:type headers: dict, None
|
|
267
|
+
:param timeout: The timeout period in seconds (defaults to ``30``)
|
|
268
|
+
:type timeout: int, str, None
|
|
269
|
+
:param show_full_error: Determines if the full error message should be displayed (defaults to ``True``)
|
|
270
|
+
:type show_full_error: bool
|
|
271
|
+
:param return_json: Determines if the response should be returned in JSON format (defaults to ``True``)
|
|
272
|
+
:returns: The API response in JSON format or as a ``requests`` object
|
|
273
|
+
"""
|
|
274
|
+
return api.api_call_with_payload(self, 'put', endpoint=endpoint, payload=payload, params=params,
|
|
275
|
+
headers=headers, timeout=timeout, show_full_error=show_full_error,
|
|
276
|
+
return_json=return_json)
|
|
277
|
+
|
|
278
|
+
def get_api_versions(self) -> list:
|
|
279
|
+
"""This method returns the API versions for the Salesforce releases.
|
|
280
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_versions.htm>`_)
|
|
281
|
+
|
|
282
|
+
:returns: A list containing the API metadata from the ``/services/data`` endpoint.
|
|
283
|
+
"""
|
|
284
|
+
return self.get('/services/data')
|
|
285
|
+
|
|
286
|
+
def get_latest_api_version(self) -> str:
|
|
287
|
+
"""This method returns the latest Salesforce API version by querying the authorized org.
|
|
288
|
+
|
|
289
|
+
.. version-added:: 1.4.0
|
|
290
|
+
|
|
291
|
+
:returns: The latest Salesforce API version for the authorized org as a string (e.g. ``65.0``)
|
|
292
|
+
"""
|
|
293
|
+
versions = self.get_api_versions()
|
|
294
|
+
try:
|
|
295
|
+
latest_version = versions[-1]['version']
|
|
296
|
+
except Exception as exc:
|
|
297
|
+
exc_type = type(exc).__name__
|
|
298
|
+
logger.warning(
|
|
299
|
+
f"Failed to retrieve API version due to a(n) {exc_type} exception; defaulting to "
|
|
300
|
+
f"the fallback version {FALLBACK_SFDC_API_VERSION}"
|
|
301
|
+
)
|
|
302
|
+
latest_version = FALLBACK_SFDC_API_VERSION
|
|
303
|
+
return latest_version
|
|
304
|
+
|
|
305
|
+
def get_org_limits(self):
|
|
306
|
+
"""This method returns a list of all org limits.
|
|
307
|
+
|
|
308
|
+
.. versionadded:: 1.1.0
|
|
309
|
+
"""
|
|
310
|
+
return self.get(f'/services/data/{self.version}/limits')
|
|
311
|
+
|
|
312
|
+
def get_all_sobjects(self):
|
|
313
|
+
"""This method returns a list of all Salesforce objects. (i.e. sObjects)
|
|
314
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_describeGlobal.htm>`_)
|
|
315
|
+
"""
|
|
316
|
+
return self.get(f'/services/data/{self.version}/sobjects')
|
|
317
|
+
|
|
318
|
+
def get_sobject(self, object_name, describe=False):
|
|
319
|
+
"""This method returns basic information or the full (describe) information for a specific sObject.
|
|
320
|
+
(`Reference 1 <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_sobject_basic_info_get.htm>`_,
|
|
321
|
+
`Reference 2 <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_sobject_describe.htm>`_)
|
|
322
|
+
|
|
323
|
+
:param object_name: The name of the Salesforce object
|
|
324
|
+
:type object_name: str
|
|
325
|
+
:param describe: Determines if the full (i.e. ``describe``) data should be returned (defaults to ``False``)
|
|
326
|
+
:type describe: bool
|
|
327
|
+
:returns: The Salesforce object data
|
|
328
|
+
"""
|
|
329
|
+
uri = f'/services/data/{self.version}/sobjects/{object_name}'
|
|
330
|
+
uri = f'{uri}/describe' if describe else uri
|
|
331
|
+
return self.get(uri)
|
|
332
|
+
|
|
333
|
+
def describe_object(self, object_name):
|
|
334
|
+
"""This method returns the full (describe) information for a specific sObject.
|
|
335
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_sobject_describe.htm>`_)
|
|
336
|
+
|
|
337
|
+
:param object_name: The name of the Salesforce object
|
|
338
|
+
:type object_name: str
|
|
339
|
+
:returns: The Salesforce object data
|
|
340
|
+
"""
|
|
341
|
+
return self.get_sobject(object_name, describe=True)
|
|
342
|
+
|
|
343
|
+
def get_rest_resources(self):
|
|
344
|
+
"""This method returns a list of all available REST resources.
|
|
345
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_discoveryresource.htm>`_)
|
|
346
|
+
"""
|
|
347
|
+
return self.get(f'/services/data/{self.version}')
|
|
348
|
+
|
|
349
|
+
def soql_query(self, query, replace_quotes=True, next_records_url=False):
|
|
350
|
+
"""This method performs a SOQL query and returns the results in JSON format.
|
|
351
|
+
(`Reference 1 <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_query.htm>`_,
|
|
352
|
+
`Reference 2 <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_development_soql_sosl_intro.htm>`_)
|
|
353
|
+
|
|
354
|
+
:param query: The SOQL query to perform
|
|
355
|
+
:type query: str
|
|
356
|
+
:param replace_quotes: Determines if double-quotes should be replaced with single-quotes (``True`` by default)
|
|
357
|
+
:type replace_quotes: bool
|
|
358
|
+
:param next_records_url: Indicates that the ``query`` parameter is a ``nextRecordsUrl`` value.
|
|
359
|
+
:type next_records_url: bool
|
|
360
|
+
:returns: The result of the SOQL query
|
|
361
|
+
"""
|
|
362
|
+
if next_records_url:
|
|
363
|
+
query = re.sub(r'^.*/', '', query) if '/' in query else query
|
|
364
|
+
else:
|
|
365
|
+
if replace_quotes:
|
|
366
|
+
query = query.replace('"', "'")
|
|
367
|
+
query = core_utils.url_encode(query)
|
|
368
|
+
query = f'?q={query}'
|
|
369
|
+
return self.get(f'/services/data/{self.version}/query/{query}')
|
|
370
|
+
|
|
371
|
+
def search_string(self, string_to_search):
|
|
372
|
+
"""This method performs a SOSL query to search for a given string.
|
|
373
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_search.htm>`_)
|
|
374
|
+
|
|
375
|
+
.. versionadded:: 1.1.0
|
|
376
|
+
|
|
377
|
+
:param string_to_search: The string for which to search
|
|
378
|
+
:type string_to_search: str
|
|
379
|
+
:returns: The SOSL response data in JSON format
|
|
380
|
+
"""
|
|
381
|
+
query = 'FIND {' + string_to_search + '}'
|
|
382
|
+
query = core_utils.url_encode(query)
|
|
383
|
+
return self.get(f'/services/data/{self.version}/search/?q={query}')
|
|
384
|
+
|
|
385
|
+
def create_sobject_record(self, sobject, payload):
|
|
386
|
+
"""This method creates a new record for a specific sObject.
|
|
387
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_create.htm>`_)
|
|
388
|
+
|
|
389
|
+
:param sobject: The sObject under which to create the new record
|
|
390
|
+
:type sobject: str
|
|
391
|
+
:param payload: The JSON payload with the record details
|
|
392
|
+
:type payload: dict
|
|
393
|
+
:returns: The API response from the POST request
|
|
394
|
+
:raises: :py:exc:`RuntimeError`, :py:exc:`TypeError`
|
|
395
|
+
"""
|
|
396
|
+
# Ensure the payload is in the appropriate format
|
|
397
|
+
if not isinstance(payload, dict):
|
|
398
|
+
raise TypeError('The sObject payload must be provided as a dictionary.')
|
|
399
|
+
|
|
400
|
+
# Perform the API call and return the response
|
|
401
|
+
response = self.post(f'/services/data/{self.version}/sobjects/{sobject}', payload=payload)
|
|
402
|
+
return response
|
|
403
|
+
|
|
404
|
+
def update_sobject_record(self, sobject, record_id, payload):
|
|
405
|
+
"""This method updates an existing sObject record.
|
|
406
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_update_fields.htm>`_)
|
|
407
|
+
|
|
408
|
+
:param sobject: The sObject under which to update the record
|
|
409
|
+
:type sobject: str
|
|
410
|
+
:param record_id: The ID of the record to be updated
|
|
411
|
+
:type record_id: str
|
|
412
|
+
:param payload: The JSON payload with the record details to be updated
|
|
413
|
+
:type payload: dict
|
|
414
|
+
:returns: The API response from the PATCH request
|
|
415
|
+
:raises: :py:exc:`RuntimeError`, :py:exc:`TypeError`
|
|
416
|
+
"""
|
|
417
|
+
# Ensure the payload is in the appropriate format
|
|
418
|
+
if not isinstance(payload, dict):
|
|
419
|
+
raise TypeError('The sObject payload must be provided as a dictionary.')
|
|
420
|
+
|
|
421
|
+
# Perform the API call and return the response
|
|
422
|
+
response = self.patch(f'/services/data/{self.version}/sobjects/{sobject}/{record_id}', payload=payload)
|
|
423
|
+
return response
|
|
424
|
+
|
|
425
|
+
def download_image(self, image_url, record_id, field_name, file_path=None, sobject=None):
|
|
426
|
+
"""This method downloads an image using the sObject Rich Text Image Retrieve functionality.
|
|
427
|
+
(`Reference 1 <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_sobject_rich_text_image_retrieve.htm>`_,
|
|
428
|
+
`Reference 2 <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_rich_text_image_retrieve.htm>`_)
|
|
429
|
+
|
|
430
|
+
:param image_url: The URL for the image to be downloaded
|
|
431
|
+
:type image_url: str
|
|
432
|
+
:param record_id: The Record ID where the image is found
|
|
433
|
+
:type record_id: str
|
|
434
|
+
:param field_name: The field name within the record where the image is found
|
|
435
|
+
:type field_name: str
|
|
436
|
+
:param file_path: The path to the directory where the image should be saved (current directory if not defined)
|
|
437
|
+
:type file_path: str, None
|
|
438
|
+
:param sobject: The sObject for the record where the image is found (``Knowledge__kav`` by default)
|
|
439
|
+
:type sobject: str
|
|
440
|
+
:returns: The full path to the downloaded image
|
|
441
|
+
:raises: :py:exc:`RuntimeError`
|
|
442
|
+
"""
|
|
443
|
+
# Ensure a valid sObject is defined (SFDC Knowledge unless otherwise specified)
|
|
444
|
+
sobject = 'Knowledge__kav' if not sobject else sobject
|
|
445
|
+
|
|
446
|
+
# Retrieve the reference ID for the image
|
|
447
|
+
ref_id = core_utils.get_image_ref_id(image_url)
|
|
448
|
+
|
|
449
|
+
# Define the URI and perform the API call
|
|
450
|
+
image_path = None
|
|
451
|
+
try:
|
|
452
|
+
uri = f'/services/data/{self.version}/sobjects/{sobject}/{record_id}/richTextImageFields/{field_name}/{ref_id}'
|
|
453
|
+
response = self.get(uri, return_json=False)
|
|
454
|
+
|
|
455
|
+
# Save the image as an image file
|
|
456
|
+
try:
|
|
457
|
+
image_path = core_utils.download_image(file_name=f'{ref_id}.jpeg', file_path=file_path,
|
|
458
|
+
response=response)
|
|
459
|
+
except RuntimeError:
|
|
460
|
+
errors.handlers.eprint(f'Failed to download the image with refid {ref_id}.')
|
|
461
|
+
except RuntimeError as exc:
|
|
462
|
+
errors.handlers.eprint(exc)
|
|
463
|
+
return image_path
|
|
464
|
+
|
|
465
|
+
class Chatter(object):
|
|
466
|
+
"""This class includes methods associated with Salesforce Chatter."""
|
|
467
|
+
def __init__(self, sfdc_object):
|
|
468
|
+
"""This method initializes the :py:class:`salespyforce.core.Salesforce.Chatter` inner class object.
|
|
469
|
+
|
|
470
|
+
:param sfdc_object: The core :py:class:`salespyforce.Salesforce` object
|
|
471
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
472
|
+
"""
|
|
473
|
+
self.sfdc_object = sfdc_object
|
|
474
|
+
|
|
475
|
+
def get_my_news_feed(self, site_id=None):
|
|
476
|
+
"""This method retrieves the news feed for the user calling the function.
|
|
477
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/quickreference_get_news_feed.htm>`_)
|
|
478
|
+
|
|
479
|
+
:param site_id: The ID of an Experience Cloud site against which to query (optional)
|
|
480
|
+
:type site_id: str, None
|
|
481
|
+
:returns: The news feed data
|
|
482
|
+
:raises: :py:exc:`RuntimeError`
|
|
483
|
+
"""
|
|
484
|
+
return chatter_module.get_my_news_feed(self.sfdc_object, site_id=site_id)
|
|
485
|
+
|
|
486
|
+
def get_user_news_feed(self, user_id, site_id=None):
|
|
487
|
+
"""This method retrieves another user's news feed.
|
|
488
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/quickreference_get_user_profile_feed.htm>`_)
|
|
489
|
+
|
|
490
|
+
:param user_id: The ID of the user whose feed you wish to return
|
|
491
|
+
:type user_id: str
|
|
492
|
+
:param site_id: The ID of an Experience Cloud site against which to query (optional)
|
|
493
|
+
:type site_id: str, None
|
|
494
|
+
:returns: The news feed data
|
|
495
|
+
:raises: :py:exc:`RuntimeError`
|
|
496
|
+
"""
|
|
497
|
+
return chatter_module.get_user_news_feed(self.sfdc_object, user_id=user_id, site_id=site_id)
|
|
498
|
+
|
|
499
|
+
def get_group_feed(self, group_id, site_id=None):
|
|
500
|
+
"""This method retrieves a group's news feed.
|
|
501
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/quickreference_get_group_feed.htm>`_)
|
|
502
|
+
|
|
503
|
+
:param group_id: The ID of the group whose feed you wish to return
|
|
504
|
+
:type group_id: str
|
|
505
|
+
:param site_id: The ID of an Experience Cloud site against which to query (optional)
|
|
506
|
+
:type site_id: str, None
|
|
507
|
+
:returns: The news feed data
|
|
508
|
+
:raises: :py:exc:`RuntimeError`
|
|
509
|
+
"""
|
|
510
|
+
return chatter_module.get_group_feed(self.sfdc_object, group_id=group_id, site_id=site_id)
|
|
511
|
+
|
|
512
|
+
def post_feed_item(self, subject_id, message_text=None, message_segments=None, site_id=None, created_by_id=None):
|
|
513
|
+
"""This method publishes a new Chatter feed item.
|
|
514
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/quickreference_post_feed_item.htm>`_)
|
|
515
|
+
|
|
516
|
+
:param subject_id: The Subject ID against which to publish the feed item (e.g. ``0F9B000000000W2``)
|
|
517
|
+
:type subject_id: str
|
|
518
|
+
:param message_text: Plaintext to be used as the message body
|
|
519
|
+
:type message_segments: str, None
|
|
520
|
+
:param message_segments: Collection of message segments to use instead of a plaintext message
|
|
521
|
+
:type message_segments: list, None
|
|
522
|
+
:param site_id: The ID of an Experience Cloud site against which to query (optional)
|
|
523
|
+
:type site_id: str, None
|
|
524
|
+
:param created_by_id: The ID of the user to impersonate (**Experimental**)
|
|
525
|
+
:type created_by_id: str, None
|
|
526
|
+
:returns: The response of the POST request
|
|
527
|
+
:raises: :py:exc:`RuntimeError`
|
|
528
|
+
"""
|
|
529
|
+
return chatter_module.post_feed_item(self.sfdc_object, subject_id=subject_id, message_text=message_text,
|
|
530
|
+
message_segments=message_segments, site_id=site_id,
|
|
531
|
+
created_by_id=created_by_id)
|
|
532
|
+
|
|
533
|
+
def post_comment(self, feed_element_id, message_text=None, message_segments=None, site_id=None, created_by_id=None):
|
|
534
|
+
"""This method publishes a comment on a Chatter feed item.
|
|
535
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/quickreference_post_comment_to_feed_element.htm>`_)
|
|
536
|
+
|
|
537
|
+
:param feed_element_id: The ID of the feed element on which to post the comment
|
|
538
|
+
:type feed_element_id: str
|
|
539
|
+
:param message_text: Plaintext to be used as the message body
|
|
540
|
+
:type message_segments: str, None
|
|
541
|
+
:param message_segments: Collection of message segments to use instead of a plaintext message
|
|
542
|
+
:type message_segments: list, None
|
|
543
|
+
:param site_id: The ID of an Experience Cloud site against which to query (optional)
|
|
544
|
+
:type site_id: str, None
|
|
545
|
+
:param created_by_id: The ID of the user to impersonate (**Experimental**)
|
|
546
|
+
:type created_by_id: str, None
|
|
547
|
+
:returns: The response of the POST request
|
|
548
|
+
:raises: :py:exc:`RuntimeError`
|
|
549
|
+
"""
|
|
550
|
+
return chatter_module.post_comment(self.sfdc_object, feed_element_id=feed_element_id,
|
|
551
|
+
message_text=message_text, message_segments=message_segments,
|
|
552
|
+
site_id=site_id, created_by_id=created_by_id)
|
|
553
|
+
|
|
554
|
+
class Knowledge(object):
|
|
555
|
+
"""This class includes methods associated with Salesforce Knowledge."""
|
|
556
|
+
def __init__(self, sfdc_object):
|
|
557
|
+
"""This method initializes the :py:class:`salespyforce.core.Salesforce.Knowledge` inner class object.
|
|
558
|
+
|
|
559
|
+
:param sfdc_object: The core :py:class:`salespyforce.Salesforce` object
|
|
560
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
561
|
+
"""
|
|
562
|
+
self.sfdc_object = sfdc_object
|
|
563
|
+
|
|
564
|
+
def check_for_existing_article(self, title, sobject=None, return_id=False, return_id_and_number=False,
|
|
565
|
+
include_archived=False):
|
|
566
|
+
"""This method checks to see if an article already exists with a given title and returns its article number.
|
|
567
|
+
(`Reference 1 <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_query.htm>`_.
|
|
568
|
+
`Reference 2 <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_development_soql_sosl_intro.htm>`_)
|
|
569
|
+
|
|
570
|
+
:param title: The title of the knowledge article for which to check
|
|
571
|
+
:type title: str
|
|
572
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
573
|
+
:type sobject: str, None
|
|
574
|
+
:param return_id: Determines if the Article ID should be returned (``False`` by default)
|
|
575
|
+
:type return_id: bool
|
|
576
|
+
:param return_id_and_number: Determines if Article ID and Article Number should be returned (``False`` by default)
|
|
577
|
+
:type return_id_and_number: bool
|
|
578
|
+
:param include_archived: Determines if archived articles should be included (``False`` by default)
|
|
579
|
+
:type include_archived: bool
|
|
580
|
+
:returns: The Article Number, Article ID, or both, if found, or a blank string if not found
|
|
581
|
+
"""
|
|
582
|
+
return knowledge_module.check_for_existing_article(self.sfdc_object, title=title,
|
|
583
|
+
sobject=sobject, return_id=return_id,
|
|
584
|
+
return_id_and_number=return_id_and_number,
|
|
585
|
+
include_archived=include_archived)
|
|
586
|
+
|
|
587
|
+
def get_article_id_from_number(self, article_number, sobject=None, return_uri=False):
|
|
588
|
+
"""This method returns the Article ID when an article number is provided.
|
|
589
|
+
(`Reference 1 <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_query.htm>`_,
|
|
590
|
+
`Reference 2 <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_development_soql_sosl_intro.htm>`_)
|
|
591
|
+
|
|
592
|
+
:param article_number: The Article Number to query
|
|
593
|
+
:type article_number: str, int
|
|
594
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
595
|
+
:type sobject: str, None
|
|
596
|
+
:param return_uri: Determines if the URI of the article should be returned rather than the ID (``False`` by default)
|
|
597
|
+
:type return_uri: bool
|
|
598
|
+
:returns: The Article ID or Article URI, or a blank string if no article is found
|
|
599
|
+
:raises: :py:exc:`ValueError`
|
|
600
|
+
"""
|
|
601
|
+
return knowledge_module.get_article_id_from_number(self.sfdc_object, article_number=article_number,
|
|
602
|
+
sobject=sobject, return_uri=return_uri)
|
|
603
|
+
|
|
604
|
+
def get_articles_list(self, query=None, sort=None, order=None, page_size=20, page_num=1):
|
|
605
|
+
"""This method retrieves a list of knowledge articles.
|
|
606
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_knowledge_support_artlist.htm>`_)
|
|
607
|
+
|
|
608
|
+
:param query: A SOQL query with which to filter the results (optional)
|
|
609
|
+
:type query: str, None
|
|
610
|
+
:param sort: One of the following optional values: ``LastPublishedDate``, ``CreatedDate``, ``Title``, or ``ViewScore``
|
|
611
|
+
:type sort: str, None
|
|
612
|
+
:param order: Optionally define the ORDER BY as ``ASC`` or ``DESC``
|
|
613
|
+
:type order: str, None
|
|
614
|
+
:param page_size: The number of results per page (``20`` by default)
|
|
615
|
+
:type page_size: int
|
|
616
|
+
:param page_num: The starting page number (``1`` by default)
|
|
617
|
+
:type page_num: int
|
|
618
|
+
:returns: The list of retrieved knowledge articles
|
|
619
|
+
"""
|
|
620
|
+
return knowledge_module.get_articles_list(self.sfdc_object, query=query, sort=sort, order=order,
|
|
621
|
+
page_size=page_size, page_num=page_num)
|
|
622
|
+
|
|
623
|
+
def get_article_details(self, article_id, sobject=None):
|
|
624
|
+
"""This method retrieves details for a single knowledge article.
|
|
625
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_knowledge_support_artdetails.htm>`_)
|
|
626
|
+
|
|
627
|
+
:param article_id: The Article ID for which to retrieve details
|
|
628
|
+
:type article_id: str
|
|
629
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
630
|
+
:type sobject: str, None
|
|
631
|
+
:returns: The details for the knowledge article
|
|
632
|
+
"""
|
|
633
|
+
return knowledge_module.get_article_details(self.sfdc_object, article_id=article_id, sobject=sobject)
|
|
634
|
+
|
|
635
|
+
def get_validation_status(self, article_id=None, article_details=None, sobject=None):
|
|
636
|
+
"""This method retrieves the Validation Status for a given Article ID.
|
|
637
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_knowledge_support_artdetails.htm>`_)
|
|
638
|
+
|
|
639
|
+
:param article_id: The Article ID for which to retrieve details
|
|
640
|
+
:type article_id: str, None
|
|
641
|
+
:param article_details: The dictionary of article details for the given article
|
|
642
|
+
:type article_details: dict, None
|
|
643
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
644
|
+
:type sobject: str, None
|
|
645
|
+
:returns: The validation status as a text string
|
|
646
|
+
:raises: :py:exc:`RuntimeError`
|
|
647
|
+
"""
|
|
648
|
+
return knowledge_module.get_validation_status(self.sfdc_object, article_id=article_id,
|
|
649
|
+
article_details=article_details, sobject=sobject)
|
|
650
|
+
|
|
651
|
+
def get_article_metadata(self, article_id):
|
|
652
|
+
"""This method retrieves metadata for a specific knowledge article.
|
|
653
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_REST_retrieve_article_metadata.htm>`_)
|
|
654
|
+
|
|
655
|
+
:param article_id: The Article ID for which to retrieve details
|
|
656
|
+
:type article_id: str
|
|
657
|
+
:returns: The article metadata as a dictionary
|
|
658
|
+
:raises: :py:exc:`RuntimeError`
|
|
659
|
+
"""
|
|
660
|
+
return knowledge_module.get_article_metadata(self.sfdc_object, article_id=article_id)
|
|
661
|
+
|
|
662
|
+
def get_article_version(self, article_id):
|
|
663
|
+
"""This method retrieves the version ID for a given master article ID.
|
|
664
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_REST_retrieve_article_version.htm>`_)
|
|
665
|
+
|
|
666
|
+
:param article_id: The Article ID for which to retrieve details
|
|
667
|
+
:type article_id: str
|
|
668
|
+
:returns: The version ID for the given master article ID
|
|
669
|
+
:raises: :py:exc:`RuntimeError`
|
|
670
|
+
"""
|
|
671
|
+
return knowledge_module.get_article_version(self.sfdc_object, article_id=article_id)
|
|
672
|
+
|
|
673
|
+
def get_article_url(self, article_id=None, article_number=None, sobject=None):
|
|
674
|
+
"""This function constructs the URL to view a knowledge article in Lightning or Classic.
|
|
675
|
+
|
|
676
|
+
:param article_id: The Article ID for which to retrieve details
|
|
677
|
+
:type article_id: str, None
|
|
678
|
+
:param article_number: The article number for which to retrieve details
|
|
679
|
+
:type article_number: str, int, None
|
|
680
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
681
|
+
:type sobject: str, None
|
|
682
|
+
:returns: The article URL as a string
|
|
683
|
+
:raises: :py:exc:`ValueError`
|
|
684
|
+
"""
|
|
685
|
+
return knowledge_module.get_article_url(self.sfdc_object, article_id=article_id,
|
|
686
|
+
article_number=article_number, sobject=sobject)
|
|
687
|
+
|
|
688
|
+
def create_article(self, article_data, sobject=None, full_response=False):
|
|
689
|
+
"""This method creates a new knowledge article draft.
|
|
690
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_create.htm>`_)
|
|
691
|
+
|
|
692
|
+
:param article_data: The article data used to populate the article
|
|
693
|
+
:type article_data: dict
|
|
694
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
695
|
+
:type sobject: str, None
|
|
696
|
+
:param full_response: Determines if the full API response should be returned instead of the article ID (``False`` by default)
|
|
697
|
+
:type full_response: bool
|
|
698
|
+
:returns: The API response or the ID of the article draft
|
|
699
|
+
:raises: :py:exc:`ValueError`, :py:exc:`TypeError`
|
|
700
|
+
"""
|
|
701
|
+
return knowledge_module.create_article(self.sfdc_object, article_data=article_data, sobject=sobject,
|
|
702
|
+
full_response=full_response)
|
|
703
|
+
|
|
704
|
+
def update_article(self, record_id, article_data, sobject=None, include_status_code=False):
|
|
705
|
+
"""This method updates an existing knowledge article draft.
|
|
706
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_update_fields.htm>`_)
|
|
707
|
+
|
|
708
|
+
:param record_id: The ID of the article draft record to be updated
|
|
709
|
+
:type record_id: str
|
|
710
|
+
:param article_data: The article data used to update the article
|
|
711
|
+
:type article_data: dict
|
|
712
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
713
|
+
:type sobject: str, None
|
|
714
|
+
:param include_status_code: Determines if the API response status code should be returned (``False`` by default)
|
|
715
|
+
:type include_status_code: bool
|
|
716
|
+
:returns: A Boolean indicating if the update operation was successful, and optionally the API response status code
|
|
717
|
+
:raises: :py:exc:`ValueError`, :py:exc:`TypeError`, :py:exc:`RuntimeError`
|
|
718
|
+
"""
|
|
719
|
+
return knowledge_module.update_article(self.sfdc_object, record_id=record_id, article_data=article_data,
|
|
720
|
+
sobject=sobject, include_status_code=include_status_code)
|
|
721
|
+
|
|
722
|
+
def create_draft_from_online_article(self, article_id, unpublish=False):
|
|
723
|
+
"""This method creates a draft knowledge article from an online article.
|
|
724
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/actions_obj_knowledge.htm#createDraftFromOnlineKnowledgeArticle>`_)
|
|
725
|
+
|
|
726
|
+
:param article_id: The ID of the online article from which to create the draft
|
|
727
|
+
:type article_id: str
|
|
728
|
+
:param unpublish: Determines if the online article should be unpublished when the draft is created (``False`` by default)
|
|
729
|
+
:type unpublish: bool
|
|
730
|
+
:returns: The API response from the POST request
|
|
731
|
+
:raises: :py:exc:`RuntimeError`
|
|
732
|
+
"""
|
|
733
|
+
return knowledge_module.create_draft_from_online_article(self.sfdc_object, article_id=article_id,
|
|
734
|
+
unpublish=unpublish)
|
|
735
|
+
|
|
736
|
+
def create_draft_from_master_version(self, article_id=None, knowledge_article_id=None, article_data=None,
|
|
737
|
+
sobject=None, full_response=False):
|
|
738
|
+
"""This method creates an online version of a master article.
|
|
739
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.198.0.knowledge_dev.meta/knowledge_dev/knowledge_REST_edit_online_master.htm>`_)
|
|
740
|
+
|
|
741
|
+
:param article_id: The Article ID from which to create the draft
|
|
742
|
+
:type article_id: str, None
|
|
743
|
+
:param knowledge_article_id: The Knowledge Article ID (``KnowledgeArticleId``) from which to create the draft
|
|
744
|
+
:type knowledge_article_id: str, None
|
|
745
|
+
:param article_data: The article data associated with the article from which to create the draft
|
|
746
|
+
:type article_data: dict, None
|
|
747
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
748
|
+
:type sobject: str, None
|
|
749
|
+
:param full_response: Determines if the full API response should be returned instead of the article ID (``False`` by default)
|
|
750
|
+
:type full_response: bool
|
|
751
|
+
:returns: The API response or the ID of the article draft
|
|
752
|
+
:raises: :py:exc:`RuntimeError`
|
|
753
|
+
"""
|
|
754
|
+
return knowledge_module.create_draft_from_master_version(self.sfdc_object, article_id=article_id,
|
|
755
|
+
knowledge_article_id=knowledge_article_id,
|
|
756
|
+
article_data=article_data, sobject=sobject,
|
|
757
|
+
full_response=full_response)
|
|
758
|
+
|
|
759
|
+
def publish_article(self, article_id, major_version=True, full_response=False):
|
|
760
|
+
"""This method publishes a draft knowledge article as a major or minor version.
|
|
761
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_REST_publish_master_version.htm>`_)
|
|
762
|
+
|
|
763
|
+
:param article_id: The Article ID to publish
|
|
764
|
+
:type article_id: str
|
|
765
|
+
:param major_version: Determines if the published article should be a major version (``True`` by default)
|
|
766
|
+
:type major_version: bool
|
|
767
|
+
:param full_response: Determines if the full API response should be returned (``False`` by default)
|
|
768
|
+
:type full_response: bool
|
|
769
|
+
:returns: A Boolean value indicating the success of the action or the API response from the PATCH request
|
|
770
|
+
:raises: :py:exc:`RuntimeError`
|
|
771
|
+
"""
|
|
772
|
+
return knowledge_module.publish_article(self.sfdc_object, article_id=article_id,
|
|
773
|
+
major_version=major_version, full_response=full_response)
|
|
774
|
+
|
|
775
|
+
def publish_multiple_articles(self, article_id_list, major_version=True):
|
|
776
|
+
"""This method publishes multiple knowledge article drafts at one time.
|
|
777
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/actions_obj_knowledge.htm#publishKnowledgeArticles>`_)
|
|
778
|
+
|
|
779
|
+
:param article_id_list: A list of Article IDs to be published
|
|
780
|
+
:type article_id_list: list
|
|
781
|
+
:param major_version: Determines if the published article should be a major version (``True`` by default)
|
|
782
|
+
:type major_version: bool
|
|
783
|
+
:returns: The API response from the POST request
|
|
784
|
+
:raises: :py:exc:`RuntimeError`, :py:exc:`TypeError`, :py:exc:`ValueError`
|
|
785
|
+
"""
|
|
786
|
+
return knowledge_module.publish_multiple_articles(self.sfdc_object, article_id_list=article_id_list,
|
|
787
|
+
major_version=major_version)
|
|
788
|
+
|
|
789
|
+
def assign_data_category(self, article_id, category_group_name, category_name):
|
|
790
|
+
"""This method assigns a single data category for a knowledge article.
|
|
791
|
+
(`Reference <https://itsmemohit.medium.com/quick-win-15-salesforce-knowledge-rest-apis-bb0725b2040e>`_)
|
|
792
|
+
|
|
793
|
+
.. versionadded:: 1.2.0
|
|
794
|
+
|
|
795
|
+
:param article_id: The ID of the article to update
|
|
796
|
+
:type article_id: str
|
|
797
|
+
:param category_group_name: The unique Data Category Group Name
|
|
798
|
+
:type category_group_name: str
|
|
799
|
+
:param category_name: The unique Data Category Name
|
|
800
|
+
:type category_name: str
|
|
801
|
+
:returns: The API response from the POST request
|
|
802
|
+
:raises: :py:exc:`RuntimeError`
|
|
803
|
+
"""
|
|
804
|
+
return knowledge_module.assign_data_category(self.sfdc_object, article_id=article_id,
|
|
805
|
+
category_group_name=category_group_name,
|
|
806
|
+
category_name=category_name)
|
|
807
|
+
|
|
808
|
+
def archive_article(self, article_id):
|
|
809
|
+
"""This function archives a published knowledge article.
|
|
810
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_REST_archive_master_version.htm>`_)
|
|
811
|
+
|
|
812
|
+
.. versionadded:: 1.3.0
|
|
813
|
+
|
|
814
|
+
:param article_id: The ID of the article to archive
|
|
815
|
+
:type article_id: str
|
|
816
|
+
:returns: The API response from the POST request
|
|
817
|
+
:raises: :py:exc:`RuntimeError`
|
|
818
|
+
"""
|
|
819
|
+
return knowledge_module.archive_article(self.sfdc_object, article_id=article_id)
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
def define_connection_info():
|
|
823
|
+
"""This function prompts the user for the connection information.
|
|
824
|
+
|
|
825
|
+
:returns: The connection info in a dictionary
|
|
826
|
+
"""
|
|
827
|
+
base_url = input('Enter your instance URL: [] ')
|
|
828
|
+
org_id = input('Enter the Org ID for your instance: [] ')
|
|
829
|
+
username = input('Enter the username of your API user: [] ')
|
|
830
|
+
password = input('Enter the password of your API user: [] ')
|
|
831
|
+
endpoint_url = input('Enter the endpoint URL: [] ')
|
|
832
|
+
client_id = input('Enter the Client ID: [] ')
|
|
833
|
+
client_secret = input('Enter the Client Secret: [] ')
|
|
834
|
+
security_token = input('Enter the Security Token: [] ')
|
|
835
|
+
connection_info = compile_connection_info(base_url, org_id, username, password, endpoint_url,
|
|
836
|
+
client_id, client_secret, security_token)
|
|
837
|
+
return connection_info
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
def compile_connection_info(base_url, org_id, username, password, endpoint_url,
|
|
841
|
+
client_id, client_secret, security_token):
|
|
842
|
+
"""This function compiles the connection info into a dictionary that can be consumed by the core object.
|
|
843
|
+
|
|
844
|
+
:param base_url: The base URL of the Salesforce instance
|
|
845
|
+
:type base_url: str
|
|
846
|
+
:param org_id: The Org ID of the Salesforce instance
|
|
847
|
+
:type org_id: str
|
|
848
|
+
:param username: The username of the API user
|
|
849
|
+
:type username: str
|
|
850
|
+
:param password: The password of the API user
|
|
851
|
+
:type password: str
|
|
852
|
+
:param endpoint_url: The endpoint URL for the Salesforce instance
|
|
853
|
+
:type endpoint_url: str
|
|
854
|
+
:param client_id: The Client ID for the Salesforce instance
|
|
855
|
+
:type client_id: str
|
|
856
|
+
:param client_secret: The Client Secret for the Salesforce instance
|
|
857
|
+
:type client_secret: str
|
|
858
|
+
:param security_token: The Security Token for the Salesforce instance
|
|
859
|
+
:type security_token: str
|
|
860
|
+
:returns: The connection info in a dictionary
|
|
861
|
+
"""
|
|
862
|
+
connection_info = {
|
|
863
|
+
'base_url': base_url,
|
|
864
|
+
'org_id': org_id,
|
|
865
|
+
'username': username,
|
|
866
|
+
'password': password,
|
|
867
|
+
'endpoint_url': endpoint_url,
|
|
868
|
+
'client_id': client_id,
|
|
869
|
+
'client_secret': client_secret,
|
|
870
|
+
'security_token': security_token,
|
|
871
|
+
}
|
|
872
|
+
return connection_info
|