amocrm-api-wrapper 0.0.20__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.
amocrm_api/base.py ADDED
@@ -0,0 +1,4191 @@
1
+ import logging
2
+ from json import JSONDecodeError, loads
3
+ from time import sleep
4
+ from requests import Session, ConnectionError, ConnectTimeout, Response
5
+ from typing import Optional, Union, Any
6
+ from urllib.parse import urlencode
7
+
8
+ from .errors import AmoException
9
+
10
+ logger = logging.getLogger("amocrm_wrapper")
11
+
12
+
13
+ class BaseClient(object):
14
+ crm_url: str = ""
15
+
16
+ def _init_session(self, headers: Optional[dict] = None) -> Session:
17
+ raise NotImplementedError()
18
+
19
+ def update_session_params(self, params: dict) -> None:
20
+ """update session
21
+
22
+ Args:
23
+ params (dict): like {'IF-MODIFIED-SINCE': <datetime>}
24
+ """
25
+ self._session = self._init_session(params)
26
+
27
+ def _parse_response_body(self, response: Response) -> dict:
28
+ raw_data = response.content.decode("utf-8")
29
+ if not raw_data:
30
+ return {}
31
+ data = loads(raw_data)
32
+ return data
33
+
34
+ def _send_api_request(
35
+ self, method: str, url: str, data: Any = None, _connection_counter: int = 0
36
+ ) -> dict:
37
+ try:
38
+ response = self._session.__getattribute__(method)(url, json=data)
39
+ if response.status_code == 204:
40
+ return {}
41
+ elif response.status_code == 429:
42
+ sleep(20)
43
+ logger.warning("429 http error, sleep 20 sec")
44
+ return self._send_api_request(method, url, data)
45
+ data = self._parse_response_body(response)
46
+ if "error" in data or response.status_code >= 400:
47
+ raise AmoException(data, code=response.status_code)
48
+ json_data = data["response"] if "response" in data else data
49
+ return json_data
50
+ except JSONDecodeError as e:
51
+ raise AmoException({"error": str(e)}, code=500)
52
+ except (ConnectTimeout, ConnectionError) as e:
53
+ if _connection_counter > 3:
54
+ raise
55
+ sleep(5)
56
+ self._update_session()
57
+ _connection_counter += 1
58
+ return self._send_api_request(method, url, data, _connection_counter)
59
+
60
+ def _update_session(self):
61
+ self._session = self._init_session(dict(self._session.headers))
62
+
63
+ def __create_filter_query(self, filters: dict) -> dict:
64
+ filter_query = {}
65
+ update_from = filters.pop("updated_at__from", None)
66
+ update_to = filters.pop("updated_at__to", None)
67
+ created_from = filters.pop("created_at__from", None)
68
+ created_to = filters.pop("created_at__to", None)
69
+ closed_from = filters.pop("closed_at__from", None)
70
+ closed_to = filters.pop("closed_at__to", None)
71
+ if update_from:
72
+ filter_query["filter[updated_at][from]"] = update_from
73
+ if update_to:
74
+ filter_query["filter[updated_at][to]"] = update_to
75
+ if created_from:
76
+ filter_query["filter[created_at][from]"] = created_from
77
+ if created_to:
78
+ filter_query["filter[created_at][to]"] = created_to
79
+ if closed_from:
80
+ filter_query["filter[closed_at][from]"] = closed_from
81
+ if closed_to:
82
+ filter_query["filter[closed_at][to]"] = closed_to
83
+ filter_query.update({f"filter[{k}]": v for k, v in filters.items()})
84
+ return filter_query
85
+
86
+ def _get_entities(
87
+ self,
88
+ entity: str,
89
+ limit: int = 250,
90
+ page: int = 1,
91
+ with_params: Optional[list] = None,
92
+ filters: Optional[dict] = None,
93
+ filter_ids: Optional[list] = None,
94
+ order: Optional[dict] = None,
95
+ ) -> dict:
96
+ url = f"{self.crm_url}/api/v4/{entity}"
97
+ params: dict = {"limit": limit, "page": page}
98
+ if with_params:
99
+ params["with"] = ",".join(param for param in with_params) # type: ignore
100
+ if filters:
101
+ filter_query = self.__create_filter_query(filters)
102
+ params.update(filter_query)
103
+ if filter_ids:
104
+ query = {f'filter[id][{index}]': id_ for index, id_ in enumerate(filter_ids)}
105
+ params.update(query)
106
+ if order:
107
+ order_query = {f"order[{k}]": v for k, v in order.items()}
108
+ params.update(order_query)
109
+ url = f"{url}?{urlencode(params)}"
110
+ return self._send_api_request("get", url)
111
+
112
+ def _get_entity_links(
113
+ self, entity: str, entity_id: int, filters: Optional[dict] = None
114
+ ) -> dict:
115
+ url = f"{self.crm_url}/api/v4/{entity}/{entity_id}/links"
116
+ if filters:
117
+ filter_query = {f"filter[{k}]": v for k, v in filters.items()}
118
+ url = f"{url}?{urlencode(filter_query)}"
119
+ return self._send_api_request("get", url)
120
+
121
+ def _link_entities(self, entity: str, entity_id: int, objects: list) -> dict:
122
+ url = f"{self.crm_url}/api/v4/{entity}/{entity_id}/link"
123
+ return self._send_api_request("post", url, objects)
124
+
125
+ def _unlink_entities(self, entity: str, entity_id: int, objects: list) -> dict:
126
+ url = f"{self.crm_url}/api/v4/{entity}/{entity_id}/unlinks"
127
+ return self._send_api_request("post", url, objects)
128
+
129
+ def unlink_leads_entity(self, entity_id: int, objects: list) -> dict:
130
+ return self._unlink_entities("leads", entity_id, objects)
131
+
132
+ def unlink_contacts_entity(self, entity_id: int, objects: list) -> dict:
133
+ return self._unlink_entities("contacts", entity_id, objects)
134
+
135
+ def unlink_customers_entity(self, entity_id: int, objects: list) -> dict:
136
+ return self._unlink_entities("customers", entity_id, objects)
137
+
138
+ def unlink_companies_entity(self, entity_id: int, objects: list) -> dict:
139
+ return self._unlink_entities("companies", entity_id, objects)
140
+
141
+ def link_leads_entity(self, entity_id: int, objects: list) -> dict:
142
+ return self._link_entities("leads", entity_id, objects)
143
+
144
+ def link_contacts_entity(self, entity_id: int, objects: list) -> dict:
145
+ return self._link_entities("contacts", entity_id, objects)
146
+
147
+ def link_companies_entity(self, entity_id: int, objects: list) -> dict:
148
+ return self._link_entities("companies", entity_id, objects)
149
+
150
+ def link_customers_entity(self, entity_id: int, objects: list) -> dict:
151
+ return self._link_entities("customers", entity_id, objects)
152
+
153
+ def get_leads_links(self, entity_id: int, filters: Optional[dict] = None) -> dict:
154
+ return self._get_entity_links("leads", entity_id, filters)
155
+
156
+ def get_contacts_links(
157
+ self, entity_id: int, filters: Optional[dict] = None
158
+ ) -> dict:
159
+ return self._get_entity_links("contacts", entity_id, filters)
160
+
161
+ def get_companies_links(
162
+ self, entity_id: int, filters: Optional[dict] = None
163
+ ) -> dict:
164
+ return self._get_entity_links("companies", entity_id, filters)
165
+
166
+ def get_customers_links(
167
+ self, entity_id: int, filters: Optional[dict] = None
168
+ ) -> dict:
169
+ return self._get_entity_links("customers", entity_id, filters)
170
+
171
+ def get_account_info(
172
+ self,
173
+ with_amojo_id: bool = False,
174
+ with_amojo_rights: bool = False,
175
+ with_users_groups: bool = False,
176
+ with_task_types: bool = False,
177
+ with_version: bool = False,
178
+ with_ventity_names: bool = False,
179
+ with_datetime_settings: bool = False,
180
+ ) -> dict:
181
+ """
182
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/account-info
183
+ Args:
184
+ with_amojo_id (bool, optional): . Defaults to False.
185
+ with_amojo_rights (bool, optional): . Defaults to False.
186
+ with_users_groups (bool, optional): . Defaults to False.
187
+ with_task_types (bool, optional):. Defaults to False.
188
+ with_version (bool, optional): . Defaults to False.
189
+ with_ventity_names (bool, optional):. Defaults to False.
190
+ with_datetime_settings (bool, optional):. Defaults to False.
191
+
192
+ Returns:
193
+ dict: {
194
+ "id": 1231414,
195
+ "name": "example",
196
+ "subdomain": "example",
197
+ "created_at": 1585840134,
198
+ "created_by": 321321,
199
+ "updated_at": 1589472711,
200
+ "updated_by": 321321,
201
+ "current_user_id": 581651,
202
+ "country": "RU",
203
+ "customers_mode": "segments",
204
+ "is_unsorted_on": true,
205
+ "is_loss_reason_enabled": true,
206
+ "is_helpbot_enabled": false,
207
+ "is_technical_account": false,
208
+ "contact_name_display_order": 1,
209
+ "amojo_id": "f3c6340d-410e-4ad1-9f7e-c5e663599909",
210
+ "uuid": "824f3a59-6154-4edf-ba90-0b5593715d07",
211
+ "version": 11,
212
+ "_links": {
213
+ "self": {
214
+ "href": "https://example.amocrm.ru/api/v4/account"
215
+ }
216
+ },
217
+ "_embedded": {
218
+ "amojo_rights": {
219
+ "can_direct": true,
220
+ "can_create_groups": true
221
+ },
222
+ "users_groups": [
223
+ {
224
+ "id": 0,
225
+ "name": "Отдел продаж",
226
+ "uuid": null
227
+ }
228
+ ],
229
+ "task_types": [
230
+ {
231
+ "id": 1,
232
+ "name": "Связаться",
233
+ "color": null,
234
+ "icon_id": null,
235
+ "code": "FOLLOW_UP"
236
+ },
237
+ {
238
+ "id": 2,
239
+ "name": "Встреча",
240
+ "color": null,
241
+ "icon_id": null,
242
+ "code": "MEETING"
243
+ }
244
+ ],
245
+ "entity_names": {
246
+ "leads": {
247
+ "ru": {
248
+ "gender": "m",
249
+ "plural_form": {
250
+ "dative": "клиентам",
251
+ "default": "клиенты",
252
+ "genitive": "клиентов",
253
+ "accusative": "клиентов",
254
+ "instrumental": "клиентами",
255
+ "prepositional": "клиентах"
256
+ },
257
+ "singular_form": {
258
+ "dative": "клиенту",
259
+ "default": "клиент",
260
+ "genitive": "клиента",
261
+ "accusative": "клиента",
262
+ "instrumental": "клиентом",
263
+ "prepositional": "клиенте"
264
+ }
265
+ },
266
+ "en": {
267
+ "singular_form": {
268
+ "default": "lead"
269
+ },
270
+ "plural_form": {
271
+ "default": "leads"
272
+ },
273
+ "gender": "f"
274
+ },
275
+ "es": {
276
+ "singular_form": {
277
+ "default": "acuerdo"
278
+ },
279
+ "plural_form": {
280
+ "default": "acuerdos"
281
+ },
282
+ "gender": "m"
283
+ }
284
+ }
285
+ },
286
+ "datetime_settings": {
287
+ "date_pattern": "d.m.Y H:i",
288
+ "short_date_pattern": "d.m.Y",
289
+ "short_time_pattern": "H:i",
290
+ "date_formant": "d.m.Y",
291
+ "time_format": "H:i:s",
292
+ "timezone": "Europe/Moscow",
293
+ "timezone_offset": "+03:00"
294
+ }
295
+ }
296
+ }
297
+ """
298
+ params = {k.replace("with_", ""): v for k, v in locals().items() if k != "self"}
299
+ with_params = [param for param, value in params.items() if value]
300
+ url = f"{self.crm_url}/api/v4/account"
301
+ url += "?with=" + ",".join(p for p in with_params)
302
+ return self._send_api_request("get", url)
303
+
304
+ def _create_or_update_entities(
305
+ self, entity: str, objects: list, update: bool = False
306
+ ) -> dict:
307
+ """method for create or update entities
308
+
309
+ Args:
310
+ entity (str): name of entities like 'leads'
311
+ objects (list): list of obejcts
312
+ update (bool): if True http method patch else post
313
+
314
+ Returns:
315
+ dict: query result
316
+ """
317
+ url = f"{self.crm_url}/api/v4/{entity}"
318
+ http_method = "patch" if update else "post"
319
+ return self._send_api_request(http_method, url, objects)
320
+
321
+ def create_leads(self, objects: list) -> dict:
322
+ """create leads
323
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads-api#leads-add
324
+ Args:
325
+ objects (list): list of leads
326
+
327
+ Returns:
328
+ dict: {
329
+ "_links": {
330
+ "self": {
331
+ "href": "https://example.amocrm.ru/api/v4/leads"
332
+ }
333
+ },
334
+ "_embedded": {
335
+ "leads": [
336
+ {
337
+ "id": 10185151,
338
+ "request_id": "0",
339
+ "_links": {
340
+ "self": {
341
+ "href": "https://example.amocrm.ru/api/v4/leads/10185151"
342
+ }
343
+ }
344
+ },
345
+ {
346
+ "id": 10185153,
347
+ "request_id": "1",
348
+ "_links": {
349
+ "self": {
350
+ "href": "https://example.amocrm.ru/api/v4/leads/10185153"
351
+ }
352
+ }
353
+ }
354
+ ]
355
+ }
356
+ }
357
+ """
358
+ return self._create_or_update_entities("leads", objects)
359
+
360
+ def update_leads(self, objects: list) -> dict:
361
+ """update leads
362
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads-api#leads-edit
363
+ Args:
364
+ objects (list): list of leads
365
+ Returns:
366
+ dict: {
367
+ "_links": {
368
+ "self": {
369
+ "href": "https://example.amocrm.ru/api/v4/leads"
370
+ }
371
+ },
372
+ "_embedded": {
373
+ "leads": [
374
+ {
375
+ "id": 54886,
376
+ "updated_at": 1589556420,
377
+ "request_id": "0",
378
+ "_links": {
379
+ "self": {
380
+ "href": "https://example.amocrm.ru/api/v4/leads/54886"
381
+ }
382
+ }
383
+ },
384
+ {
385
+ "id": 54884,
386
+ "updated_at": 1589556420,
387
+ "request_id": "1",
388
+ "_links": {
389
+ "self": {
390
+ "href": "https://example.amocrm.ru/api/v4/leads/54884"
391
+ }
392
+ }
393
+ }
394
+ ]
395
+ }
396
+ }
397
+ """
398
+ return self._create_or_update_entities("leads", objects, True)
399
+
400
+ def get_lead(self, lead_id: int) -> dict:
401
+ """return lead
402
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads-api#lead-detail
403
+ Args:
404
+ lead_id (int): id of lead
405
+
406
+ Returns:
407
+ dict: {
408
+ "id": 3912171,
409
+ "name": "Example",
410
+ "price": 12,
411
+ "responsible_user_id": 504141,
412
+ "group_id": 0,
413
+ "status_id": 143,
414
+ "pipeline_id": 3104455,
415
+ "loss_reason_id": 4203748,
416
+ "source_id": null,
417
+ "created_by": 504141,
418
+ "updated_by": 504141,
419
+ "created_at": 1585299171,
420
+ "updated_at": 1590683337,
421
+ "closed_at": 1590683337,
422
+ "closest_task_at": null,
423
+ "is_deleted": false,
424
+ "custom_fields_values": null,
425
+ "score": null,
426
+ "account_id": 28805383,
427
+ "is_price_modified_by_robot": false,
428
+ "_links": {
429
+ "self": {
430
+ "href": "https://example.amocrm.ru/api/v4/leads/3912171"
431
+ }
432
+ },
433
+ "_embedded": {
434
+ "tags": [
435
+ {
436
+ "id": 100667,
437
+ "name": "тест"
438
+ }
439
+ ],
440
+ "catalog_elements": [
441
+ {
442
+ "id": 525439,
443
+ "metadata": {
444
+ "quantity": 1,
445
+ "catalog_id": 4521
446
+ }
447
+ }
448
+ ],
449
+ "loss_reason": [
450
+ {
451
+ "id": 4203748,
452
+ "name": "Пропала потребность",
453
+ "sort": 100000,
454
+ "created_at": 1582117280,
455
+ "updated_at": 1582117280,
456
+ "_links": {
457
+ "self": {
458
+ "href": "https://example.amocrm.ru/api/v4/leads/loss_reasons/4203748"
459
+ }
460
+ }
461
+ }
462
+ ],
463
+ "companies": [
464
+ {
465
+ "id": 10971463,
466
+ "_links": {
467
+ "self": {
468
+ "href": "https://example.amocrm.ru/api/v4/companies/10971463"
469
+ }
470
+ }
471
+ }
472
+ ],
473
+ "contacts": [
474
+ {
475
+ "id": 10971465,
476
+ "is_main": true,
477
+ "_links": {
478
+ "self": {
479
+ "href": "https://example.amocrm.ru/api/v4/contacts/10971465"
480
+ }
481
+ }
482
+ }
483
+ ]
484
+ }
485
+ }
486
+ """
487
+ url = f"{self.crm_url}/api/v4/leads/{lead_id}"
488
+ return self._send_api_request("get", url)
489
+
490
+ def get_leads(
491
+ self,
492
+ limit: int = 250,
493
+ page: int = 1,
494
+ with_params: Optional[list] = None,
495
+ filters: Optional[dict] = None,
496
+ filter_ids: Optional[list] = None,
497
+ order: Optional[dict] = None,
498
+ ) -> dict:
499
+ """Get leads
500
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads-api#leads-list
501
+ Args:
502
+ limit (int, optional): limit of rows. Defaults to 250.
503
+ page (int, optional): number of page. Defaults to 1.
504
+ with_params (Optional[list], optional): params. Defaults to None.
505
+ filters (Optional[dict], optional): filter params like {'[updated_at][from]': '<timestamp>'}. Defaults to None.
506
+ filter_ids (Optional[list], optional): filter ids like [1,2,2310]. Defaults to None.
507
+ order (Optional[dict], optional): order params like {'update_at': 'asc'}. Defaults to None.
508
+
509
+ Returns:
510
+ dict: {
511
+ "_page": 2,
512
+ "_links": {
513
+ "self": {
514
+ "href": "https://example.amocrm.ru/api/v4/leads?limit=2&page=2"
515
+ },
516
+ "next": {
517
+ "href": "https://example.amocrm.ru/api/v4/leads?limit=2&page=3"
518
+ },
519
+ "first": {
520
+ "href": "https://example.amocrm.ru/api/v4/leads?limit=2&page=1"
521
+ },
522
+ "prev": {
523
+ "href": "https://example.amocrm.ru/api/v4/leads?limit=2&page=1"
524
+ }
525
+ },
526
+ "_embedded": {
527
+ "leads": [
528
+ {
529
+ "id": 19619,
530
+ "name": "Сделка для примера",
531
+ "price": 46333,
532
+ "responsible_user_id": 123321,
533
+ "group_id": 625,
534
+ "status_id": 142,
535
+ "pipeline_id": 1300,
536
+ "loss_reason_id": null,
537
+ "source_id": null,
538
+ "created_by": 321123,
539
+ "updated_by": 321123,
540
+ "created_at": 1453279607,
541
+ "updated_at": 1502193501,
542
+ "closed_at": 1483005931,
543
+ "closest_task_at": null,
544
+ "is_deleted": false,
545
+ "custom_fields_values": null,
546
+ "score": null,
547
+ "account_id": 5135160,
548
+ "_links": {
549
+ "self": {
550
+ "href": "https://example.amocrm.ru/api/v4/leads/19619"
551
+ }
552
+ },
553
+ "_embedded": {
554
+ "tags": [],
555
+ "companies": []
556
+ }
557
+ },
558
+ {
559
+ "id": 14460,
560
+ "name": "Сделка для примера 2",
561
+ "price": 655,
562
+ "responsible_user_id": 123321,
563
+ "group_id": 625,
564
+ "status_id": 142,
565
+ "pipeline_id": 1300,
566
+ "loss_reason_id": null,
567
+ "source_id": null,
568
+ "created_by": 321123,
569
+ "updated_by": 321123,
570
+ "created_at": 1453279607,
571
+ "updated_at": 1502193501,
572
+ "closed_at": 1483005931,
573
+ "closest_task_at": null,
574
+ "is_deleted": false,
575
+ "custom_fields_values": null,
576
+ "score": null,
577
+ "account_id": 1351360,
578
+ "_links": {
579
+ "self": {
580
+ "href": "https://example.amocrm.ru/api/v4/leads/14460"
581
+ }
582
+ },
583
+ "_embedded": {
584
+ "tags": [],
585
+ "companies": []
586
+ }
587
+ }
588
+ ]
589
+ }
590
+ }
591
+ """
592
+ params: dict = {k: v for k, v in locals().items() if k != "self"}
593
+ return self._get_entities("leads", **params)
594
+
595
+ def get_unsorted_leads(
596
+ self,
597
+ page: int = 1,
598
+ limit: int = 250,
599
+ filter_by_uids: Union[str, list, None] = None,
600
+ filter_by_pipeline_id: Union[str, list, None] = None,
601
+ filter_by_category: Union[str, list, None] = None,
602
+ order_by: Optional[dict] = None,
603
+ ) -> dict:
604
+ """get unsorted leads
605
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/unsorted-api#unsorted-list
606
+ Args:
607
+ page (int, optional): number of page. Defaults to 1.
608
+ limit (int, optional): limit rows. Defaults to 250.
609
+ filter_by_uids (Union[str, list, None], optional): filter by uids, values str or list. Defaults to None.
610
+ filter_by_pipeline_id (Union[str, list, None], optional): filter by pipelines. Defaults to None.
611
+ filter_by_category (Union[str, list, None], optional): filter by category(sip, mail, forms, chats). Defaults to None.
612
+ order_by (Optional[dict], optional): orber by params like {'created_at': 'asc'}. Defaults to None.
613
+
614
+ Returns:
615
+ dict: {
616
+ "_page": 1,
617
+ "_links": {
618
+ "self": {
619
+ "href": "https://example.amocrm.ru/api/v4/leads/unsorted?filter[uid]=98fb033cefde74f5de1a5d3980a2a2d108037"
620
+ }
621
+ },
622
+ "_embedded": {
623
+ "unsorted": [
624
+ {
625
+ "uid": "98fb033cefde74f5de1a5d3980a2a2d108037",
626
+ "source_uid": null,
627
+ "source_name": "UIS",
628
+ "category": "sip",
629
+ "pipeline_id": 2194576,
630
+ "created_at": 1583156937,
631
+ "metadata": {
632
+ "from": "7999999999",
633
+ "phone": 7999999999,
634
+ "called_at": 1583156916,
635
+ "duration": "0",
636
+ "link": null,
637
+ "service_code": "uis_widget"
638
+ },
639
+ "account_id": 123312,
640
+ "_links": {
641
+ "self": {
642
+ "href": "https://example.amocrm.ru/api/v4/leads/unsorted/98fb033cefde74f5de1a5d3980a2a2d108037"
643
+ }
644
+ },
645
+ "_embedded": {
646
+ "contacts": [
647
+ {
648
+ "id": 13176707,
649
+ "_links": {
650
+ "self": {
651
+ "href": "https://example.amocrm.ru/api/v4/contacts/13176707"
652
+ }
653
+ }
654
+ }
655
+ ],
656
+ "leads": [
657
+ {
658
+ "id": 7002787,
659
+ "_links": {
660
+ "self": {
661
+ "href": "https://example.amocrm.ru/api/v4/leads/7002787"
662
+ }
663
+ }
664
+ }
665
+ ],
666
+ "companies": []
667
+ }
668
+ }
669
+ ]
670
+ }
671
+ }
672
+ """
673
+ url = f"{self.crm_url}/api/v4/leads/unsorted"
674
+ params: dict = {"limit": limit, "page": page}
675
+ orders = {}
676
+ if filter_by_uids:
677
+ params["filter[uid]"] = filter_by_uids # type: ignore
678
+ if filter_by_category:
679
+ params["filter[category]"] = filter_by_category # type: ignore
680
+ if filter_by_pipeline_id:
681
+ params["filter[pipeline_id]"] = filter_by_pipeline_id # type: ignore
682
+ if order_by:
683
+ orders = {f"order[{key}]": value for key, value in order_by.items()}
684
+ url = f"{url}?{urlencode(params)}"
685
+ if orders:
686
+ url = f"{url}&{urlencode(orders)}"
687
+ return self._send_api_request("get", url)
688
+
689
+ def get_unsorted_by_uid(self, uid: str) -> dict:
690
+ """Get unsorted obj by uid
691
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/unsorted-api#unsorted-detail
692
+ Args:
693
+ uid (str): uid
694
+
695
+ Returns:
696
+ dict: {
697
+ "uid": "aa401affb0094076b7449008363c1dc77d6790ad13fb5b08176dc46daa18",
698
+ "source_uid": "my_unique_uid",
699
+ "source_name": "Название источника",
700
+ "category": "forms",
701
+ "pipeline_id": 3166396,
702
+ "created_at": 1588840852,
703
+ "metadata": {
704
+ "form_id": "my_best_form",
705
+ "form_name": "Обратная связь",
706
+ "form_page": "https://example.com/form",
707
+ "ip": "192.168.0.1",
708
+ "form_sent_at": "1570178452",
709
+ "referer": "https://google.com/search",
710
+ "visitor_uid": null
711
+ },
712
+ "account_id": 28805383,
713
+ "_links": {
714
+ "self": {
715
+ "href": "https://example.amocrm.ru/api/v4/leads/unsorted/aa401affb0094076b7449008363c1dc77d6790ad13fb5b08176dc46daa18"
716
+ }
717
+ },
718
+ "_embedded": {
719
+ "contacts": [
720
+ {
721
+ "id": 9567221,
722
+ "_links": {
723
+ "self": {
724
+ "href": "https://example.amocrm.ru/api/v4/contacts/9567221"
725
+ }
726
+ }
727
+ }
728
+ ],
729
+ "leads": [
730
+ {
731
+ "id": 6414851,
732
+ "_links": {
733
+ "self": {
734
+ "href": "https://example.amocrm.ru/api/v4/leads/6414851"
735
+ }
736
+ }
737
+ }
738
+ ],
739
+ "companies": []
740
+ }
741
+ }
742
+ """
743
+ url = f"{self.crm_url}/api/v4/leads/unsorted/{uid}"
744
+ return self._send_api_request("get", url)
745
+
746
+ def _create_unsorted(
747
+ self,
748
+ entity: str,
749
+ source_uid: str,
750
+ source_name: str,
751
+ metadata: dict,
752
+ contact: dict,
753
+ lead: dict,
754
+ comapany: dict,
755
+ pipeline_id: Optional[int] = None,
756
+ created_at: Optional[int] = None,
757
+ request_id: Optional[str] = None,
758
+ ) -> dict:
759
+ """create unsorted
760
+
761
+ Args:
762
+ entity (str): form or sip
763
+ source_uid (str): unique uid
764
+ source_name (str): name of unsorted object
765
+ metadata (dict): meta object
766
+ contact (dict): contact object
767
+ lead (dict): lead object
768
+ comapany (dict): company object
769
+ pipeline_id (Optional[int], optional): id of pipeline. Defaults to None.
770
+ created_at (Optional[int], optional): tamstamp of lead created. Defaults to None.
771
+ request_id (Optional[str], optional): str. Defaults to None.
772
+
773
+ Returns:
774
+ dict: {
775
+ "_total_items": 1,
776
+ "_embedded": {
777
+ "unsorted": [
778
+ {
779
+ "uid": "aa401affb0094076b74442bc3f401d53e103f264d6668fd3ecfd5acef42f",
780
+ "account_id": 28805383,
781
+ "request_id": "123",
782
+ "_links": {
783
+ "self": {
784
+ "href": "https://example.amocrm.ru/api/v4/leads/unsorted/aa401affb0094076b74442bc3f401d53e103f264d6668fd3ecfd5acef42f"
785
+ }
786
+ },
787
+ "_embedded": {
788
+ "contacts": [
789
+ {
790
+ "id": 11075541,
791
+ "_links": {
792
+ "self": {
793
+ "href": "https://example.amocrm.ru/api/v4/contacts/11075541"
794
+ }
795
+ }
796
+ }
797
+ ],
798
+ "leads": [
799
+ {
800
+ "id": 7706509,
801
+ "_links": {
802
+ "self": {
803
+ "href": "https://example.amocrm.ru/api/v4/leads/7706509"
804
+ }
805
+ }
806
+ }
807
+ ],
808
+ "companies": []
809
+ }
810
+ }
811
+ ]
812
+ }
813
+ }
814
+ """
815
+ url = f"{self.crm_url}/api/v4/leads/unsorted/{entity}"
816
+ params: dict = {
817
+ "source_uid": source_uid,
818
+ "source_name": source_name,
819
+ "metadata": metadata,
820
+ "contact": contact,
821
+ }
822
+ _embedded = {"contacts": [contact], "leads": [lead], "companies": [comapany]}
823
+ params["_embedded"] = _embedded
824
+ if request_id:
825
+ params["request_id"] = request_id
826
+ if pipeline_id:
827
+ params["pipeline_id"] = pipeline_id # type: ignore
828
+ if created_at:
829
+ params["created_at"] = created_at # type: ignore
830
+ return self._send_api_request("post", url, [params])
831
+
832
+ def create_unsorted_by_sip(
833
+ self,
834
+ source_uid: str,
835
+ source_name: str,
836
+ metadata: dict,
837
+ contact: dict,
838
+ lead: dict,
839
+ comapany: dict,
840
+ pipeline_id: Optional[int] = None,
841
+ created_at: Optional[int] = None,
842
+ request_id: Optional[str] = None,
843
+ ) -> dict:
844
+ """
845
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/unsorted-api#unsorted-add-sip
846
+ """
847
+ params: dict = {k: v for k, v in locals().items() if k != "self"}
848
+ return self._create_unsorted(entity="sip", **params)
849
+
850
+ def create_unsorted_by_form(
851
+ self,
852
+ source_uid: str,
853
+ source_name: str,
854
+ metadata: dict,
855
+ contact: dict,
856
+ lead: dict,
857
+ comapany: dict,
858
+ pipeline_id: Optional[int] = None,
859
+ created_at: Optional[int] = None,
860
+ request_id: Optional[str] = None,
861
+ ) -> dict:
862
+ """
863
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/unsorted-api#unsorted-add-form
864
+ """
865
+ params: dict = {k: v for k, v in locals().items() if k != "self"}
866
+ return self._create_unsorted(entity="form", **params)
867
+
868
+ def accept_unsorted(self, uid: str, user_id: int, status_id: int) -> dict:
869
+ """Accept unsorted
870
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/unsorted-api#unsorted-accept
871
+ Args:
872
+ uid (str): unsorted obejct uid
873
+ user_id (int): user id
874
+ status_id (int): status id
875
+
876
+ Returns:
877
+ dict: {
878
+ "uid": "3cvd1de2ebfsd152fd6a465cd3e586cbdba6827",
879
+ "pipeline_id": 31634,
880
+ "category": "mail",
881
+ "created_at": 1589165593,
882
+ "_embedded": {
883
+ "leads": [
884
+ {
885
+ "id": 9944789,
886
+ "_links": {
887
+ "self": {
888
+ "href": "https://example.amocrm.ru/api/v4/leads/9944789"
889
+ }
890
+ }
891
+ }
892
+ ],
893
+ "contacts": [
894
+ {
895
+ "id": 16522451,
896
+ "_links": {
897
+ "self": {
898
+ "href": "https://example.amocrm.ru/api/v4/contacts/16522451"
899
+ }
900
+ }
901
+ }
902
+ ],
903
+ "companies": []
904
+ }
905
+ }
906
+ """
907
+ url = f"{self.crm_url}/api/v4/leads/unsorted/{uid}/accept"
908
+ params = {"user_id": user_id, "status_id": status_id}
909
+ return self._send_api_request("post", url, params)
910
+
911
+ def decline_unsorted(self, uid: str, user_id: int) -> dict:
912
+ """Decline unsorted
913
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/unsorted-api#unsorted-decline
914
+ Args:
915
+ uid (str): unsorted object uid
916
+ user_id (int): user id
917
+
918
+ Returns:
919
+ dict: {
920
+ "uid": "98bc1d1de2f960a2ad0e34b52823",
921
+ "pipeline_id": 1394576,
922
+ "category": "mail",
923
+ "created_at": 1589115506,
924
+ "_embedded": {
925
+ "leads": [
926
+ {
927
+ "id": 9937533,
928
+ "_links": {
929
+ "self": {
930
+ "href": "https://example.amocrm.ru/api/v4/leads/9937533"
931
+ }
932
+ }
933
+ }
934
+ ],
935
+ "contacts": [
936
+ {
937
+ "id": 163141,
938
+ "_links": {
939
+ "self": {
940
+ "href": "https://example.amocrm.ru/api/v4/contacts/163141"
941
+ }
942
+ }
943
+ }
944
+ ]
945
+ }
946
+ }
947
+ """
948
+ url = f"{self.crm_url}/api/v4/leads/unsorted/{uid}/decline"
949
+ params = {"user_id": user_id}
950
+ return self._send_api_request("delete", url, params)
951
+
952
+ def link_unsorted(self, uid: str, user_id: int, link: dict) -> dict:
953
+ """Link unsorted to another entity
954
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/unsorted-api#unsorted-link
955
+ Args:
956
+ uid (str): unsorted object uid
957
+ user_id (int): user id
958
+ link (dict): link object like {'entity_id': 123, 'entity_type': 'leads'}
959
+
960
+ Returns:
961
+ dict: {
962
+ "uid": "d7faa21ce091fe0da05d8d4c2075090c1e9bfd4",
963
+ "_embedded": {
964
+ "leads": [
965
+ {
966
+ "id": 93144801,
967
+ "_links": {
968
+ "self": {
969
+ "href": "https://example.amocrm.ru/api/v4/leads/93144801"
970
+ }
971
+ }
972
+ }
973
+ ]
974
+ }
975
+ }
976
+ """
977
+ url = f"{self.crm_url}api/v4/leads/unsorted/{uid}/link"
978
+ params = {"user_id": user_id, "link": link}
979
+ return self._send_api_request("post", url, params)
980
+
981
+ def get_summary_unsorted(
982
+ self,
983
+ uid: Union[str, list, None] = None,
984
+ created_at__from: Optional[str] = None,
985
+ created_at__to: Optional[str] = None,
986
+ pipeline_id: Union[str, list, None] = None,
987
+ ) -> dict:
988
+ """Get summarty unsorted object
989
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/unsorted-api#unsorted-summary
990
+ Args:
991
+ uid (Union[str, list, None], optional): list or str uids. Defaults to None.
992
+ created_at__from (Optional[str], optional): timestamp. Defaults to None.
993
+ created_at__to (Optional[str]], optional): timestamp. Defaults to None.
994
+ pipeline_id (Union[str, list, None], optional): int. Defaults to None.
995
+
996
+ Returns:
997
+ dict: {
998
+ "total": 168,
999
+ "accepted": 6,
1000
+ "declined": 2,
1001
+ "average_sort_time": 34521,
1002
+ "categories": {
1003
+ "sip": {
1004
+ "total": 31
1005
+ },
1006
+ "mail": {
1007
+ "total": 41
1008
+ },
1009
+ "forms": {
1010
+ "total": 27
1011
+ },
1012
+ "chats": {
1013
+ "total": 69
1014
+ }
1015
+ }
1016
+ }
1017
+ """
1018
+ params = {}
1019
+ if uid:
1020
+ params["filter[uid]"] = uid
1021
+ if created_at__from:
1022
+ params["filter[created_at][from]"] = created_at__from
1023
+ if created_at__to:
1024
+ params["filter[created_at][to]"] = created_at__to
1025
+ if pipeline_id:
1026
+ params["filter[pipeline_id]"] = pipeline_id
1027
+ url = f"{self.crm_url}/api/v4/leads/unsorted/summary?{urlencode(params)}"
1028
+ return self._send_api_request("get", url)
1029
+
1030
+ def get_pipelines(self) -> dict:
1031
+ """get leads pipelines
1032
+
1033
+ Returns:
1034
+ dict: {
1035
+ "_total_items": 1,
1036
+ "_links": {
1037
+ "self": {
1038
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines"
1039
+ }
1040
+ },
1041
+ "_embedded": {
1042
+ "pipelines": [
1043
+ {
1044
+ "id": 3177727,
1045
+ "name": "Воронка",
1046
+ "sort": 1,
1047
+ "is_main": true,
1048
+ "is_unsorted_on": true,
1049
+ "is_archive": false,
1050
+ "account_id": 12345678,
1051
+ "_links": {
1052
+ "self": {
1053
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727"
1054
+ }
1055
+ },
1056
+ "_embedded": {
1057
+ "statuses": [
1058
+ {
1059
+ "id": 32392156,
1060
+ "name": "Неразобранное",
1061
+ "sort": 10,
1062
+ "is_editable": false,
1063
+ "pipeline_id": 3177727,
1064
+ "color": "#c1c1c1",
1065
+ "type": 1,
1066
+ "account_id": 12345678,
1067
+ "_links": {
1068
+ "self": {
1069
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/32392156"
1070
+ }
1071
+ }
1072
+ },
1073
+ {
1074
+ "id": 32392159,
1075
+ "name": "Первичный контакт",
1076
+ "sort": 20,
1077
+ "is_editable": true,
1078
+ "pipeline_id": 3177727,
1079
+ "color": "#99ccff",
1080
+ "type": 0,
1081
+ "account_id": 12345678,
1082
+ "_links": {
1083
+ "self": {
1084
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/32392159"
1085
+ }
1086
+ }
1087
+ },
1088
+ {
1089
+ "id": 32392165,
1090
+ "name": "Принимают решение",
1091
+ "sort": 30,
1092
+ "is_editable": true,
1093
+ "pipeline_id": 3177727,
1094
+ "color": "#ffcc66",
1095
+ "type": 0,
1096
+ "account_id": 12345678,
1097
+ "_links": {
1098
+ "self": {
1099
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/32392165"
1100
+ }
1101
+ }
1102
+ },
1103
+ {
1104
+ "id": 142,
1105
+ "name": "Успешно реализовано",
1106
+ "sort": 10000,
1107
+ "is_editable": false,
1108
+ "pipeline_id": 3177727,
1109
+ "color": "#CCFF66",
1110
+ "type": 0,
1111
+ "account_id": 12345678,
1112
+ "_links": {
1113
+ "self": {
1114
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/142"
1115
+ }
1116
+ }
1117
+ },
1118
+ {
1119
+ "id": 143,
1120
+ "name": "Закрыто и не реализовано",
1121
+ "sort": 11000,
1122
+ "is_editable": false,
1123
+ "pipeline_id": 3177727,
1124
+ "color": "#D5D8DB",
1125
+ "type": 0,
1126
+ "account_id": 12345678,
1127
+ "_links": {
1128
+ "self": {
1129
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/143"
1130
+ }
1131
+ }
1132
+ }
1133
+ ]
1134
+ }
1135
+ }
1136
+ ]
1137
+ }
1138
+ }
1139
+ """
1140
+ url = f"{self.crm_url}/api/v4/leads/pipelines"
1141
+ return self._send_api_request("get", url)
1142
+
1143
+ def get_pipeline(self, pipeline_id: int) -> dict:
1144
+ """get leads pipeline
1145
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads_pipelines#pipelines-list
1146
+ Returns:
1147
+ dict: {
1148
+ "id": 3177727,
1149
+ "name": "Воронка",
1150
+ "sort": 1,
1151
+ "is_main": true,
1152
+ "is_unsorted_on": true,
1153
+ "is_archive": false,
1154
+ "account_id": 28847170,
1155
+ "_links": {
1156
+ "self": {
1157
+ "href": "https://shard152.amocrm.ru/api/v4/leads/pipelines/3177727"
1158
+ }
1159
+ },
1160
+ "_embedded": {
1161
+ "statuses": [
1162
+ {
1163
+ "id": 32392156,
1164
+ "name": "Неразобранное",
1165
+ "sort": 10,
1166
+ "is_editable": false,
1167
+ "pipeline_id": 3177727,
1168
+ "color": "#c1c1c1",
1169
+ "type": 1,
1170
+ "account_id": 28847170,
1171
+ "_links": {
1172
+ "self": {
1173
+ "href": "https://shard152.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/32392156"
1174
+ }
1175
+ }
1176
+ },
1177
+ {
1178
+ "id": 32392159,
1179
+ "name": "Первичный контакт",
1180
+ "sort": 20,
1181
+ "is_editable": true,
1182
+ "pipeline_id": 3177727,
1183
+ "color": "#99ccff",
1184
+ "type": 0,
1185
+ "account_id": 28847170,
1186
+ "_links": {
1187
+ "self": {
1188
+ "href": "https://shard152.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/32392159"
1189
+ }
1190
+ }
1191
+ },
1192
+ {
1193
+ "id": 32392165,
1194
+ "name": "Принимают решение",
1195
+ "sort": 30,
1196
+ "is_editable": true,
1197
+ "pipeline_id": 3177727,
1198
+ "color": "#ffcc66",
1199
+ "type": 0,
1200
+ "account_id": 28847170,
1201
+ "_links": {
1202
+ "self": {
1203
+ "href": "https://shard152.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/32392165"
1204
+ }
1205
+ }
1206
+ },
1207
+ {
1208
+ "id": 142,
1209
+ "name": "Успешно реализовано",
1210
+ "sort": 10000,
1211
+ "is_editable": false,
1212
+ "pipeline_id": 3177727,
1213
+ "color": "#CCFF66",
1214
+ "type": 0,
1215
+ "account_id": 28847170,
1216
+ "_links": {
1217
+ "self": {
1218
+ "href": "https://shard152.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/142"
1219
+ }
1220
+ }
1221
+ },
1222
+ {
1223
+ "id": 143,
1224
+ "name": "Закрыто и не реализовано",
1225
+ "sort": 11000,
1226
+ "is_editable": false,
1227
+ "pipeline_id": 3177727,
1228
+ "color": "#D5D8DB",
1229
+ "type": 0,
1230
+ "account_id": 28847170,
1231
+ "_links": {
1232
+ "self": {
1233
+ "href": "https://shard152.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/143"
1234
+ }
1235
+ }
1236
+ }
1237
+ ]
1238
+ }
1239
+ }
1240
+ """
1241
+ url = f"{self.crm_url}/api/v4/leads/pipelines/{pipeline_id}"
1242
+ return self._send_api_request("get", url)
1243
+
1244
+ def create_pipeline(
1245
+ self,
1246
+ name: str,
1247
+ sort: int,
1248
+ is_main: bool,
1249
+ statuses: list,
1250
+ is_unsorted_on: bool = False,
1251
+ request_id: Optional[str] = None,
1252
+ ) -> dict:
1253
+ """craete pipeline
1254
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads_pipelines#pipelines-add
1255
+ Args:
1256
+ name (str): name of pipeline
1257
+ sort (int): sort of pipeline
1258
+ is_main (bool): True or False, True if is main pipeline
1259
+ statuses (list): list of statuses objects
1260
+ is_unsorted_on (bool, optional): True if unsorted is enabled. Defaults to False.
1261
+ request_id (Optional[str], optional): random string for check request. Defaults to None.
1262
+
1263
+ Returns:
1264
+ dict: query result
1265
+ """
1266
+ url = f"{self.crm_url}/api/v4/leads/pipelines"
1267
+ params = {
1268
+ "name": name,
1269
+ "sort": sort,
1270
+ "is_main": is_main,
1271
+ "_embedded": {"statuses": statuses},
1272
+ "is_unsorted_on": is_unsorted_on,
1273
+ }
1274
+ if request_id:
1275
+ params["request_id"] = request_id
1276
+ return self._send_api_request("post", url, [params])
1277
+
1278
+ def edit_pipeline(
1279
+ self,
1280
+ pipeline_id: int,
1281
+ name: str,
1282
+ sort: int,
1283
+ is_main: bool,
1284
+ is_unsorted_on: bool,
1285
+ ) -> dict:
1286
+ """Edit pipeline
1287
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads_pipelines#pipeline-edit
1288
+ Args:
1289
+ pipeline_id (int): id of pipeline
1290
+ name (str): name of pipeline
1291
+ sort (int): sort of pipeline
1292
+ is_main (bool): True or False, True if is main pipeline
1293
+ is_unsorted_on (bool): True if unsorted is enabled
1294
+
1295
+ Returns:
1296
+ dict: query result
1297
+ """
1298
+ url = f"{self.crm_url}/api/v4/leads/pipelines/{pipeline_id}"
1299
+ params = {
1300
+ "name": name,
1301
+ "sort": sort,
1302
+ "is_main": is_main,
1303
+ "is_unsorted_on": is_unsorted_on,
1304
+ }
1305
+ return self._send_api_request("patch", url, params)
1306
+
1307
+ def delete_pipeline(self, pipeline_id: int) -> dict:
1308
+ """Delete pipeline
1309
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads_pipelines#pipeline-delete
1310
+ Args:
1311
+ pipeline_id (int): id of pipeline
1312
+
1313
+ Returns:
1314
+ dict: query result
1315
+ """
1316
+ url = f"{self.crm_url}/api/v4/leads/pipelines/{pipeline_id}"
1317
+ return self._send_api_request("delete", url)
1318
+
1319
+ def get_pipeline_statuses(self, pipeline_id: int) -> dict:
1320
+ """return pipeline Statuses
1321
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads_pipelines#statuses-list
1322
+ Args:
1323
+ pipeline_id (int): id of pipeline
1324
+ Returns:
1325
+ dict: {
1326
+ "_total_items": 1,
1327
+ "_links": {
1328
+ "self": {
1329
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines"
1330
+ }
1331
+ },
1332
+ "_embedded": {
1333
+ "pipelines": [
1334
+ {
1335
+ "id": 3177727,
1336
+ "name": "Воронка",
1337
+ "sort": 1,
1338
+ "is_main": true,
1339
+ "is_unsorted_on": true,
1340
+ "is_archive": false,
1341
+ "account_id": 12345678,
1342
+ "_links": {
1343
+ "self": {
1344
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727"
1345
+ }
1346
+ },
1347
+ "_embedded": {
1348
+ "statuses": [
1349
+ {
1350
+ "id": 32392156,
1351
+ "name": "Неразобранное",
1352
+ "sort": 10,
1353
+ "is_editable": false,
1354
+ "pipeline_id": 3177727,
1355
+ "color": "#c1c1c1",
1356
+ "type": 1,
1357
+ "account_id": 12345678,
1358
+ "_links": {
1359
+ "self": {
1360
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/32392156"
1361
+ }
1362
+ }
1363
+ },
1364
+ {
1365
+ "id": 32392159,
1366
+ "name": "Первичный контакт",
1367
+ "sort": 20,
1368
+ "is_editable": true,
1369
+ "pipeline_id": 3177727,
1370
+ "color": "#99ccff",
1371
+ "type": 0,
1372
+ "account_id": 12345678,
1373
+ "_links": {
1374
+ "self": {
1375
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/32392159"
1376
+ }
1377
+ }
1378
+ },
1379
+ {
1380
+ "id": 32392165,
1381
+ "name": "Принимают решение",
1382
+ "sort": 30,
1383
+ "is_editable": true,
1384
+ "pipeline_id": 3177727,
1385
+ "color": "#ffcc66",
1386
+ "type": 0,
1387
+ "account_id": 12345678,
1388
+ "_links": {
1389
+ "self": {
1390
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/32392165"
1391
+ }
1392
+ }
1393
+ },
1394
+ {
1395
+ "id": 142,
1396
+ "name": "Успешно реализовано",
1397
+ "sort": 10000,
1398
+ "is_editable": false,
1399
+ "pipeline_id": 3177727,
1400
+ "color": "#CCFF66",
1401
+ "type": 0,
1402
+ "account_id": 12345678,
1403
+ "_links": {
1404
+ "self": {
1405
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/142"
1406
+ }
1407
+ }
1408
+ },
1409
+ {
1410
+ "id": 143,
1411
+ "name": "Закрыто и не реализовано",
1412
+ "sort": 11000,
1413
+ "is_editable": false,
1414
+ "pipeline_id": 3177727,
1415
+ "color": "#D5D8DB",
1416
+ "type": 0,
1417
+ "account_id": 12345678,
1418
+ "_links": {
1419
+ "self": {
1420
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/143"
1421
+ }
1422
+ }
1423
+ }
1424
+ ]
1425
+ }
1426
+ }
1427
+ ]
1428
+ }
1429
+ }
1430
+ """
1431
+ url = f"{self.crm_url}/api/v4/leads/pipelines/{pipeline_id}/statuses"
1432
+ return self._send_api_request("get", url)
1433
+
1434
+ def get_pipeline_status(self, pipeline_id: int, status_id: int) -> dict:
1435
+ """Get status
1436
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads_pipelines#status-detail
1437
+ Args:
1438
+ pipeline_id (int): id of pipeline
1439
+ status_id (int): id of status
1440
+
1441
+ Returns:
1442
+ dict: {
1443
+ "id": 32392156,
1444
+ "name": "Неразобранное",
1445
+ "sort": 10,
1446
+ "is_editable": false,
1447
+ "pipeline_id": 3177727,
1448
+ "color": "#c1c1c1",
1449
+ "type": 1,
1450
+ "account_id": 12345678,
1451
+ "_links": {
1452
+ "self": {
1453
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/32392156"
1454
+ }
1455
+ }
1456
+ }
1457
+ """
1458
+ url = (
1459
+ f"{self.crm_url}/api/v4/leads/pipelines/{pipeline_id}/statuses/{status_id}"
1460
+ )
1461
+ return self._send_api_request("get", url)
1462
+
1463
+ def add_statuses_to_pipeline(self, pipeline_id: int, statuses: list) -> dict:
1464
+ """Add status tot pipeline
1465
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads_pipelines#statuses-add
1466
+ Args:
1467
+ pipeline_id (int): id of pipeline
1468
+ statuses (list): list of status object
1469
+
1470
+ Returns:
1471
+ dict: {
1472
+ "_total_items": 2,
1473
+ "_embedded": {
1474
+ "statuses": [
1475
+ {
1476
+ "id": 33035290,
1477
+ "name": "Новый этап",
1478
+ "sort": 60,
1479
+ "is_editable": true,
1480
+ "pipeline_id": 3270355,
1481
+ "color": "#fffeb2",
1482
+ "type": 0,
1483
+ "account_id": 1415131,
1484
+ "request_id": "0",
1485
+ "_links": {
1486
+ "self": {
1487
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3270355/statuses/33035290"
1488
+ }
1489
+ }
1490
+ },
1491
+ {
1492
+ "id": 33035293,
1493
+ "name": "Новый этап 2",
1494
+ "sort": 70,
1495
+ "is_editable": true,
1496
+ "pipeline_id": 3270355,
1497
+ "color": "#fffeb2",
1498
+ "type": 0,
1499
+ "account_id": 1415131,
1500
+ "request_id": "1",
1501
+ "_links": {
1502
+ "self": {
1503
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3270355/statuses/33035293"
1504
+ }
1505
+ }
1506
+ }
1507
+ ]
1508
+ }
1509
+ }
1510
+ """
1511
+ url = f"{self.crm_url}/api/v4/leads/pipelines/{pipeline_id}/statuses"
1512
+ return self._send_api_request("post", url, statuses)
1513
+
1514
+ def edit_pipeline_status(
1515
+ self, pipeline_id: int, status_id: int, name: str, sort: int, color: str
1516
+ ) -> dict:
1517
+ """Edit pipeline status
1518
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads_pipelines#status-edit
1519
+ Args:
1520
+ pipeline_id (int): id of pipeline
1521
+ status_id (int): id of status
1522
+ name (str): status name
1523
+ sort (int): sort of status
1524
+ color (str): status color
1525
+
1526
+ Returns:
1527
+ dict: {
1528
+ "id": 32392165,
1529
+ "name": "Новое название для статуса",
1530
+ "sort": 20,
1531
+ "is_editable": true,
1532
+ "pipeline_id": 3177727,
1533
+ "color": "#c1e0ff",
1534
+ "type": 0,
1535
+ "account_id": 12345678,
1536
+ "request_id": "0",
1537
+ "_links": {
1538
+ "self": {
1539
+ "href": "https://example.amocrm.ru/api/v4/leads/pipelines/3177727/statuses/32392165"
1540
+ }
1541
+ }
1542
+ }
1543
+ """
1544
+ url = (
1545
+ f"{self.crm_url}/api/v4/leads/pipelines/{pipeline_id}/statuses/{status_id}"
1546
+ )
1547
+ params = {"name": name, "sort": sort, "color": color}
1548
+ return self._send_api_request("patch", url, params)
1549
+
1550
+ def delete_status_from_pipeline(self, pipeline_id: int, status_id: int) -> dict:
1551
+ """Delete status from pipeline
1552
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/leads_pipelines#status-delete
1553
+ Args:
1554
+ pipeline_id (int): id of pipeline
1555
+ status_id (int): id of status
1556
+
1557
+ Returns:
1558
+ dict: {}
1559
+ """
1560
+ url = (
1561
+ f"{self.crm_url}/api/v4/leads/pipelines/{pipeline_id}/statuses/{status_id}"
1562
+ )
1563
+ return self._send_api_request("delete", url)
1564
+
1565
+ def get_contacts(
1566
+ self,
1567
+ limit: int = 250,
1568
+ page: int = 1,
1569
+ with_params: Optional[list] = None,
1570
+ filters: Optional[dict] = None,
1571
+ order: Optional[dict] = None,
1572
+ ) -> dict:
1573
+ """Get contacts
1574
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/contacts-api#contacts-list
1575
+ Args:
1576
+ limit (int, optional): limit of rows. Defaults to 250.
1577
+ page (int, optional): number of page. Defaults to 1.
1578
+ with_params (Optional[list], optional): params. Defaults to None.
1579
+ filters (Optional[dict], optional): filter params like {'[updated_at][from]': '<timestamp>'}. Defaults to None.
1580
+ order (Optional[dict], optional): filter params like {'updated_at': 'asc'}. Defaults to None.
1581
+ Returns:
1582
+ dict:{
1583
+ "_page": 1,
1584
+ "_links": {
1585
+ "self": {
1586
+ "href": "https://example.amocrm.ru/api/v4/contacts?limit=2&page=1"
1587
+ },
1588
+ "next": {
1589
+ "href": "https://example.amocrm.ru/api/v4/contacts?limit=2&page=2"
1590
+ }
1591
+ },
1592
+ "_embedded": {
1593
+ "contacts": [
1594
+ {
1595
+ "id": 7143599,
1596
+ "name": "1",
1597
+ "first_name": "",
1598
+ "last_name": "",
1599
+ "responsible_user_id": 504141,
1600
+ "group_id": 0,
1601
+ "created_by": 504141,
1602
+ "updated_by": 504141,
1603
+ "created_at": 1585758065,
1604
+ "updated_at": 1585758065,
1605
+ "closest_task_at": null,
1606
+ "custom_fields_values": null,
1607
+ "account_id": 28805383,
1608
+ "_links": {
1609
+ "self": {
1610
+ "href": "https://example.amocrm.ru/api/v4/contacts/7143599"
1611
+ }
1612
+ },
1613
+ "_embedded": {
1614
+ "tags": [],
1615
+ "companies": []
1616
+ }
1617
+ },
1618
+ {
1619
+ "id": 7767065,
1620
+ "name": "dsgdsg",
1621
+ "first_name": "",
1622
+ "last_name": "",
1623
+ "responsible_user_id": 504141,
1624
+ "group_id": 0,
1625
+ "created_by": 504141,
1626
+ "updated_by": 504141,
1627
+ "created_at": 1586359590,
1628
+ "updated_at": 1586359590,
1629
+ "closest_task_at": null,
1630
+ "custom_fields_values": null,
1631
+ "account_id": 28805383,
1632
+ "_links": {
1633
+ "self": {
1634
+ "href": "https://example.amocrm.ru/api/v4/contacts/7767065"
1635
+ }
1636
+ },
1637
+ "_embedded": {
1638
+ "tags": [],
1639
+ "companies": []
1640
+ }
1641
+ }
1642
+ ]
1643
+ }
1644
+ }
1645
+ """
1646
+ params = {k: v for k, v in locals().items() if k != "self"}
1647
+ return self._get_entities("contacts", **params)
1648
+
1649
+ def get_contact(self, contact_id: int) -> dict:
1650
+ """Get contact
1651
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/contacts-api#contact-detail
1652
+ Args:
1653
+ contact_id (int): id of contact
1654
+
1655
+ Returns:
1656
+ dict: {
1657
+ "id": 3,
1658
+ "name": "Иван Иванов",
1659
+ "first_name": "Иван",
1660
+ "last_name": "Иванов",
1661
+ "responsible_user_id": 504141,
1662
+ "group_id": 0,
1663
+ "created_by": 504141,
1664
+ "updated_by": 504141,
1665
+ "created_at": 1582117331,
1666
+ "updated_at": 1590943929,
1667
+ "closest_task_at": null,
1668
+ "custom_fields_values": [
1669
+ {
1670
+ "field_id": 3,
1671
+ "field_name": "Телефон",
1672
+ "field_code": "PHONE",
1673
+ "field_type": "multitext",
1674
+ "values": [
1675
+ {
1676
+ "value": "+79123",
1677
+ "enum_id": 1,
1678
+ "enum": "WORK"
1679
+ }
1680
+ ]
1681
+ }
1682
+ ],
1683
+ "account_id": 28805383,
1684
+ "_links": {
1685
+ "self": {
1686
+ "href": "https://example.amocrm.ru/api/v4/contacts/3"
1687
+ }
1688
+ },
1689
+ "_embedded": {
1690
+ "tags": [],
1691
+ "leads": [
1692
+ {
1693
+ "id": 1,
1694
+ "_links": {
1695
+ "self": {
1696
+ "href": "https://example.amocrm.ru/api/v4/leads/1"
1697
+ }
1698
+ }
1699
+ },
1700
+ {
1701
+ "id": 3916883,
1702
+ "_links": {
1703
+ "self": {
1704
+ "href": "https://example.amocrm.ru/api/v4/leads/3916883"
1705
+ }
1706
+ }
1707
+ }
1708
+ ],
1709
+ "customers": [
1710
+ {
1711
+ "id": 134923,
1712
+ "_links": {
1713
+ "self": {
1714
+ "href": "https://example.amocrm.ru/api/v4/customers/134923"
1715
+ }
1716
+ }
1717
+ }
1718
+ ],
1719
+ "catalog_elements": [],
1720
+ "companies": [
1721
+ {
1722
+ "id": 1,
1723
+ "_links": {
1724
+ "self": {
1725
+ "href": "https://example.amocrm.ru/api/v4/companies/1"
1726
+ }
1727
+ }
1728
+ }
1729
+ ]
1730
+ }
1731
+ }
1732
+ """
1733
+ url = f"{self.crm_url}/api/v4/contacts/{contact_id}"
1734
+ return self._send_api_request("get", url)
1735
+
1736
+ def create_contacts(self, contacts: list) -> dict:
1737
+ """Create contacts
1738
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/contacts-api#contacts-add
1739
+ Args:
1740
+ contacts (list): list of contacts objects
1741
+
1742
+ Returns:
1743
+ dict: {
1744
+ "_links": {
1745
+ "self": {
1746
+ "href": "https://example.amocrm.ru/api/v4/contacts"
1747
+ }
1748
+ },
1749
+ "_embedded": {
1750
+ "contacts": [
1751
+ {
1752
+ "id": 40401635,
1753
+ "request_id": "0",
1754
+ "_links": {
1755
+ "self": {
1756
+ "href": "https://example.amocrm.ru/api/v4/contacts/40401635"
1757
+ }
1758
+ },
1759
+ {
1760
+ "id": 40401636,
1761
+ "request_id": "1",
1762
+ "_links": {
1763
+ "self": {
1764
+ "href": "https://example.amocrm.ru/api/v4/contacts/40401636"
1765
+ }
1766
+ }
1767
+ }
1768
+ ]
1769
+ }
1770
+ }
1771
+ """
1772
+ return self._create_or_update_entities("contacts", contacts)
1773
+
1774
+ def update_contacts(self, contacts: list) -> dict:
1775
+ """Update contacts
1776
+
1777
+ Args:
1778
+ contacts (list): list of contacts object
1779
+
1780
+ Returns:
1781
+ dict: {
1782
+ "_links": {
1783
+ "self": {
1784
+ "href": "https://example.amocrm.ru/api/v4/contacts"
1785
+ }
1786
+ },
1787
+ "_embedded": {
1788
+ "contacts": [
1789
+ {
1790
+ "id": 3,
1791
+ "name": "Иван Иванов",
1792
+ "updated_at": 1590945248,
1793
+ "_links": {
1794
+ "self": {
1795
+ "href": "https://example.amocrm.ru/api/v4/contacts/3"
1796
+ }
1797
+ }
1798
+ }
1799
+ ]
1800
+ }
1801
+ }
1802
+ """
1803
+ url = f"{self.crm_url}/api/v4/contacts"
1804
+ return self._create_or_update_entities("contacts", contacts, True)
1805
+
1806
+ def get_companies(
1807
+ self,
1808
+ limit: int = 250,
1809
+ page: int = 1,
1810
+ with_params: Optional[list] = None,
1811
+ filters: Optional[dict] = None,
1812
+ order: Optional[dict] = None,
1813
+ ) -> dict:
1814
+ """Get companies
1815
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/companies-api#companies-list
1816
+ Args:
1817
+ limit (int, optional): limit of page. Defaults to 250.
1818
+ page (int, optional): page index. Defaults to 1.
1819
+ with_params (Optional[list], optional): with params(check dock). Defaults to None.
1820
+ filters (Optional[dict], optional): dict filters like({'[updated_at][from]: "<timestamp>"'}). Defaults to None.
1821
+ order (Optional[dict], optional): dict like - {'updated_at': 'asc'}. Defaults to None.
1822
+
1823
+ Returns:
1824
+ dict: {
1825
+ "_page": 1,
1826
+ "_links": {
1827
+ "self": {
1828
+ "href": "https://example.amocrm.ru/api/v4/companies?limit=2&page=1"
1829
+ },
1830
+ "next": {
1831
+ "href": "https://example.amocrm.ru/api/v4/companies?limit=2&page=2"
1832
+ }
1833
+ },
1834
+ "_embedded": {
1835
+ "companies": [
1836
+ {
1837
+ "id": 7767077,
1838
+ "name": "Компания Васи",
1839
+ "responsible_user_id": 504141,
1840
+ "group_id": 0,
1841
+ "created_by": 504141,
1842
+ "updated_by": 504141,
1843
+ "created_at": 1586359618,
1844
+ "updated_at": 1586359618,
1845
+ "closest_task_at": null,
1846
+ "custom_fields_values": null,
1847
+ "account_id": 28805383,
1848
+ "_links": {
1849
+ "self": {
1850
+ "href": "https://example.amocrm.ru/api/v4/companies/7767077"
1851
+ }
1852
+ },
1853
+ "_embedded": {
1854
+ "tags": []
1855
+ }
1856
+ },
1857
+ {
1858
+ "id": 7767457,
1859
+ "name": "Example",
1860
+ "responsible_user_id": 504141,
1861
+ "group_id": 0,
1862
+ "created_by": 504141,
1863
+ "updated_by": 504141,
1864
+ "created_at": 1586360394,
1865
+ "updated_at": 1586360394,
1866
+ "closest_task_at": null,
1867
+ "custom_fields_values": null,
1868
+ "account_id": 28805383,
1869
+ "_links": {
1870
+ "self": {
1871
+ "href": "https://example.amocrm.ru/api/v4/companies/7767457"
1872
+ }
1873
+ },
1874
+ "_embedded": {
1875
+ "tags": []
1876
+ }
1877
+ }
1878
+ ]
1879
+ }
1880
+ }
1881
+ """
1882
+ params = {k: v for k, v in locals().items() if k != "self"}
1883
+ return self._get_entities("companies", **params)
1884
+
1885
+ def get_company(self, company_id: int) -> dict:
1886
+ """Get company
1887
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/companies-api#company-detail
1888
+ Args:
1889
+ company_id (int): id of company
1890
+
1891
+ Returns:
1892
+ dict: {
1893
+ "id": 1,
1894
+ "name": "АО Рога и копыта",
1895
+ "responsible_user_id": 504141,
1896
+ "group_id": 0,
1897
+ "created_by": 504141,
1898
+ "updated_by": 504141,
1899
+ "created_at": 1582117331,
1900
+ "updated_at": 1586361223,
1901
+ "closest_task_at": null,
1902
+ "custom_fields_values": [
1903
+ {
1904
+ "field_id": 3,
1905
+ "field_name": "Телефон",
1906
+ "field_code": "PHONE",
1907
+ "field_type": "multitext",
1908
+ "values": [
1909
+ {
1910
+ "value": "123213",
1911
+ "enum_id": 1,
1912
+ "enum": "WORK"
1913
+ }
1914
+ ]
1915
+ }
1916
+ ],
1917
+ "account_id": 28805383,
1918
+ "_links": {
1919
+ "self": {
1920
+ "href": "https://exmaple.amocrm.ru/api/v4/companies/1"
1921
+ }
1922
+ },
1923
+ "_embedded": {
1924
+ "tags": []
1925
+ }
1926
+ }
1927
+ """
1928
+ url = f"{self.crm_url}/api/v4/companies/{company_id}"
1929
+ return self._send_api_request("get", url)
1930
+
1931
+ def create_companies(self, companies: list) -> dict:
1932
+ """Create companies
1933
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/companies-api#companies-add
1934
+ Args:
1935
+ companies (list): list of companies
1936
+
1937
+ Returns:
1938
+ dict: {
1939
+ "_links": {
1940
+ "self": {
1941
+ "href": "https://example.amocrm.ru/api/v4/companies"
1942
+ }
1943
+ },
1944
+ "_embedded": {
1945
+ "companies": [
1946
+ {
1947
+ "id": 11090825,
1948
+ "request_id": "0",
1949
+ "_links": {
1950
+ "self": {
1951
+ "href": "https://example.amocrm.ru/api/v4/companies/11090825"
1952
+ }
1953
+ }
1954
+ }
1955
+ ]
1956
+ }
1957
+ }
1958
+ """
1959
+ url = f"{self.crm_url}/api/v4/companies"
1960
+ return self._send_api_request("post", url, companies)
1961
+
1962
+ def update_companies(self, companies: list) -> dict:
1963
+ """Update companies
1964
+
1965
+ Args:
1966
+ companies (list): list of companies
1967
+
1968
+ Returns:
1969
+ dict: {
1970
+ "_links": {
1971
+ "self": {
1972
+ "href": "https://example.amocrm.ru/api/v4/companies"
1973
+ }
1974
+ },
1975
+ "_embedded": {
1976
+ "companies": [
1977
+ {
1978
+ "id": 11090825,
1979
+ "name": "Новое название компании",
1980
+ "updated_at": 1590998669,
1981
+ "_links": {
1982
+ "self": {
1983
+ "href": "https://example.amocrm.ru/api/v4/companies/11090825"
1984
+ }
1985
+ }
1986
+ }
1987
+ ]
1988
+ }
1989
+ }
1990
+ """
1991
+ url = f"{self.crm_url}/api/v4/companies"
1992
+ return self._send_api_request("post", url, companies)
1993
+
1994
+ def get_catalogs(self, page: int = 1, limit: int = 250) -> dict:
1995
+ """Get catalogs
1996
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/catalogs-api#lists-list
1997
+ Args:
1998
+ page (int, optional): page number. Defaults to 1.
1999
+ limit (int, optional): limit of page result. Defaults to 250.
2000
+
2001
+ Returns:
2002
+ dict: {
2003
+ "_page": 1,
2004
+ "_links": {
2005
+ "self": {
2006
+ "href": "https://example.amocrm.ru/api/v4/catalogs?page=1&limit=50"
2007
+ },
2008
+ "next": {
2009
+ "href": "https://example.amocrm.ru/api/v4/catalogs?page=2&limit=50"
2010
+ }
2011
+ },
2012
+ "_embedded": {
2013
+ "catalogs": [
2014
+ {
2015
+ "id": 4589,
2016
+ "name": "Просто список",
2017
+ "created_by": 504141,
2018
+ "updated_by": 504141,
2019
+ "created_at": 1590742040,
2020
+ "updated_at": 1590742040,
2021
+ "sort": 10,
2022
+ "type": "regular",
2023
+ "can_add_elements": true,
2024
+ "can_show_in_cards": false,
2025
+ "can_link_multiple": true,
2026
+ "can_be_deleted": true,
2027
+ "sdk_widget_code": null,
2028
+ "account_id": 28805383,
2029
+ "_links": {
2030
+ "self": {
2031
+ "href": "https://example.amocrm.ru/api/v4/catalogs/4589"
2032
+ }
2033
+ }
2034
+ },
2035
+ {
2036
+ "id": 4521,
2037
+ "name": "Товары",
2038
+ "created_by": 504141,
2039
+ "updated_by": 504141,
2040
+ "created_at": 1589390310,
2041
+ "updated_at": 1590742040,
2042
+ "sort": 20,
2043
+ "type": "products",
2044
+ "can_add_elements": true,
2045
+ "can_show_in_cards": false,
2046
+ "can_link_multiple": true,
2047
+ "can_be_deleted": false,
2048
+ "sdk_widget_code": null,
2049
+ "account_id": 28805383,
2050
+ "_links": {
2051
+ "self": {
2052
+ "href": "https://example.amocrm.ru/api/v4/catalogs/4521"
2053
+ }
2054
+ }
2055
+ },
2056
+ {
2057
+ "id": 4517,
2058
+ "name": "Счета",
2059
+ "created_by": 504141,
2060
+ "updated_by": 504141,
2061
+ "created_at": 1589379462,
2062
+ "updated_at": 1590742040,
2063
+ "sort": 30,
2064
+ "type": "invoices",
2065
+ "can_add_elements": false,
2066
+ "can_show_in_cards": false,
2067
+ "can_link_multiple": true,
2068
+ "can_be_deleted": true,
2069
+ "sdk_widget_code": null,
2070
+ "account_id": 28805383,
2071
+ "_links": {
2072
+ "self": {
2073
+ "href": "https://example.amocrm.ru/api/v4/catalogs/4517"
2074
+ }
2075
+ }
2076
+ }
2077
+ ]
2078
+ }
2079
+ }
2080
+ """
2081
+ params: dict = {"page": page, "limit": limit}
2082
+ return self._get_entities("catalogs", **params)
2083
+
2084
+ def get_catalog(self, catalog_id: int) -> dict:
2085
+ """Get catalog
2086
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/catalogs-api#list-detail
2087
+ Args:
2088
+ catalog_id (int): id of catalog
2089
+
2090
+ Returns:
2091
+ dict: {
2092
+ "id": 4589,
2093
+ "name": "Просто список",
2094
+ "created_by": 504141,
2095
+ "updated_by": 504141,
2096
+ "created_at": 1590742040,
2097
+ "updated_at": 1590742040,
2098
+ "sort": 10,
2099
+ "type": "regular",
2100
+ "can_add_elements": true,
2101
+ "can_show_in_cards": false,
2102
+ "can_link_multiple": true,
2103
+ "can_be_deleted": true,
2104
+ "sdk_widget_code": null,
2105
+ "account_id": 28805383,
2106
+ "_links": {
2107
+ "self": {
2108
+ "href": "https://example.amocrm.ru/api/v4/catalogs/4589"
2109
+ }
2110
+ }
2111
+ }
2112
+ """
2113
+ url = f"{self.crm_url}/api/v4/catalogs/{catalog_id}"
2114
+ return self._send_api_request("get", url)
2115
+
2116
+ def create_catalogs(self, catalogs: list) -> dict:
2117
+ """Create catalogs
2118
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/catalogs-api#lists-add
2119
+ Args:
2120
+ catalogs (list): list of catalogs
2121
+
2122
+ Returns:
2123
+ dict: {
2124
+ "_links": {
2125
+ "self": {
2126
+ "href": "https://example.amocrm.ru/api/v4/catalogs"
2127
+ }
2128
+ },
2129
+ "_embedded": {
2130
+ "catalogs": [
2131
+ {
2132
+ "id": 5785,
2133
+ "name": "Тестовый список",
2134
+ "created_by": 3944275,
2135
+ "updated_by": 3944275,
2136
+ "created_at": 1589397957,
2137
+ "updated_at": 1589397957,
2138
+ "sort": 10,
2139
+ "type": "regular",
2140
+ "can_add_elements": true,
2141
+ "can_show_in_cards": false,
2142
+ "can_link_multiple": false,
2143
+ "can_be_deleted": true,
2144
+ "account_id": 123123,
2145
+ "request_id": "123",
2146
+ "_links": {
2147
+ "self": {
2148
+ "href": "https://example.amocrm.ru/api/v4/catalogs/5785"
2149
+ }
2150
+ }
2151
+ }
2152
+ ]
2153
+ }
2154
+ }
2155
+ """
2156
+ return self._create_or_update_entities("catalogs", catalogs)
2157
+
2158
+ def update_catalogs(self, catalogs: list) -> dict:
2159
+ """Update catalogs
2160
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/catalogs-api#lists-edit
2161
+ Args:
2162
+ catalogs (list): list of catalogs
2163
+
2164
+ Returns:
2165
+ dict: {
2166
+ "id": 5787,
2167
+ "name": "Новое имя списка",
2168
+ "created_by": 3944275,
2169
+ "updated_by": 3944275,
2170
+ "created_at": 1589399557,
2171
+ "updated_at": 1589399886,
2172
+ "sort": 30,
2173
+ "type": "regular",
2174
+ "can_add_elements": true,
2175
+ "can_show_in_cards": false,
2176
+ "can_link_multiple": false,
2177
+ "can_be_deleted": true,
2178
+ "account_id": 123123,
2179
+ "request_id": "5787",
2180
+ "_links": {
2181
+ "self": {
2182
+ "href": "https://example.amocrm.ru/api/v4/catalogs/5787"
2183
+ }
2184
+ }
2185
+ }
2186
+ """
2187
+ return self._create_or_update_entities("catalogs", catalogs, True)
2188
+
2189
+ def get_catalog_elements(
2190
+ self,
2191
+ catalog_id: int,
2192
+ page: int = 1,
2193
+ limit: int = 250,
2194
+ filters: Optional[dict] = None,
2195
+ ) -> dict:
2196
+ """Get elements by catalog id
2197
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/catalogs-api#list-elements-list
2198
+ Args:
2199
+ catalog_id (int): id of catalog
2200
+ page (int, optional): number of page. Defaults to 1.
2201
+ limit (int, optional): limit rows. Defaults to 250.
2202
+ filters (Optional[dict], optional): filter dict. Defaults to None.
2203
+
2204
+ Returns:
2205
+ dict: {
2206
+ "_page": 1,
2207
+ "_links": {
2208
+ "self": {
2209
+ "href": "https://example.amocrm.ru/api/v4/catalogs/4521/elements?page=1&limit=50"
2210
+ },
2211
+ "next": {
2212
+ "href": "https://example.amocrm.ru/api/v4/catalogs/4521/elements?page=2&limit=50"
2213
+ }
2214
+ },
2215
+ "_embedded": {
2216
+ "elements": [
2217
+ {
2218
+ "id": 525439,
2219
+ "name": "Элемент",
2220
+ "created_by": 504141,
2221
+ "updated_by": 504141,
2222
+ "created_at": 1589390333,
2223
+ "updated_at": 1590683336,
2224
+ "is_deleted": null,
2225
+ "custom_fields_values": [
2226
+ {
2227
+ "field_id": 271207,
2228
+ "field_name": "Артикул",
2229
+ "field_code": "SKU",
2230
+ "field_type": "text",
2231
+ "values": [
2232
+ {
2233
+ "value": "dsg"
2234
+ }
2235
+ ]
2236
+ },
2237
+ {
2238
+ "field_id": 271209,
2239
+ "field_name": "Описание",
2240
+ "field_code": "DESCRIPTION",
2241
+ "field_type": "textarea",
2242
+ "values": [
2243
+ {
2244
+ "value": "Описание"
2245
+ }
2246
+ ]
2247
+ },
2248
+ {
2249
+ "field_id": 271211,
2250
+ "field_name": "Цена",
2251
+ "field_code": "PRICE",
2252
+ "field_type": "numeric",
2253
+ "values": [
2254
+ {
2255
+ "value": "12"
2256
+ }
2257
+ ]
2258
+ },
2259
+ {
2260
+ "field_id": 271213,
2261
+ "field_name": "Группа",
2262
+ "field_code": "GROUP",
2263
+ "field_type": "category",
2264
+ "values": [
2265
+ {
2266
+ "value": "Телефоны",
2267
+ "enum_id": 10663
2268
+ }
2269
+ ]
2270
+ }
2271
+ ],
2272
+ "catalog_id": 4521,
2273
+ "account_id": 28805383,
2274
+ "_links": {
2275
+ "self": {
2276
+ "href": "https://example.amocrm.ru/api/v4/catalogs/4521/elements/525439"
2277
+ }
2278
+ }
2279
+ }
2280
+ ]
2281
+ }
2282
+ }
2283
+ """
2284
+ params: dict = {"page": page, "limit": limit, "filters": filters}
2285
+ entity = f"catalogs/{catalog_id}/elements"
2286
+ return self._get_entities(entity, **params)
2287
+
2288
+ def get_catalog_element(self, catalog_id: int, element_id: int) -> dict:
2289
+ """Get catalog element
2290
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/catalogs-api#list-elements-detail
2291
+ Args:
2292
+ catalog_id (int): id of catalog
2293
+ element_id (int): id of element
2294
+
2295
+ Returns:
2296
+ dict: {
2297
+ "id": 525439,
2298
+ "name": "Элемент",
2299
+ "created_by": 504141,
2300
+ "updated_by": 504141,
2301
+ "created_at": 1589390333,
2302
+ "updated_at": 1590683336,
2303
+ "is_deleted": null,
2304
+ "custom_fields_values": [
2305
+ {
2306
+ "field_id": 271207,
2307
+ "field_name": "Артикул",
2308
+ "field_code": "SKU",
2309
+ "field_type": "text",
2310
+ "values": [
2311
+ {
2312
+ "value": "dsg"
2313
+ }
2314
+ ]
2315
+ },
2316
+ {
2317
+ "field_id": 271209,
2318
+ "field_name": "Описание",
2319
+ "field_code": "DESCRIPTION",
2320
+ "field_type": "textarea",
2321
+ "values": [
2322
+ {
2323
+ "value": "Супер телефон"
2324
+ }
2325
+ ]
2326
+ },
2327
+ {
2328
+ "field_id": 271211,
2329
+ "field_name": "Цена",
2330
+ "field_code": "PRICE",
2331
+ "field_type": "numeric",
2332
+ "values": [
2333
+ {
2334
+ "value": "12"
2335
+ }
2336
+ ]
2337
+ },
2338
+ {
2339
+ "field_id": 271213,
2340
+ "field_name": "Группа",
2341
+ "field_code": "GROUP",
2342
+ "field_type": "category",
2343
+ "values": [
2344
+ {
2345
+ "value": "Телефоны",
2346
+ "enum_id": 10663
2347
+ }
2348
+ ]
2349
+ }
2350
+ ],
2351
+ "catalog_id": 4521,
2352
+ "account_id": 28805383,
2353
+ "_links": {
2354
+ "self": {
2355
+ "href": "https://example.amocrm.ru/api/v4/catalogs/4521/elements/525439"
2356
+ }
2357
+ }
2358
+ }
2359
+ """
2360
+ url = f"{self.crm_url}/api/v4/catalogs/{catalog_id}/elements/{element_id}"
2361
+ return self._send_api_request("get", url)
2362
+
2363
+ def add_elements_to_catalog(self, catalog_id: int, elements: list) -> dict:
2364
+ """Add elements to catalog
2365
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/catalogs-api#list-elements-add
2366
+ Args:
2367
+ catalog_id (int): id of catalog
2368
+ elements (list): list of elements
2369
+
2370
+ Returns:
2371
+ dict: {
2372
+ "_links": {
2373
+ "self": {
2374
+ "href": "https://example.amocrm.ru/api/v4/catalogs/1209/elements"
2375
+ }
2376
+ },
2377
+ "_embedded": {
2378
+ "elements": [
2379
+ {
2380
+ "id": 986757,
2381
+ "name": "Новый элемент списка",
2382
+ "created_by": 3944275,
2383
+ "updated_by": 3944275,
2384
+ "created_at": 1589294541,
2385
+ "updated_at": 1589294541,
2386
+ "is_deleted": false,
2387
+ "custom_fields_values": [
2388
+ {
2389
+ "field_id": 14687,
2390
+ "field_name": "Цена",
2391
+ "field_code": "PRICE",
2392
+ "field_type": "numeric",
2393
+ "values": [
2394
+ {
2395
+ "value": "1000"
2396
+ }
2397
+ ]
2398
+ }
2399
+ ],
2400
+ "catalog_id": 1209,
2401
+ "account_id": 123123,
2402
+ "request_id": 0,
2403
+ "_links": {
2404
+ "self": {
2405
+ "href": "https://example.amocrm.ru/api/v4/catalogs/1209/elements/986757"
2406
+ }
2407
+ }
2408
+ }
2409
+ ]
2410
+ }
2411
+ }
2412
+ """
2413
+ return self._create_or_update_entities(
2414
+ f"catalogs/{catalog_id}/elements", elements
2415
+ )
2416
+
2417
+ def update_elements_in_catalog(self, catalog_id: int, elements: list) -> dict:
2418
+ """Add elements to catalog
2419
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/catalogs-api#list-elements-edit
2420
+ Args:
2421
+ catalog_id (int): id of catalog
2422
+ elements (list): list of elements
2423
+
2424
+ Returns:
2425
+ dict: {
2426
+ "_links": {
2427
+ "self": {
2428
+ "href": "https://example.amocrm.ru/api/v4/catalogs/1209/elements"
2429
+ }
2430
+ },
2431
+ "_embedded": {
2432
+ "elements": [
2433
+ {
2434
+ "id": 986757,
2435
+ "name": "Новое имя элемента",
2436
+ "created_by": 3944275,
2437
+ "updated_by": 3944275,
2438
+ "created_at": 1589294541,
2439
+ "updated_at": 1589295769,
2440
+ "is_deleted": false,
2441
+ "custom_fields_values": [ ],
2442
+ "catalog_id": 1209,
2443
+ "account_id": 123123,
2444
+ "request_id": 986757,
2445
+ "_links": {
2446
+ "self": {
2447
+ "href": "https://example.amocrm.ru/api/v4/catalogs/1209/elements/986757"
2448
+ }
2449
+ }
2450
+ },
2451
+ {
2452
+ "id": 986753,
2453
+ "name": "Новое имя элемента 2",
2454
+ "created_by": 3944275,
2455
+ "updated_by": 3944275,
2456
+ "created_at": 1589294429,
2457
+ "updated_at": 1589295769,
2458
+ "is_deleted": false,
2459
+ "custom_fields_values": [],
2460
+ "catalog_id": 1209,
2461
+ "account_id": 123123,
2462
+ "request_id": 986753,
2463
+ "_links": {
2464
+ "self": {
2465
+ "href": "https://example.amocrm.ru/api/v4/catalogs/1209/elements/986753"
2466
+ }
2467
+ }
2468
+ }
2469
+ ]
2470
+ }
2471
+ }
2472
+ """
2473
+ return self._create_or_update_entities(
2474
+ f"catalogs/{catalog_id}/elements", elements, True
2475
+ )
2476
+
2477
+ def _get_custom_fields(self, entity: str, page: Optional[int] = None) -> dict:
2478
+ url = f"{self.crm_url}/api/v4/{entity}/custom_fields"
2479
+ if page:
2480
+ url = f"{url}?page={page}"
2481
+ return self._send_api_request("get", url)
2482
+
2483
+ def get_contacts_custom_fields(self, page: Optional[int] = None) -> dict:
2484
+ return self._get_custom_fields("contacts", page=page)
2485
+
2486
+ def get_leads_custom_fields(self, page: Optional[int] = None) -> dict:
2487
+ return self._get_custom_fields("leads", page=page)
2488
+
2489
+ def get_companies_custom_fields(self, page: Optional[int] = None) -> dict:
2490
+ return self._get_custom_fields("companies", page=page)
2491
+
2492
+ def get_customers_custom_fields(self, page: Optional[int] = None) -> dict:
2493
+ return self._get_custom_fields("customers", page=page)
2494
+
2495
+ def get_customer_segments_custom_fields(self, page: Optional[int] = None) -> dict:
2496
+ return self._get_custom_fields("customers/segments", page=page)
2497
+
2498
+ def get_catalog_custom_fields(self, catalog_id: str) -> dict:
2499
+ return self._get_custom_fields(f"catalogs/{catalog_id}")
2500
+
2501
+ def get_users(
2502
+ self,
2503
+ page: int = 1,
2504
+ limit: int = 250,
2505
+ with_role: bool = False,
2506
+ with_group: bool = False,
2507
+ ) -> dict:
2508
+ """Get users
2509
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/users-api#users-list
2510
+ Args:
2511
+ page (int, optional): number of page. Defaults to 1.
2512
+ limit (int, optional): limit rows. Defaults to 250.
2513
+ with_role (bool, optional): return roles by user. Defaults to False.
2514
+ with_group (bool, optional): retur groups by user. Defaults to False.
2515
+
2516
+ Returns:
2517
+ dict: {
2518
+ "_total_items": 2,
2519
+ "_page": 1,
2520
+ "_page_count": 1,
2521
+ "_links": {
2522
+ "self": {
2523
+ "href": "https://example.amocrm.ru/api/v4/users/?with=role,group"
2524
+ }
2525
+ },
2526
+ "_embedded": {
2527
+ "users": [
2528
+ {
2529
+ "id": 123123,
2530
+ "name": "Пользователь для примера 2",
2531
+ "email": "example2@mail.com",
2532
+ "lang": "en",
2533
+ "rights": {
2534
+ "leads": {
2535
+ "view": "A",
2536
+ "edit": "A",
2537
+ "add": "A",
2538
+ "delete": "A",
2539
+ "export": "A"
2540
+ },
2541
+ "contacts": {
2542
+ "view": "A",
2543
+ "edit": "A",
2544
+ "add": "A",
2545
+ "delete": "A",
2546
+ "export": "A"
2547
+ },
2548
+ "companies": {
2549
+ "view": "A",
2550
+ "edit": "A",
2551
+ "add": "A",
2552
+ "delete": "A",
2553
+ "export": "A"
2554
+ },
2555
+ "tasks": {
2556
+ "edit": "A",
2557
+ "delete": "A"
2558
+ },
2559
+ "mail_access": false,
2560
+ "catalog_access": false,
2561
+ "status_rights": [
2562
+ {
2563
+ "entity_type": "leads",
2564
+ "pipeline_id": 2194576,
2565
+ "status_id": 30846277,
2566
+ "rights": {
2567
+ "view": "A",
2568
+ "edit": "A",
2569
+ "delete": "A"
2570
+ }
2571
+ },
2572
+ {
2573
+ "entity_type": "leads",
2574
+ "pipeline_id": 2212201,
2575
+ "status_id": 30965377,
2576
+ "rights": {
2577
+ "view": "A",
2578
+ "edit": "A",
2579
+ "delete": "A"
2580
+ }
2581
+ }
2582
+ ],
2583
+ "is_admin": false,
2584
+ "is_free": false,
2585
+ "is_active": true,
2586
+ "group_id": null,
2587
+ "role_id": null
2588
+ },
2589
+ "_links": {
2590
+ "self": {
2591
+ "href": "https://example.amocrm.ru/api/v4/users/123123/"
2592
+ }
2593
+ },
2594
+ "_embedded": {
2595
+ "roles": [
2596
+ {
2597
+ "id": 3141,
2598
+ "name": "Менеджер",
2599
+ "_links": {
2600
+ "self": {
2601
+ "href": "https://example.amocrm.ru/api/v4/roles/3141"
2602
+ }
2603
+ }
2604
+ }
2605
+ ],
2606
+ "groups": [
2607
+ {
2608
+ "id": 267688,
2609
+ "name": "Менеджеры"
2610
+ }
2611
+ ]
2612
+ }
2613
+ },
2614
+ {
2615
+ "id": 321321,
2616
+ "name": "Пользователь для примера 2",
2617
+ "email": "example2@mail.com",
2618
+ "lang": "ru",
2619
+ "rights": {
2620
+ "leads": {
2621
+ "view": "A",
2622
+ "edit": "A",
2623
+ "add": "G",
2624
+ "delete": "D",
2625
+ "export": "M"
2626
+ },
2627
+ "contacts": {
2628
+ "view": "A",
2629
+ "edit": "A",
2630
+ "add": "G",
2631
+ "delete": "M",
2632
+ "export": "D"
2633
+ },
2634
+ "companies": {
2635
+ "view": "A",
2636
+ "edit": "G",
2637
+ "add": "G",
2638
+ "delete": "D",
2639
+ "export": "D"
2640
+ },
2641
+ "tasks": {
2642
+ "edit": "A",
2643
+ "delete": "A"
2644
+ },
2645
+ "mail_access": true,
2646
+ "catalog_access": true,
2647
+ "status_rights": null,
2648
+ "is_admin": true,
2649
+ "is_free": false,
2650
+ "is_active": true,
2651
+ "group_id": null,
2652
+ "role_id": null
2653
+ },
2654
+ "_links": {
2655
+ "self": {
2656
+ "href": "https://example.amocrm.ru/api/v4/users/321321"
2657
+ }
2658
+ },
2659
+ "_embedded": {
2660
+ "roles": [],
2661
+ "groups": []
2662
+ }
2663
+ }
2664
+ ]
2665
+ }
2666
+ }
2667
+ """
2668
+ url = f"{self.crm_url}/api/v4/users"
2669
+ params = {"page": page, "limit": limit}
2670
+ with_ = []
2671
+ if with_group:
2672
+ with_.append("group")
2673
+ if with_role:
2674
+ with_.append("role")
2675
+ url = f"{url}?{urlencode(params)}"
2676
+ if with_:
2677
+ with_str = ",".join(i for i in with_)
2678
+ url = f"{url}&with={with_str}"
2679
+ return self._send_api_request("get", url)
2680
+
2681
+ def get_user(
2682
+ self,
2683
+ user_id: int,
2684
+ with_role: bool = False,
2685
+ with_group: bool = False,
2686
+ ) -> dict:
2687
+ """Get user
2688
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/users-api#user-detail
2689
+ Args:
2690
+ user_id (int): id of user
2691
+ with_role (bool, optional): return roles. Defaults to False.
2692
+ with_group (bool, optional): return groups. Defaults to False.
2693
+
2694
+ Returns:
2695
+ dict: {
2696
+ "id": 185848,
2697
+ "name": "Алексей Поимцев",
2698
+ "email": "test@example.com",
2699
+ "lang": "ru",
2700
+ "rights": {
2701
+ "leads": {
2702
+ "view": "M",
2703
+ "edit": "M",
2704
+ "add": "D",
2705
+ "delete": "M",
2706
+ "export": "M"
2707
+ },
2708
+ "contacts": {
2709
+ "view": "M",
2710
+ "edit": "M",
2711
+ "add": "D",
2712
+ "delete": "M",
2713
+ "export": "M"
2714
+ },
2715
+ "companies": {
2716
+ "view": "M",
2717
+ "edit": "M",
2718
+ "add": "D",
2719
+ "delete": "M",
2720
+ "export": "M"
2721
+ },
2722
+ "tasks": {
2723
+ "edit": "A",
2724
+ "delete": "A"
2725
+ },
2726
+ "mail_access": false,
2727
+ "catalog_access": true,
2728
+ "status_rights": [
2729
+ {
2730
+ "entity_type": "leads",
2731
+ "pipeline_id": 3166396,
2732
+ "status_id": 142,
2733
+ "rights": {
2734
+ "view": "D",
2735
+ "edit": "D",
2736
+ "delete": "D",
2737
+ "export": "D"
2738
+ }
2739
+ },
2740
+ {
2741
+ "entity_type": "leads",
2742
+ "pipeline_id": 3166396,
2743
+ "status_id": 32311027,
2744
+ "rights": {
2745
+ "view": "D",
2746
+ "edit": "D",
2747
+ "delete": "D"
2748
+ }
2749
+ },
2750
+ {
2751
+ "entity_type": "leads",
2752
+ "pipeline_id": 3104455,
2753
+ "status_id": 31881115,
2754
+ "rights": {
2755
+ "view": "D",
2756
+ "edit": "D",
2757
+ "delete": "D"
2758
+ }
2759
+ }
2760
+ ],
2761
+ "is_admin": false,
2762
+ "is_free": false,
2763
+ "is_active": true,
2764
+ "group_id": null,
2765
+ "role_id": null
2766
+ },
2767
+ "_links": {
2768
+ "self": {
2769
+ "href": "https://example.amocrm.ru/api/v4/users/185848"
2770
+ }
2771
+ }
2772
+ }
2773
+ """
2774
+ url = f"{self.crm_url}/api/v4/users/{user_id}"
2775
+ with_ = []
2776
+ if with_group:
2777
+ with_.append("group")
2778
+ if with_role:
2779
+ with_.append("role")
2780
+ if with_:
2781
+ with_str = ",".join(i for i in with_)
2782
+ url = f"{url}?with={with_str}"
2783
+ return self._send_api_request("get", url)
2784
+
2785
+ def get_webhooks(self, distansion: Optional[str] = None) -> dict:
2786
+ """Get webwooks
2787
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/webhooks-api#webhooks-list
2788
+ Args:
2789
+ distansion (Optional[str], optional): filter by webhook url. Defaults to None.
2790
+
2791
+ Returns:
2792
+ dict: {
2793
+ "_total_items": 2,
2794
+ "_embedded": {
2795
+ "webhooks": [
2796
+ {
2797
+ "id": 839656,
2798
+ "destination": "https://webhook-uri.com",
2799
+ "created_at": 1575539157,
2800
+ "updated_at": 1575539157,
2801
+ "account_id": 321321,
2802
+ "created_by": 123123,
2803
+ "sort": 1,
2804
+ "disabled": false,
2805
+ "settings": [
2806
+ "add_task"
2807
+ ]
2808
+ },
2809
+ {
2810
+ "id": 849193,
2811
+ "destination": "https://api.test.ru/amoWebHook",
2812
+ "created_at": 1576157524,
2813
+ "updated_at": 1585816857,
2814
+ "account_id": 321321,
2815
+ "created_by": 123123,
2816
+ "sort": 2,
2817
+ "disabled": true,
2818
+ "settings": [
2819
+ "update_lead"
2820
+ ]
2821
+ }
2822
+ ]
2823
+ }
2824
+ }
2825
+ """
2826
+ url = f"{self.crm_url}/api/v4/webhooks"
2827
+ if distansion:
2828
+ params = {"filter[distansion]": distansion}
2829
+ url = f"{url}?{urlencode(params)}"
2830
+ return self._send_api_request("get", url)
2831
+
2832
+ def subscribe_webhook(self, destination: str, settings: list) -> dict:
2833
+ """Subscribe on webhook
2834
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/webhooks-api#webhook-subscribe
2835
+ Args:
2836
+ destination (str): webhook url
2837
+ settings (list): webhook settings
2838
+
2839
+ Returns:
2840
+ dict: {
2841
+ "id": 1056949,
2842
+ "destination": "https://example.test",
2843
+ "created_at": 1589012268,
2844
+ "updated_at": 1589012268,
2845
+ "account_id": 321321,
2846
+ "created_by": 3944275,
2847
+ "sort": 1,
2848
+ "disabled": false,
2849
+ "settings": [
2850
+ "add_lead"
2851
+ ]
2852
+ }
2853
+ """
2854
+ url = f"{self.crm_url}/api/v4/webhooks"
2855
+ params = {"destination": destination, "settings": settings}
2856
+ return self._send_api_request("post", url, data=params)
2857
+
2858
+ def unsubscribe_webhook(self):
2859
+ """
2860
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/webhooks-api#webhooks-delete
2861
+ """
2862
+ url = f"{self.crm_url}/api/v4/webhooks"
2863
+ return self._send_api_request("delete", url)
2864
+
2865
+ def get_widgets(self, page: int = 1, limit: int = 250) -> dict:
2866
+ """Get widgets
2867
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/widgets-api#widgets-list
2868
+ Args:
2869
+ page (int, optional): number of page. Defaults to 1.
2870
+ limit (int, optional): limit rows. Defaults to 250.
2871
+
2872
+ Returns:
2873
+ dict: {
2874
+ "_page": 1,
2875
+ "_links": {
2876
+ "self": {
2877
+ "href": "https://example.amocrm.ru/api/v4/widgets?limit=2&page=1"
2878
+ },
2879
+ "next": {
2880
+ "href": "https://example.amocrm.ru/api/v4/widgets?limit=2&page=2"
2881
+ }
2882
+ },
2883
+ "_embedded": {
2884
+ "widgets": [
2885
+ {
2886
+ "id": 742,
2887
+ "code": "amo_dropbox",
2888
+ "version": "0.0.13",
2889
+ "rating": "2,8",
2890
+ "settings_template": [
2891
+ {
2892
+ "key": "conf",
2893
+ "name": "custom",
2894
+ "type": "custom",
2895
+ "is_required": false
2896
+ }
2897
+ ],
2898
+ "is_lead_source": false,
2899
+ "is_work_with_dp": false,
2900
+ "is_crm_template": false,
2901
+ "client_uuid": null,
2902
+ "is_active_in_account": false,
2903
+ "pipeline_id": null,
2904
+ "_links": {
2905
+ "self": {
2906
+ "href": "https://example.amocrm.ru/api/v4/widgets/amo_dropbox"
2907
+ }
2908
+ }
2909
+ },
2910
+ {
2911
+ "id": 796,
2912
+ "code": "amo_mailchimp",
2913
+ "version": "1.1.12",
2914
+ "rating": "3,4",
2915
+ "settings_template": [
2916
+ {
2917
+ "key": "api",
2918
+ "name": "custom",
2919
+ "type": "custom",
2920
+ "is_required": false
2921
+ }
2922
+ ],
2923
+ "is_lead_source": false,
2924
+ "is_work_with_dp": false,
2925
+ "is_crm_template": false,
2926
+ "client_uuid": null,
2927
+ "is_active_in_account": false,
2928
+ "pipeline_id": null,
2929
+ "_links": {
2930
+ "self": {
2931
+ "href": "https://example.amocrm.ru/api/v4/widgets/amo_mailchimp"
2932
+ }
2933
+ }
2934
+ }
2935
+ ]
2936
+ }
2937
+ }
2938
+ """
2939
+ url = f"{self.crm_url}/api/v4/widgets"
2940
+ params = {"page": page, "limit": limit}
2941
+ url = f"{url}?{urlencode(params)}"
2942
+ return self._send_api_request("get", url)
2943
+
2944
+ def get_widget(self, widget_code: str) -> dict:
2945
+ """Get widget
2946
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/widgets-api#widget-detail
2947
+ Args:
2948
+ widget_code (str): code of widget
2949
+
2950
+ Returns:
2951
+ dict: {
2952
+ "id": 742,
2953
+ "code": "amo_dropbox",
2954
+ "version": "0.0.13",
2955
+ "rating": "2,8",
2956
+ "settings_template": [
2957
+ {
2958
+ "key": "conf",
2959
+ "name": "custom",
2960
+ "type": "custom",
2961
+ "is_required": false
2962
+ }
2963
+ ],
2964
+ "is_lead_source": false,
2965
+ "is_work_with_dp": false,
2966
+ "is_crm_template": false,
2967
+ "client_uuid": null,
2968
+ "is_active_in_account": false,
2969
+ "pipeline_id": null,
2970
+ "_links": {
2971
+ "self": {
2972
+ "href": "https://example.amocrm.ru/api/v4/widgets/amo_dropbox"
2973
+ }
2974
+ }
2975
+ }
2976
+ """
2977
+ url = f"{self.crm_url}/api/v4/widgets/{widget_code}"
2978
+ return self._send_api_request("get", url)
2979
+
2980
+ def install_widget(self, widget_code: str, **kwargs) -> dict:
2981
+ """Install widget
2982
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/widgets-api#widget-install
2983
+ Args:
2984
+ widget_code (str): widget code
2985
+
2986
+ Returns:
2987
+ dict: {
2988
+ "id": 972,
2989
+ "code": "amo_asterisk",
2990
+ "version": "1.1.6",
2991
+ "rating": "2,7",
2992
+ "settings_template": [
2993
+ {
2994
+ "key": "login",
2995
+ "name": "Логин",
2996
+ "type": "text",
2997
+ "is_required": true
2998
+ },
2999
+ {
3000
+ "key": "password",
3001
+ "name": "Пароль",
3002
+ "type": "pass",
3003
+ "is_required": true
3004
+ },
3005
+ {
3006
+ "key": "phones",
3007
+ "name": "Список телефонов",
3008
+ "type": "users",
3009
+ "is_required": true
3010
+ },
3011
+ {
3012
+ "key": "script_path",
3013
+ "name": "Путь к скрипту",
3014
+ "type": "text",
3015
+ "is_required": true
3016
+ }
3017
+ ],
3018
+ "is_lead_source": false,
3019
+ "is_work_with_dp": false,
3020
+ "is_crm_template": false,
3021
+ "client_uuid": null,
3022
+ "is_active_in_account": true,
3023
+ "pipeline_id": null,
3024
+ "settings": {
3025
+ "login": "example",
3026
+ "password": "eXaMp1E",
3027
+ "phones": {
3028
+ "504141": "1039"
3029
+ },
3030
+ "script_path": "https://example.com/"
3031
+ },
3032
+ "_links": {
3033
+ "self": {
3034
+ "href": "https://example.amocrm.ru/api/v4/widgets/amo_asterisk"
3035
+ }
3036
+ }
3037
+ }
3038
+ """
3039
+ url = f"{self.crm_url}/api/v4/widgets/{widget_code}"
3040
+ return self._send_api_request("post", url, kwargs)
3041
+
3042
+ def uninstall_widget(self, widget_code: str) -> dict:
3043
+ """Uninstall widget
3044
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/widgets-api#widget-uninstall
3045
+ Args:
3046
+ widget_code (str): code of widget
3047
+
3048
+ Returns:
3049
+ dict: {}
3050
+ """
3051
+
3052
+ url = f"{self.crm_url}/api/v4/widgets/{widget_code}"
3053
+ return self._send_api_request("delete", url)
3054
+
3055
+ def get_tasks(
3056
+ self,
3057
+ page: int = 1,
3058
+ limit: int = 250,
3059
+ filters: Optional[dict] = None,
3060
+ order: Optional[dict] = None,
3061
+ ) -> dict:
3062
+ """Get tasks
3063
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/tasks-api#tasks-list
3064
+ Args:
3065
+ page (int, optional): number of page. Defaults to 1.
3066
+ limit (int, optional): limit row. Defaults to 250.
3067
+ filters (Optional[dict], optional): {'[updated_at][from]': <timestamp>}. Defaults to None.
3068
+ order (Optional[dict], optional): {'updated_at': <timestamp>}. Defaults to None.
3069
+
3070
+ Returns:
3071
+ dict: {
3072
+ "_page": 1,
3073
+ "_links": {
3074
+ "self": {
3075
+ "href": "https://example.amocrm.ru/api/v4/tasks?filter[task_type][]=2&filter[is_completed][]=1&limit=2&page=1"
3076
+ },
3077
+ "next": {
3078
+ "href": "https://example.amocrm.ru/api/v4/tasks?filter[task_type][]=2&filter[is_completed][]=1&limit=2&page=2"
3079
+ }
3080
+ },
3081
+ "_embedded": {
3082
+ "tasks": [
3083
+ {
3084
+ "id": 7087,
3085
+ "created_by": 3987910,
3086
+ "updated_by": 3987910,
3087
+ "created_at": 1575364000,
3088
+ "updated_at": 1575364851,
3089
+ "responsible_user_id": 123123,
3090
+ "group_id": 0,
3091
+ "entity_id": 167353,
3092
+ "entity_type": "leads",
3093
+ "duration": 0,
3094
+ "is_completed": true,
3095
+ "task_type_id": 2,
3096
+ "text": "Пригласить на бесплатную тренировку",
3097
+ "result": [],
3098
+ "complete_till": 1575665940,
3099
+ "account_id": 321321,
3100
+ "_links": {
3101
+ "self": {
3102
+ "href": "https://example.amocrm.ru/api/v4/tasks/7087"
3103
+ }
3104
+ }
3105
+ },
3106
+ {
3107
+ "id": 215089,
3108
+ "created_by": 0,
3109
+ "updated_by": 3987910,
3110
+ "created_at": 1576767879,
3111
+ "updated_at": 1576767914,
3112
+ "responsible_user_id": 123123,
3113
+ "group_id": 0,
3114
+ "entity_id": 1035487,
3115
+ "entity_type": "leads",
3116
+ "duration": 0,
3117
+ "is_completed": true,
3118
+ "task_type_id": 2,
3119
+ "text": "Назначить встречу с клиентом",
3120
+ "result": [],
3121
+ "complete_till": 1576768179,
3122
+ "account_id": 321312,
3123
+ "_links": {
3124
+ "self": {
3125
+ "href": "https://example.amocrm.ru/api/v4/tasks/215089"
3126
+ }
3127
+ }
3128
+ }
3129
+ ]
3130
+ }
3131
+ }
3132
+ """
3133
+ params = {k: v for k, v in locals().items() if k != "self"}
3134
+ return self._get_entities("tasks", **params)
3135
+
3136
+ def get_task(self, task_id: int) -> dict:
3137
+ """Get task
3138
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/tasks-api#task-detail
3139
+ Args:
3140
+ task_id (int): id of task
3141
+
3142
+ Returns:
3143
+ dict: {
3144
+ "id": 56981,
3145
+ "created_by": 54224,
3146
+ "updated_by": 3987910,
3147
+ "created_at": 1575910123,
3148
+ "updated_at": 1576767989,
3149
+ "responsible_user_id": 123123,
3150
+ "group_id": 0,
3151
+ "entity_id": 180765,
3152
+ "entity_type": "leads",
3153
+ "duration": 0,
3154
+ "is_completed": true,
3155
+ "task_type_id": 2,
3156
+ "text": "Назначить встречу с клиентом",
3157
+ "result": {
3158
+ "text": "Результат есть"
3159
+ },
3160
+ "complete_till": 1575910423,
3161
+ "account_id": 321312,
3162
+ "_links": {
3163
+ "self": {
3164
+ "href": "https://example.amocrm.ru/api/v4/tasks/56981"
3165
+ }
3166
+ }
3167
+ }
3168
+ """
3169
+ url = f"{self.crm_url}/api/v4/tasks/{task_id}"
3170
+ return self._send_api_request("get", url)
3171
+
3172
+ def add_tasks(self, tasks: list) -> dict:
3173
+ """Add tasks
3174
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/tasks-api#tasks-add
3175
+ Args:
3176
+ tasks (list): list of task objects
3177
+
3178
+ Returns:
3179
+ dict: {
3180
+ "_links": {
3181
+ "self": {
3182
+ "href": "https://example.amocrm.ru/api/v4/tasks"
3183
+ }
3184
+ },
3185
+ "_embedded": {
3186
+ "tasks": [
3187
+ {
3188
+ "id": 4745251,
3189
+ "updated_at": 1588760725,
3190
+ "request_id": "0",
3191
+ "_links": {
3192
+ "self": {
3193
+ "href": "https://example.amocrm.ru/api/v4/tasks/4745251"
3194
+ }
3195
+ }
3196
+ },
3197
+ {
3198
+ "id": 4747929,
3199
+ "updated_at": 1588760725,
3200
+ "request_id": "1",
3201
+ "_links": {
3202
+ "self": {
3203
+ "href": "https://example.amocrm.ru/api/v4/tasks/4747929"
3204
+ }
3205
+ }
3206
+ }
3207
+ ]
3208
+ }
3209
+ }
3210
+ """
3211
+ return self._create_or_update_entities("tasks", tasks)
3212
+
3213
+ def update_tasks(self, tasks: list) -> dict:
3214
+ """Add tasks
3215
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/tasks-api#tasks-edit
3216
+ Args:
3217
+ tasks (list): list of task objects
3218
+
3219
+ Returns:
3220
+ dict: {
3221
+ "_links": {
3222
+ "self": {
3223
+ "href": "https://example.amocrm.ru/api/v4/tasks"
3224
+ }
3225
+ },
3226
+ "_embedded": {
3227
+ "tasks": [
3228
+ {
3229
+ "id": 4745251,
3230
+ "updated_at": 1588760725,
3231
+ "request_id": "0",
3232
+ "_links": {
3233
+ "self": {
3234
+ "href": "https://example.amocrm.ru/api/v4/tasks/4745251"
3235
+ }
3236
+ }
3237
+ },
3238
+ {
3239
+ "id": 4747929,
3240
+ "updated_at": 1588760725,
3241
+ "request_id": "1",
3242
+ "_links": {
3243
+ "self": {
3244
+ "href": "https://example.amocrm.ru/api/v4/tasks/4747929"
3245
+ }
3246
+ }
3247
+ }
3248
+ ]
3249
+ }
3250
+ }
3251
+ """
3252
+ return self._create_or_update_entities("tasks", tasks, True)
3253
+
3254
+ def execution_task(self, task_id: int, is_completed: bool, result: str) -> dict:
3255
+ """Executuin task
3256
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/tasks-api#tasks-complete
3257
+ Args:
3258
+ task_id (int): id of task
3259
+ is_completed (bool): true if completed
3260
+ result: (str) text of result
3261
+
3262
+ Returns:
3263
+ dict: {
3264
+ "is_completed": true,
3265
+ "result": {
3266
+ "text": "Удалось связаться с клиентом"
3267
+ }
3268
+ }
3269
+ """
3270
+ url = f"{self.crm_url}/api/v4/tasks/{task_id}"
3271
+ params = {"is_completed": is_completed, "result": {"text": result}}
3272
+ return self._send_api_request("patch", url, params)
3273
+
3274
+ def get_tags_by_entity_type(
3275
+ self,
3276
+ entity_type: str,
3277
+ page: int = 1,
3278
+ limit: int = 250,
3279
+ filters: Optional[dict] = None,
3280
+ ) -> dict:
3281
+ """Get tags by entity_type
3282
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/tags-api#tags-list
3283
+ Args:
3284
+ entity_type (str): leads|contacts|companies|customers
3285
+ page (int, optional): page number. Defaults to 1.
3286
+ limit (int, optional): limit of rows. Defaults to 250.
3287
+ filters (Optional[dict], optional): {'[name]': <name>}. Defaults to None.
3288
+
3289
+ Returns:
3290
+ dict: {
3291
+ "_page": 1,
3292
+ "_links": {
3293
+ "self": {
3294
+ "href": "https://example.amocrm.ru/api/v4/leads/tags?filter[id][]=2707&filter[id][]=2709&page=1&limit=50"
3295
+ },
3296
+ "next": {
3297
+ "href": "https://example.amocrm.ru/api/v4/leads/tags?filter[id][]=2707&filter[id][]=2709&page=2&limit=50"
3298
+ }
3299
+ },
3300
+ "_embedded": {
3301
+ "tags": [
3302
+ {
3303
+ "id": 2707,
3304
+ "name": "Заявка с сайта"
3305
+ },
3306
+ {
3307
+ "id": 2709,
3308
+ "name": "Техническая поддержка"
3309
+ }
3310
+ ]
3311
+ }
3312
+ }
3313
+ """
3314
+ params: dict = {"page": page, "limit": limit, "filters": filters}
3315
+ return self._get_entities(f"{entity_type}/tags", **params)
3316
+
3317
+ def add_tags_for_entity_type(self, entity_type: str, tags: list) -> dict:
3318
+ """Add tags for entity type
3319
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/tags-api#tags-add
3320
+ Args:
3321
+ entity_type (str): leads|contacts|companies|customers
3322
+ tags (list): list of tags
3323
+
3324
+ Returns:
3325
+ dict: {
3326
+ "_total_items": 3,
3327
+ "_embedded": {
3328
+ "tags": [
3329
+ {
3330
+ "id": 263807,
3331
+ "name": "Tag 1",
3332
+ "request_id": "0"
3333
+ },
3334
+ {
3335
+ "id": 263809,
3336
+ "name": "Tag 2",
3337
+ "request_id": "my_request_id"
3338
+ },
3339
+ {
3340
+ "id": 263811,
3341
+ "name": "Tag 3",
3342
+ "request_id": "2"
3343
+ }
3344
+ ]
3345
+ }
3346
+ }
3347
+ """
3348
+ return self._create_or_update_entities(f"{entity_type}/tags", tags)
3349
+
3350
+ def _get_custom_field_by_entity_type(
3351
+ self, entity_type: str, custom_field_id: int
3352
+ ) -> dict:
3353
+ """Get custom field
3354
+
3355
+ Args:
3356
+ entity_type (str): entity type
3357
+ custom_field_id (int): id of custom field
3358
+
3359
+ Returns:
3360
+ dict: {
3361
+ "id": 3,
3362
+ "name": "Телефон",
3363
+ "type": "multitext",
3364
+ "account_id": 28805383,
3365
+ "code": "PHONE",
3366
+ "sort": 4,
3367
+ "is_api_only": false,
3368
+ "enums": [
3369
+ {
3370
+ "id": 1,
3371
+ "value": "WORK",
3372
+ "sort": 2
3373
+ },
3374
+ {
3375
+ "id": 3,
3376
+ "value": "WORKDD",
3377
+ "sort": 4
3378
+ },
3379
+ {
3380
+ "id": 5,
3381
+ "value": "MOB",
3382
+ "sort": 6
3383
+ },
3384
+ {
3385
+ "id": 7,
3386
+ "value": "FAX",
3387
+ "sort": 8
3388
+ },
3389
+ {
3390
+ "id": 9,
3391
+ "value": "HOME",
3392
+ "sort": 10
3393
+ },
3394
+ {
3395
+ "id": 11,
3396
+ "value": "OTHER",
3397
+ "sort": 12
3398
+ }
3399
+ ],
3400
+ "group_id": null,
3401
+ "required_statuses": [],
3402
+ "is_deletable": false,
3403
+ "is_predefined": true,
3404
+ "entity_type": "contacts",
3405
+ "remind": null,
3406
+ "_links": {
3407
+ "self": {
3408
+ "href": "https://example.amocrm.ru/api/v4/contacts/custom_fields/3"
3409
+ }
3410
+ }
3411
+ }
3412
+ """
3413
+ url = f"{self.crm_url}/api/v4/{entity_type}/custom_fields/{custom_field_id}"
3414
+ return self._send_api_request("get", url)
3415
+
3416
+ def get_leads_custom_field(self, custom_field_id: int) -> dict:
3417
+ return self._get_custom_field_by_entity_type("leads", custom_field_id)
3418
+
3419
+ def get_contacts_custom_field(self, custom_field_id: int) -> dict:
3420
+ return self._get_custom_field_by_entity_type("contacts", custom_field_id)
3421
+
3422
+ def get_companies_custom_field(self, custom_field_id: int) -> dict:
3423
+ return self._get_custom_field_by_entity_type("companies", custom_field_id)
3424
+
3425
+ def get_customers_custom_field(self, custom_field_id: int) -> dict:
3426
+ return self._get_custom_field_by_entity_type("customers", custom_field_id)
3427
+
3428
+ def get_customers_segments_custom_field(self, custom_field_id: int) -> dict:
3429
+ return self._get_custom_field_by_entity_type(
3430
+ "customers/segments", custom_field_id
3431
+ )
3432
+
3433
+ def get_catalog_custom_field(self, catalog_id: int, custom_field_id: int) -> dict:
3434
+ return self._get_custom_field_by_entity_type(
3435
+ f"catalogs/{catalog_id}", custom_field_id
3436
+ )
3437
+
3438
+ def _create_custom_fields(self, entity_type: str, custom_fields: list) -> dict:
3439
+ """Create custom fields by entity type
3440
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/custom-fields#custom-fields-add
3441
+ Args:
3442
+ entity_type (str): entity type
3443
+ custom_fields (list): list
3444
+
3445
+ Returns:
3446
+ dict: {
3447
+ "_total_items": 1,
3448
+ "_embedded": {
3449
+ "custom_fields": [
3450
+ {
3451
+ "name": "multi select",
3452
+ "type": "multiselect",
3453
+ "sort": 510,
3454
+ "settings": null,
3455
+ "is_predefined": false,
3456
+ "id": 4457223,
3457
+ "remind": null,
3458
+ "is_api_only": false,
3459
+ "enums": [
3460
+ {
3461
+ "value": "Значение 1",
3462
+ "sort": 1,
3463
+ "id": 3778801
3464
+ },
3465
+ {
3466
+ "value": "Значение 2",
3467
+ "sort": 2,
3468
+ "id": 3778803
3469
+ }
3470
+ ],
3471
+ "group_id": null,
3472
+ "required_statuses": [
3473
+ {
3474
+ "status_id": 20540473,
3475
+ "pipeline_id": 16056
3476
+ },
3477
+ ],
3478
+ "_links": {
3479
+ "self": {
3480
+ "href": "https://example.amocrm.ru/api/v4/custom_fields/4457223/"
3481
+ }
3482
+ }
3483
+ }
3484
+ ]
3485
+ }
3486
+ }
3487
+ """
3488
+ url = f"{self.crm_url}/api/v4/{entity_type}/custom_fields"
3489
+ return self._send_api_request("post", url, custom_fields)
3490
+
3491
+ def create_leads_custom_fields(self, custom_fields: list) -> dict:
3492
+ return self._create_custom_fields("leads", custom_fields)
3493
+
3494
+ def create_contacts_custom_fields(self, custom_fields: list) -> dict:
3495
+ return self._create_custom_fields("contacts", custom_fields)
3496
+
3497
+ def create_companies_custom_fields(self, custom_fields: list) -> dict:
3498
+ return self._create_custom_fields("companies", custom_fields)
3499
+
3500
+ def create_customers_custom_fields(self, custom_fields: list) -> dict:
3501
+ return self._create_custom_fields("customers", custom_fields)
3502
+
3503
+ def create_customers_segments_custom_fields(self, custom_fields: list) -> dict:
3504
+ return self._create_custom_fields("customers/segments", custom_fields)
3505
+
3506
+ def create_catalog_custom_fields(
3507
+ self, catalog_id: int, custom_fields: list
3508
+ ) -> dict:
3509
+ return self._create_custom_fields(f"catalogs/{catalog_id}", custom_fields)
3510
+
3511
+ def _update_custom_fields(self, entity_type: str, custom_fields: list) -> dict:
3512
+ """Create custom fields by entity type
3513
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/custom-fields#custom-fields-add
3514
+ Args:
3515
+ entity_type (str): entity type
3516
+ custom_fields (list): list
3517
+
3518
+ Returns:
3519
+ dict: {
3520
+ "_total_items": 1,
3521
+ "_embedded": {
3522
+ "custom_fields": [
3523
+ {
3524
+ "name": "multi select",
3525
+ "type": "multiselect",
3526
+ "sort": 510,
3527
+ "settings": null,
3528
+ "is_predefined": false,
3529
+ "id": 4457223,
3530
+ "remind": null,
3531
+ "is_api_only": false,
3532
+ "enums": [
3533
+ {
3534
+ "value": "Значение 1",
3535
+ "sort": 1,
3536
+ "id": 3778801
3537
+ },
3538
+ {
3539
+ "value": "Значение 2",
3540
+ "sort": 2,
3541
+ "id": 3778803
3542
+ }
3543
+ ],
3544
+ "group_id": null,
3545
+ "required_statuses": [
3546
+ {
3547
+ "status_id": 20540473,
3548
+ "pipeline_id": 16056
3549
+ },
3550
+ ],
3551
+ "_links": {
3552
+ "self": {
3553
+ "href": "https://example.amocrm.ru/api/v4/custom_fields/4457223/"
3554
+ }
3555
+ }
3556
+ }
3557
+ ]
3558
+ }
3559
+ }
3560
+ """
3561
+ url = f"{self.crm_url}/api/v4/{entity_type}/custom_fields"
3562
+ return self._send_api_request("patch", url, custom_fields)
3563
+
3564
+ def update_leads_custom_fields(self, custom_fields: list) -> dict:
3565
+ return self._update_custom_fields("leads", custom_fields)
3566
+
3567
+ def update_contacts_custom_fields(self, custom_fields: list) -> dict:
3568
+ return self._update_custom_fields("contacts", custom_fields)
3569
+
3570
+ def update_companies_custom_fields(self, custom_fields: list) -> dict:
3571
+ return self._update_custom_fields("companies", custom_fields)
3572
+
3573
+ def update_customers_custom_fields(self, custom_fields: list) -> dict:
3574
+ return self._update_custom_fields("customers", custom_fields)
3575
+
3576
+ def update_customers_segments_custom_fields(self, custom_fields: list) -> dict:
3577
+ return self._update_custom_fields("customers/segments", custom_fields)
3578
+
3579
+ def update_catalog_custom_fields(
3580
+ self, catalog_id: int, custom_fields: list
3581
+ ) -> dict:
3582
+ return self._update_custom_fields(f"catalogs/{catalog_id}", custom_fields)
3583
+
3584
+ def get_events_type(
3585
+ self,
3586
+ language_code: Optional[str] = None,
3587
+ ) -> dict:
3588
+ """get events types
3589
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/events-and-notes#events-types
3590
+
3591
+ Args:
3592
+ language_code (Optional[str], optional): language. Defaults to None.
3593
+
3594
+ Returns:
3595
+ dict: {
3596
+ "_total_items": 35,
3597
+ "_links": {
3598
+ "self": {
3599
+ "href": "https://example.amocrm.ru/api/v4/events/types?limit=6"
3600
+ }
3601
+ },
3602
+ "_embedded": {
3603
+ "events_types": [
3604
+ {
3605
+ "key": "lead_added",
3606
+ "type": 1,
3607
+ "lang": "Новая сделка"
3608
+ },
3609
+ {
3610
+ "key": "lead_deleted",
3611
+ "type": 7,
3612
+ "lang": "Сделка удалена"
3613
+ },
3614
+ ...
3615
+ ]
3616
+ }
3617
+ }
3618
+ """
3619
+ params = {"language_code": language_code}
3620
+ url = f"{self.crm_url}/api/v4/events/types?{urlencode(params)}"
3621
+ return self._send_api_request("get", url)
3622
+
3623
+ def get_events(
3624
+ self,
3625
+ page: int = 1,
3626
+ limit: int = 250,
3627
+ with_params: Optional[list] = None,
3628
+ filter_by_ids: Union[str, list, None] = None,
3629
+ filter_by_created_from: Union[str, list, None] = None,
3630
+ filter_by_created_to: Union[str, list, None] = None,
3631
+ filter_by_created_by: Union[str, list, None] = None,
3632
+ filter_by_entity: Union[str, list, None] = None,
3633
+ filter_by_entity_id: Union[str, list, None] = None,
3634
+ filter_by_type: Union[str, list, None] = None,
3635
+ ) -> dict:
3636
+ """Get events
3637
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/events-and-notes#events-list
3638
+ Args:
3639
+ page (int, optional): page number. Defaults to 1.
3640
+ limit (int, optional): limit per page. Defaults to 250.
3641
+ with_params (Optional[list], optional): with params in doc. Defaults to None.
3642
+ filter_by_ids (Union[str, list, None], optional): ids filter. Defaults to None.
3643
+ filter_by_created_from (Union[str, list, None], optional): createdfrom. Defaults to None.
3644
+ filter_by_created_to (Union[str, list, None], optional): created to. Defaults to None.
3645
+ filter_by_created_by (Union[str, list, None], optional): created by. Defaults to None.
3646
+ filter_by_entity (Union[str, list, None], optional): by entity. Defaults to None.
3647
+ filter_by_entity_id (Union[str, list, None], optional): by entity_id. Defaults to None.
3648
+ filter_by_type (Union[str, list, None], optional): by type. Defaults to None.
3649
+
3650
+ Returns:
3651
+ dict: {
3652
+ "_page": 1,
3653
+ "_links": {
3654
+ "self": {
3655
+ "href": "https://example.amocrm.ru/api/v4/events?limit=1&page=1"
3656
+ },
3657
+ "next": {
3658
+ "href": "https://example.amocrm.ru/api/v4/events?limit=1&page=2"
3659
+ }
3660
+ },
3661
+ "_embedded": {
3662
+ "events": [
3663
+ {
3664
+ "id": "01pz58t6p04ymgsgfbmfyfy1mf",
3665
+ "type": "lead_added",
3666
+ "entity_id": 26060763,
3667
+ "entity_type": "lead",
3668
+ "created_by": 939801,
3669
+ "created_at": 1888888888,
3670
+ "value_after": [
3671
+ {
3672
+ "note": {
3673
+ "id": 42743871
3674
+ }
3675
+ }
3676
+ ],
3677
+ "value_before": [],
3678
+ "account_id": 17079858,
3679
+ "_links": {
3680
+ "self": {
3681
+ "href": https://example.amocrm.ru/api/v4/events/01pz58t6p04ymgsgfbmfyfy1mf"
3682
+ }
3683
+ },
3684
+ "_embedded": {
3685
+ "entity": {
3686
+ "id": 26060763,
3687
+ "_links": {
3688
+ "self": {
3689
+ "href": "https://example.amocrm.ru/api/v4/leads/26060763"
3690
+ }
3691
+ }
3692
+ }
3693
+ }
3694
+ }
3695
+ ]
3696
+ }
3697
+ }
3698
+ """
3699
+ url = f"{self.crm_url}/api/v4/events"
3700
+ params: dict = {"limit": limit, "page": page}
3701
+ if with_params:
3702
+ params["with"] = ",".join(param for param in with_params) # type: ignore
3703
+ if filter_by_ids:
3704
+ params["filter[id]"] = filter_by_ids # type: ignore
3705
+ if filter_by_created_from:
3706
+ params["filter[created_at][from]"] = filter_by_created_from # type: ignore
3707
+ if filter_by_created_to:
3708
+ params["filter[created_at][to]"] = filter_by_created_to # type: ignore
3709
+ if filter_by_created_by:
3710
+ params["filter[created_by][]"] = filter_by_created_by # type: ignore
3711
+ if filter_by_entity:
3712
+ params["filter[entity][]"] = filter_by_entity # type: ignore
3713
+ if filter_by_entity_id:
3714
+ params["filter[entity_id][]"] = filter_by_entity_id # type: ignore
3715
+ if filter_by_type:
3716
+ params["filter[type]"] = filter_by_type # type: ignore
3717
+
3718
+ url = f"{url}?{urlencode(params)}"
3719
+ return self._send_api_request("get", url)
3720
+
3721
+ def get_event(
3722
+ self,
3723
+ id: int,
3724
+ with_params: Optional[list] = None,
3725
+ ) -> dict:
3726
+ """Get event
3727
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/events-and-notes#events-detail
3728
+ Args:
3729
+ id (int): event id.
3730
+ with_params (Optional[list], optional): with params(check dock). Defaults to None.
3731
+ Returns: {
3732
+ "id": "01pz58t6p04ymgsgfbmfyfy1mf",
3733
+ "type": "lead_added",
3734
+ "entity_id": 26060763,
3735
+ "entity_type": "lead",
3736
+ "created_by": 939801,
3737
+ "created_at": 1888888888,
3738
+ "value_after": [
3739
+ {
3740
+ "note": {
3741
+ "id": 42743871
3742
+ }
3743
+ }
3744
+ ],
3745
+ "value_before": [],
3746
+ "account_id": 17079858,
3747
+ "_links": {
3748
+ "self": {
3749
+ "href": "https://example.amocrm.ru/api/v4/events/01pz58t6p04ymgsgfbmfyfy1mf"
3750
+ }
3751
+ },
3752
+ "_embedded": {
3753
+ "entity": {
3754
+ "id": 26060763,
3755
+ "_links": {
3756
+ "self": {
3757
+ "href": "https://example.amocrm.ru/api/v4/leads/26060763"
3758
+ }
3759
+ }
3760
+ }
3761
+ }
3762
+ }
3763
+ """
3764
+ url = f"{self.crm_url}/api/v4/events/{id}"
3765
+ params = {}
3766
+ if with_params:
3767
+ params["with"] = ",".join(param for param in with_params)
3768
+
3769
+ url = f"{url}?{urlencode(params)}"
3770
+ return self._send_api_request("get", url)
3771
+
3772
+ def get_notes_by_entity_type(
3773
+ self,
3774
+ entity_type: str,
3775
+ page: int = 1,
3776
+ limit: int = 250,
3777
+ filter_by_id: Union[int, list, None] = None,
3778
+ filter_by_entity_id: Optional[list] = None,
3779
+ filter_by_note_type: Optional[Union[list, str]] = None,
3780
+ filter_by_updated_at: Optional[int] = None,
3781
+ filter_by_updated_at_from: Optional[int] = None,
3782
+ filter_by_updated_at_to: Optional[int] = None,
3783
+ order_by_updated_at: str = "asc",
3784
+ order_by_id: str = "asc",
3785
+ ) -> dict:
3786
+ """Get notes by event type
3787
+
3788
+ Args:
3789
+ entity_type (str): entity type
3790
+ page (int, optional): page. Defaults to 1.
3791
+ limit (int, optional): limit per page. Defaults to 250.
3792
+ filter_by_id (Union[int, list, None], optional): list or id. Defaults to None.
3793
+ filter_by_entity_id (Optional[list], optional): list or entity id. Defaults to None.
3794
+ filter_by_note_type (Optional[Union[list, str]], optional): list of not types. Defaults to None.
3795
+ filter_by_updated_at (Optional[int], optional): timestamp. Defaults to None.
3796
+ filter_by_updated_at_from (Optional[int], optional): timestamp. Defaults to None.
3797
+ filter_by_updated_at_to (Optional[int], optional): timestamp. Defaults to None.
3798
+ order_by_updated_at (str): asc or decs. Defaults to asc.
3799
+ order_by_id (str): asc or decs. Defaults to asc.
3800
+
3801
+ Returns:
3802
+ dict: {
3803
+ "_page": 1,
3804
+ "_links": {
3805
+ "self": {
3806
+ "href": "https://example.amocrm.ru/api/v4/leads/notes?filter[id][0]=42709325&filter[id][1]=42709842&page=1&limit=50"
3807
+ },
3808
+ "next": {
3809
+ "href": "https://example.amocrm.ru/api/v4/leads/notes?filter[id][0]=42709325&filter[id][1]=42709842&page=2&limit=50"
3810
+ }
3811
+ },
3812
+ "_embedded": {
3813
+ "notes": [
3814
+ {
3815
+ "id": 42709325,
3816
+ "entity_id": 26050861,
3817
+ "created_by": 940088,
3818
+ "updated_by": 940088,
3819
+ "created_at": 1540407495,
3820
+ "updated_at": 1540408317,
3821
+ "responsible_user_id": 939801,
3822
+ "group_id": 0,
3823
+ "note_type": "common",
3824
+ "params": {
3825
+ "text": "Текст примечания"
3826
+ },
3827
+ "account_id": 17079858,
3828
+ "_links": {
3829
+ "self": {
3830
+ "href": "https://example.amocrm.ru/api/v4/leads/26050861/notes/42709325"
3831
+ }
3832
+ }
3833
+ },
3834
+ {
3835
+ "id": 42709842,
3836
+ "entity_id": 26053794,
3837
+ "created_by": 939801,
3838
+ "updated_by": 939801,
3839
+ "created_at": 1548280113,
3840
+ "updated_at": 1548280115,
3841
+ "responsible_user_id": 939801,
3842
+ "group_id": 0,
3843
+ "note_type": "attachment",
3844
+ "params": {
3845
+ "original_name": "Снимок экрана 2020-05-16 в 13.12.20.png",
3846
+ "attachment": "gijy_Snimok_ekrana_2020-05-16_v_13.12.20.png"
3847
+ },
3848
+ "account_id": 17079858,
3849
+ "_links": {
3850
+ "self": {
3851
+ "href": "https://example.amocrm.ru/api/v4/leads/26053794/notes/42709842"
3852
+ }
3853
+ }
3854
+ }
3855
+ ]
3856
+ }
3857
+ }
3858
+ """
3859
+ url = f"{self.crm_url}/api/v4/{entity_type}/notes"
3860
+ params: dict = {"page": page, "limit": limit}
3861
+ if filter_by_id:
3862
+ params["filter[id]"] = filter_by_id # type: ignore
3863
+ if filter_by_note_type:
3864
+ params["filter[note_type]"] = filter_by_note_type # type: ignore
3865
+ if filter_by_entity_id:
3866
+ params["filter[entity_id]"] = filter_by_entity_id # type: ignore
3867
+ if filter_by_updated_at:
3868
+ params["filter[updated_at]"] = filter_by_updated_at # type: ignore
3869
+ if filter_by_updated_at_from:
3870
+ params["filter[updated_at][from]"] = filter_by_updated_at_from
3871
+ if filter_by_updated_at_to:
3872
+ params["filter[updated_at][to]"] = filter_by_updated_at_to
3873
+ if order_by_updated_at:
3874
+ params["order[updated_at]"] = order_by_updated_at # type: ignore
3875
+ if order_by_id:
3876
+ params["order[id]"] = order_by_id # type: ignore
3877
+
3878
+ url = f"{url}?{urlencode(params)}"
3879
+ return self._send_api_request("get", url)
3880
+
3881
+ def get_notes_by_entity_type_and_entity_id(
3882
+ self,
3883
+ entity_type: str,
3884
+ entity_id: int,
3885
+ page: int = 1,
3886
+ limit: int = 250,
3887
+ filter_by_id: Union[int, list, None] = None,
3888
+ filter_by_note_type: Optional[Union[list, str]] = None,
3889
+ filter_by_updated_at: Optional[int] = None,
3890
+ filter_by_updated_at_from: Optional[int] = None,
3891
+ filter_by_updated_at_to: Optional[int] = None,
3892
+ order_by_updated_at: str = "asc",
3893
+ order_by_id: str = "asc",
3894
+ ) -> dict:
3895
+ """Get notes by event type and entity id
3896
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/events-and-notes#notes-entity-list
3897
+ Args:
3898
+ entity_type (str): entity type
3899
+ event_type (int): entity id
3900
+ page (int, optional): page. Defaults to 1.
3901
+ limit (int, optional): limit per page. Defaults to 250.
3902
+ filter_by_id (Union[int, list, None], optional): list or id. Defaults to None.
3903
+ filter_by_entity_id (Optional[list], optional): list or entity id. Defaults to None.
3904
+ filter_by_note_type (Optional[Union[list, str]], optional): list of not types. Defaults to None.
3905
+ filter_by_updated_at (Optional[int], optional): timestamp. Defaults to None.
3906
+ filter_by_updated_at_from (Optional[int], optional): timestamp. Defaults to None.
3907
+ filter_by_updated_at_to (Optional[int], optional): timestamp. Defaults to None.
3908
+ order_by_updated_at (str): asc or decs. Defaults to asc.
3909
+ order_by_id (str): asc or decs. Defaults to asc.
3910
+
3911
+ Returns:
3912
+ dict: {
3913
+ "_page": 1,
3914
+ "_links": {
3915
+ "self": {
3916
+ "href": "https://example.amocrm.ru/api/v4/leads/26050861/notes?limit=2&page=1"
3917
+ },
3918
+ "next": {
3919
+ "href": "https://example.amocrm.ru/api/v4/leads/26050861/notes?limit=2&page=2"
3920
+ }
3921
+ },
3922
+ "_embedded": {
3923
+ "notes": [
3924
+ {
3925
+ "id": 42709325,
3926
+ "entity_id": 26050861,
3927
+ "created_by": 940088,
3928
+ "updated_by": 940088,
3929
+ "created_at": 1540407495,
3930
+ "updated_at": 1540408317,
3931
+ "responsible_user_id": 939801,
3932
+ "group_id": 0,
3933
+ "note_type": "common",
3934
+ "params": {
3935
+ "text": "Текст примечания 2"
3936
+ },
3937
+ "account_id": 17079858,
3938
+ "_links": {
3939
+ "self": {
3940
+ "href": "https://example.amocrm.ru/api/v4/leads/26050861/notes/42709325"
3941
+ }
3942
+ }
3943
+ },
3944
+ {
3945
+ "id": 42736075,
3946
+ "entity_id": 26050861,
3947
+ "created_by": 939801,
3948
+ "updated_by": 939801,
3949
+ "created_at": 1587555198,
3950
+ "updated_at": 1587555199,
3951
+ "responsible_user_id": 939801,
3952
+ "group_id": 0,
3953
+ "note_type": "common",
3954
+ "params": {
3955
+ "text": "Текст примечания"
3956
+ },
3957
+ "account_id": 17079858,
3958
+ "_links": {
3959
+ "self": {
3960
+ "href": "https://example.amocrm.ru/api/v4/leads/26050861/notes/42736075"
3961
+ }
3962
+ }
3963
+ }
3964
+ ]
3965
+ }
3966
+ }
3967
+ """
3968
+ url = f"{self.crm_url}/api/v4/{entity_type}/{entity_id}/notes"
3969
+ params: dict = {"page": page, "limit": limit}
3970
+ if filter_by_id:
3971
+ params["filter[id]"] = filter_by_id # type: ignore
3972
+ if filter_by_note_type:
3973
+ params["filter[note_type]"] = filter_by_note_type # type: ignore
3974
+ if filter_by_updated_at:
3975
+ params["filter[updated_at]"] = filter_by_updated_at # type: ignore
3976
+ if filter_by_updated_at_from:
3977
+ params["filter[updated_at][from]"] = filter_by_updated_at_from
3978
+ if filter_by_updated_at_to:
3979
+ params["filter[updated_at][to]"] = filter_by_updated_at_to
3980
+ if order_by_updated_at:
3981
+ params["order[updated_at]"] = order_by_updated_at # type: ignore
3982
+ if order_by_id:
3983
+ params["order[id]"] = order_by_id # type: ignore
3984
+
3985
+ url = f"{url}?{urlencode(params)}"
3986
+ return self._send_api_request("get", url)
3987
+
3988
+ def get_entity_note(
3989
+ self, entity_type: str, id_: int, entity_id: Optional[int] = None
3990
+ ) -> dict:
3991
+ """get entity note
3992
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/events-and-notes#note-detail
3993
+ Args:
3994
+ entity_type (str): entity type
3995
+ id_ (int): note id
3996
+ entity_id (Optional[int], optional): entity id. Defaults to None.
3997
+
3998
+ Returns:
3999
+ dict: {
4000
+ "id": 42709325,
4001
+ "entity_id": 26050861,
4002
+ "created_by": 940088,
4003
+ "updated_by": 940088,
4004
+ "created_at": 1540407495,
4005
+ "updated_at": 1540408317,
4006
+ "responsible_user_id": 939801,
4007
+ "group_id": 0,
4008
+ "note_type": "common",
4009
+ "params": {
4010
+ "text": "Текст примечания"
4011
+ },
4012
+ "account_id": 17079858,
4013
+ "_links": {
4014
+ "self": {
4015
+ "href": "https://example.amocrm.ru/api/v4/leads/26050861/notes/42709325"
4016
+ }
4017
+ }
4018
+ }
4019
+ """
4020
+ if entity_id:
4021
+ url = f"{self.crm_url}/api/v4/{entity_type}/{entity_id}/notes/{id_}"
4022
+ else:
4023
+ url = f"{self.crm_url}/api/v4/{entity_type}/notes/{id_}"
4024
+ return self._send_api_request("get", url)
4025
+
4026
+ def create_entity_note(
4027
+ self, entity_type: str, notes: list, entity_id: Optional[int] = None
4028
+ ) -> dict:
4029
+ """create entity note
4030
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/events-and-notes#notes-add
4031
+ Args:
4032
+ entity_type (str): entity type
4033
+ notes (list): list of notes
4034
+ entity_id (Optional[int], optional): entity id. Defaults to None.
4035
+
4036
+ Returns:
4037
+ dict: {
4038
+ "_links": {
4039
+ "self": {
4040
+ "href": "http://example.amocrm.ru/api/v4/leads/notes"
4041
+ }
4042
+ },
4043
+ "_embedded": {
4044
+ "notes": [
4045
+ {
4046
+ "id": 76787983,
4047
+ "entity_id": 167353,
4048
+ "request_id": "0",
4049
+ "_links": {
4050
+ "self": {
4051
+ "href": "https://example.amocrm.ru/api/v4/leads/167353/notes/76787983"
4052
+ }
4053
+ }
4054
+ },
4055
+ {
4056
+ "id": 76787985,
4057
+ "entity_id": 167353,
4058
+ "request_id": "1",
4059
+ "_links": {
4060
+ "self": {
4061
+ "href": "https://example.amocrm.ru/api/v4/leads/167353/notes/76787985"
4062
+ }
4063
+ }
4064
+ },
4065
+ {
4066
+ "id": 76787987,
4067
+ "entity_id": 167353,
4068
+ "request_id": "2",
4069
+ "_links": {
4070
+ "self": {
4071
+ "href": "https://example.amocrm.ru/api/v4/leads/167353/notes/76787987"
4072
+ }
4073
+ }
4074
+ },
4075
+ {
4076
+ "id": 76787989,
4077
+ "entity_id": 167353,
4078
+ "request_id": "3",
4079
+ "_links": {
4080
+ "self": {
4081
+ "href": "https://example.amocrm.ru/api/v4/leads/167353/notes/76787989"
4082
+ }
4083
+ }
4084
+ }
4085
+ ]
4086
+ }
4087
+ }
4088
+ """
4089
+ if entity_id:
4090
+ url = f"{self.crm_url}/api/v4/{entity_type}/{entity_id}/notes"
4091
+ else:
4092
+ url = f"{self.crm_url}/api/v4/{entity_type}/notes"
4093
+ return self._send_api_request("post", url, data=notes)
4094
+
4095
+ def update_entity_note(
4096
+ self, entity_type: str, entity_id: int, id_: int, params: dict
4097
+ ) -> dict:
4098
+ """update single entity note
4099
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/events-and-notes#notes-edit
4100
+ Args:
4101
+ entity_type (str): entity type
4102
+ entity_id (int): entity_id
4103
+ id_ (int): note id
4104
+
4105
+ Returns:
4106
+ dict: {
4107
+ "_links": {
4108
+ "self": {
4109
+ "href": "https://example.amocrm.ru/api/v4/leads/notes"
4110
+ }
4111
+ },
4112
+ "_embedded": {
4113
+ "notes": [
4114
+ {
4115
+ "id": 76610421,
4116
+ "entity_id": 167353,
4117
+ "updated_at": 1588841241,
4118
+ "_links": {
4119
+ "self": {
4120
+ "href": "https://example.amocrm.ru/api/v4/leads/167353/notes/76610421"
4121
+ }
4122
+ }
4123
+ },
4124
+ {
4125
+ "id": 76610423,
4126
+ "entity_id": 167353,
4127
+ "updated_at": 1588841241,
4128
+ "_links": {
4129
+ "self": {
4130
+ "href": "https://example.amocrm.ru/api/v4/leads/167353/notes/76610423"
4131
+ }
4132
+ }
4133
+ }
4134
+ ]
4135
+ }
4136
+ }
4137
+ """
4138
+ url = f"{self.crm_url}/api/v4/{entity_type}/{entity_id}/notes/{id_}"
4139
+ return self._send_api_request("patch", url, params)
4140
+
4141
+ def update_entity_many_notes(
4142
+ self,
4143
+ entity_type: str,
4144
+ notes: list,
4145
+ entity_id: Optional[int] = None,
4146
+ ) -> dict:
4147
+ """update many entity note
4148
+ Doc: https://www.amocrm.ru/developers/content/crm_platform/events-and-notes#notes-edit
4149
+ Args:
4150
+ entity_type (str): entity type
4151
+ notes (list): list of notes
4152
+ entity_id (Optional[int], optional): entity id. Defaults to None.
4153
+
4154
+ Returns:
4155
+ dict: {
4156
+ "_links": {
4157
+ "self": {
4158
+ "href": "https://example.amocrm.ru/api/v4/leads/notes"
4159
+ }
4160
+ },
4161
+ "_embedded": {
4162
+ "notes": [
4163
+ {
4164
+ "id": 76610421,
4165
+ "entity_id": 167353,
4166
+ "updated_at": 1588841241,
4167
+ "_links": {
4168
+ "self": {
4169
+ "href": "https://example.amocrm.ru/api/v4/leads/167353/notes/76610421"
4170
+ }
4171
+ }
4172
+ },
4173
+ {
4174
+ "id": 76610423,
4175
+ "entity_id": 167353,
4176
+ "updated_at": 1588841241,
4177
+ "_links": {
4178
+ "self": {
4179
+ "href": "https://example.amocrm.ru/api/v4/leads/167353/notes/76610423"
4180
+ }
4181
+ }
4182
+ }
4183
+ ]
4184
+ }
4185
+ }
4186
+ """
4187
+ if entity_id:
4188
+ url = f"{self.crm_url}/api/v4/{entity_type}/{entity_id}/notes"
4189
+ else:
4190
+ url = f"{self.crm_url}/api/v4/{entity_type}/notes"
4191
+ return self._send_api_request("patch", url, data=notes)