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
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
:Module: salespyforce.knowledge
|
|
4
|
+
:Synopsis: Defines the Knowledge-related functions associated with the Salesforce API
|
|
5
|
+
:Created By: Jeff Shurtliff
|
|
6
|
+
:Last Modified: Jeff Shurtliff
|
|
7
|
+
:Modified Date: 14 Nov 2023
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from . import errors
|
|
11
|
+
from .utils import log_utils
|
|
12
|
+
|
|
13
|
+
# Initialize logging
|
|
14
|
+
logger = log_utils.initialize_logging(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def check_for_existing_article(sfdc_object, title, sobject=None, return_id=False, return_id_and_number=False,
|
|
18
|
+
include_archived=False):
|
|
19
|
+
"""This method checks to see if an article already exists with a given title and returns its article number.
|
|
20
|
+
(`Reference 1 <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_query.htm>`_,
|
|
21
|
+
`Reference 2 <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_development_soql_sosl_intro.htm>`_)
|
|
22
|
+
|
|
23
|
+
.. versionchanged:: 1.2.2
|
|
24
|
+
You can now specify whether archived articles are included in the query results.
|
|
25
|
+
|
|
26
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
27
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
28
|
+
:param title: The title of the knowledge article for which to check
|
|
29
|
+
:type title: str
|
|
30
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
31
|
+
:type sobject: str, None
|
|
32
|
+
:param return_id: Determines if the Article ID should be returned (``False`` by default)
|
|
33
|
+
:type return_id: bool
|
|
34
|
+
:param return_id_and_number: Determines if Article ID and Article Number should be returned (``False`` by default)
|
|
35
|
+
:type return_id_and_number: bool
|
|
36
|
+
:param include_archived: Determines if archived articles should be included (``False`` by default)
|
|
37
|
+
:type include_archived: bool
|
|
38
|
+
:returns: The Article Number, Article ID, or both, if found, or a blank string if not found
|
|
39
|
+
"""
|
|
40
|
+
sobject = 'Knowledge__kav' if sobject is None else sobject
|
|
41
|
+
query = f"SELECT Id,ArticleNumber FROM {sobject} WHERE Title = '{title}'"
|
|
42
|
+
query += " AND PublishStatus != 'Archived'" if not include_archived else query
|
|
43
|
+
response = sfdc_object.soql_query(query, replace_quotes=False)
|
|
44
|
+
return_value = ''
|
|
45
|
+
if response.get('totalSize') > 0:
|
|
46
|
+
if return_id:
|
|
47
|
+
return_value = response['records'][0]['Id']
|
|
48
|
+
elif return_id_and_number:
|
|
49
|
+
return_value = (response['records'][0]['Id'], response['records'][0]['ArticleNumber'])
|
|
50
|
+
else:
|
|
51
|
+
return_value = response['records'][0]['ArticleNumber']
|
|
52
|
+
elif return_id_and_number:
|
|
53
|
+
return_value = ('', '')
|
|
54
|
+
return return_value
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_article_id_from_number(sfdc_object, article_number, sobject=None, return_uri=False):
|
|
58
|
+
"""This method returns the Article ID when an article number is provided.
|
|
59
|
+
(`Reference 1 <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_query.htm>`_,
|
|
60
|
+
`Reference 2 <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_development_soql_sosl_intro.htm>`_)
|
|
61
|
+
|
|
62
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
63
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
64
|
+
:param article_number: The Article Number to query
|
|
65
|
+
:type article_number: str, int
|
|
66
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
67
|
+
:type sobject: str, None
|
|
68
|
+
:param return_uri: Determines if the URI of the article should be returned rather than the ID (``False`` by default)
|
|
69
|
+
:type return_uri: bool
|
|
70
|
+
:returns: The Article ID or Article URI, or a blank string if no article is found
|
|
71
|
+
:raises: :py:exc:`ValueError`
|
|
72
|
+
"""
|
|
73
|
+
sobject = 'Knowledge__kav' if sobject is None else sobject
|
|
74
|
+
if sobject is None:
|
|
75
|
+
raise ValueError('The sObject must be defined for the Article Type in order to query for the ID.')
|
|
76
|
+
if len(str(article_number)) < 9:
|
|
77
|
+
query = f"SELECT Id FROM {sobject} WHERE ArticleNumber LIKE '%0{article_number}'"
|
|
78
|
+
else:
|
|
79
|
+
query = f"SELECT Id FROM {sobject} WHERE ArticleNumber = '{article_number}'"
|
|
80
|
+
response = sfdc_object.soql_query(query)
|
|
81
|
+
if response.get('totalSize') > 0:
|
|
82
|
+
if return_uri:
|
|
83
|
+
return_value = response['records'][0]['attributes']['url']
|
|
84
|
+
else:
|
|
85
|
+
return_value = response['records'][0]['Id']
|
|
86
|
+
else:
|
|
87
|
+
return_value = ''
|
|
88
|
+
print(f'No results were returned when querying for the article number {article_number}')
|
|
89
|
+
return return_value
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def get_articles_list(sfdc_object, query=None, sort=None, order=None, page_size=20, page_num=1):
|
|
93
|
+
"""This function retrieves a list of knowledge articles.
|
|
94
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_knowledge_support_artlist.htm>`_)
|
|
95
|
+
|
|
96
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
97
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
98
|
+
:param query: A SOQL query with which to filter the results (optional)
|
|
99
|
+
:type query: str, None
|
|
100
|
+
:param sort: One of the following optional values: ``LastPublishedDate``, ``CreatedDate``, ``Title``, or ``ViewScore``
|
|
101
|
+
:type sort: str, None
|
|
102
|
+
:param order: Optionally define the ORDER BY as ``ASC`` or ``DESC``
|
|
103
|
+
:type order: str, None
|
|
104
|
+
:param page_size: The number of results per page (``20`` by default)
|
|
105
|
+
:type page_size: int
|
|
106
|
+
:param page_num: The starting page number (``1`` by default)
|
|
107
|
+
:type page_num: int
|
|
108
|
+
:returns: The list of retrieved knowledge articles
|
|
109
|
+
"""
|
|
110
|
+
# Define the headers
|
|
111
|
+
headers = sfdc_object._get_headers('articles')
|
|
112
|
+
|
|
113
|
+
# Validate the sort field
|
|
114
|
+
valid_sort_options = ['LastPublishedDate', 'CreatedDate', 'Title', 'ViewScore']
|
|
115
|
+
if sort and sort not in valid_sort_options:
|
|
116
|
+
errors.handlers.eprint(f'The sort value {sort} is not valid and will be ignored.')
|
|
117
|
+
sort = None
|
|
118
|
+
|
|
119
|
+
# Validate the order field
|
|
120
|
+
if order and order.upper() not in ['ASC', 'DESC']:
|
|
121
|
+
errors.handlers.eprint(f'The order value {order} is not valid and will be ignored.')
|
|
122
|
+
order = None
|
|
123
|
+
|
|
124
|
+
# Validate the page size field
|
|
125
|
+
if page_size > 100:
|
|
126
|
+
errors.handlers.eprint(f'The pageSize value exceeds the maximum and will default to 100.')
|
|
127
|
+
page_size = 100
|
|
128
|
+
|
|
129
|
+
# Validate the pageNumber field
|
|
130
|
+
if page_num < 1:
|
|
131
|
+
errors.handlers.eprint(f'The pageNumber value is not valid and will default to 1.')
|
|
132
|
+
page_num = 1
|
|
133
|
+
|
|
134
|
+
# Add values to the parameters dictionary if they have been defined
|
|
135
|
+
params = {}
|
|
136
|
+
if query:
|
|
137
|
+
params['q'] = query
|
|
138
|
+
if sort:
|
|
139
|
+
params['sort'] = sort
|
|
140
|
+
if order:
|
|
141
|
+
params['order'] = order
|
|
142
|
+
params['pageSize'] = page_size
|
|
143
|
+
params['pageNumber'] = page_num
|
|
144
|
+
|
|
145
|
+
# Perform the query
|
|
146
|
+
return sfdc_object.get(f'/services/data/{sfdc_object.version}/support/knowledgeArticles',
|
|
147
|
+
params=params, headers=headers)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def get_article_details(sfdc_object, article_id, sobject=None):
|
|
151
|
+
"""This function retrieves details for a single knowledge article.
|
|
152
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_knowledge_support_artdetails.htm>`_)
|
|
153
|
+
|
|
154
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
155
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
156
|
+
:param article_id: The Article ID for which to retrieve details
|
|
157
|
+
:type article_id: str
|
|
158
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
159
|
+
:type sobject: str, None
|
|
160
|
+
:returns: The details for the knowledge article
|
|
161
|
+
"""
|
|
162
|
+
# Define the headers
|
|
163
|
+
headers = sfdc_object._get_headers('articles')
|
|
164
|
+
|
|
165
|
+
# Perform the query and return the data
|
|
166
|
+
sobject = 'Knowledge__kav' if sobject is None else sobject
|
|
167
|
+
if sobject is not None:
|
|
168
|
+
data = sfdc_object.get(f'/services/data/{sfdc_object.version}/sobjects/{sobject}/{article_id}')
|
|
169
|
+
else:
|
|
170
|
+
data = sfdc_object.get(f'/services/data/{sfdc_object.version}/support/knowledgeArticles/{article_id}',
|
|
171
|
+
headers=headers)
|
|
172
|
+
return data
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def get_validation_status(sfdc_object, article_id=None, article_details=None, sobject=None):
|
|
176
|
+
"""This function retrieves the Validation Status for a given Article ID.
|
|
177
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/resources_knowledge_support_artdetails.htm>`_)
|
|
178
|
+
|
|
179
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
180
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
181
|
+
:param article_id: The Article ID for which to retrieve details
|
|
182
|
+
:type article_id: str, None
|
|
183
|
+
:param article_details: The dictionary of article details for the given article
|
|
184
|
+
:type article_details: dict, None
|
|
185
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
186
|
+
:type sobject: str, None
|
|
187
|
+
:returns: The validation status as a text string
|
|
188
|
+
:raises: :py:exc:`RuntimeError`
|
|
189
|
+
"""
|
|
190
|
+
if not any((article_id, article_details)):
|
|
191
|
+
raise RuntimeError('The article ID or article details must be provided.')
|
|
192
|
+
|
|
193
|
+
# Retrieve the article details if not already supplied
|
|
194
|
+
if not article_details:
|
|
195
|
+
article_details = get_article_details(sfdc_object, article_id, sobject)
|
|
196
|
+
|
|
197
|
+
# Identify the validation status
|
|
198
|
+
return article_details.get('ValidationStatus')
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def get_article_metadata(sfdc_object, article_id):
|
|
202
|
+
"""This function retrieves metadata for a specific knowledge article.
|
|
203
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_REST_retrieve_article_metadata.htm>`_)
|
|
204
|
+
|
|
205
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
206
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
207
|
+
:param article_id: The Article ID for which to retrieve details
|
|
208
|
+
:type article_id: str
|
|
209
|
+
:returns: The article metadata as a dictionary
|
|
210
|
+
:raises: :py:exc:`RuntimeError`
|
|
211
|
+
"""
|
|
212
|
+
return sfdc_object.get(f'/services/data/{sfdc_object.version}/knowledgeManagement/articles/{article_id}')
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def get_article_version(sfdc_object, article_id):
|
|
216
|
+
"""This function retrieves the version ID for a given master article ID.
|
|
217
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_REST_retrieve_article_version.htm>`_)
|
|
218
|
+
|
|
219
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
220
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
221
|
+
:param article_id: The Article ID for which to retrieve details
|
|
222
|
+
:type article_id: str
|
|
223
|
+
:returns: The version ID for the given master article ID
|
|
224
|
+
:raises: :py:exc:`RuntimeError`
|
|
225
|
+
"""
|
|
226
|
+
endpoint = f'/services/data/{sfdc_object.version}/knowledgeManagement/articleversions/masterVersions/{article_id}'
|
|
227
|
+
return sfdc_object.get(endpoint)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def get_article_url(sfdc_object, article_id=None, article_number=None, sobject=None):
|
|
231
|
+
"""This function constructs the URL to view a knowledge article in Lightning or Classic.
|
|
232
|
+
|
|
233
|
+
.. versionchanged:: 1.2.0
|
|
234
|
+
Changed when lightning URLs are defined and fixed an issue with extraneous slashes.
|
|
235
|
+
|
|
236
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
237
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
238
|
+
:param article_id: The Article ID for which to retrieve details
|
|
239
|
+
:type article_id: str, None
|
|
240
|
+
:param article_number: The article number for which to retrieve details
|
|
241
|
+
:type article_number: str, int, None
|
|
242
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
243
|
+
:type sobject: str, None
|
|
244
|
+
:returns: The article URL as a string
|
|
245
|
+
:raises: :py:exc:`ValueError`
|
|
246
|
+
"""
|
|
247
|
+
sobject = 'Knowledge__kav' if sobject is None else sobject
|
|
248
|
+
if not any((article_id, article_number)):
|
|
249
|
+
raise ValueError('An article ID or an article number must be provided to retrieve the article URL.')
|
|
250
|
+
if article_number and not article_id:
|
|
251
|
+
article_id = get_article_id_from_number(sfdc_object, article_number, sobject)
|
|
252
|
+
segment = '' if sfdc_object.base_url.endswith('/') else '/'
|
|
253
|
+
if 'lightning' in sfdc_object.base_url or sobject == 'Knowledge__kav':
|
|
254
|
+
article_url = f'{sfdc_object.base_url}{segment}lightning/r/Knowledge__kav/{article_id}/view'
|
|
255
|
+
else:
|
|
256
|
+
article_url = f'{sfdc_object.base_url}{segment}knowledge/publishing/articleDraftDetail.apexp?id={article_id}'
|
|
257
|
+
return article_url
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def create_article(sfdc_object, article_data, sobject=None, full_response=False):
|
|
261
|
+
"""This function creates a new knowledge article draft.
|
|
262
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_create.htm>`_)
|
|
263
|
+
|
|
264
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
265
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
266
|
+
:param article_data: The article data used to populate the article
|
|
267
|
+
:type article_data: dict
|
|
268
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
269
|
+
:type sobject: str, None
|
|
270
|
+
:param full_response: Determines if the full API response should be returned instead of the article ID (``False`` by default)
|
|
271
|
+
:type full_response: bool
|
|
272
|
+
:returns: The API response or the ID of the article draft
|
|
273
|
+
:raises: :py:exc:`ValueError`, :py:exc:`TypeError`, :py:exc:`RuntimeError`
|
|
274
|
+
"""
|
|
275
|
+
# Get the appropriate sObject to call
|
|
276
|
+
sobject = 'Knowledge__kav' if sobject is None else sobject
|
|
277
|
+
|
|
278
|
+
# Ensure the payload is in the appropriate format
|
|
279
|
+
if not isinstance(article_data, dict):
|
|
280
|
+
raise TypeError('The article data must be provided as a dictionary.')
|
|
281
|
+
|
|
282
|
+
# Ensure that the required fields have been provided
|
|
283
|
+
required_fields = ['Title', 'UrlName']
|
|
284
|
+
for field in required_fields:
|
|
285
|
+
if field not in article_data:
|
|
286
|
+
raise ValueError(f'The following required field is missing from the article data: {field}')
|
|
287
|
+
|
|
288
|
+
# Perform the API call
|
|
289
|
+
response = sfdc_object.post(f'/services/data/{sfdc_object.version}/sobjects/{sobject}', payload=article_data)
|
|
290
|
+
|
|
291
|
+
# Return the full response or just the article ID
|
|
292
|
+
if not full_response:
|
|
293
|
+
response = response.get('id')
|
|
294
|
+
return response
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def update_article(sfdc_object, record_id, article_data, sobject=None, include_status_code=False):
|
|
298
|
+
"""This function updates an existing knowledge article draft.
|
|
299
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_update_fields.htm>`_)
|
|
300
|
+
|
|
301
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
302
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
303
|
+
:param record_id: The ID of the article draft record to be updated
|
|
304
|
+
:type record_id: str
|
|
305
|
+
:param article_data: The article data used to update the article
|
|
306
|
+
:type article_data: dict
|
|
307
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
308
|
+
:type sobject: str, None
|
|
309
|
+
:param include_status_code: Determines if the API response status code should be returned (``False`` by default)
|
|
310
|
+
:type include_status_code: bool
|
|
311
|
+
:returns: A Boolean indicating if the update operation was successful, and optionally the API response status code
|
|
312
|
+
:raises: :py:exc:`ValueError`, :py:exc:`TypeError`, :py:exc:`RuntimeError`
|
|
313
|
+
"""
|
|
314
|
+
# Get the appropriate sObject to call
|
|
315
|
+
sobject = 'Knowledge__kav' if sobject is None else sobject
|
|
316
|
+
|
|
317
|
+
# Ensure the payload is in the appropriate format
|
|
318
|
+
if not isinstance(article_data, dict):
|
|
319
|
+
raise TypeError('The article data must be provided as a dictionary.')
|
|
320
|
+
|
|
321
|
+
# Ensure that the required fields have been provided
|
|
322
|
+
required_fields = ['Title', 'UrlName']
|
|
323
|
+
for field in required_fields:
|
|
324
|
+
if field not in article_data:
|
|
325
|
+
raise ValueError(f'The following required field is missing from the article data: {field}')
|
|
326
|
+
|
|
327
|
+
# Perform the API call
|
|
328
|
+
response = sfdc_object.patch(f'/services/data/{sfdc_object.version}/sobjects/{sobject}/{record_id}',
|
|
329
|
+
payload=article_data)
|
|
330
|
+
|
|
331
|
+
# Determine whether the call was successful
|
|
332
|
+
successful = True if response.status_code == 204 else False
|
|
333
|
+
|
|
334
|
+
# Return the success determination and optionally the status code
|
|
335
|
+
if include_status_code:
|
|
336
|
+
return successful, response.status_code
|
|
337
|
+
return successful
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def create_draft_from_online_article(sfdc_object, article_id, unpublish=False):
|
|
341
|
+
"""This function creates a draft knowledge article from an online article.
|
|
342
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/actions_obj_knowledge.htm#createDraftFromOnlineKnowledgeArticle>`_)
|
|
343
|
+
|
|
344
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
345
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
346
|
+
:param article_id: The ID of the online article from which to create the draft
|
|
347
|
+
:type article_id: str
|
|
348
|
+
:param unpublish: Determines if the online article should be unpublished when the draft is created (``False`` by default)
|
|
349
|
+
:type unpublish: bool
|
|
350
|
+
:returns: The API response from the POST request
|
|
351
|
+
:raises: :py:exc:`RuntimeError`
|
|
352
|
+
"""
|
|
353
|
+
# Define the payload for the API call
|
|
354
|
+
payload = {
|
|
355
|
+
"inputs": [
|
|
356
|
+
{
|
|
357
|
+
"action": "EDIT_AS_DRAFT_ARTICLE",
|
|
358
|
+
"unpublish": unpublish,
|
|
359
|
+
"articleId": f"{article_id}"
|
|
360
|
+
}
|
|
361
|
+
]
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
# Perform the API call
|
|
365
|
+
endpoint = f'/services/data/{sfdc_object.version}/actions/standard/createDraftFromOnlineKnowledgeArticle'
|
|
366
|
+
return sfdc_object.post(endpoint, payload)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def create_draft_from_master_version(sfdc_object, article_id=None, knowledge_article_id=None, article_data=None,
|
|
370
|
+
sobject=None, full_response=False):
|
|
371
|
+
"""This function creates an online version of a master article.
|
|
372
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.198.0.knowledge_dev.meta/knowledge_dev/knowledge_REST_edit_online_master.htm>`_)
|
|
373
|
+
|
|
374
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
375
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
376
|
+
:param article_id: The Article ID from which to create the draft
|
|
377
|
+
:type article_id: str, None
|
|
378
|
+
:param knowledge_article_id: The Knowledge Article ID (``KnowledgeArticleId``) from which to create the draft
|
|
379
|
+
:type knowledge_article_id: str, None
|
|
380
|
+
:param article_data: The article data associated with the article from which to create the draft
|
|
381
|
+
:type article_data: dict, None
|
|
382
|
+
:param sobject: The Salesforce object to query (``Knowledge__kav`` by default)
|
|
383
|
+
:type sobject: str, None
|
|
384
|
+
:param full_response: Determines if the full API response should be returned instead of the article ID (``False`` by default)
|
|
385
|
+
:type full_response: bool
|
|
386
|
+
:returns: The API response or the ID of the article draft
|
|
387
|
+
:raises: :py:exc:`RuntimeError`
|
|
388
|
+
"""
|
|
389
|
+
if not any((article_id, knowledge_article_id, article_data)):
|
|
390
|
+
raise RuntimeError('Need to provide article ID, knowledge article ID, or article data.')
|
|
391
|
+
|
|
392
|
+
# Get the appropriate sObject to call
|
|
393
|
+
sobject = 'Knowledge__kav' if sobject is None else sobject
|
|
394
|
+
|
|
395
|
+
# Get the knowledge article ID as needed
|
|
396
|
+
if not knowledge_article_id:
|
|
397
|
+
if not article_data:
|
|
398
|
+
article_data = sfdc_object.get_article_details(article_id, sobject=sobject)
|
|
399
|
+
knowledge_article_id = article_data.get('KnowledgeArticleId')
|
|
400
|
+
|
|
401
|
+
# Perform the API call to retrieve the new draft ID
|
|
402
|
+
endpoint = f'/services/data/{sfdc_object.version}/knowledgeManagement/articleVersions/masterVersions'
|
|
403
|
+
response = sfdc_object.post(endpoint, {'articleId': knowledge_article_id})
|
|
404
|
+
|
|
405
|
+
# Return the full response or the draft ID
|
|
406
|
+
if not full_response:
|
|
407
|
+
response = response.get('id')
|
|
408
|
+
return response
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def publish_article(sfdc_object, article_id, major_version=True, full_response=False):
|
|
412
|
+
"""This function publishes a draft knowledge article as a major or minor version.
|
|
413
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_REST_publish_master_version.htm>`_)
|
|
414
|
+
|
|
415
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
416
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
417
|
+
:param article_id: The Article ID to publish
|
|
418
|
+
:type article_id: str
|
|
419
|
+
:param major_version: Determines if the published article should be a major version (``True`` by default)
|
|
420
|
+
:type major_version: bool
|
|
421
|
+
:param full_response: Determines if the full API response should be returned (``False`` by default)
|
|
422
|
+
:type full_response: bool
|
|
423
|
+
:returns: A Boolean value indicating the success of the action or the API response from the PATCH request
|
|
424
|
+
:raises: :py:exc:`RuntimeError`
|
|
425
|
+
"""
|
|
426
|
+
# Define the payload for the API call
|
|
427
|
+
payload = {
|
|
428
|
+
"publishStatus": "Online"
|
|
429
|
+
}
|
|
430
|
+
if major_version:
|
|
431
|
+
payload['versionNumber'] = 'NextVersion'
|
|
432
|
+
|
|
433
|
+
# Perform the API call
|
|
434
|
+
endpoint = f'/services/data/{sfdc_object.version}/knowledgeManagement/articleVersions/masterVersions/{article_id}'
|
|
435
|
+
result = sfdc_object.patch(endpoint, payload)
|
|
436
|
+
|
|
437
|
+
# Return the appropriate value depending on if a full response was requested
|
|
438
|
+
if not full_response:
|
|
439
|
+
result = True if result.status_code == 204 else False
|
|
440
|
+
return result
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
def publish_multiple_articles(sfdc_object, article_id_list, major_version=True):
|
|
444
|
+
"""This function publishes multiple knowledge article drafts at one time.
|
|
445
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/actions_obj_knowledge.htm#publishKnowledgeArticles>`_)
|
|
446
|
+
|
|
447
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
448
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
449
|
+
:param article_id_list: A list of Article IDs to be published
|
|
450
|
+
:type article_id_list: list
|
|
451
|
+
:param major_version: Determines if the published article should be a major version (``True`` by default)
|
|
452
|
+
:type major_version: bool
|
|
453
|
+
:returns: The API response from the POST request
|
|
454
|
+
:raises: :py:exc:`RuntimeError`, :py:exc:`TypeError`, :py:exc:`ValueError`
|
|
455
|
+
"""
|
|
456
|
+
# Define the endpoint URI
|
|
457
|
+
endpoint = f'/services/data/{sfdc_object.version}/actions/standard/publishKnowledgeArticles'
|
|
458
|
+
|
|
459
|
+
# Ensure there is at least one article ID to publish
|
|
460
|
+
if not isinstance(article_id_list, list) or not isinstance(article_id_list[0], str):
|
|
461
|
+
raise TypeError('A list of Article ID strings must be provided in order to publish multiple articles.')
|
|
462
|
+
elif len(article_id_list) == 0:
|
|
463
|
+
raise ValueError('No article ID strings were found in the article ID list variable.')
|
|
464
|
+
|
|
465
|
+
# Define the action to perform
|
|
466
|
+
action = 'PUBLISH_ARTICLE_NEW_VERSION' if major_version else 'PUBLISH_ARTICLE'
|
|
467
|
+
|
|
468
|
+
# Construct the payload
|
|
469
|
+
payload = {
|
|
470
|
+
"inputs": [
|
|
471
|
+
{
|
|
472
|
+
"articleVersionIdList": article_id_list,
|
|
473
|
+
"pubAction": action
|
|
474
|
+
}
|
|
475
|
+
]
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
# Perform the API call
|
|
479
|
+
return sfdc_object.post(endpoint, payload)
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
def assign_data_category(sfdc_object, article_id, category_group_name, category_name):
|
|
483
|
+
"""This function assigns a single data category for a knowledge article.
|
|
484
|
+
(`Reference <https://itsmemohit.medium.com/quick-win-15-salesforce-knowledge-rest-apis-bb0725b2040e>`_)
|
|
485
|
+
|
|
486
|
+
.. versionadded:: 1.2.0
|
|
487
|
+
|
|
488
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
489
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
490
|
+
:param article_id: The ID of the article to update
|
|
491
|
+
:type article_id: str
|
|
492
|
+
:param category_group_name: The unique Data Category Group Name
|
|
493
|
+
:type category_group_name: str
|
|
494
|
+
:param category_name: The unique Data Category Name
|
|
495
|
+
:type category_name: str
|
|
496
|
+
:returns: The API response from the POST request
|
|
497
|
+
:raises: :py:exc:`RuntimeError`
|
|
498
|
+
"""
|
|
499
|
+
# Define the payload for the API call
|
|
500
|
+
payload = {
|
|
501
|
+
"ParentId": article_id,
|
|
502
|
+
"DataCategoryGroupName": category_group_name,
|
|
503
|
+
"DataCategoryName": category_name
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
# Perform the API call
|
|
507
|
+
endpoint = f'/services/data/{sfdc_object.version}/sobjects/Knowledge__DataCategorySelection'
|
|
508
|
+
return sfdc_object.post(endpoint, payload)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
def archive_article(sfdc_object, article_id):
|
|
512
|
+
"""This function archives a published knowledge article.
|
|
513
|
+
(`Reference <https://developer.salesforce.com/docs/atlas.en-us.knowledge_dev.meta/knowledge_dev/knowledge_REST_archive_master_version.htm>`_)
|
|
514
|
+
|
|
515
|
+
.. versionadded:: 1.3.0
|
|
516
|
+
|
|
517
|
+
:param sfdc_object: The instantiated SalesPyForce object
|
|
518
|
+
:type sfdc_object: class[salespyforce.Salesforce]
|
|
519
|
+
:param article_id: The ID of the article to archive
|
|
520
|
+
:type article_id: str
|
|
521
|
+
:returns: The API response from the POST request
|
|
522
|
+
:raises: :py:exc:`RuntimeError`
|
|
523
|
+
"""
|
|
524
|
+
# Define the payload for the API call
|
|
525
|
+
payload = {
|
|
526
|
+
"publishStatus": "Archived"
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
# Perform the API call
|
|
530
|
+
endpoint = f'/services/data/{sfdc_object.version}/knowledgeManagement/articleVersions/masterVersions/{article_id}'
|
|
531
|
+
return sfdc_object.patch(endpoint, payload)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
:Package: salespyforce.utils
|
|
4
|
+
:Synopsis: This is the ``__init__`` module for the salespyforce.utils modules
|
|
5
|
+
:Created By: Jeff Shurtliff
|
|
6
|
+
:Last Modified: Jeff Shurtliff
|
|
7
|
+
:Modified Date: 13 Mar 2023
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
__all__ = ['core_utils', 'helper', 'version']
|