diff --git a/README.md b/README.md index b400b7a..9e10a39 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2Fintercom%2Fpython-intercom) [![pypi](https://img.shields.io/pypi/v/python-intercom)](https://pypi.python.org/pypi/python-intercom) -The Intercom Python library provides convenient access to the Intercom API from Python. +The Intercom Python library provides convenient access to the Intercom APIs from Python. ## Installation @@ -25,12 +25,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.articles.create( - title="Thanks for everything", - description="Description of the Article", - body="Body of the Article", - author_id=1295, - state="published", +client.ai_content.create_content_import_source( + url="https://www.example.com", ) ``` @@ -49,12 +45,8 @@ client = AsyncIntercom( async def main() -> None: - await client.articles.create( - title="Thanks for everything", - description="Description of the Article", - body="Body of the Article", - author_id=1295, - state="published", + await client.ai_content.create_content_import_source( + url="https://www.example.com", ) @@ -70,7 +62,7 @@ will be thrown. from intercom.core.api_error import ApiError try: - client.articles.create(...) + client.ai_content.create_content_import_source(...) except ApiError as e: print(e.status_code) print(e.body) @@ -107,7 +99,7 @@ from intercom import Intercom client = Intercom( ..., ) -response = client.articles.with_raw_response.create(...) +response = client.ai_content.with_raw_response.create_content_import_source(...) print(response.headers) # access the response headers print(response.data) # access the underlying object pager = client.articles.list(...) @@ -135,7 +127,7 @@ A request is deemed retryable when any of the following HTTP status codes is ret Use the `max_retries` request option to configure this behavior. ```python -client.articles.create(..., request_options={ +client.ai_content.create_content_import_source(..., request_options={ "max_retries": 1 }) ``` @@ -155,7 +147,7 @@ client = Intercom( # Override timeout for a specific method -client.articles.create(..., request_options={ +client.ai_content.create_content_import_source(..., request_options={ "timeout_in_seconds": 1 }) ``` diff --git a/poetry.lock b/poetry.lock index 792606b..7f8488f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -38,13 +38,13 @@ trio = ["trio (>=0.26.1)"] [[package]] name = "certifi" -version = "2025.7.14" +version = "2025.8.3" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" files = [ - {file = "certifi-2025.7.14-py3-none-any.whl", hash = "sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2"}, - {file = "certifi-2025.7.14.tar.gz", hash = "sha256:8ea99dbdfaaf2ba2f9bac77b9249ef62ec5218e7c2b2e903378ed5fccf765995"}, + {file = "certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5"}, + {file = "certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index b19f40e..de2e2b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "python-intercom" [tool.poetry] name = "python-intercom" -version = "4.0.0" +version = "5.0.0" description = "" readme = "README.md" authors = [] diff --git a/reference.md b/reference.md index 32c5a74..b8e9b18 100644 --- a/reference.md +++ b/reference.md @@ -98,7 +98,7 @@ client = Intercom( token="YOUR_TOKEN", ) client.admins.away( - admin_id="admin_id", + admin_id=1, away_mode_enabled=True, away_mode_reassign=True, ) @@ -117,7 +117,7 @@ client.admins.away(
-**admin_id:** `str` — The unique identifier of a given admin +**admin_id:** `int` — The unique identifier of a given admin
@@ -141,6 +141,14 @@ client.admins.away(
+**away_status_reason_id:** `typing.Optional[int]` — The unique identifier of the away status reason + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -325,7 +333,7 @@ client = Intercom( token="YOUR_TOKEN", ) client.admins.find( - admin_id="123", + admin_id=1, ) ``` @@ -342,7 +350,7 @@ client.admins.find(
-**admin_id:** `str` — The unique identifier of a given admin +**admin_id:** `int` — The unique identifier of a given admin
@@ -362,8 +370,8 @@ client.admins.find(
-## Articles -
client.articles.list(...) +## AI Content +
client.ai_content.list_content_import_sources()
@@ -375,11 +383,7 @@ client.admins.find(
-You can fetch a list of all articles by making a GET request to `https://api.intercom.io/articles`. - -> 📘 How are the articles sorted and ordered? -> -> Articles will be returned in descending order on the `updated_at` attribute. This means if you need to iterate through results then we'll show the most recently updated articles first. +You can retrieve a list of all content import sources for a workspace.
@@ -399,12 +403,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -response = client.articles.list() -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page +client.ai_content.list_content_import_sources() ``` @@ -420,22 +419,6 @@ for page in response.iter_pages():
-**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page - -
-
- -
-
- -**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15 - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -448,7 +431,7 @@ for page in response.iter_pages():
-
client.articles.create(...) +
client.ai_content.create_content_import_source(...)
@@ -460,7 +443,7 @@ for page in response.iter_pages():
-You can create a new article by making a POST request to `https://api.intercom.io/articles`. +You can create a new content import source by sending a POST request to this endpoint.
@@ -480,12 +463,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.articles.create( - title="Thanks for everything", - description="Description of the Article", - body="Body of the Article", - author_id=1295, - state="published", +client.ai_content.create_content_import_source( + url="https://www.example.com", ) ``` @@ -502,55 +481,7 @@ client.articles.create(
-**title:** `str` — The title of the article.For multilingual articles, this will be the title of the default language's content. - -
-
- -
-
- -**author_id:** `int` — The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. - -
-
- -
-
- -**description:** `typing.Optional[str]` — The description of the article. For multilingual articles, this will be the description of the default language's content. - -
-
- -
-
- -**body:** `typing.Optional[str]` — The content of the article. For multilingual articles, this will be the body of the default language's content. - -
-
- -
-
- -**state:** `typing.Optional[CreateArticleRequestState]` — Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. - -
-
- -
-
- -**parent_id:** `typing.Optional[int]` — The id of the article's parent collection or section. An article without this field stands alone. - -
-
- -
-
- -**parent_type:** `typing.Optional[CreateArticleRequestParentType]` — The type of parent, which can either be a `collection` or `section`. +**url:** `str` — The URL of the content import source.
@@ -558,7 +489,7 @@ client.articles.create(
-**translated_content:** `typing.Optional[ArticleTranslatedContent]` +**status:** `typing.Optional[CreateContentImportSourceRequestStatus]` — The status of the content import source.
@@ -578,24 +509,10 @@ client.articles.create(
-
client.articles.find(...) -
-
- -#### 📝 Description - -
-
- +
client.ai_content.get_content_import_source(...)
-You can fetch the details of a single article by making a GET request to `https://api.intercom.io/articles/`. -
-
-
-
- #### 🔌 Usage
@@ -610,8 +527,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.articles.find( - article_id="123", +client.ai_content.get_content_import_source( + source_id="source_id", ) ``` @@ -628,7 +545,7 @@ client.articles.find(
-**article_id:** `str` — The unique identifier for the article which is given by Intercom. +**source_id:** `str` — The unique identifier for the content import source which is given by Intercom.
@@ -648,7 +565,7 @@ client.articles.find(
-
client.articles.update(...) +
client.ai_content.update_content_import_source(...)
@@ -660,7 +577,7 @@ client.articles.find(
-You can update the details of a single article by making a PUT request to `https://api.intercom.io/articles/`. +You can update an existing content import source.
@@ -680,10 +597,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.articles.update( - article_id="123", - title="Christmas is here!", - body="

New gifts in store for the jolly season

", +client.ai_content.update_content_import_source( + source_id="source_id", + sync_behavior="api", + url="https://www.example.com", ) ``` @@ -700,7 +617,7 @@ client.articles.update(
-**article_id:** `str` — The unique identifier for the article which is given by Intercom. +**source_id:** `str` — The unique identifier for the content import source which is given by Intercom.
@@ -708,7 +625,7 @@ client.articles.update(
-**title:** `typing.Optional[str]` — The title of the article.For multilingual articles, this will be the title of the default language's content. +**sync_behavior:** `UpdateContentImportSourceRequestSyncBehavior` — If you intend to create or update External Pages via the API, this should be set to `api`. You can not change the value to or from api.
@@ -716,7 +633,7 @@ client.articles.update(
-**description:** `typing.Optional[str]` — The description of the article. For multilingual articles, this will be the description of the default language's content. +**url:** `str` — The URL of the content import source. This may only be different from the existing value if the sync behavior is API.
@@ -724,7 +641,7 @@ client.articles.update(
-**body:** `typing.Optional[str]` — The content of the article. For multilingual articles, this will be the body of the default language's content. +**status:** `typing.Optional[UpdateContentImportSourceRequestStatus]` — The status of the content import source.
@@ -732,39 +649,69 @@ client.articles.update(
-**author_id:** `typing.Optional[int]` — The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
-
-
-**state:** `typing.Optional[UpdateArticleRequestBodyState]` — Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. -
+
+
client.ai_content.delete_content_import_source(...)
-**parent_id:** `typing.Optional[str]` — The id of the article's parent collection or section. An article without this field stands alone. - +#### 📝 Description + +
+
+ +
+
+ +You can delete a content import source by making a DELETE request this endpoint. This will also delete all external pages that were imported from this source. +
+
+#### 🔌 Usage +
-**parent_type:** `typing.Optional[UpdateArticleRequestBodyParentType]` — The type of parent, which can either be a `collection` or `section`. - +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.ai_content.delete_content_import_source( + source_id="source_id", +) + +``` +
+
+#### ⚙️ Parameters +
-**translated_content:** `typing.Optional[ArticleTranslatedContent]` +
+
+ +**source_id:** `str` — The unique identifier for the content import source which is given by Intercom.
@@ -784,7 +731,7 @@ client.articles.update(
-
client.articles.delete(...) +
client.ai_content.list_external_pages()
@@ -796,7 +743,7 @@ client.articles.update(
-You can delete a single article by making a DELETE request to `https://api.intercom.io/articles/`. +You can retrieve a list of all external pages for a workspace.
@@ -816,9 +763,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.articles.delete( - article_id="123", -) +client.ai_content.list_external_pages() ``` @@ -834,14 +779,6 @@ client.articles.delete(
-**article_id:** `str` — The unique identifier for the article which is given by Intercom. - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -854,7 +791,7 @@ client.articles.delete(
-
client.articles.search(...) +
client.ai_content.create_external_page(...)
@@ -866,7 +803,7 @@ client.articles.delete(
-You can search for articles by making a GET request to `https://api.intercom.io/articles/search`. +You can create a new external page by sending a POST request to this endpoint. If an external page already exists with the specified source_id and external_id, it will be updated instead.
@@ -886,9 +823,12 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.articles.search( - phrase="Getting started", - state="published", +client.ai_content.create_external_page( + title="Test", + html="

Test

", + url="https://www.example.com", + source_id=44, + external_id="abc1234", ) ``` @@ -905,7 +845,7 @@ client.articles.search(
-**phrase:** `typing.Optional[str]` — The phrase within your articles to search for. +**title:** `str` — The title of the external page.
@@ -913,7 +853,7 @@ client.articles.search(
-**state:** `typing.Optional[str]` — The state of the Articles returned. One of `published`, `draft` or `all`. +**html:** `str` — The body of the external page in HTML.
@@ -921,7 +861,7 @@ client.articles.search(
-**help_center_id:** `typing.Optional[int]` — The ID of the Help Center to search in. +**source_id:** `int` — The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response.
@@ -929,7 +869,31 @@ client.articles.search(
-**highlight:** `typing.Optional[bool]` — Return a highlighted version of the matching content within your articles. Refer to the response schema for more details. +**external_id:** `str` — The identifier for the external page which was given by the source. Must be unique for the source. + +
+
+ +
+
+ +**url:** `typing.Optional[str]` — The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. When a URL is not present, Fin will not reference the source. + +
+
+ +
+
+ +**ai_agent_availability:** `typing.Optional[bool]` — Whether the external page should be used to answer questions by AI Agent. Will not default when updating an existing external page. + +
+
+ +
+
+ +**ai_copilot_availability:** `typing.Optional[bool]` — Whether the external page should be used to answer questions by AI Copilot. Will not default when updating an existing external page.
@@ -949,8 +913,7 @@ client.articles.search(
-## HelpCenters -
client.help_centers.find(...) +
client.ai_content.get_external_page(...)
@@ -962,7 +925,7 @@ client.articles.search(
-You can fetch the details of a single Help Center by making a GET request to `https://api.intercom.io/help_center/help_center/`. +You can retrieve an external page.
@@ -982,8 +945,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.help_centers.find( - help_center_id="123", +client.ai_content.get_external_page( + page_id="page_id", ) ``` @@ -1000,7 +963,7 @@ client.help_centers.find(
-**help_center_id:** `str` — The unique identifier for the Help Center which is given by Intercom. +**page_id:** `str` — The unique identifier for the external page which is given by Intercom.
@@ -1020,7 +983,7 @@ client.help_centers.find(
-
client.help_centers.list(...) +
client.ai_content.update_external_page(...)
@@ -1032,7 +995,7 @@ client.help_centers.find(
-You can list all Help Centers by making a GET request to `https://api.intercom.io/help_center/help_centers`. +You can update an existing external page (if it was created via the API).
@@ -1052,12 +1015,14 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -response = client.help_centers.list() -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page +client.ai_content.update_external_page( + page_id="page_id", + title="Test", + html="

Test

", + url="https://www.example.com", + source_id=47, + external_id="5678", +) ``` @@ -1073,7 +1038,7 @@ for page in response.iter_pages():
-**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page +**page_id:** `str` — The unique identifier for the external page which is given by Intercom.
@@ -1081,7 +1046,7 @@ for page in response.iter_pages():
-**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15 +**title:** `str` — The title of the external page.
@@ -1089,107 +1054,23 @@ for page in response.iter_pages():
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**html:** `str` — The body of the external page in HTML.
- -
+
+
+**url:** `str` — The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. +
-
-## Companies -
client.companies.retrieve(...)
-#### 📝 Description - -
-
- -
-
- -You can fetch a single company by passing in `company_id` or `name`. - - `https://api.intercom.io/companies?name={name}` - - `https://api.intercom.io/companies?company_id={company_id}` - -You can fetch all companies and filter by `segment_id` or `tag_id` as a query parameter. - - `https://api.intercom.io/companies?tag_id={tag_id}` - - `https://api.intercom.io/companies?segment_id={segment_id}` -
-
-
-
- -#### 🔌 Usage - -
-
- -
-
- -```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.companies.retrieve( - name="my company", - company_id="12345", - tag_id="678910", - segment_id="98765", -) - -``` -
-
-
-
- -#### ⚙️ Parameters - -
-
- -
-
- -**name:** `typing.Optional[str]` — The `name` of the company to filter by. - -
-
- -
-
- -**company_id:** `typing.Optional[str]` — The `company_id` of the company to filter by. - -
-
- -
-
- -**tag_id:** `typing.Optional[str]` — The `tag_id` of the company to filter by. - -
-
- -
-
- -**segment_id:** `typing.Optional[str]` — The `segment_id` of the company to filter by. +**source_id:** `int` — The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response.
@@ -1197,7 +1078,7 @@ client.companies.retrieve(
-**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page +**fin_availability:** `typing.Optional[bool]` — Whether the external page should be used to answer questions by Fin.
@@ -1205,7 +1086,7 @@ client.companies.retrieve(
-**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15 +**external_id:** `typing.Optional[str]` — The identifier for the external page which was given by the source. Must be unique for the source.
@@ -1225,7 +1106,7 @@ client.companies.retrieve(
-
client.companies.create_or_update(...) +
client.ai_content.delete_external_page(...)
@@ -1237,15 +1118,7 @@ client.companies.retrieve(
-You can create or update a company. - -Companies will be only visible in Intercom when there is at least one associated user. - -Companies are looked up via `company_id` in a `POST` request, if not found via `company_id`, the new company will be created, if found, that company will be updated. - -{% admonition type="warning" name="Using `company_id`" %} - You can set a unique `company_id` value when creating a company. However, it is not possible to update `company_id`. Be sure to set a unique value once upon creation of the company. -{% /admonition %} +Sending a DELETE request for an external page will remove it from the content library UI and from being used for AI answers.
@@ -1265,7 +1138,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.companies.create_or_update() +client.ai_content.delete_external_page( + page_id="page_id", +) ``` @@ -1281,7 +1156,7 @@ client.companies.create_or_update()
-**name:** `typing.Optional[str]` — The name of the Company +**page_id:** `str` — The unique identifier for the external page which is given by Intercom.
@@ -1289,55 +1164,77 @@ client.companies.create_or_update()
-**company_id:** `typing.Optional[str]` — The company id you have defined for the company. Can't be updated +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
-
-
-**plan:** `typing.Optional[str]` — The name of the plan you have associated with the company. -
+
+## Articles +
client.articles.list(...)
-**size:** `typing.Optional[int]` — The number of employees in this company. - -
-
+#### 📝 Description
-**website:** `typing.Optional[str]` — The URL for this company's website. Please note that the value specified here is not validated. Accepts any string. - -
-
-
-**industry:** `typing.Optional[str]` — The industry that this company operates in. - +You can fetch a list of all articles by making a GET request to `https://api.intercom.io/articles`. + +> 📘 How are the articles sorted and ordered? +> +> Articles will be returned in descending order on the `updated_at` attribute. This means if you need to iterate through results then we'll show the most recently updated articles first.
+ + + +#### 🔌 Usage
-**custom_attributes:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — A hash of key/value pairs containing any other data about the company you want Intercom to store. - +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +response = client.articles.list() +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page + +``` +
+
+#### ⚙️ Parameters + +
+
+
-**remote_created_at:** `typing.Optional[int]` — The time the company was created by you. +**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page
@@ -1345,7 +1242,7 @@ client.companies.create_or_update()
-**monthly_spend:** `typing.Optional[int]` — How much revenue the company generates for your business. Note that this will truncate floats. i.e. it only allow for whole integers, 155.98 will be truncated to 155. Note that this has an upper limit of 2**31-1 or 2147483647.. +**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15
@@ -1365,7 +1262,7 @@ client.companies.create_or_update()
-
client.companies.find(...) +
client.articles.create(...)
@@ -1377,7 +1274,7 @@ client.companies.create_or_update()
-You can fetch a single company. +You can create a new article by making a POST request to `https://api.intercom.io/articles`.
@@ -1392,13 +1289,19 @@ You can fetch a single company.
```python -from intercom import Intercom +from intercom import CreateArticleRequest, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.companies.find( - company_id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +client.articles.create( + request=CreateArticleRequest( + title="Thanks for everything", + description="Description of the Article", + body="Body of the Article", + author_id=1295, + state="published", + ), ) ``` @@ -1415,7 +1318,7 @@ client.companies.find(
-**company_id:** `str` — The unique identifier for the company which is given by Intercom +**request:** `typing.Optional[CreateArticleRequest]`
@@ -1435,7 +1338,7 @@ client.companies.find(
-
client.companies.update(...) +
client.articles.find(...)
@@ -1447,11 +1350,7 @@ client.companies.find(
-You can update a single company using the Intercom provisioned `id`. - -{% admonition type="warning" name="Using `company_id`" %} - When updating a company it is not possible to update `company_id`. This can only be set once upon creation of the company. -{% /admonition %} +You can fetch the details of a single article by making a GET request to `https://api.intercom.io/articles/`.
@@ -1471,8 +1370,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.companies.update( - company_id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +client.articles.find( + article_id=1, ) ``` @@ -1489,7 +1388,7 @@ client.companies.update(
-**company_id:** `str` — The unique identifier for the company which is given by Intercom +**article_id:** `int` — The unique identifier for the article which is given by Intercom.
@@ -1509,7 +1408,7 @@ client.companies.update(
-
client.companies.delete(...) +
client.articles.update(...)
@@ -1521,7 +1420,7 @@ client.companies.update(
-You can delete a single company. +You can update the details of a single article by making a PUT request to `https://api.intercom.io/articles/`.
@@ -1541,8 +1440,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.companies.delete( - company_id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +client.articles.update( + article_id=1, + title="Christmas is here!", + body="

New gifts in store for the jolly season

", ) ``` @@ -1559,7 +1460,7 @@ client.companies.delete(
-**company_id:** `str` — The unique identifier for the company which is given by Intercom +**article_id:** `int` — The unique identifier for the article which is given by Intercom.
@@ -1567,69 +1468,47 @@ client.companies.delete(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**title:** `typing.Optional[str]` — The title of the article.For multilingual articles, this will be the title of the default language's content.
- -
+
+
+**description:** `typing.Optional[str]` — The description of the article. For multilingual articles, this will be the description of the default language's content. +
-
-
client.companies.list_attached_contacts(...)
-#### 📝 Description - -
-
+**body:** `typing.Optional[str]` — The content of the article. For multilingual articles, this will be the body of the default language's content. + +
+
-You can fetch a list of all contacts that belong to a company. -
-
+**author_id:** `typing.Optional[int]` — The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. +
-#### 🔌 Usage -
-
-
- -```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.companies.list_attached_contacts( - company_id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", -) - -``` -
-
+**state:** `typing.Optional[UpdateArticleRequestState]` — Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. +
-#### ⚙️ Parameters - -
-
-
-**company_id:** `str` — The unique identifier for the company which is given by Intercom +**parent_id:** `typing.Optional[str]` — The id of the article's parent collection or section. An article without this field stands alone.
@@ -1637,7 +1516,7 @@ client.companies.list_attached_contacts(
-**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page +**parent_type:** `typing.Optional[str]` — The type of parent, which can either be a `collection` or `section`.
@@ -1645,7 +1524,7 @@ client.companies.list_attached_contacts(
-**per_page:** `typing.Optional[int]` — How many results to return per page. Defaults to 15 +**translated_content:** `typing.Optional[ArticleTranslatedContent]`
@@ -1665,7 +1544,7 @@ client.companies.list_attached_contacts(
-
client.companies.list_attached_segments(...) +
client.articles.delete(...)
@@ -1677,7 +1556,7 @@ client.companies.list_attached_contacts(
-You can fetch a list of all segments that belong to a company. +You can delete a single article by making a DELETE request to `https://api.intercom.io/articles/`.
@@ -1697,8 +1576,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.companies.list_attached_segments( - company_id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +client.articles.delete( + article_id=1, ) ``` @@ -1715,7 +1594,7 @@ client.companies.list_attached_segments(
-**company_id:** `str` — The unique identifier for the company which is given by Intercom +**article_id:** `int` — The unique identifier for the article which is given by Intercom.
@@ -1735,7 +1614,7 @@ client.companies.list_attached_segments(
-
client.companies.list(...) +
client.articles.search(...)
@@ -1747,19 +1626,11 @@ client.companies.list_attached_segments(
-You can list companies. The company list is sorted by the `last_request_at` field and by default is ordered descending, most recently requested first. - -Note that the API does not include companies who have no associated users in list responses. - -When using the Companies endpoint and the pages object to iterate through the returned companies, there is a limit of 10,000 Companies that can be returned. If you need to list or iterate on more than 10,000 Companies, please use the [Scroll API](https://developers.intercom.com/reference#iterating-over-all-companies). -{% admonition type="warning" name="Pagination" %} - You can use pagination to limit the number of results returned. The default is `20` results per page. - See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. -{% /admonition %} -
-
-
-
+You can search for articles by making a GET request to `https://api.intercom.io/articles/search`. + + + + #### 🔌 Usage @@ -1775,14 +1646,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -response = client.companies.list( - order="desc", +client.articles.search( + phrase="Getting started", + state="published", ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` @@ -1798,7 +1665,7 @@ for page in response.iter_pages():
-**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page +**phrase:** `typing.Optional[str]` — The phrase within your articles to search for.
@@ -1806,7 +1673,7 @@ for page in response.iter_pages():
-**per_page:** `typing.Optional[int]` — How many results to return per page. Defaults to 15 +**state:** `typing.Optional[str]` — The state of the Articles returned. One of `published`, `draft` or `all`.
@@ -1814,7 +1681,15 @@ for page in response.iter_pages():
-**order:** `typing.Optional[str]` — `asc` or `desc`. Return the companies in ascending or descending order. Defaults to desc +**help_center_id:** `typing.Optional[int]` — The ID of the Help Center to search in. + +
+
+ +
+
+ +**highlight:** `typing.Optional[bool]` — Return a highlighted version of the matching content within your articles. Refer to the response schema for more details.
@@ -1834,7 +1709,8 @@ for page in response.iter_pages():
-
client.companies.scroll(...) +## Away Status Reasons +
client.away_status_reasons.list_away_status_reasons()
@@ -1846,21 +1722,7 @@ for page in response.iter_pages():
- The `list all companies` functionality does not work well for huge datasets, and can result in errors and performance problems when paging deeply. The Scroll API provides an efficient mechanism for iterating over all companies in a dataset. - -- Each app can only have 1 scroll open at a time. You'll get an error message if you try to have more than one open per app. -- If the scroll isn't used for 1 minute, it expires and calls with that scroll param will fail -- If the end of the scroll is reached, "companies" will be empty and the scroll parameter will expire - -{% admonition type="info" name="Scroll Parameter" %} - You can get the first page of companies by simply sending a GET request to the scroll endpoint. - For subsequent requests you will need to use the scroll parameter from the response. -{% /admonition %} -{% admonition type="danger" name="Scroll network timeouts" %} - Since scroll is often used on large datasets network errors such as timeouts can be encountered. When this occurs you will see a HTTP 500 error with the following message: - "Request failed due to an internal network error. Please restart the scroll operation." - If this happens, you will need to restart your scroll query: It is not possible to continue from a specific point when using scroll. -{% /admonition %} +Returns a list of all away status reasons configured for the workspace, including deleted ones.
@@ -1880,12 +1742,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -response = client.companies.scroll() -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page +client.away_status_reasons.list_away_status_reasons() ``` @@ -1901,14 +1758,6 @@ for page in response.iter_pages():
-**scroll_param:** `typing.Optional[str]` — - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -1921,24 +1770,11 @@ for page in response.iter_pages():
-
client.companies.attach_contact(...) -
-
- -#### 📝 Description - -
-
- +## Export +
client.export.enqueue_a_new_reporting_data_export_job(...)
-You can attach a company to a single contact. -
-
-
-
- #### 🔌 Usage
@@ -1953,9 +1789,11 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.companies.attach_contact( - contact_id="contact_id", - company_id="123", +client.export.enqueue_a_new_reporting_data_export_job( + dataset_id="conversation", + attribute_ids=["conversation_id", "conversation_started_at"], + start_time=1717490000, + end_time=1717510000, ) ``` @@ -1972,7 +1810,7 @@ client.companies.attach_contact(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**dataset_id:** `str`
@@ -1980,7 +1818,23 @@ client.companies.attach_contact(
-**company_id:** `str` — The unique identifier for the company which is given by Intercom +**attribute_ids:** `typing.Sequence[str]` + +
+
+ +
+
+ +**start_time:** `int` + +
+
+ +
+
+ +**end_time:** `int`
@@ -2000,11 +1854,11 @@ client.companies.attach_contact(
-
client.companies.detach_contact(...) +
client.export.list_available_datasets_and_attributes()
-#### 📝 Description +#### 🔌 Usage
@@ -2012,11 +1866,44 @@ client.companies.attach_contact(
-You can detach a company from a single contact. +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.export.list_available_datasets_and_attributes() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+ +
+
+ +## Data Export +
client.data_export.export_reporting_data(...) +
+
#### 🔌 Usage @@ -2032,9 +1919,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.companies.detach_contact( - contact_id="58a430d35458202d41b1e65b", - company_id="58a430d35458202d41b1e65b", +client.data_export.export_reporting_data( + job_identifier="job_identifier", + app_id="app_id", + client_id="client_id", ) ``` @@ -2051,7 +1939,7 @@ client.companies.detach_contact(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**job_identifier:** `str` — Unique identifier of the job.
@@ -2059,7 +1947,15 @@ client.companies.detach_contact(
-**company_id:** `str` — The unique identifier for the company which is given by Intercom +**app_id:** `str` — The Intercom defined code of the workspace the company is associated to. + +
+
+ +
+
+ +**client_id:** `str`
@@ -2079,25 +1975,10 @@ client.companies.detach_contact(
-## Contacts -
client.contacts.list_attached_companies(...) -
-
- -#### 📝 Description - +
client.data_export.download_reporting_data_export(...)
-
-
- -You can fetch a list of companies that are associated to a contact. -
-
-
-
- #### 🔌 Usage
@@ -2112,14 +1993,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -response = client.contacts.list_attached_companies( - contact_id="63a07ddf05a32042dffac965", +client.data_export.download_reporting_data_export( + job_identifier="job_identifier", + app_id="app_id", ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -2135,15 +2012,7 @@ for page in response.iter_pages():
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom - -
-
- -
-
- -**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page +**job_identifier:** `str`
@@ -2151,7 +2020,7 @@ for page in response.iter_pages():
-**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15 +**app_id:** `str`
@@ -2171,7 +2040,7 @@ for page in response.iter_pages():
-
client.contacts.list_attached_segments(...) +
client.data_export.create(...)
@@ -2183,7 +2052,21 @@ for page in response.iter_pages():
-You can fetch a list of segments that are associated to a contact. +To create your export job, you need to send a `POST` request to the export endpoint `https://api.intercom.io/export/content/data`. + +The only parameters you need to provide are the range of dates that you want exported. + +>🚧 Limit of one active job +> +> You can only have one active job per workspace. You will receive a HTTP status code of 429 with the message Exceeded rate limit of 1 pending message data export jobs if you attempt to create a second concurrent job. + +>❗️ Updated_at not included +> +> It should be noted that the timeframe only includes messages sent during the time period and not messages that were only updated during this period. For example, if a message was updated yesterday but sent two days ago, you would need to set the created_at_after date before the message was sent to include that in your retrieval job. + +>📘 Date ranges are inclusive +> +> Requesting data for 2018-06-01 until 2018-06-30 will get all data for those days including those specified - e.g. 2018-06-01 00:00:00 until 2018-06-30 23:59:99.
@@ -2203,8 +2086,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.list_attached_segments( - contact_id="63a07ddf05a32042dffac965", +client.data_export.create( + created_at_after=1734519776, + created_at_before=1734537776, ) ``` @@ -2221,7 +2105,15 @@ client.contacts.list_attached_segments(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**created_at_after:** `int` — The start date that you request data for. It must be formatted as a unix timestamp. + +
+
+ +
+
+ +**created_at_before:** `int` — The end date that you request data for. It must be formatted as a unix timestamp.
@@ -2241,7 +2133,7 @@ client.contacts.list_attached_segments(
-
client.contacts.list_attached_subscriptions(...) +
client.data_export.find(...)
@@ -2253,13 +2145,11 @@ client.contacts.list_attached_segments(
-You can fetch a list of subscription types that are attached to a contact. These can be subscriptions that a user has 'opted-in' to or has 'opted-out' from, depending on the subscription type. -This will return a list of Subscription Type objects that the contact is associated with. - -The data property will show a combined list of: +You can view the status of your job by sending a `GET` request to the URL +`https://api.intercom.io/export/content/data/{job_identifier}` - the `{job_identifier}` is the value returned in the response when you first created the export job. More on it can be seen in the Export Job Model. - 1.Opt-out subscription types that the user has opted-out from. - 2.Opt-in subscription types that the user has opted-in to receiving. +> 🚧 Jobs expire after two days +> All jobs that have completed processing (and are thus available to download from the provided URL) will have an expiry limit of two days from when the export ob completed. After this, the data will no longer be available.
@@ -2279,8 +2169,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.list_attached_subscriptions( - contact_id="63a07ddf05a32042dffac965", +client.data_export.find( + job_identifier="job_identifier", ) ``` @@ -2297,7 +2187,7 @@ client.contacts.list_attached_subscriptions(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**job_identifier:** `str` — job_identifier
@@ -2317,7 +2207,7 @@ client.contacts.list_attached_subscriptions(
-
client.contacts.attach_subscription(...) +
client.data_export.cancel(...)
@@ -2329,13 +2219,7 @@ client.contacts.list_attached_subscriptions(
-You can add a specific subscription to a contact. In Intercom, we have two different subscription types based on user consent - opt-out and opt-in: - - 1.Attaching a contact to an opt-out subscription type will opt that user out from receiving messages related to that subscription type. - - 2.Attaching a contact to an opt-in subscription type will opt that user in to receiving messages related to that subscription type. - -This will return a subscription type model for the subscription type that was added to the contact. +You can cancel your job
@@ -2355,10 +2239,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.attach_subscription( - contact_id="63a07ddf05a32042dffac965", - subscription_id="invalid_id", - consent_type="opt_in", +client.data_export.cancel( + job_identifier="job_identifier", ) ``` @@ -2375,7 +2257,7 @@ client.contacts.attach_subscription(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**job_identifier:** `str` — job_identifier
@@ -2383,15 +2265,75 @@ client.contacts.attach_subscription(
-**subscription_id:** `str` — The unique identifier for the subscription which is given by Intercom +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
+ + + +
+ +
client.data_export.download(...)
-**consent_type:** `str` — The consent_type of a subscription, opt_out or opt_in. +#### 📝 Description + +
+
+ +
+
+ +When a job has a status of complete, and thus a filled download_url, you can download your data by hitting that provided URL, formatted like so: https://api.intercom.io/download/content/data/xyz1234. + +Your exported message data will be streamed continuously back down to you in a gzipped CSV format. + +> 📘 Octet header required +> +> You will have to specify the header Accept: `application/octet-stream` when hitting this endpoint. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.data_export.download( + job_identifier="job_identifier", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**job_identifier:** `str` — job_identifier
@@ -2411,7 +2353,8 @@ client.contacts.attach_subscription(
-
client.contacts.detach_subscription(...) +## HelpCenters +
client.help_centers.find(...)
@@ -2423,7 +2366,7 @@ client.contacts.attach_subscription(
-You can remove a specific subscription from a contact. This will return a subscription type model for the subscription type that was removed from the contact. +You can fetch the details of a single Help Center by making a GET request to `https://api.intercom.io/help_center/help_center/`.
@@ -2443,9 +2386,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.detach_subscription( - contact_id="63a07ddf05a32042dffac965", - subscription_id="37846", +client.help_centers.find( + help_center_id=1, ) ``` @@ -2462,15 +2404,7 @@ client.contacts.detach_subscription(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom - -
-
- -
-
- -**subscription_id:** `str` — The unique identifier for the subscription type which is given by Intercom +**help_center_id:** `int` — The unique identifier for the collection which is given by Intercom.
@@ -2490,7 +2424,7 @@ client.contacts.detach_subscription(
-
client.contacts.list_attached_tags(...) +
client.help_centers.list(...)
@@ -2502,7 +2436,7 @@ client.contacts.detach_subscription(
-You can fetch a list of all tags that are attached to a specific contact. +You can list all Help Centers by making a GET request to `https://api.intercom.io/help_center/help_centers`.
@@ -2522,9 +2456,12 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.list_attached_tags( - contact_id="63a07ddf05a32042dffac965", -) +response = client.help_centers.list() +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ``` @@ -2540,7 +2477,15 @@ client.contacts.list_attached_tags(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page + +
+
+ +
+
+ +**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15
@@ -2560,7 +2505,8 @@ client.contacts.list_attached_tags(
-
client.contacts.find(...) +## Internal Articles +
client.internal_articles.list_internal_articles()
@@ -2572,7 +2518,7 @@ client.contacts.list_attached_tags(
-You can fetch the details of a single contact. +You can fetch a list of all internal articles by making a GET request to `https://api.intercom.io/internal_articles`.
@@ -2592,9 +2538,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.find( - contact_id="63a07ddf05a32042dffac965", -) +client.internal_articles.list_internal_articles() ``` @@ -2610,14 +2554,6 @@ client.contacts.find(
-**contact_id:** `str` — id - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -2630,7 +2566,7 @@ client.contacts.find(
-
client.contacts.update(...) +
client.internal_articles.create_internal_article(...)
@@ -2642,7 +2578,7 @@ client.contacts.find(
-You can update an existing contact (ie. user or lead). +You can create a new internal article by making a POST request to `https://api.intercom.io/internal_articles`.
@@ -2657,15 +2593,18 @@ You can update an existing contact (ie. user or lead).
```python -from intercom import Intercom +from intercom import CreateInternalArticleRequest, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.update( - contact_id="63a07ddf05a32042dffac965", - email="joebloggs@intercom.io", - name="joe bloggs", +client.internal_articles.create_internal_article( + request=CreateInternalArticleRequest( + title="Thanks for everything", + body="Body of the Internal Article", + author_id=1295, + owner_id=1295, + ), ) ``` @@ -2682,7 +2621,7 @@ client.contacts.update(
-**contact_id:** `str` — id +**request:** `typing.Optional[CreateInternalArticleRequest]`
@@ -2690,31 +2629,69 @@ client.contacts.update(
-**role:** `typing.Optional[str]` — The role of the contact. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+ + + + +
+
client.internal_articles.retrieve_internal_article(...)
-**external_id:** `typing.Optional[str]` — A unique identifier for the contact which is given to Intercom - +#### 📝 Description + +
+
+ +
+
+ +You can fetch the details of a single internal article by making a GET request to `https://api.intercom.io/internal_articles/`.
+
+
+ +#### 🔌 Usage
-**email:** `typing.Optional[str]` — The contacts email - +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.internal_articles.retrieve_internal_article( + internal_article_id=1, +) + +``` +
+
+#### ⚙️ Parameters +
-**phone:** `typing.Optional[str]` — The contacts phone +
+
+ +**internal_article_id:** `int` — The unique identifier for the article which is given by Intercom.
@@ -2722,23 +2699,71 @@ client.contacts.update(
-**name:** `typing.Optional[str]` — The contacts name +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+ + +
+
+
+
client.internal_articles.update_internal_article(...)
-**avatar:** `typing.Optional[str]` — An image URL containing the avatar of a contact - +#### 📝 Description + +
+
+ +
+
+ +You can update the details of a single internal article by making a PUT request to `https://api.intercom.io/internal_articles/`. +
+
+#### 🔌 Usage +
-**signed_up_at:** `typing.Optional[int]` — The time specified for when a contact signed up +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.internal_articles.update_internal_article( + internal_article_id=1, + title="Christmas is here!", + body="

New gifts in store for the jolly season

", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**internal_article_id:** `int` — The unique identifier for the internal article which is given by Intercom.
@@ -2746,7 +2771,7 @@ client.contacts.update(
-**last_seen_at:** `typing.Optional[int]` — The time when the contact was last seen (either where the Intercom Messenger was installed or when specified manually) +**title:** `typing.Optional[str]` — The title of the article.
@@ -2754,7 +2779,7 @@ client.contacts.update(
-**owner_id:** `typing.Optional[int]` — The id of an admin that has been assigned account ownership of the contact +**body:** `typing.Optional[str]` — The content of the article.
@@ -2762,7 +2787,7 @@ client.contacts.update(
-**unsubscribed_from_emails:** `typing.Optional[bool]` — Whether the contact is unsubscribed from emails +**author_id:** `typing.Optional[int]` — The id of the author of the article.
@@ -2770,7 +2795,7 @@ client.contacts.update(
-**custom_attributes:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — The custom attributes which are set for the contact +**owner_id:** `typing.Optional[int]` — The id of the author of the article.
@@ -2790,7 +2815,7 @@ client.contacts.update(
-
client.contacts.delete(...) +
client.internal_articles.delete_internal_article(...)
@@ -2802,7 +2827,7 @@ client.contacts.update(
-You can delete a single contact. +You can delete a single internal article by making a DELETE request to `https://api.intercom.io/internal_articles/`.
@@ -2822,8 +2847,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.delete( - contact_id="contact_id", +client.internal_articles.delete_internal_article( + internal_article_id=1, ) ``` @@ -2840,7 +2865,7 @@ client.contacts.delete(
-**contact_id:** `str` — id +**internal_article_id:** `int` — The unique identifier for the internal article which is given by Intercom.
@@ -2860,7 +2885,7 @@ client.contacts.delete(
-
client.contacts.merge_lead_in_user(...) +
client.internal_articles.search_internal_articles(...)
@@ -2872,7 +2897,7 @@ client.contacts.delete(
-You can merge a contact with a `role` of `lead` into a contact with a `role` of `user`. +You can search for internal articles by making a GET request to `https://api.intercom.io/internal_articles/search`.
@@ -2892,10 +2917,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.merge_lead_in_user( - lead_id="667d60ac8a68186f43bafdbb", - contact_id="667d60ac8a68186f43bafdbc", -) +client.internal_articles.search_internal_articles() ``` @@ -2911,15 +2933,7 @@ client.contacts.merge_lead_in_user(
-**lead_id:** `str` — The unique identifier for the contact to merge away from. Must be a lead. - -
-
- -
-
- -**contact_id:** `str` — The unique identifier for the contact to merge into. Must be a user. +**folder_id:** `typing.Optional[str]` — The ID of the folder to search in.
@@ -2939,7 +2953,8 @@ client.contacts.merge_lead_in_user(
-
client.contacts.search(...) +## Companies +
client.companies.retrieve(...)
@@ -2951,105 +2966,17 @@ client.contacts.merge_lead_in_user(
-You can search for multiple contacts by the value of their attributes in order to fetch exactly who you want. +You can fetch a single company by passing in `company_id` or `name`. -To search for contacts, you need to send a `POST` request to `https://api.intercom.io/contacts/search`. + `https://api.intercom.io/companies?name={name}` -This will accept a query object in the body which will define your filters in order to search for contacts. + `https://api.intercom.io/companies?company_id={company_id}` -{% admonition type="warning" name="Optimizing search queries" %} - Search queries can be complex, so optimizing them can help the performance of your search. - Use the `AND` and `OR` operators to combine multiple filters to get the exact results you need and utilize - pagination to limit the number of results returned. The default is `50` results per page. - See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#example-search-conversations-request) for more details on how to use the `starting_after` param. -{% /admonition %} -### Contact Creation Delay - -If a contact has recently been created, there is a possibility that it will not yet be available when searching. This means that it may not appear in the response. This delay can take a few minutes. If you need to be instantly notified it is recommended to use webhooks and iterate to see if they match your search filters. - -### Nesting & Limitations - -You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4). -There are some limitations to the amount of multiple's there can be: -* There's a limit of max 2 nested filters -* There's a limit of max 15 filters for each AND or OR group - -### Searching for Timestamp Fields - -All timestamp fields (created_at, updated_at etc.) are indexed as Dates for Contact Search queries; Datetime queries are not currently supported. This means you can only query for timestamp fields by day - not hour, minute or second. -For example, if you search for all Contacts with a created_at value greater (>) than 1577869200 (the UNIX timestamp for January 1st, 2020 9:00 AM), that will be interpreted as 1577836800 (January 1st, 2020 12:00 AM). The search results will then include Contacts created from January 2nd, 2020 12:00 AM onwards. -If you'd like to get contacts created on January 1st, 2020 you should search with a created_at value equal (=) to 1577836800 (January 1st, 2020 12:00 AM). -This behaviour applies only to timestamps used in search queries. The search results will still contain the full UNIX timestamp and be sorted accordingly. - -### Accepted Fields - -Most key listed as part of the Contacts Model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). - -| Field | Type | -| ---------------------------------- | ------------------------------ | -| id | String | -| role | String
Accepts user or lead | -| name | String | -| avatar | String | -| owner_id | Integer | -| email | String | -| email_domain | String | -| phone | String | -| external_id | String | -| created_at | Date (UNIX Timestamp) | -| signed_up_at | Date (UNIX Timestamp) | -| updated_at | Date (UNIX Timestamp) | -| last_seen_at | Date (UNIX Timestamp) | -| last_contacted_at | Date (UNIX Timestamp) | -| last_replied_at | Date (UNIX Timestamp) | -| last_email_opened_at | Date (UNIX Timestamp) | -| last_email_clicked_at | Date (UNIX Timestamp) | -| language_override | String | -| browser | String | -| browser_language | String | -| os | String | -| location.country | String | -| location.region | String | -| location.city | String | -| unsubscribed_from_emails | Boolean | -| marked_email_as_spam | Boolean | -| has_hard_bounced | Boolean | -| ios_last_seen_at | Date (UNIX Timestamp) | -| ios_app_version | String | -| ios_device | String | -| ios_app_device | String | -| ios_os_version | String | -| ios_app_name | String | -| ios_sdk_version | String | -| android_last_seen_at | Date (UNIX Timestamp) | -| android_app_version | String | -| android_device | String | -| android_app_name | String | -| andoid_sdk_version | String | -| segment_id | String | -| tag_id | String | -| custom_attributes.{attribute_name} | String | - -### Accepted Operators - -{% admonition type="warning" name="Searching based on `created_at`" %} - You cannot use the `<=` or `>=` operators to search by `created_at`. -{% /admonition %} +You can fetch all companies and filter by `segment_id` or `tag_id` as a query parameter. -The table below shows the operators you can use to define how you want to search for the value. The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates). + `https://api.intercom.io/companies?tag_id={tag_id}` -| Operator | Valid Types | Description | -| :------- | :------------------------------- | :--------------------------------------------------------------- | -| = | All | Equals | -| != | All | Doesn't Equal | -| IN | All | In
Shortcut for `OR` queries
Values must be in Array | -| NIN | All | Not In
Shortcut for `OR !` queries
Values must be in Array | -| > | Integer
Date (UNIX Timestamp) | Greater than | -| < | Integer
Date (UNIX Timestamp) | Lower than | -| ~ | String | Contains | -| !~ | String | Doesn't Contain | -| ^ | String | Starts With | -| $ | String | Ends With | + `https://api.intercom.io/companies?segment_id={segment_id}`
@@ -3064,36 +2991,17 @@ The table below shows the operators you can use to define how you want to search
```python -from intercom import ( - Intercom, - MultipleFilterSearchRequest, - SingleFilterSearchRequest, - StartingAfterPaging, -) +from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -response = client.contacts.search( - query=MultipleFilterSearchRequest( - operator="AND", - value=[ - SingleFilterSearchRequest( - field="created_at", - operator=">", - value="1306054154", - ) - ], - ), - pagination=StartingAfterPaging( - per_page=5, - ), +client.companies.retrieve( + name="my company", + company_id="12345", + tag_id="678910", + segment_id="98765", ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -3109,7 +3017,7 @@ for page in response.iter_pages():
-**query:** `SearchRequestQuery` +**name:** `typing.Optional[str]` — The `name` of the company to filter by.
@@ -3117,7 +3025,39 @@ for page in response.iter_pages():
-**pagination:** `typing.Optional[StartingAfterPaging]` +**company_id:** `typing.Optional[str]` — The `company_id` of the company to filter by. + +
+
+ +
+
+ +**tag_id:** `typing.Optional[str]` — The `tag_id` of the company to filter by. + +
+
+ +
+
+ +**segment_id:** `typing.Optional[str]` — The `segment_id` of the company to filter by. + +
+
+ +
+
+ +**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page + +
+
+ +
+
+ +**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15
@@ -3137,7 +3077,7 @@ for page in response.iter_pages():
-
client.contacts.list(...) +
client.companies.create_or_update(...)
@@ -3149,10 +3089,14 @@ for page in response.iter_pages():
-You can fetch a list of all contacts (ie. users or leads) in your workspace. -{% admonition type="warning" name="Pagination" %} - You can use pagination to limit the number of results returned. The default is `50` results per page. - See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. +You can create or update a company. + +Companies will be only visible in Intercom when there is at least one associated user. + +Companies are looked up via `company_id` in a `POST` request, if not found via `company_id`, the new company will be created, if found, that company will be updated. + +{% admonition type="warning" name="Using `company_id`" %} + You can set a unique `company_id` value when creating a company. However, it is not possible to update `company_id`. Be sure to set a unique value once upon creation of the company. {% /admonition %}
@@ -3168,17 +3112,18 @@ You can fetch a list of all contacts (ie. users or leads) in your workspace.
```python -from intercom import Intercom +from intercom import CreateOrUpdateCompanyRequest, Intercom client = Intercom( token="YOUR_TOKEN", ) -response = client.contacts.list() -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page +client.companies.create_or_update( + request=CreateOrUpdateCompanyRequest( + name="my company", + company_id="company_remote_id", + remote_created_at=1374138000, + ), +) ```
@@ -3194,23 +3139,7 @@ for page in response.iter_pages():
-**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page - -
-
- -
-
- -**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15 - -
-
- -
-
- -**starting_after:** `typing.Optional[str]` — String used to get the next page of conversations. +**request:** `typing.Optional[CreateOrUpdateCompanyRequest]`
@@ -3230,7 +3159,7 @@ for page in response.iter_pages():
-
client.contacts.create(...) +
client.companies.find(...)
@@ -3242,7 +3171,7 @@ for page in response.iter_pages():
-You can create a new contact (ie. user or lead). +You can fetch a single company.
@@ -3257,15 +3186,13 @@ You can create a new contact (ie. user or lead).
```python -from intercom import CreateContactRequestWithEmail, Intercom +from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.create( - request=CreateContactRequestWithEmail( - email="joebloggs@intercom.io", - ), +client.companies.find( + company_id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", ) ``` @@ -3282,7 +3209,7 @@ client.contacts.create(
-**request:** `CreateContactRequest` +**company_id:** `str` — The unique identifier for the company which is given by Intercom
@@ -3302,7 +3229,7 @@ client.contacts.create(
-
client.contacts.archive(...) +
client.companies.update(...)
@@ -3314,7 +3241,11 @@ client.contacts.create(
-You can archive a single contact. +You can update a single company using the Intercom provisioned `id`. + +{% admonition type="warning" name="Using `company_id`" %} + When updating a company it is not possible to update `company_id`. This can only be set once upon creation of the company. +{% /admonition %}
@@ -3334,8 +3265,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.archive( - contact_id="63a07ddf05a32042dffac965", +client.companies.update( + company_id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", ) ``` @@ -3352,7 +3283,7 @@ client.contacts.archive(
-**contact_id:** `str` — id +**company_id:** `str` — The unique identifier for the company which is given by Intercom
@@ -3372,7 +3303,7 @@ client.contacts.archive(
-
client.contacts.unarchive(...) +
client.companies.delete(...)
@@ -3384,7 +3315,7 @@ client.contacts.archive(
-You can unarchive a single contact. +You can delete a single company.
@@ -3404,8 +3335,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.contacts.unarchive( - contact_id="63a07ddf05a32042dffac965", +client.companies.delete( + company_id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", ) ``` @@ -3422,7 +3353,7 @@ client.contacts.unarchive(
-**contact_id:** `str` — id +**company_id:** `str` — The unique identifier for the company which is given by Intercom
@@ -3442,8 +3373,7 @@ client.contacts.unarchive(
-## Notes -
client.notes.list(...) +
client.companies.list_attached_contacts(...)
@@ -3455,7 +3385,7 @@ client.contacts.unarchive(
-You can fetch a list of notes that are associated to a contact. +You can fetch a list of all contacts that belong to a company.
@@ -3475,14 +3405,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -response = client.notes.list( - contact_id="contact_id", +client.companies.list_attached_contacts( + company_id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ``` @@ -3498,7 +3423,7 @@ for page in response.iter_pages():
-**contact_id:** `str` — The unique identifier of a contact. +**company_id:** `str` — The unique identifier for the company which is given by Intercom
@@ -3506,23 +3431,7 @@ for page in response.iter_pages():
-**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page - -
-
- -
-
- -**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15 - -
-
- -
-
- -**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -3534,7 +3443,7 @@ for page in response.iter_pages():
-
client.notes.create(...) +
client.companies.list_attached_segments(...)
@@ -3546,7 +3455,7 @@ for page in response.iter_pages():
-You can add a note to a single contact. +You can fetch a list of all segments that belong to a company.
@@ -3566,10 +3475,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.notes.create( - contact_id="123", - body="Hello", - admin_id="123", +client.companies.list_attached_segments( + company_id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", ) ``` @@ -3586,23 +3493,7 @@ client.notes.create(
-**contact_id:** `str` — The unique identifier of a given contact. - -
-
- -
-
- -**body:** `str` — The text of the note. - -
-
- -
-
- -**admin_id:** `typing.Optional[str]` — The unique identifier of a given admin. +**company_id:** `str` — The unique identifier for the company which is given by Intercom
@@ -3622,7 +3513,7 @@ client.notes.create(
-
client.notes.find(...) +
client.companies.list(...)
@@ -3634,7 +3525,15 @@ client.notes.create(
-You can fetch the details of a single note. +You can list companies. The company list is sorted by the `last_request_at` field and by default is ordered descending, most recently requested first. + +Note that the API does not include companies who have no associated users in list responses. + +When using the Companies endpoint and the pages object to iterate through the returned companies, there is a limit of 10,000 Companies that can be returned. If you need to list or iterate on more than 10,000 Companies, please use the [Scroll API](https://developers.intercom.com/reference#iterating-over-all-companies). +{% admonition type="warning" name="Pagination" %} + You can use pagination to limit the number of results returned. The default is `20` results per page. + See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. +{% /admonition %}
@@ -3654,9 +3553,14 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.notes.find( - note_id="1", +response = client.companies.list( + order="desc", ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ``` @@ -3672,7 +3576,23 @@ client.notes.find(
-**note_id:** `str` — The unique identifier of a given note +**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page + +
+
+ +
+
+ +**per_page:** `typing.Optional[int]` — How many results to return per page. Defaults to 15 + +
+
+ +
+
+ +**order:** `typing.Optional[str]` — `asc` or `desc`. Return the companies in ascending or descending order. Defaults to desc
@@ -3692,8 +3612,7 @@ client.notes.find(
-## Tags -
client.tags.tag_contact(...) +
client.companies.scroll(...)
@@ -3705,7 +3624,21 @@ client.notes.find(
-You can tag a specific contact. This will return a tag object for the tag that was added to the contact. + The `list all companies` functionality does not work well for huge datasets, and can result in errors and performance problems when paging deeply. The Scroll API provides an efficient mechanism for iterating over all companies in a dataset. + +- Each app can only have 1 scroll open at a time. You'll get an error message if you try to have more than one open per app. +- If the scroll isn't used for 1 minute, it expires and calls with that scroll param will fail +- If the end of the scroll is reached, "companies" will be empty and the scroll parameter will expire + +{% admonition type="info" name="Scroll Parameter" %} + You can get the first page of companies by simply sending a GET request to the scroll endpoint. + For subsequent requests you will need to use the scroll parameter from the response. +{% /admonition %} +{% admonition type="danger" name="Scroll network timeouts" %} + Since scroll is often used on large datasets network errors such as timeouts can be encountered. When this occurs you will see a HTTP 500 error with the following message: + "Request failed due to an internal network error. Please restart the scroll operation." + If this happens, you will need to restart your scroll query: It is not possible to continue from a specific point when using scroll. +{% /admonition %}
@@ -3725,10 +3658,12 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.tags.tag_contact( - contact_id="63a07ddf05a32042dffac965", - tag_id="123", -) +response = client.companies.scroll() +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ``` @@ -3744,15 +3679,7 @@ client.tags.tag_contact(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom - -
-
- -
-
- -**tag_id:** `str` — The unique identifier for the tag which is given by Intercom +**scroll_param:** `typing.Optional[str]` —
@@ -3772,7 +3699,7 @@ client.tags.tag_contact(
-
client.tags.untag_contact(...) +
client.companies.attach_contact(...)
@@ -3784,7 +3711,7 @@ client.tags.tag_contact(
-You can remove tag from a specific contact. This will return a tag object for the tag that was removed from the contact. +You can attach a company to a single contact.
@@ -3804,9 +3731,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.tags.untag_contact( - contact_id="63a07ddf05a32042dffac965", - tag_id="7522907", +client.companies.attach_contact( + contact_id=1, + company_id="123", ) ``` @@ -3823,7 +3750,7 @@ client.tags.untag_contact(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**contact_id:** `int` — The unique identifier for the contact which is given by Intercom
@@ -3831,7 +3758,7 @@ client.tags.untag_contact(
-**tag_id:** `str` — The unique identifier for the tag which is given by Intercom +**company_id:** `str` — The unique identifier for the company which is given by Intercom
@@ -3851,7 +3778,7 @@ client.tags.untag_contact(
-
client.tags.tag_conversation(...) +
client.companies.detach_contact(...)
@@ -3863,7 +3790,7 @@ client.tags.untag_contact(
-You can tag a specific conversation. This will return a tag object for the tag that was added to the conversation. +You can detach a company from a single contact.
@@ -3883,10 +3810,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.tags.tag_conversation( - conversation_id="64619700005694", - tag_id="7522907", - admin_id="780", +client.companies.detach_contact( + contact_id="58a430d35458202d41b1e65b", + company_id="58a430d35458202d41b1e65b", ) ``` @@ -3903,15 +3829,7 @@ client.tags.tag_conversation(
-**conversation_id:** `str` — conversation_id - -
-
- -
-
- -**tag_id:** `str` — The unique identifier for the tag which is given by Intercom +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom
@@ -3919,7 +3837,7 @@ client.tags.tag_conversation(
-**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. +**company_id:** `str` — The unique identifier for the company which is given by Intercom
@@ -3939,7 +3857,8 @@ client.tags.tag_conversation(
-
client.tags.untag_conversation(...) +## Contacts +
client.contacts.list_attached_companies(...)
@@ -3951,7 +3870,7 @@ client.tags.tag_conversation(
-You can remove tag from a specific conversation. This will return a tag object for the tag that was removed from the conversation. +You can fetch a list of companies that are associated to a contact.
@@ -3971,11 +3890,14 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.tags.untag_conversation( - conversation_id="64619700005694", - tag_id="7522907", - admin_id="123", +response = client.contacts.list_attached_companies( + contact_id="63a07ddf05a32042dffac965", ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ``` @@ -3991,7 +3913,7 @@ client.tags.untag_conversation(
-**conversation_id:** `str` — conversation_id +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom
@@ -3999,7 +3921,7 @@ client.tags.untag_conversation(
-**tag_id:** `str` — id +**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page
@@ -4007,7 +3929,7 @@ client.tags.untag_conversation(
-**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. +**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15
@@ -4027,7 +3949,7 @@ client.tags.untag_conversation(
-
client.tags.list() +
client.contacts.list_attached_segments(...)
@@ -4039,7 +3961,7 @@ client.tags.untag_conversation(
-You can fetch a list of all tags for a given workspace. +You can fetch a list of segments that are associated to a contact.
@@ -4059,7 +3981,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.tags.list() +client.contacts.list_attached_segments( + contact_id="63a07ddf05a32042dffac965", +) ``` @@ -4075,6 +3999,14 @@ client.tags.list()
+**contact_id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -4087,7 +4019,7 @@ client.tags.list()
-
client.tags.create(...) +
client.contacts.list_attached_subscriptions(...)
@@ -4099,19 +4031,13 @@ client.tags.list()
-You can use this endpoint to perform the following operations: - - **1. Create a new tag:** You can create a new tag by passing in the tag name as specified in "Create or Update Tag Request Payload" described below. - - **2. Update an existing tag:** You can update an existing tag by passing the id of the tag as specified in "Create or Update Tag Request Payload" described below. - - **3. Tag Companies:** You can tag single company or a list of companies. You can tag a company by passing in the tag name and the company details as specified in "Tag Company Request Payload" described below. Also, if the tag doesn't exist then a new one will be created automatically. - - **4. Untag Companies:** You can untag a single company or a list of companies. You can untag a company by passing in the tag id and the company details as specified in "Untag Company Request Payload" described below. +You can fetch a list of subscription types that are attached to a contact. These can be subscriptions that a user has 'opted-in' to or has 'opted-out' from, depending on the subscription type. +This will return a list of Subscription Type objects that the contact is associated with. - **5. Tag Multiple Users:** You can tag a list of users. You can tag the users by passing in the tag name and the user details as specified in "Tag Users Request Payload" described below. +The data property will show a combined list of: -Each operation will return a tag object. + 1.Opt-out subscription types that the user has opted-out from. + 2.Opt-in subscription types that the user has opted-in to receiving.
@@ -4126,24 +4052,13 @@ Each operation will return a tag object.
```python -from intercom import ( - Intercom, - TagMultipleUsersRequest, - TagMultipleUsersRequestUsersItem, -) +from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.tags.create( - request=TagMultipleUsersRequest( - name="test", - users=[ - TagMultipleUsersRequestUsersItem( - id="123", - ) - ], - ), +client.contacts.list_attached_subscriptions( + contact_id="63a07ddf05a32042dffac965", ) ``` @@ -4160,7 +4075,7 @@ client.tags.create(
-**request:** `TagsCreateRequestBody` +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom
@@ -4180,7 +4095,7 @@ client.tags.create(
-
client.tags.find(...) +
client.contacts.attach_subscription(...)
@@ -4192,8 +4107,13 @@ client.tags.create(
-You can fetch the details of tags that are on the workspace by their id. -This will return a tag object. +You can add a specific subscription to a contact. In Intercom, we have two different subscription types based on user consent - opt-out and opt-in: + + 1.Attaching a contact to an opt-out subscription type will opt that user out from receiving messages related to that subscription type. + + 2.Attaching a contact to an opt-in subscription type will opt that user in to receiving messages related to that subscription type. + +This will return a subscription type model for the subscription type that was added to the contact.
@@ -4213,8 +4133,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.tags.find( - tag_id="123", +client.contacts.attach_subscription( + contact_id="63a07ddf05a32042dffac965", + subscription_id="invalid_id", + consent_type="opt_in", ) ``` @@ -4231,7 +4153,7 @@ client.tags.find(
-**tag_id:** `str` — The unique identifier of a given tag +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom
@@ -4239,19 +4161,35 @@ client.tags.find(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**subscription_id:** `str` — The unique identifier for the subscription which is given by Intercom
- -
+
+
+**consent_type:** `str` — The consent_type of a subscription, opt_out or opt_in. +
-
-
client.tags.delete(...) +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+ + + + + + +
+ +
client.contacts.detach_subscription(...)
@@ -4263,7 +4201,7 @@ client.tags.find(
-You can delete the details of tags that are on the workspace by passing in the id. +You can remove a specific subscription from a contact. This will return a subscription type model for the subscription type that was removed from the contact.
@@ -4283,8 +4221,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.tags.delete( - tag_id="123", +client.contacts.detach_subscription( + contact_id="63a07ddf05a32042dffac965", + subscription_id="37846", ) ``` @@ -4301,7 +4240,15 @@ client.tags.delete(
-**tag_id:** `str` — The unique identifier of a given tag +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ +**subscription_id:** `str` — The unique identifier for the subscription type which is given by Intercom
@@ -4321,7 +4268,7 @@ client.tags.delete(
-
client.tags.tag_ticket(...) +
client.contacts.list_attached_tags(...)
@@ -4333,7 +4280,7 @@ client.tags.delete(
-You can tag a specific ticket. This will return a tag object for the tag that was added to the ticket. +You can fetch a list of all tags that are attached to a specific contact.
@@ -4353,10 +4300,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.tags.tag_ticket( - ticket_id="64619700005694", - tag_id="7522907", - admin_id="780", +client.contacts.list_attached_tags( + contact_id="63a07ddf05a32042dffac965", ) ``` @@ -4373,23 +4318,7 @@ client.tags.tag_ticket(
-**ticket_id:** `str` — ticket_id - -
-
- -
-
- -**tag_id:** `str` — The unique identifier for the tag which is given by Intercom - -
-
- -
-
- -**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom
@@ -4409,7 +4338,7 @@ client.tags.tag_ticket(
-
client.tags.untag_ticket(...) +
client.contacts.find(...)
@@ -4421,7 +4350,7 @@ client.tags.tag_ticket(
-You can remove tag from a specific ticket. This will return a tag object for the tag that was removed from the ticket. +You can fetch the details of a single contact.
@@ -4441,10 +4370,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.tags.untag_ticket( - ticket_id="64619700005694", - tag_id="7522907", - admin_id="123", +client.contacts.find( + contact_id="63a07ddf05a32042dffac965", ) ``` @@ -4461,23 +4388,7 @@ client.tags.untag_ticket(
-**ticket_id:** `str` — ticket_id - -
-
- -
-
- -**tag_id:** `str` — The unique identifier for the tag which is given by Intercom - -
-
- -
-
- -**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. +**contact_id:** `str` — contact_id
@@ -4497,8 +4408,7 @@ client.tags.untag_ticket(
-## Conversations -
client.conversations.list(...) +
client.contacts.update(...)
@@ -4510,12 +4420,12 @@ client.tags.untag_ticket(
-You can fetch a list of all conversations. +You can update an existing contact (ie. user or lead). -You can optionally request the result page size and the cursor to start after to fetch the result. -{% admonition type="warning" name="Pagination" %} - You can use pagination to limit the number of results returned. The default is `20` results per page. - See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. +{% admonition type="info" %} + This endpoint handles both **contact updates** and **custom object associations**. + + See _`update a contact with an association to a custom object instance`_ in the request/response examples to see the custom object association format. {% /admonition %}
@@ -4536,12 +4446,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -response = client.conversations.list() -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page +client.contacts.update( + contact_id="63a07ddf05a32042dffac965", + custom_attributes={"order": ["21"]}, +) ```
@@ -4557,7 +4465,7 @@ for page in response.iter_pages():
-**per_page:** `typing.Optional[int]` — How many results per page +**contact_id:** `str` — id
@@ -4565,7 +4473,7 @@ for page in response.iter_pages():
-**starting_after:** `typing.Optional[str]` — String used to get the next page of conversations. +**role:** `typing.Optional[str]` — The role of the contact.
@@ -4573,82 +4481,63 @@ for page in response.iter_pages():
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**external_id:** `typing.Optional[str]` — A unique identifier for the contact which is given to Intercom
- -
+
+
+**email:** `typing.Optional[str]` — The contacts email +
-
-
client.conversations.create(...)
-#### 📝 Description - -
-
+**phone:** `typing.Optional[str]` — The contacts phone + +
+
-You can create a conversation that has been initiated by a contact (ie. user or lead). -The conversation can be an in-app message only. - -{% admonition type="info" name="Sending for visitors" %} -You can also send a message from a visitor by specifying their `user_id` or `id` value in the `from` field, along with a `type` field value of `contact`. -This visitor will be automatically converted to a contact with a lead role once the conversation is created. -{% /admonition %} - -This will return the Message model that has been created. -
-
+**name:** `typing.Optional[str]` — The contacts name +
-#### 🔌 Usage -
+**avatar:** `typing.Optional[str]` — An image URL containing the avatar of a contact + +
+
+
-```python -from intercom import Intercom -from intercom.conversations import CreateConversationRequestFrom - -client = Intercom( - token="YOUR_TOKEN", -) -client.conversations.create( - from_=CreateConversationRequestFrom( - type="user", - id="123_doesnt_exist", - ), - body="Hello there", -) - -``` -
-
+**signed_up_at:** `typing.Optional[int]` — The time specified for when a contact signed up + -#### ⚙️ Parameters -
+**last_seen_at:** `typing.Optional[int]` — The time when the contact was last seen (either where the Intercom Messenger was installed or when specified manually) + +
+
+
-**from_:** `CreateConversationRequestFrom` +**owner_id:** `typing.Optional[int]` — The id of an admin that has been assigned account ownership of the contact
@@ -4656,7 +4545,7 @@ client.conversations.create(
-**body:** `str` — The content of the message. HTML is not supported. +**unsubscribed_from_emails:** `typing.Optional[bool]` — Whether the contact is unsubscribed from emails
@@ -4664,7 +4553,7 @@ client.conversations.create(
-**created_at:** `typing.Optional[int]` — The time the conversation was created as a UTC Unix timestamp. If not provided, the current time will be used. This field is only recommneded for migrating past conversations from another source into Intercom. +**custom_attributes:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — The custom attributes which are set for the contact
@@ -4684,7 +4573,7 @@ client.conversations.create(
-
client.conversations.find(...) +
client.contacts.delete(...)
@@ -4696,16 +4585,7 @@ client.conversations.create(
- -You can fetch the details of a single conversation. - -This will return a single Conversation model with all its conversation parts. - -{% admonition type="warning" name="Hard limit of 500 parts" %} -The maximum number of conversation parts that can be returned via the API is 500. If you have more than that we will return the 500 most recent conversation parts. -{% /admonition %} - -For AI agent conversation metadata, please note that you need to have the agent enabled in your workspace, which is a [paid feature](https://www.intercom.com/help/en/articles/8205718-fin-resolutions#h_97f8c2e671). +You can delete a single contact.
@@ -4725,9 +4605,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.conversations.find( - conversation_id="123", - display_as="plaintext", +client.contacts.delete( + contact_id="contact_id", ) ``` @@ -4744,15 +4623,7 @@ client.conversations.find(
-**conversation_id:** `str` — The id of the conversation to target - -
-
- -
-
- -**display_as:** `typing.Optional[str]` — Set to plaintext to retrieve conversation messages in plain text. +**contact_id:** `str` — contact_id
@@ -4772,7 +4643,7 @@ client.conversations.find(
-
client.conversations.update(...) +
client.contacts.merge_lead_in_user(...)
@@ -4784,12 +4655,7 @@ client.conversations.find(
- -You can update an existing conversation. - -{% admonition type="info" name="Replying and other actions" %} -If you want to reply to a coveration or take an action such as assign, unassign, open, close or snooze, take a look at the reply and manage endpoints. -{% /admonition %} +You can merge a contact with a `role` of `lead` into a contact with a `role` of `user`.
@@ -4809,11 +4675,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.conversations.update( - conversation_id="123", - display_as="plaintext", - read=True, - custom_attributes={"issue_type": "Billing", "priority": "High"}, +client.contacts.merge_lead_in_user( + lead_id="6762f0d51bb69f9f2193bb7f", + contact_id="6762f0d51bb69f9f2193bb80", ) ``` @@ -4830,23 +4694,7 @@ client.conversations.update(
-**conversation_id:** `str` — The id of the conversation to target - -
-
- -
-
- -**display_as:** `typing.Optional[str]` — Set to plaintext to retrieve conversation messages in plain text. - -
-
- -
-
- -**read:** `typing.Optional[bool]` — Mark a conversation as read within Intercom. +**lead_id:** `typing.Optional[str]` — The unique identifier for the contact to merge away from. Must be a lead.
@@ -4854,7 +4702,7 @@ client.conversations.update(
-**custom_attributes:** `typing.Optional[CustomAttributes]` +**contact_id:** `typing.Optional[str]` — The unique identifier for the contact to merge into. Must be a user.
@@ -4874,7 +4722,7 @@ client.conversations.update(
-
client.conversations.search(...) +
client.contacts.search(...)
@@ -4886,105 +4734,105 @@ client.conversations.update(
-You can search for multiple conversations by the value of their attributes in order to fetch exactly which ones you want. +You can search for multiple contacts by the value of their attributes in order to fetch exactly who you want. -To search for conversations, you need to send a `POST` request to `https://api.intercom.io/conversations/search`. +To search for contacts, you need to send a `POST` request to `https://api.intercom.io/contacts/search`. + +This will accept a query object in the body which will define your filters in order to search for contacts. -This will accept a query object in the body which will define your filters in order to search for conversations. {% admonition type="warning" name="Optimizing search queries" %} Search queries can be complex, so optimizing them can help the performance of your search. Use the `AND` and `OR` operators to combine multiple filters to get the exact results you need and utilize - pagination to limit the number of results returned. The default is `20` results per page and maximum is `150`. + pagination to limit the number of results returned. The default is `50` results per page. See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#example-search-conversations-request) for more details on how to use the `starting_after` param. {% /admonition %} +### Contact Creation Delay + +If a contact has recently been created, there is a possibility that it will not yet be available when searching. This means that it may not appear in the response. This delay can take a few minutes. If you need to be instantly notified it is recommended to use webhooks and iterate to see if they match your search filters. ### Nesting & Limitations You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4). There are some limitations to the amount of multiple's there can be: -- There's a limit of max 2 nested filters -- There's a limit of max 15 filters for each AND or OR group +* There's a limit of max 2 nested filters +* There's a limit of max 15 filters for each AND or OR group + +### Searching for Timestamp Fields + +All timestamp fields (created_at, updated_at etc.) are indexed as Dates for Contact Search queries; Datetime queries are not currently supported. This means you can only query for timestamp fields by day - not hour, minute or second. +For example, if you search for all Contacts with a created_at value greater (>) than 1577869200 (the UNIX timestamp for January 1st, 2020 9:00 AM), that will be interpreted as 1577836800 (January 1st, 2020 12:00 AM). The search results will then include Contacts created from January 2nd, 2020 12:00 AM onwards. +If you'd like to get contacts created on January 1st, 2020 you should search with a created_at value equal (=) to 1577836800 (January 1st, 2020 12:00 AM). +This behaviour applies only to timestamps used in search queries. The search results will still contain the full UNIX timestamp and be sorted accordingly. ### Accepted Fields -Most keys listed as part of the The conversation model is searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). -The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. +Most key listed as part of the Contacts Model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). -| Field | Type | -| :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | -| id | String | -| created_at | Date (UNIX timestamp) | -| updated_at | Date (UNIX timestamp) | -| source.type | String
Accepted fields are `conversation`, `email`, `facebook`, `instagram`, `phone_call`, `phone_switch`, `push`, `sms`, `twitter` and `whatsapp`. | -| source.id | String | -| source.delivered_as | String | -| source.subject | String | -| source.body | String | -| source.author.id | String | -| source.author.type | String | -| source.author.name | String | -| source.author.email | String | -| source.url | String | -| contact_ids | String | -| teammate_ids | String | -| admin_assignee_id | String | -| team_assignee_id | String | -| channel_initiated | String | -| open | Boolean | -| read | Boolean | -| state | String | -| waiting_since | Date (UNIX timestamp) | -| snoozed_until | Date (UNIX timestamp) | -| tag_ids | String | -| priority | String | -| statistics.time_to_assignment | Integer | -| statistics.time_to_admin_reply | Integer | -| statistics.time_to_first_close | Integer | -| statistics.time_to_last_close | Integer | -| statistics.median_time_to_reply | Integer | -| statistics.first_contact_reply_at | Date (UNIX timestamp) | -| statistics.first_assignment_at | Date (UNIX timestamp) | -| statistics.first_admin_reply_at | Date (UNIX timestamp) | -| statistics.first_close_at | Date (UNIX timestamp) | -| statistics.last_assignment_at | Date (UNIX timestamp) | -| statistics.last_assignment_admin_reply_at | Date (UNIX timestamp) | -| statistics.last_contact_reply_at | Date (UNIX timestamp) | -| statistics.last_admin_reply_at | Date (UNIX timestamp) | -| statistics.last_close_at | Date (UNIX timestamp) | -| statistics.last_closed_by_id | String | -| statistics.count_reopens | Integer | -| statistics.count_assignments | Integer | -| statistics.count_conversation_parts | Integer | -| conversation_rating.requested_at | Date (UNIX timestamp) | -| conversation_rating.replied_at | Date (UNIX timestamp) | -| conversation_rating.score | Integer | -| conversation_rating.remark | String | -| conversation_rating.contact_id | String | -| conversation_rating.admin_d | String | -| ai_agent_participated | Boolean | -| ai_agent.resolution_state | String | -| ai_agent.last_answer_type | String | -| ai_agent.rating | Integer | -| ai_agent.rating_remark | String | -| ai_agent.source_type | String | -| ai_agent.source_title | String | +| Field | Type | +| ---------------------------------- | ------------------------------ | +| id | String | +| role | String
Accepts user or lead | +| name | String | +| avatar | String | +| owner_id | Integer | +| email | String | +| email_domain | String | +| phone | String | +| external_id | String | +| created_at | Date (UNIX Timestamp) | +| signed_up_at | Date (UNIX Timestamp) | +| updated_at | Date (UNIX Timestamp) | +| last_seen_at | Date (UNIX Timestamp) | +| last_contacted_at | Date (UNIX Timestamp) | +| last_replied_at | Date (UNIX Timestamp) | +| last_email_opened_at | Date (UNIX Timestamp) | +| last_email_clicked_at | Date (UNIX Timestamp) | +| language_override | String | +| browser | String | +| browser_language | String | +| os | String | +| location.country | String | +| location.region | String | +| location.city | String | +| unsubscribed_from_emails | Boolean | +| marked_email_as_spam | Boolean | +| has_hard_bounced | Boolean | +| ios_last_seen_at | Date (UNIX Timestamp) | +| ios_app_version | String | +| ios_device | String | +| ios_app_device | String | +| ios_os_version | String | +| ios_app_name | String | +| ios_sdk_version | String | +| android_last_seen_at | Date (UNIX Timestamp) | +| android_app_version | String | +| android_device | String | +| android_app_name | String | +| andoid_sdk_version | String | +| segment_id | String | +| tag_id | String | +| custom_attributes.{attribute_name} | String | ### Accepted Operators -The table below shows the operators you can use to define how you want to search for the value. The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates). +{% admonition type="warning" name="Searching based on `created_at`" %} + You cannot use the `<=` or `>=` operators to search by `created_at`. +{% /admonition %} -| Operator | Valid Types | Description | -| :------- | :----------------------------- | :----------------------------------------------------------- | -| = | All | Equals | -| != | All | Doesn't Equal | -| IN | All | In Shortcut for `OR` queries Values most be in Array | -| NIN | All | Not In Shortcut for `OR !` queries Values must be in Array | -| > | Integer Date (UNIX Timestamp) | Greater (or equal) than | -| < | Integer Date (UNIX Timestamp) | Lower (or equal) than | -| ~ | String | Contains | -| !~ | String | Doesn't Contain | -| ^ | String | Starts With | -| $ | String | Ends With | +The table below shows the operators you can use to define how you want to search for the value. The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates). + +| Operator | Valid Types | Description | +| :------- | :------------------------------- | :--------------------------------------------------------------- | +| = | All | Equals | +| != | All | Doesn't Equal | +| IN | All | In
Shortcut for `OR` queries
Values must be in Array | +| NIN | All | Not In
Shortcut for `OR !` queries
Values must be in Array | +| > | Integer
Date (UNIX Timestamp) | Greater than | +| < | Integer
Date (UNIX Timestamp) | Lower than | +| ~ | String | Contains | +| !~ | String | Doesn't Contain | +| ^ | String | Starts With | +| $ | String | Ends With |
@@ -5009,7 +4857,7 @@ from intercom import ( client = Intercom( token="YOUR_TOKEN", ) -response = client.conversations.search( +response = client.contacts.search( query=MultipleFilterSearchRequest( operator="AND", value=[ @@ -5072,7 +4920,7 @@ for page in response.iter_pages():
-
client.conversations.reply(...) +
client.contacts.list(...)
@@ -5084,7 +4932,11 @@ for page in response.iter_pages():
-You can reply to a conversation with a message from an admin or on behalf of a contact, or with a note for admins. +You can fetch a list of all contacts (ie. users or leads) in your workspace. +{% admonition type="warning" name="Pagination" %} + You can use pagination to limit the number of results returned. The default is `50` results per page. + See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. +{% /admonition %}
@@ -5099,18 +4951,17 @@ You can reply to a conversation with a message from an admin or on behalf of a c
```python -from intercom import ContactReplyIntercomUserIdRequest, Intercom +from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.conversations.reply( - conversation_id='123 or "last"', - request=ContactReplyIntercomUserIdRequest( - body="Thanks again :)", - intercom_user_id="667d60f18a68186f43bafdf4", - ), -) +response = client.contacts.list() +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -5126,7 +4977,7 @@ client.conversations.reply(
-**conversation_id:** `str` — The Intercom provisioned identifier for the conversation or the string "last" to reply to the last part of the conversation +**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page
@@ -5134,7 +4985,15 @@ client.conversations.reply(
-**request:** `ReplyConversationRequest` +**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15 + +
+
+ +
+
+ +**starting_after:** `typing.Optional[str]` — String used to get the next page of conversations.
@@ -5154,7 +5013,7 @@ client.conversations.reply(
-
client.conversations.manage(...) +
client.contacts.create(...)
@@ -5166,11 +5025,7 @@ client.conversations.reply(
-For managing conversations you can: -- Close a conversation -- Snooze a conversation to reopen on a future date -- Open a conversation which is `snoozed` or `closed` -- Assign a conversation to an admin and/or team. +You can create a new contact (ie. user or lead).
@@ -5185,16 +5040,14 @@ For managing conversations you can:
```python -from intercom import Intercom -from intercom.conversations import ConversationsManageRequestBody_Close +from intercom import CreateContactRequestWithEmail, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.conversations.manage( - conversation_id="123", - request=ConversationsManageRequestBody_Close( - admin_id="12345", +client.contacts.create( + request=CreateContactRequestWithEmail( + email="joebloggs@intercom.io", ), ) @@ -5212,15 +5065,7 @@ client.conversations.manage(
-**conversation_id:** `str` — The identifier for the conversation as given by Intercom. - -
-
- -
-
- -**request:** `ConversationsManageRequestBody` +**request:** `CreateContactRequest`
@@ -5240,7 +5085,7 @@ client.conversations.manage(
-
client.conversations.run_assignment_rules(...) +
client.contacts.show_contact_by_external_id(...)
@@ -5252,13 +5097,7 @@ client.conversations.manage(
-{% admonition type="danger" name="Deprecation of Run Assignment Rules" %} -Run assignment rules is now deprecated in version 2.12 and future versions and will be permanently removed on December 31, 2026. After this date, any requests made to this endpoint will fail. -{% /admonition %} -You can let a conversation be automatically assigned following assignment rules. -{% admonition type="warning" name="When using workflows" %} -It is not possible to use this endpoint with Workflows. -{% /admonition %} +You can fetch the details of a single contact by external ID. Note that this endpoint only supports users and not leads.
@@ -5278,8 +5117,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.conversations.run_assignment_rules( - conversation_id="123", +client.contacts.show_contact_by_external_id( + external_id="cdd29344-5e0c-4ef0-ac56-f9ba2979bc27", ) ``` @@ -5296,7 +5135,7 @@ client.conversations.run_assignment_rules(
-**conversation_id:** `str` — The identifier for the conversation as given by Intercom. +**external_id:** `str` — The external ID of the user that you want to retrieve
@@ -5316,7 +5155,7 @@ client.conversations.run_assignment_rules(
-
client.conversations.attach_contact_as_admin(...) +
client.contacts.archive(...)
@@ -5328,11 +5167,7 @@ client.conversations.run_assignment_rules(
-You can add participants who are contacts to a conversation, on behalf of either another contact or an admin. - -{% admonition type="warning" name="Contacts without an email" %} -If you add a contact via the email parameter and there is no user/lead found on that workspace with he given email, then we will create a new contact with `role` set to `lead`. -{% /admonition %} +You can archive a single contact.
@@ -5348,19 +5183,12 @@ If you add a contact via the email parameter and there is no user/lead found on ```python from intercom import Intercom -from intercom.conversations import ( - AttachContactToConversationRequestCustomerIntercomUserId, -) client = Intercom( token="YOUR_TOKEN", ) -client.conversations.attach_contact_as_admin( - conversation_id="123", - admin_id="12345", - customer=AttachContactToConversationRequestCustomerIntercomUserId( - intercom_user_id="667d61188a68186f43bafe0e", - ), +client.contacts.archive( + contact_id="63a07ddf05a32042dffac965", ) ``` @@ -5377,23 +5205,7 @@ client.conversations.attach_contact_as_admin(
-**conversation_id:** `str` — The identifier for the conversation as given by Intercom. - -
-
- -
-
- -**admin_id:** `typing.Optional[str]` — The `id` of the admin who is adding the new participant. - -
-
- -
-
- -**customer:** `typing.Optional[AttachContactToConversationRequestCustomer]` +**contact_id:** `str` — contact_id
@@ -5413,7 +5225,7 @@ client.conversations.attach_contact_as_admin(
-
client.conversations.detach_contact_as_admin(...) +
client.contacts.unarchive(...)
@@ -5425,11 +5237,7 @@ client.conversations.attach_contact_as_admin(
-You can add participants who are contacts to a conversation, on behalf of either another contact or an admin. - -{% admonition type="warning" name="Contacts without an email" %} -If you add a contact via the email parameter and there is no user/lead found on that workspace with he given email, then we will create a new contact with `role` set to `lead`. -{% /admonition %} +You can unarchive a single contact.
@@ -5449,10 +5257,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.conversations.detach_contact_as_admin( - conversation_id="123", - contact_id="123", - admin_id="5017690", +client.contacts.unarchive( + contact_id="63a07ddf05a32042dffac965", ) ``` @@ -5469,23 +5275,7 @@ client.conversations.detach_contact_as_admin(
-**conversation_id:** `str` — The identifier for the conversation as given by Intercom. - -
-
- -
-
- -**contact_id:** `str` — The identifier for the contact as given by Intercom. - -
-
- -
-
- -**admin_id:** `str` — The `id` of the admin who is performing the action. +**contact_id:** `str` — contact_id
@@ -5505,7 +5295,7 @@ client.conversations.detach_contact_as_admin(
-
client.conversations.redact_conversation_part(...) +
client.contacts.block_contact(...)
@@ -5517,11 +5307,7 @@ client.conversations.detach_contact_as_admin(
-You can redact a conversation part or the source message of a conversation (as seen in the source object). - -{% admonition type="info" name="Redacting parts and messages" %} -If you are redacting a conversation part, it must have a `body`. If you are redacting a source message, it must have been created by a contact. We will return a `conversation_part_not_redactable` error if these criteria are not met. -{% /admonition %} +Block a single contact.
**Note:** conversations of the contact will also be archived during the process.
More details in [FAQ How do I block Inbox spam?](https://www.intercom.com/help/en/articles/8838656-inbox-faqs)
@@ -5536,16 +5322,13 @@ If you are redacting a conversation part, it must have a `body`. If you are reda
```python -from intercom import Intercom, RedactConversationRequest_ConversationPart +from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.conversations.redact_conversation_part( - request=RedactConversationRequest_ConversationPart( - conversation_id="really_123_doesnt_exist", - conversation_part_id="really_123_doesnt_exist", - ), +client.contacts.block_contact( + contact_id="63a07ddf05a32042dffac965", ) ``` @@ -5562,7 +5345,7 @@ client.conversations.redact_conversation_part(
-**request:** `RedactConversationRequest` +**contact_id:** `str` — contact_id
@@ -5582,7 +5365,8 @@ client.conversations.redact_conversation_part(
-
client.conversations.convert_to_ticket(...) +## Notes +
client.notes.list(...)
@@ -5594,7 +5378,7 @@ client.conversations.redact_conversation_part(
-You can convert a conversation to a ticket. +You can fetch a list of notes that are associated to a contact.
@@ -5614,10 +5398,14 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.conversations.convert_to_ticket( - conversation_id="123", - ticket_type_id="80", +response = client.notes.list( + contact_id="contact_id", ) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ``` @@ -5633,7 +5421,7 @@ client.conversations.convert_to_ticket(
-**conversation_id:** `str` — The id of the conversation to target +**contact_id:** `str` — The unique identifier of a contact.
@@ -5641,7 +5429,7 @@ client.conversations.convert_to_ticket(
-**ticket_type_id:** `str` — The ID of the type of ticket you want to convert the conversation to +**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page
@@ -5649,7 +5437,7 @@ client.conversations.convert_to_ticket(
-**attributes:** `typing.Optional[TicketRequestCustomAttributes]` +**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15
@@ -5669,8 +5457,7 @@ client.conversations.convert_to_ticket(
-## Data Attributes -
client.data_attributes.list(...) +
client.notes.create(...)
@@ -5682,7 +5469,7 @@ client.conversations.convert_to_ticket(
-You can fetch a list of all data attributes belonging to a workspace for contacts, companies or conversations. +You can add a note to a single contact.
@@ -5702,7 +5489,11 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.data_attributes.list() +client.notes.create( + contact_id="123", + body="Hello", + admin_id="123", +) ``` @@ -5718,7 +5509,7 @@ client.data_attributes.list()
-**model:** `typing.Optional[DataAttributesListRequestModel]` — Specify the data attribute model to return. +**contact_id:** `str` — The unique identifier of a given contact.
@@ -5726,7 +5517,15 @@ client.data_attributes.list()
-**include_archived:** `typing.Optional[bool]` — Include archived attributes in the list. By default we return only non archived data attributes. +**body:** `str` — The text of the note. + +
+
+ +
+
+ +**admin_id:** `typing.Optional[str]` — The unique identifier of a given admin.
@@ -5746,7 +5545,7 @@ client.data_attributes.list()
-
client.data_attributes.create(...) +
client.notes.find(...)
@@ -5758,7 +5557,7 @@ client.data_attributes.list()
-You can create a data attributes for a `contact` or a `company`. +You can fetch the details of a single note.
@@ -5778,12 +5577,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.data_attributes.create( - name="My Data Attribute", - model="contact", - data_type="string", - description="Just a plain old ring", - options=["options"], +client.notes.find( + note_id=1, ) ``` @@ -5800,7 +5595,7 @@ client.data_attributes.create(
-**name:** `str` — The name of the data attribute. +**note_id:** `int` — The unique identifier of a given note
@@ -5808,31 +5603,71 @@ client.data_attributes.create(
-**model:** `CreateDataAttributeRequestModel` — The model that the data attribute belongs to. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
+ + + + +
+## Tags +
client.tags.tag_contact(...)
-**data_type:** `CreateDataAttributeRequestDataType` — The type of data stored for this attribute. - +#### 📝 Description + +
+
+ +
+
+ +You can tag a specific contact. This will return a tag object for the tag that was added to the contact.
+
+
+ +#### 🔌 Usage
-**description:** `typing.Optional[str]` — The readable description you see in the UI for the attribute. - +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.tags.tag_contact( + contact_id="63a07ddf05a32042dffac965", + tag_id="123", +) + +```
+
+
+ +#### ⚙️ Parameters
-**options:** `typing.Optional[typing.Sequence[str]]` — To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. +
+
+ +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom
@@ -5840,7 +5675,7 @@ client.data_attributes.create(
-**messenger_writable:** `typing.Optional[bool]` — Can this attribute be updated by the Messenger +**tag_id:** `str` — The unique identifier for the tag which is given by Intercom
@@ -5860,7 +5695,7 @@ client.data_attributes.create(
-
client.data_attributes.update(...) +
client.tags.untag_contact(...)
@@ -5872,12 +5707,7 @@ client.data_attributes.create(
- -You can update a data attribute. - -> 🚧 Updating the data type is not possible -> -> It is currently a dangerous action to execute changing a data attribute's type via the API. You will need to update the type via the UI instead. +You can remove tag from a specific contact. This will return a tag object for the tag that was removed from the contact.
@@ -5897,10 +5727,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.data_attributes.update( - data_attribute_id="1", - archived=True, - description="Trying to archieve", +client.tags.untag_contact( + contact_id="63a07ddf05a32042dffac965", + tag_id="7522907", ) ``` @@ -5917,31 +5746,7 @@ client.data_attributes.update(
-**data_attribute_id:** `str` — The data attribute id - -
-
- -
-
- -**archived:** `typing.Optional[bool]` — Whether the attribute is to be archived or not. - -
-
- -
-
- -**description:** `typing.Optional[str]` — The readable description you see in the UI for the attribute. - -
-
- -
-
- -**options:** `typing.Optional[typing.Sequence[UpdateDataAttributeRequestOptionsItem]]` — To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom
@@ -5949,7 +5754,7 @@ client.data_attributes.update(
-**messenger_writable:** `typing.Optional[bool]` — Can this attribute be updated by the Messenger +**tag_id:** `str` — The unique identifier for the tag which is given by Intercom
@@ -5969,8 +5774,7 @@ client.data_attributes.update(
-## Events -
client.events.list(...) +
client.tags.tag_conversation(...)
@@ -5982,20 +5786,7 @@ client.data_attributes.update(
- -> 🚧 -> -> Please note that you can only 'list' events that are less than 90 days old. Event counts and summaries will still include your events older than 90 days but you cannot 'list' these events individually if they are older than 90 days - -The events belonging to a customer can be listed by sending a GET request to `https://api.intercom.io/events` with a user or lead identifier along with a `type` parameter. The identifier parameter can be one of `user_id`, `email` or `intercom_user_id`. The `type` parameter value must be `user`. - -- `https://api.intercom.io/events?type=user&user_id={user_id}` -- `https://api.intercom.io/events?type=user&email={email}` -- `https://api.intercom.io/events?type=user&intercom_user_id={id}` (this call can be used to list leads) - -The `email` parameter value should be [url encoded](http://en.wikipedia.org/wiki/Percent-encoding) when sending. - -You can optionally define the result page size as well with the `per_page` parameter. +You can tag a specific conversation. This will return a tag object for the tag that was added to the conversation.
@@ -6015,8 +5806,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.events.list( - type="type", +client.tags.tag_conversation( + conversation_id="64619700005694", + tag_id="7522907", + admin_id="780", ) ``` @@ -6033,7 +5826,7 @@ client.events.list(
-**type:** `str` — The value must be user +**conversation_id:** `str` — conversation_id
@@ -6041,7 +5834,7 @@ client.events.list(
-**user_id:** `typing.Optional[str]` — user_id query parameter +**tag_id:** `str` — The unique identifier for the tag which is given by Intercom
@@ -6049,7 +5842,7 @@ client.events.list(
-**intercom_user_id:** `typing.Optional[str]` — intercom_user_id query parameter +**admin_id:** `str` — The unique identifier for the admin which is given by Intercom.
@@ -6057,47 +5850,37 @@ client.events.list(
-**email:** `typing.Optional[str]` — email query parameter +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
-
-
-**summary:** `typing.Optional[bool]` — summary flag -
+
+
client.tags.untag_conversation(...)
-**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15 - -
-
+#### 📝 Description
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. - -
-
+
+
+ +You can remove tag from a specific conversation. This will return a tag object for the tag that was removed from the conversation.
- - -
- -
client.events.create(...) -
-
-#### 📝 Description +#### 🔌 Usage
@@ -6105,53 +5888,25 @@ client.events.list(
+```python +from intercom import Intercom -You will need an Access Token that has write permissions to send Events. Once you have a key you can submit events via POST to the Events resource, which is located at https://api.intercom.io/events, or you can send events using one of the client libraries. When working with the HTTP API directly a client should send the event with a `Content-Type` of `application/json`. - -When using the JavaScript API, [adding the code to your app](http://docs.intercom.io/configuring-Intercom/tracking-user-events-in-your-app) makes the Events API available. Once added, you can submit an event using the `trackEvent` method. This will associate the event with the Lead or currently logged-in user or logged-out visitor/lead and send it to Intercom. The final parameter is a map that can be used to send optional metadata about the event. +client = Intercom( + token="YOUR_TOKEN", +) +client.tags.untag_conversation( + conversation_id="64619700005694", + tag_id="7522907", + admin_id="123", +) -With the Ruby client you pass a hash describing the event to `Intercom::Event.create`, or call the `track_user` method directly on the current user object (e.g. `user.track_event`). - -**NB: For the JSON object types, please note that we do not currently support nested JSON structure.** - -| Type | Description | Example | -| :-------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- | -| String | The value is a JSON String | `"source":"desktop"` | -| Number | The value is a JSON Number | `"load": 3.67` | -| Date | The key ends with the String `_date` and the value is a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time), assumed to be in the [UTC](http://en.wikipedia.org/wiki/Coordinated_Universal_Time) timezone. | `"contact_date": 1392036272` | -| Link | The value is a HTTP or HTTPS URI. | `"article": "https://example.org/ab1de.html"` | -| Rich Link | The value is a JSON object that contains `url` and `value` keys. | `"article": {"url": "https://example.org/ab1de.html", "value":"the dude abides"}` | -| Monetary Amount | The value is a JSON object that contains `amount` and `currency` keys. The `amount` key is a positive integer representing the amount in cents. The price in the example to the right denotes €349.99. | `"price": {"amount": 34999, "currency": "eur"}` | - -**Lead Events** - -When submitting events for Leads, you will need to specify the Lead's `id`. - -**Metadata behaviour** - -- We currently limit the number of tracked metadata keys to 10 per event. Once the quota is reached, we ignore any further keys we receive. The first 10 metadata keys are determined by the order in which they are sent in with the event. -- It is not possible to change the metadata keys once the event has been sent. A new event will need to be created with the new keys and you can archive the old one. -- There might be up to 24 hrs delay when you send a new metadata for an existing event. - -**Event de-duplication** - -The API may detect and ignore duplicate events. Each event is uniquely identified as a combination of the following data - the Workspace identifier, the Contact external identifier, the Data Event name and the Data Event created time. As a result, it is **strongly recommended** to send a second granularity Unix timestamp in the `created_at` field. - -Duplicated events are responded to using the normal `202 Accepted` code - an error is not thrown, however repeat requests will be counted against any rate limit that is in place. - -### HTTP API Responses - -- Successful responses to submitted events return `202 Accepted` with an empty body. -- Unauthorised access will be rejected with a `401 Unauthorized` or `403 Forbidden` response code. -- Events sent about users that cannot be found will return a `404 Not Found`. -- Event lists containing duplicate events will have those duplicates ignored. -- Server errors will return a `500` response code and may contain an error message in the body. +```
-#### 🔌 Usage +#### ⚙️ Parameters
@@ -6159,35 +5914,23 @@ Duplicated events are responded to using the normal `202 Accepted` code - an err
-```python -from intercom import CreateDataEventRequestWithId, Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.events.create( - request=CreateDataEventRequestWithId( - id="8a88a590-e1c3-41e2-a502-e0649dbf721c", - event_name="invited-friend", - created_at=1671028894, - ), -) - -``` -
-
+**conversation_id:** `str` — conversation_id +
-#### ⚙️ Parameters -
+**tag_id:** `str` — tag_id + +
+
+
-**request:** `CreateDataEventRequest` +**admin_id:** `str` — The unique identifier for the admin which is given by Intercom.
@@ -6207,7 +5950,7 @@ client.events.create(
-
client.events.summaries(...) +
client.tags.list()
@@ -6219,7 +5962,7 @@ client.events.create(
-Create event summaries for a user. Event summaries are used to track the number of times an event has occurred, the first time it occurred and the last time it occurred. +You can fetch a list of all tags for a given workspace.
@@ -6239,7 +5982,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.events.summaries() +client.tags.list() ``` @@ -6255,22 +5998,6 @@ client.events.summaries()
-**user_id:** `typing.Optional[str]` — Your identifier for the user. - -
-
- -
-
- -**event_summaries:** `typing.Optional[CreateDataEventSummariesRequestEventSummaries]` — A list of event summaries for the user. Each event summary should contain the event name, the time the event occurred, and the number of times the event occurred. The event name should be a past tense 'verb-noun' combination, to improve readability, for example `updated-plan`. - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -6283,8 +6010,7 @@ client.events.summaries()
-## Data Export -
client.data_export.create(...) +
client.tags.create(...)
@@ -6296,21 +6022,19 @@ client.events.summaries()
-To create your export job, you need to send a `POST` request to the export endpoint `https://api.intercom.io/export/content/data`. +You can use this endpoint to perform the following operations: -The only parameters you need to provide are the range of dates that you want exported. + **1. Create a new tag:** You can create a new tag by passing in the tag name as specified in "Create or Update Tag Request Payload" described below. ->🚧 Limit of one active job -> -> You can only have one active job per workspace. You will receive a HTTP status code of 429 with the message Exceeded rate limit of 1 pending message data export jobs if you attempt to create a second concurrent job. + **2. Update an existing tag:** You can update an existing tag by passing the id of the tag as specified in "Create or Update Tag Request Payload" described below. ->❗️ Updated_at not included -> -> It should be noted that the timeframe only includes messages sent during the time period and not messages that were only updated during this period. For example, if a message was updated yesterday but sent two days ago, you would need to set the created_at_after date before the message was sent to include that in your retrieval job. + **3. Tag Companies:** You can tag single company or a list of companies. You can tag a company by passing in the tag name and the company details as specified in "Tag Company Request Payload" described below. Also, if the tag doesn't exist then a new one will be created automatically. ->📘 Date ranges are inclusive -> -> Requesting data for 2018-06-01 until 2018-06-30 will get all data for those days including those specified - e.g. 2018-06-01 00:00:00 until 2018-06-30 23:59:99. + **4. Untag Companies:** You can untag a single company or a list of companies. You can untag a company by passing in the tag id and the company details as specified in "Untag Company Request Payload" described below. + + **5. Tag Multiple Users:** You can tag a list of users. You can tag the users by passing in the tag name and the user details as specified in "Tag Users Request Payload" described below. + +Each operation will return a tag object.
@@ -6325,14 +6049,24 @@ The only parameters you need to provide are the range of dates that you want exp
```python -from intercom import Intercom +from intercom import ( + Intercom, + TagMultipleUsersRequest, + TagMultipleUsersRequestUsersItem, +) client = Intercom( token="YOUR_TOKEN", ) -client.data_export.create( - created_at_after=1719474967, - created_at_before=1719492967, +client.tags.create( + request=TagMultipleUsersRequest( + name="test", + users=[ + TagMultipleUsersRequestUsersItem( + id="123", + ) + ], + ), ) ``` @@ -6349,15 +6083,7 @@ client.data_export.create(
-**created_at_after:** `int` — The start date that you request data for. It must be formatted as a unix timestamp. - -
-
- -
-
- -**created_at_before:** `int` — The end date that you request data for. It must be formatted as a unix timestamp. +**request:** `TagsCreateRequestBody`
@@ -6377,7 +6103,7 @@ client.data_export.create(
-
client.data_export.find(...) +
client.tags.find(...)
@@ -6389,11 +6115,8 @@ client.data_export.create(
-You can view the status of your job by sending a `GET` request to the URL -`https://api.intercom.io/export/content/data/{job_identifier}` - the `{job_identifier}` is the value returned in the response when you first created the export job. More on it can be seen in the Export Job Model. - -> 🚧 Jobs expire after two days -> All jobs that have completed processing (and are thus available to download from the provided URL) will have an expiry limit of two days from when the export ob completed. After this, the data will no longer be available. +You can fetch the details of tags that are on the workspace by their id. +This will return a tag object.
@@ -6413,8 +6136,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.data_export.find( - job_identifier="job_identifier", +client.tags.find( + tag_id="123", ) ``` @@ -6431,7 +6154,7 @@ client.data_export.find(
-**job_identifier:** `str` — job_identifier +**tag_id:** `str` — The unique identifier of a given tag
@@ -6451,7 +6174,7 @@ client.data_export.find(
-
client.data_export.cancel(...) +
client.tags.delete(...)
@@ -6463,7 +6186,7 @@ client.data_export.find(
-You can cancel your job +You can delete the details of tags that are on the workspace by passing in the id.
@@ -6483,8 +6206,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.data_export.cancel( - job_identifier="job_identifier", +client.tags.delete( + tag_id="123", ) ``` @@ -6501,7 +6224,7 @@ client.data_export.cancel(
-**job_identifier:** `str` — job_identifier +**tag_id:** `str` — The unique identifier of a given tag
@@ -6521,7 +6244,7 @@ client.data_export.cancel(
-
client.data_export.download(...) +
client.tags.tag_ticket(...)
@@ -6533,13 +6256,7 @@ client.data_export.cancel(
-When a job has a status of complete, and thus a filled download_url, you can download your data by hitting that provided URL, formatted like so: https://api.intercom.io/download/content/data/xyz1234. - -Your exported message data will be streamed continuously back down to you in a gzipped CSV format. - -> 📘 Octet header required -> -> You will have to specify the header Accept: `application/octet-stream` when hitting this endpoint. +You can tag a specific ticket. This will return a tag object for the tag that was added to the ticket.
@@ -6559,8 +6276,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.data_export.download( - job_identifier="job_identifier", +client.tags.tag_ticket( + ticket_id="64619700005694", + tag_id="7522907", + admin_id="780", ) ``` @@ -6577,7 +6296,23 @@ client.data_export.download(
-**job_identifier:** `str` — job_identifier +**ticket_id:** `str` — ticket_id + +
+
+ +
+
+ +**tag_id:** `str` — The unique identifier for the tag which is given by Intercom + +
+
+ +
+
+ +**admin_id:** `str` — The unique identifier for the admin which is given by Intercom.
@@ -6597,8 +6332,7 @@ client.data_export.download(
-## Messages -
client.messages.create(...) +
client.tags.untag_ticket(...)
@@ -6610,17 +6344,7 @@ client.data_export.download(
-You can create a message that has been initiated by an admin. The conversation can be either an in-app message or an email. - -> 🚧 Sending for visitors -> -> There can be a short delay between when a contact is created and when a contact becomes available to be messaged through the API. A 404 Not Found error will be returned in this case. - -This will return the Message model that has been created. - -> 🚧 Retrieving Associated Conversations -> -> As this is a message, there will be no conversation present until the contact responds. Once they do, you will have to search for a contact's conversations with the id of the message. +You can remove tag from a specific ticket. This will return a tag object for the tag that was removed from the ticket.
@@ -6635,29 +6359,15 @@ This will return the Message model that has been created.
```python -from intercom import ( - CreateMessageRequest_Email, - CreateMessageRequestFrom, - CreateMessageRequestTo, - Intercom, -) +from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.messages.create( - request=CreateMessageRequest_Email( - subject="Thanks for everything", - body="Hello there", - template="plain", - from_=CreateMessageRequestFrom( - id=394051, - ), - to=CreateMessageRequestTo( - type="user", - id="536e564f316c83104c000020", - ), - ), +client.tags.untag_ticket( + ticket_id="64619700005694", + tag_id="7522907", + admin_id="123", ) ``` @@ -6674,7 +6384,23 @@ client.messages.create(
-**request:** `CreateMessageRequest` +**ticket_id:** `str` — ticket_id + +
+
+ +
+
+ +**tag_id:** `str` — The unique identifier for the tag which is given by Intercom + +
+
+ +
+
+ +**admin_id:** `str` — The unique identifier for the admin which is given by Intercom.
@@ -6694,8 +6420,8 @@ client.messages.create(
-## Segments -
client.segments.list(...) +## Conversations +
client.conversations.list(...)
@@ -6707,7 +6433,13 @@ client.messages.create(
-You can fetch a list of all segments. +You can fetch a list of all conversations. + +You can optionally request the result page size and the cursor to start after to fetch the result. +{% admonition type="warning" name="Pagination" %} + You can use pagination to limit the number of results returned. The default is `20` results per page. + See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. +{% /admonition %}
@@ -6727,7 +6459,12 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.segments.list() +response = client.conversations.list() +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ``` @@ -6743,7 +6480,15 @@ client.segments.list()
-**include_count:** `typing.Optional[bool]` — It includes the count of contacts that belong to each segment. +**per_page:** `typing.Optional[int]` — How many results per page + +
+
+ +
+
+ +**starting_after:** `typing.Optional[str]` — String used to get the next page of conversations.
@@ -6763,7 +6508,7 @@ client.segments.list()
-
client.segments.find(...) +
client.conversations.create(...)
@@ -6775,7 +6520,15 @@ client.segments.list()
-You can fetch the details of a single segment. +You can create a conversation that has been initiated by a contact (ie. user or lead). +The conversation can be an in-app message only. + +{% admonition type="info" name="Sending for visitors" %} +You can also send a message from a visitor by specifying their `user_id` or `id` value in the `from` field, along with a `type` field value of `contact`. +This visitor will be automatically converted to a contact with a lead role once the conversation is created. +{% /admonition %} + +This will return the Message model that has been created.
@@ -6791,12 +6544,17 @@ You can fetch the details of a single segment. ```python from intercom import Intercom +from intercom.conversations import CreateConversationRequestFrom client = Intercom( token="YOUR_TOKEN", ) -client.segments.find( - segment_id="123", +client.conversations.create( + from_=CreateConversationRequestFrom( + type="user", + id="123_doesnt_exist", + ), + body="Hello there", ) ``` @@ -6813,7 +6571,7 @@ client.segments.find(
-**segment_id:** `str` — The unique identified of a given segment. +**from_:** `CreateConversationRequestFrom`
@@ -6821,64 +6579,19 @@ client.segments.find(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**body:** `str` — The content of the message. HTML is not supported.
- -
- - - - -
- -## Subscription Types -
client.subscription_types.list() -
-
- -#### 📝 Description - -
-
- -
-
- -You can list all subscription types. A list of subscription type objects will be returned. -
-
-
-
- -#### 🔌 Usage - -
-
-```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.subscription_types.list() - -``` -
-
+**created_at:** `typing.Optional[int]` — The time the conversation was created as a UTC Unix timestamp. If not provided, the current time will be used. This field is only recommneded for migrating past conversations from another source into Intercom. +
-#### ⚙️ Parameters - -
-
-
@@ -6894,8 +6607,7 @@ client.subscription_types.list()
-## PhoneCallRedirects -
client.phone_call_redirects.create(...) +
client.conversations.find(...)
@@ -6907,10 +6619,16 @@ client.subscription_types.list()
-You can use the API to deflect phone calls to the Intercom Messenger. -Calling this endpoint will send an SMS with a link to the Messenger to the phone number specified. -If custom attributes are specified, they will be added to the user or lead's custom data attributes. +You can fetch the details of a single conversation. + +This will return a single Conversation model with all its conversation parts. + +{% admonition type="warning" name="Hard limit of 500 parts" %} +The maximum number of conversation parts that can be returned via the API is 500. If you have more than that we will return the 500 most recent conversation parts. +{% /admonition %} + +For AI agent conversation metadata, please note that you need to have the agent enabled in your workspace, which is a [paid feature](https://www.intercom.com/help/en/articles/8205718-fin-resolutions#h_97f8c2e671).
@@ -6930,9 +6648,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.phone_call_redirects.create( - phone="+40241100100", - custom_attributes={"issue_type": "Billing", "priority": "High"}, +client.conversations.find( + conversation_id=1, + display_as="plaintext", ) ``` @@ -6949,7 +6667,7 @@ client.phone_call_redirects.create(
-**phone:** `str` — Phone number in E.164 format, that will receive the SMS to continue the conversation in the Messenger. +**conversation_id:** `int` — The id of the conversation to target
@@ -6957,7 +6675,15 @@ client.phone_call_redirects.create(
-**custom_attributes:** `typing.Optional[CustomAttributes]` +**display_as:** `typing.Optional[str]` — Set to plaintext to retrieve conversation messages in plain text. + +
+
+ +
+
+ +**include_translations:** `typing.Optional[bool]` — If set to true, conversation parts will be translated to the detected language of the conversation.
@@ -6977,8 +6703,7 @@ client.phone_call_redirects.create(
-## Teams -
client.teams.list() +
client.conversations.update(...)
@@ -6990,7 +6715,18 @@ client.phone_call_redirects.create(
-This will return a list of team objects for the App. + +You can update an existing conversation. + +{% admonition type="info" name="Replying and other actions" %} +If you want to reply to a coveration or take an action such as assign, unassign, open, close or snooze, take a look at the reply and manage endpoints. +{% /admonition %} + +{% admonition type="info" %} + This endpoint handles both **conversation updates** and **custom object associations**. + + See _`update a conversation with an association to a custom object instance`_ in the request/response examples to see the custom object association format. +{% /admonition %}
@@ -7010,7 +6746,13 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.teams.list() +client.conversations.update( + conversation_id=1, + display_as="plaintext", + read=True, + title="new conversation title", + custom_attributes={"issue_type": "Billing", "priority": "High"}, +) ``` @@ -7026,69 +6768,47 @@ client.teams.list()
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**conversation_id:** `int` — The id of the conversation to target
- -
+
+
+**display_as:** `typing.Optional[str]` — Set to plaintext to retrieve conversation messages in plain text. +
-
-
client.teams.find(...)
-#### 📝 Description - -
-
+**read:** `typing.Optional[bool]` — Mark a conversation as read within Intercom. + +
+
-You can fetch the details of a single team, containing an array of admins that belong to this team. -
-
+**title:** `typing.Optional[str]` — The title given to the conversation +
-#### 🔌 Usage - -
-
-
-```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.teams.find( - team_id="123", -) - -``` -
-
+**custom_attributes:** `typing.Optional[CustomAttributes]` +
-#### ⚙️ Parameters - -
-
-
-**team_id:** `str` — The unique identifier of a given team. +**company_id:** `typing.Optional[str]` — The ID of the company that the conversation is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company.
@@ -7108,8 +6828,7 @@ client.teams.find(
-## Ticket Types -
client.ticket_types.list() +
client.conversations.delete_conversation(...)
@@ -7121,7 +6840,7 @@ client.teams.find(
-You can get a list of all ticket types for a workspace. +You can delete a single conversation.
@@ -7141,7 +6860,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.ticket_types.list() +client.conversations.delete_conversation( + conversation_id=1, +) ``` @@ -7157,6 +6878,14 @@ client.ticket_types.list()
+**conversation_id:** `int` — id + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -7169,7 +6898,7 @@ client.ticket_types.list()
-
client.ticket_types.create(...) +
client.conversations.search(...)
@@ -7181,76 +6910,165 @@ client.ticket_types.list()
-You can create a new ticket type. -> 📘 Creating ticket types. -> -> Every ticket type will be created with two default attributes: _default_title_ and _default_description_. -> For the `icon` propery, use an emoji from [Twemoji Cheatsheet](https://twemoji-cheatsheet.vercel.app/) -
-
-
-
- -#### 🔌 Usage +You can search for multiple conversations by the value of their attributes in order to fetch exactly which ones you want. -
-
+To search for conversations, you need to send a `POST` request to `https://api.intercom.io/conversations/search`. -
-
+This will accept a query object in the body which will define your filters in order to search for conversations. +{% admonition type="warning" name="Optimizing search queries" %} + Search queries can be complex, so optimizing them can help the performance of your search. + Use the `AND` and `OR` operators to combine multiple filters to get the exact results you need and utilize + pagination to limit the number of results returned. The default is `20` results per page and maximum is `150`. + See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#example-search-conversations-request) for more details on how to use the `starting_after` param. +{% /admonition %} -```python -from intercom import Intercom +### Nesting & Limitations -client = Intercom( - token="YOUR_TOKEN", -) -client.ticket_types.create( - name="Customer Issue", - description="Customer Report Template", - category="Customer", - icon="🎟️", -) +You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4). +There are some limitations to the amount of multiple's there can be: +- There's a limit of max 2 nested filters +- There's a limit of max 15 filters for each AND or OR group -``` -
-
-
-
+### Accepted Fields -#### ⚙️ Parameters +Most keys listed in the conversation model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). +The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. -
-
+| Field | Type | +| :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | +| id | String | +| created_at | Date (UNIX timestamp) | +| updated_at | Date (UNIX timestamp) | +| source.type | String
Accepted fields are `conversation`, `email`, `facebook`, `instagram`, `phone_call`, `phone_switch`, `push`, `sms`, `twitter` and `whatsapp`. | +| source.id | String | +| source.delivered_as | String | +| source.subject | String | +| source.body | String | +| source.author.id | String | +| source.author.type | String | +| source.author.name | String | +| source.author.email | String | +| source.url | String | +| contact_ids | String | +| teammate_ids | String | +| admin_assignee_id | String | +| team_assignee_id | String | +| channel_initiated | String | +| open | Boolean | +| read | Boolean | +| state | String | +| waiting_since | Date (UNIX timestamp) | +| snoozed_until | Date (UNIX timestamp) | +| tag_ids | String | +| priority | String | +| statistics.time_to_assignment | Integer | +| statistics.time_to_admin_reply | Integer | +| statistics.time_to_first_close | Integer | +| statistics.time_to_last_close | Integer | +| statistics.median_time_to_reply | Integer | +| statistics.first_contact_reply_at | Date (UNIX timestamp) | +| statistics.first_assignment_at | Date (UNIX timestamp) | +| statistics.first_admin_reply_at | Date (UNIX timestamp) | +| statistics.first_close_at | Date (UNIX timestamp) | +| statistics.last_assignment_at | Date (UNIX timestamp) | +| statistics.last_assignment_admin_reply_at | Date (UNIX timestamp) | +| statistics.last_contact_reply_at | Date (UNIX timestamp) | +| statistics.last_admin_reply_at | Date (UNIX timestamp) | +| statistics.last_close_at | Date (UNIX timestamp) | +| statistics.last_closed_by_id | String | +| statistics.count_reopens | Integer | +| statistics.count_assignments | Integer | +| statistics.count_conversation_parts | Integer | +| conversation_rating.requested_at | Date (UNIX timestamp) | +| conversation_rating.replied_at | Date (UNIX timestamp) | +| conversation_rating.score | Integer | +| conversation_rating.remark | String | +| conversation_rating.contact_id | String | +| conversation_rating.admin_d | String | +| ai_agent_participated | Boolean | +| ai_agent.resolution_state | String | +| ai_agent.last_answer_type | String | +| ai_agent.rating | Integer | +| ai_agent.rating_remark | String | +| ai_agent.source_type | String | +| ai_agent.source_title | String | -
-
+### Accepted Operators -**name:** `str` — The name of the ticket type. - +The table below shows the operators you can use to define how you want to search for the value. The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates). + +| Operator | Valid Types | Description | +| :------- | :----------------------------- | :----------------------------------------------------------- | +| = | All | Equals | +| != | All | Doesn't Equal | +| IN | All | In Shortcut for `OR` queries Values most be in Array | +| NIN | All | Not In Shortcut for `OR !` queries Values must be in Array | +| > | Integer Date (UNIX Timestamp) | Greater (or equal) than | +| < | Integer Date (UNIX Timestamp) | Lower (or equal) than | +| ~ | String | Contains | +| !~ | String | Doesn't Contain | +| ^ | String | Starts With | +| $ | String | Ends With | +
+
+#### 🔌 Usage +
-**description:** `typing.Optional[str]` — The description of the ticket type. - -
-
-
-**category:** `typing.Optional[CreateTicketTypeRequestCategory]` — Category of the Ticket Type. - +```python +from intercom import ( + Intercom, + MultipleFilterSearchRequest, + SingleFilterSearchRequest, + StartingAfterPaging, +) + +client = Intercom( + token="YOUR_TOKEN", +) +response = client.conversations.search( + query=MultipleFilterSearchRequest( + operator="AND", + value=[ + SingleFilterSearchRequest( + field="created_at", + operator=">", + value="1306054154", + ) + ], + ), + pagination=StartingAfterPaging( + per_page=5, + ), +) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page + +```
+ + + +#### ⚙️ Parameters
-**icon:** `typing.Optional[str]` — The icon of the ticket type. +
+
+ +**query:** `SearchRequestQuery`
@@ -7258,7 +7076,7 @@ client.ticket_types.create(
-**is_internal:** `typing.Optional[bool]` — Whether the tickets associated with this ticket type are intended for internal use only or will be shared with customers. This is currently a limited attribute. +**pagination:** `typing.Optional[StartingAfterPaging]`
@@ -7278,7 +7096,7 @@ client.ticket_types.create(
-
client.ticket_types.get(...) +
client.conversations.reply(...)
@@ -7290,7 +7108,7 @@ client.ticket_types.create(
-You can fetch the details of a single ticket type. +You can reply to a conversation with a message from an admin or on behalf of a contact, or with a note for admins.
@@ -7305,13 +7123,17 @@ You can fetch the details of a single ticket type.
```python -from intercom import Intercom +from intercom import ContactReplyIntercomUserIdRequest, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.ticket_types.get( - ticket_type_id="ticket_type_id", +client.conversations.reply( + conversation_id='123 or "last"', + request=ContactReplyIntercomUserIdRequest( + body="Thanks again :)", + intercom_user_id="6762f1571bb69f9f2193bbbb", + ), ) ``` @@ -7328,7 +7150,15 @@ client.ticket_types.get(
-**ticket_type_id:** `str` — The unique identifier for the ticket type which is given by Intercom. +**conversation_id:** `str` — The Intercom provisioned identifier for the conversation or the string "last" to reply to the last part of the conversation + +
+
+ +
+
+ +**request:** `ReplyConversationRequest`
@@ -7348,7 +7178,7 @@ client.ticket_types.get(
-
client.ticket_types.update(...) +
client.conversations.manage(...)
@@ -7360,12 +7190,11 @@ client.ticket_types.get(
- -You can update a ticket type. - -> 📘 Updating a ticket type. -> -> For the `icon` propery, use an emoji from [Twemoji Cheatsheet](https://twemoji-cheatsheet.vercel.app/) +For managing conversations you can: +- Close a conversation +- Snooze a conversation to reopen on a future date +- Open a conversation which is `snoozed` or `closed` +- Assign a conversation to an admin and/or team.
@@ -7381,13 +7210,16 @@ You can update a ticket type. ```python from intercom import Intercom +from intercom.conversations import ConversationsManageRequestBody_Close client = Intercom( token="YOUR_TOKEN", ) -client.ticket_types.update( - ticket_type_id="ticket_type_id", - name="Bug Report 2", +client.conversations.manage( + conversation_id="123", + request=ConversationsManageRequestBody_Close( + admin_id="12345", + ), ) ``` @@ -7404,47 +7236,7 @@ client.ticket_types.update(
-**ticket_type_id:** `str` — The unique identifier for the ticket type which is given by Intercom. - -
-
- -
-
- -**name:** `typing.Optional[str]` — The name of the ticket type. - -
-
- -
-
- -**description:** `typing.Optional[str]` — The description of the ticket type. - -
-
- -
-
- -**category:** `typing.Optional[UpdateTicketTypeRequestBodyCategory]` — Category of the Ticket Type. - -
-
- -
-
- -**icon:** `typing.Optional[str]` — The icon of the ticket type. - -
-
- -
-
- -**archived:** `typing.Optional[bool]` — The archived status of the ticket type. +**conversation_id:** `str` — The identifier for the conversation as given by Intercom.
@@ -7452,7 +7244,7 @@ client.ticket_types.update(
-**is_internal:** `typing.Optional[bool]` — Whether the tickets associated with this ticket type are intended for internal use only or will be shared with customers. This is currently a limited attribute. +**request:** `ConversationsManageRequestBody`
@@ -7472,8 +7264,7 @@ client.ticket_types.update(
-## Tickets -
client.tickets.reply(...) +
client.conversations.attach_contact_as_admin(...)
@@ -7485,7 +7276,11 @@ client.ticket_types.update(
-You can reply to a ticket with a message from an admin or on behalf of a contact, or with a note for admins. +You can add participants who are contacts to a conversation, on behalf of either another contact or an admin. + +{% admonition type="warning" name="Contacts without an email" %} +If you add a contact via the email parameter and there is no user/lead found on that workspace with he given email, then we will create a new contact with `role` set to `lead`. +{% /admonition %}
@@ -7500,16 +7295,19 @@ You can reply to a ticket with a message from an admin or on behalf of a contact
```python -from intercom import ContactReplyTicketIntercomUserIdRequest, Intercom +from intercom import Intercom +from intercom.conversations import ( + AttachContactToConversationRequestCustomerIntercomUserId, +) client = Intercom( token="YOUR_TOKEN", ) -client.tickets.reply( - ticket_id="123", - request=ContactReplyTicketIntercomUserIdRequest( - body="Thanks again :)", - intercom_user_id="667d619d8a68186f43bafe82", +client.conversations.attach_contact_as_admin( + conversation_id="123", + admin_id="12345", + customer=AttachContactToConversationRequestCustomerIntercomUserId( + intercom_user_id="6762f19e1bb69f9f2193bbd5", ), ) @@ -7527,7 +7325,7 @@ client.tickets.reply(
-**ticket_id:** `str` +**conversation_id:** `str` — The identifier for the conversation as given by Intercom.
@@ -7535,7 +7333,7 @@ client.tickets.reply(
-**request:** `TicketsReplyRequestBody` +**admin_id:** `typing.Optional[str]` — The `id` of the admin who is adding the new participant.
@@ -7543,19 +7341,27 @@ client.tickets.reply(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**customer:** `typing.Optional[AttachContactToConversationRequestCustomer]`
-
-
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+ +
-
client.tickets.create(...) +
client.conversations.detach_contact_as_admin(...)
@@ -7567,7 +7373,11 @@ client.tickets.reply(
-You can create a new ticket. +You can add participants who are contacts to a conversation, on behalf of either another contact or an admin. + +{% admonition type="warning" name="Contacts without an email" %} +If you add a contact via the email parameter and there is no user/lead found on that workspace with he given email, then we will create a new contact with `role` set to `lead`. +{% /admonition %}
@@ -7582,22 +7392,15 @@ You can create a new ticket.
```python -from intercom import CreateTicketRequestContactsItemId, Intercom +from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.tickets.create( - ticket_type_id="1234", - contacts=[ - CreateTicketRequestContactsItemId( - id="667d61b78a68186f43bafe8d", - ) - ], - ticket_attributes={ - "_default_title_": "example", - "_default_description_": "there is a problem", - }, +client.conversations.detach_contact_as_admin( + conversation_id="123", + contact_id="123", + admin_id="5017690", ) ``` @@ -7614,23 +7417,7 @@ client.tickets.create(
-**ticket_type_id:** `str` — The ID of the type of ticket you want to create - -
-
- -
-
- -**contacts:** `typing.Sequence[CreateTicketRequestContactsItem]` — The list of contacts (users or leads) affected by this ticket. Currently only one is allowed - -
-
- -
-
- -**company_id:** `typing.Optional[str]` — The ID of the company that the ticket is associated with. The ID that you set upon company creation. +**conversation_id:** `str` — The identifier for the conversation as given by Intercom.
@@ -7638,7 +7425,7 @@ client.tickets.create(
-**created_at:** `typing.Optional[int]` — The time the ticket was created. If not provided, the current time will be used. +**contact_id:** `str` — The identifier for the contact as given by Intercom.
@@ -7646,7 +7433,7 @@ client.tickets.create(
-**ticket_attributes:** `typing.Optional[TicketRequestCustomAttributes]` +**admin_id:** `str` — The `id` of the admin who is performing the action.
@@ -7666,7 +7453,7 @@ client.tickets.create(
-
client.tickets.get(...) +
client.conversations.redact_conversation_part(...)
@@ -7678,7 +7465,11 @@ client.tickets.create(
-You can fetch the details of a single ticket. +You can redact a conversation part or the source message of a conversation (as seen in the source object). + +{% admonition type="info" name="Redacting parts and messages" %} +If you are redacting a conversation part, it must have a `body`. If you are redacting a source message, it must have been created by a contact. We will return a `conversation_part_not_redactable` error if these criteria are not met. +{% /admonition %}
@@ -7693,13 +7484,16 @@ You can fetch the details of a single ticket.
```python -from intercom import Intercom +from intercom import Intercom, RedactConversationRequest_ConversationPart client = Intercom( token="YOUR_TOKEN", ) -client.tickets.get( - ticket_id="ticket_id", +client.conversations.redact_conversation_part( + request=RedactConversationRequest_ConversationPart( + conversation_id="really_123_doesnt_exist", + conversation_part_id="really_123_doesnt_exist", + ), ) ``` @@ -7716,7 +7510,7 @@ client.tickets.get(
-**ticket_id:** `str` — The unique identifier for the ticket which is given by Intercom. +**request:** `RedactConversationRequest`
@@ -7736,7 +7530,7 @@ client.tickets.get(
-
client.tickets.update(...) +
client.conversations.convert_to_ticket(...)
@@ -7748,7 +7542,7 @@ client.tickets.get(
-You can update a ticket. +You can convert a conversation to a ticket.
@@ -7764,22 +7558,13 @@ You can update a ticket. ```python from intercom import Intercom -from intercom.tickets import UpdateTicketRequestAssignment client = Intercom( token="YOUR_TOKEN", ) -client.tickets.update( - ticket_id="ticket_id", - ticket_attributes={ - "_default_title_": "example", - "_default_description_": "there is a problem", - }, - state="in_progress", - assignment=UpdateTicketRequestAssignment( - admin_id="991267899", - assignee_id="456", - ), +client.conversations.convert_to_ticket( + conversation_id=1, + ticket_type_id="54", ) ``` @@ -7796,7 +7581,7 @@ client.tickets.update(
-**ticket_id:** `str` — The unique identifier for the ticket which is given by Intercom +**conversation_id:** `int` — The id of the conversation to target
@@ -7804,7 +7589,7 @@ client.tickets.update(
-**ticket_attributes:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — The attributes set on the ticket. +**ticket_type_id:** `str` — The ID of the type of ticket you want to convert the conversation to
@@ -7812,7 +7597,7 @@ client.tickets.update(
-**state:** `typing.Optional[UpdateTicketRequestState]` — The state of the ticket. +**attributes:** `typing.Optional[TicketRequestCustomAttributes]`
@@ -7820,31 +7605,55 @@ client.tickets.update(
-**open:** `typing.Optional[bool]` — Specify if a ticket is open. Set to false to close a ticket. Closing a ticket will also unsnooze it. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
-
-
-**is_shared:** `typing.Optional[bool]` — Specify whether the ticket is visible to users. -
+
+
client.conversations.run_assignment_rules(...)
-**snoozed_until:** `typing.Optional[int]` — The time you want the ticket to reopen. - +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.conversations.run_assignment_rules( + conversation_id="conversation_id", +) + +```
+
+
+ +#### ⚙️ Parameters
-**assignment:** `typing.Optional[UpdateTicketRequestAssignment]` +
+
+ +**conversation_id:** `str`
@@ -7864,7 +7673,8 @@ client.tickets.update(
-
client.tickets.search(...) +## Custom Channel Events +
client.custom_channel_events.notify_new_conversation(...)
@@ -7876,67 +7686,8 @@ client.tickets.update(
-You can search for multiple tickets by the value of their attributes in order to fetch exactly which ones you want. - -To search for tickets, you send a `POST` request to `https://api.intercom.io/tickets/search`. - -This will accept a query object in the body which will define your filters. -{% admonition type="warning" name="Optimizing search queries" %} - Search queries can be complex, so optimizing them can help the performance of your search. - Use the `AND` and `OR` operators to combine multiple filters to get the exact results you need and utilize - pagination to limit the number of results returned. The default is `20` results per page. - See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#example-search-conversations-request) for more details on how to use the `starting_after` param. -{% /admonition %} - -### Nesting & Limitations - -You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4). -There are some limitations to the amount of multiples there can be: -- There's a limit of max 2 nested filters -- There's a limit of max 15 filters for each AND or OR group - -### Accepted Fields - -Most keys listed as part of the Ticket model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foobar"`). - -| Field | Type | -| :---------------------------------------- | :--------------------------------------------------------------------------------------- | -| id | String | -| created_at | Date (UNIX timestamp) | -| updated_at | Date (UNIX timestamp) | -| _default_title_ | String | -| _default_description_ | String | -| category | String | -| ticket_type_id | String | -| contact_ids | String | -| teammate_ids | String | -| admin_assignee_id | String | -| team_assignee_id | String | -| open | Boolean | -| state | String | -| snoozed_until | Date (UNIX timestamp) | -| ticket_attribute.{id} | String or Boolean or Date (UNIX timestamp) or Float or Integer | - -### Accepted Operators - -{% admonition type="info" name="Searching based on `created_at`" %} - You may use the `<=` or `>=` operators to search by `created_at`. -{% /admonition %} - -The table below shows the operators you can use to define how you want to search for the value. The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates). - -| Operator | Valid Types | Description | -| :------- | :----------------------------- | :----------------------------------------------------------- | -| = | All | Equals | -| != | All | Doesn't Equal | -| IN | All | In Shortcut for `OR` queries Values most be in Array | -| NIN | All | Not In Shortcut for `OR !` queries Values must be in Array | -| > | Integer Date (UNIX Timestamp) | Greater (or equal) than | -| < | Integer Date (UNIX Timestamp) | Lower (or equal) than | -| ~ | String | Contains | -| !~ | String | Doesn't Contain | -| ^ | String | Starts With | -| $ | String | Ends With | +Notifies Intercom that a new conversation was created in your custom channel/platform. This triggers conversation creation and workflow automations within Intercom for your custom channel integration. +> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support.
@@ -7951,36 +7702,19 @@ The table below shows the operators you can use to define how you want to search
```python -from intercom import ( - Intercom, - MultipleFilterSearchRequest, - SingleFilterSearchRequest, - StartingAfterPaging, -) +from intercom import CustomChannelContact, Intercom client = Intercom( token="YOUR_TOKEN", ) -response = client.tickets.search( - query=MultipleFilterSearchRequest( - operator="AND", - value=[ - SingleFilterSearchRequest( - field="created_at", - operator=">", - value="1306054154", - ) - ], - ), - pagination=StartingAfterPaging( - per_page=5, +client.custom_channel_events.notify_new_conversation( + event_id="event_id", + external_conversation_id="external_conversation_id", + contact=CustomChannelContact( + type="user", + external_id="external_id", ), ) -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page ```
@@ -7996,7 +7730,7 @@ for page in response.iter_pages():
-**query:** `SearchRequestQuery` +**event_id:** `str` — Unique identifier for the event.
@@ -8004,7 +7738,15 @@ for page in response.iter_pages():
-**pagination:** `typing.Optional[StartingAfterPaging]` +**external_conversation_id:** `str` — Identifier for the conversation in your application. + +
+
+ +
+
+ +**contact:** `CustomChannelContact`
@@ -8024,8 +7766,7 @@ for page in response.iter_pages():
-## Visitors -
client.visitors.find(...) +
client.custom_channel_events.notify_new_message(...)
@@ -8037,7 +7778,8 @@ for page in response.iter_pages():
-You can fetch the details of a single visitor. +Notifies Intercom that a new message was sent in a conversation on your custom channel/platform. This allows Intercom to process the message and trigger any relevant workflow automations. +> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support.
@@ -8052,13 +7794,19 @@ You can fetch the details of a single visitor.
```python -from intercom import Intercom +from intercom import CustomChannelContact, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.visitors.find( - user_id="user_id", +client.custom_channel_events.notify_new_message( + body="body", + event_id="event_id", + external_conversation_id="external_conversation_id", + contact=CustomChannelContact( + type="user", + external_id="external_id", + ), ) ``` @@ -8075,7 +7823,7 @@ client.visitors.find(
-**user_id:** `str` — The user_id of the Visitor you want to retrieve. +**body:** `str` — The message content sent by the user.
@@ -8083,35 +7831,56 @@ client.visitors.find(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**event_id:** `str` — Unique identifier for the event.
-
-
+
+
+**external_conversation_id:** `str` — Identifier for the conversation in your application. +
-
-
client.visitors.update(...)
-#### 📝 Description - -
-
+**contact:** `CustomChannelContact` + +
+
-Sending a PUT request to `/visitors` will result in an update of an existing Visitor. - -**Option 1.** You can update a visitor by passing in the `user_id` of the visitor in the Request body. - -**Option 2.** You can update a visitor by passing in the `id` of the visitor in the Request body. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + + + +
+ +
client.custom_channel_events.notify_quick_reply_selected(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Notifies Intercom that a user selected a quick reply option in your custom channel/platform. This allows Intercom to process the response and trigger any relevant workflow automations. +> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support.
@@ -8126,16 +7895,21 @@ Sending a PUT request to `/visitors` will result in an update of an existing Vis
```python -from intercom import Intercom, UpdateVisitorRequestWithUserId +from intercom import CustomChannelContact, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.visitors.update( - request=UpdateVisitorRequestWithUserId( - user_id="fail", - name="Christian Fail", +client.custom_channel_events.notify_quick_reply_selected( + event_id="evt_67890", + external_conversation_id="conv_13579", + contact=CustomChannelContact( + type="user", + external_id="user_003", + name="Alice Example", + email="alice@example.com", ), + quick_reply_option_id="1234", ) ``` @@ -8152,7 +7926,31 @@ client.visitors.update(
-**request:** `UpdateVisitorRequest` +**quick_reply_option_id:** `str` — Id of the selected quick reply option. + +
+
+ +
+
+ +**event_id:** `str` — Unique identifier for the event. + +
+
+ +
+
+ +**external_conversation_id:** `str` — Identifier for the conversation in your application. + +
+
+ +
+
+ +**contact:** `CustomChannelContact`
@@ -8172,7 +7970,7 @@ client.visitors.update(
-
client.visitors.merge_to_contact(...) +
client.custom_channel_events.notify_attribute_collected(...)
@@ -8184,11 +7982,8 @@ client.visitors.update(
-You can merge a Visitor to a Contact of role type `lead` or `user`. - -> 📘 What happens upon a visitor being converted? -> -> If the User exists, then the Visitor will be merged into it, the Visitor deleted and the User returned. If the User does not exist, the Visitor will be converted to a User, with the User identifiers replacing it's Visitor identifiers. +Notifies Intercom that a user provided a response to an attribute collector in your custom channel/platform. This allows Intercom to process the attribute and trigger any relevant workflow automations. +> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support.
@@ -8203,20 +7998,21 @@ You can merge a Visitor to a Contact of role type `lead` or `user`.
```python -from intercom import Intercom -from intercom.visitors import UserWithId, VisitorWithUserId +from intercom import CustomChannelAttribute, CustomChannelContact, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.visitors.merge_to_contact( - type="user", - user=UserWithId( - id="8a88a590-e1c3-41e2-a502-e0649dbf721c", - email="foo@bar.com", +client.custom_channel_events.notify_attribute_collected( + attribute=CustomChannelAttribute( + id="id", + value="value", ), - visitor=VisitorWithUserId( - user_id="3ecf64d0-9ed1-4e9f-88e1-da7d6e6782f3", + event_id="event_id", + external_conversation_id="external_conversation_id", + contact=CustomChannelContact( + type="user", + external_id="external_id", ), ) @@ -8234,7 +8030,7 @@ client.visitors.merge_to_contact(
-**type:** `str` — Represents the role of the Contact model. Accepts `lead` or `user`. +**attribute:** `CustomChannelAttribute`
@@ -8242,7 +8038,7 @@ client.visitors.merge_to_contact(
-**user:** `ConvertVisitorRequestUser` — The unique identifiers retained after converting or merging. +**event_id:** `str` — Unique identifier for the event.
@@ -8250,7 +8046,15 @@ client.visitors.merge_to_contact(
-**visitor:** `ConvertVisitorRequestVisitor` — The unique identifiers to convert a single Visitor. +**external_conversation_id:** `str` — Identifier for the conversation in your application. + +
+
+ +
+
+ +**contact:** `CustomChannelContact`
@@ -8270,8 +8074,8 @@ client.visitors.merge_to_contact(
-## HelpCenters Collections -
client.help_centers.collections.list(...) +## Custom Object Instances +
client.custom_object_instances.get_custom_object_instances_by_external_id(...)
@@ -8283,9 +8087,7 @@ client.visitors.merge_to_contact(
-You can fetch a list of all collections by making a GET request to `https://api.intercom.io/help_center/collections`. - -Collections will be returned in descending order on the `updated_at` attribute. This means if you need to iterate through results then we'll show the most recently updated collections first. +Fetch a Custom Object Instance by external_id.
@@ -8305,12 +8107,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -response = client.help_centers.collections.list() -for item in response: - yield item -# alternatively, you can paginate page-by-page -for page in response.iter_pages(): - yield page +client.custom_object_instances.get_custom_object_instances_by_external_id( + custom_object_type_identifier="Order", + external_id="external_id", +) ``` @@ -8326,7 +8126,7 @@ for page in response.iter_pages():
-**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page +**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance.
@@ -8334,7 +8134,7 @@ for page in response.iter_pages():
-**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15 +**external_id:** `str`
@@ -8354,7 +8154,7 @@ for page in response.iter_pages():
-
client.help_centers.collections.create(...) +
client.custom_object_instances.create_custom_object_instances(...)
@@ -8366,7 +8166,7 @@ for page in response.iter_pages():
-You can create a new collection by making a POST request to `https://api.intercom.io/help_center/collections.` +Create or update a custom object instance
@@ -8386,9 +8186,15 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.help_centers.collections.create( - name="collection 51", - description="Missing required parameter", +client.custom_object_instances.create_custom_object_instances( + custom_object_type_identifier="Order", + external_id="123", + external_created_at=1392036272, + external_updated_at=1392036272, + custom_attributes={ + "order_number": "ORDER-12345", + "total_amount": "custom_attributes", + }, ) ``` @@ -8405,7 +8211,7 @@ client.help_centers.collections.create(
-**name:** `str` — The name of the collection. For multilingual collections, this will be the name of the default language's content. +**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance.
@@ -8413,7 +8219,7 @@ client.help_centers.collections.create(
-**description:** `typing.Optional[str]` — The description of the collection. For multilingual collections, this will be the description of the default language's content. +**external_id:** `typing.Optional[str]` — A unique identifier for the Custom Object instance in the external system it originated from.
@@ -8421,7 +8227,7 @@ client.help_centers.collections.create(
-**translated_content:** `typing.Optional[GroupTranslatedContent]` +**external_created_at:** `typing.Optional[int]` — The time when the Custom Object instance was created in the external system it originated from.
@@ -8429,7 +8235,7 @@ client.help_centers.collections.create(
-**parent_id:** `typing.Optional[str]` — The id of the parent collection. If `null` then it will be created as the first level collection. +**external_updated_at:** `typing.Optional[int]` — The time when the Custom Object instance was last updated in the external system it originated from.
@@ -8437,7 +8243,7 @@ client.help_centers.collections.create(
-**help_center_id:** `typing.Optional[int]` — The id of the help center where the collection will be created. If `null` then it will be created in the default help center. +**custom_attributes:** `typing.Optional[typing.Dict[str, typing.Optional[str]]]` — The custom attributes which are set for the Custom Object instance.
@@ -8457,7 +8263,7 @@ client.help_centers.collections.create(
-
client.help_centers.collections.find(...) +
client.custom_object_instances.delete_custom_object_instances_by_id(...)
@@ -8469,7 +8275,7 @@ client.help_centers.collections.create(
-You can fetch the details of a single collection by making a GET request to `https://api.intercom.io/help_center/collections/`. +Delete a single Custom Object instance by external_id.
@@ -8489,8 +8295,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.help_centers.collections.find( - collection_id="123", +client.custom_object_instances.delete_custom_object_instances_by_id( + custom_object_type_identifier="Order", + external_id="external_id", ) ``` @@ -8507,7 +8314,15 @@ client.help_centers.collections.find(
-**collection_id:** `str` — The unique identifier for the collection which is given by Intercom. +**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance. + +
+
+ +
+
+ +**external_id:** `str`
@@ -8527,7 +8342,7 @@ client.help_centers.collections.find(
-
client.help_centers.collections.update(...) +
client.custom_object_instances.get_custom_object_instances_by_id(...)
@@ -8539,7 +8354,7 @@ client.help_centers.collections.find(
-You can update the details of a single collection by making a PUT request to `https://api.intercom.io/collections/`. +Fetch a Custom Object Instance by id.
@@ -8559,9 +8374,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.help_centers.collections.update( - collection_id="123", - name="Update collection name", +client.custom_object_instances.get_custom_object_instances_by_id( + custom_object_type_identifier="Order", + custom_object_instance_id="custom_object_instance_id", ) ``` @@ -8578,31 +8393,7 @@ client.help_centers.collections.update(
-**collection_id:** `str` — The unique identifier for the collection which is given by Intercom. - -
-
- -
-
- -**name:** `typing.Optional[str]` — The name of the collection. For multilingual collections, this will be the name of the default language's content. - -
-
- -
-
- -**description:** `typing.Optional[str]` — The description of the collection. For multilingual collections, this will be the description of the default language's content. - -
-
- -
-
- -**translated_content:** `typing.Optional[GroupTranslatedContent]` +**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance.
@@ -8610,7 +8401,7 @@ client.help_centers.collections.update(
-**parent_id:** `typing.Optional[str]` — The id of the parent collection. If `null` then it will be updated as the first level collection. +**custom_object_instance_id:** `str` — The id or external_id of the custom object instance
@@ -8630,7 +8421,7 @@ client.help_centers.collections.update(
-
client.help_centers.collections.delete(...) +
client.custom_object_instances.delete_custom_object_instances_by_external_id(...)
@@ -8642,7 +8433,7 @@ client.help_centers.collections.update(
-You can delete a single collection by making a DELETE request to `https://api.intercom.io/collections/`. +Delete a single Custom Object instance using the Intercom defined id.
@@ -8662,8 +8453,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.help_centers.collections.delete( - collection_id="123", +client.custom_object_instances.delete_custom_object_instances_by_external_id( + custom_object_type_identifier="Order", + custom_object_instance_id="custom_object_instance_id", ) ``` @@ -8680,7 +8472,15 @@ client.help_centers.collections.delete(
-**collection_id:** `str` — The unique identifier for the collection which is given by Intercom. +**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance. + +
+
+ +
+
+ +**custom_object_instance_id:** `str` — The Intercom defined id of the custom object instance
@@ -8700,8 +8500,8 @@ client.help_centers.collections.delete(
-## News Items -
client.news.items.list() +## Data Attributes +
client.data_attributes.list(...)
@@ -8713,7 +8513,7 @@ client.help_centers.collections.delete(
-You can fetch a list of all news items +You can fetch a list of all data attributes belonging to a workspace for contacts, companies or conversations.
@@ -8733,7 +8533,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.news.items.list() +client.data_attributes.list() ``` @@ -8749,6 +8549,22 @@ client.news.items.list()
+**model:** `typing.Optional[DataAttributesListRequestModel]` — Specify the data attribute model to return. + +
+
+ +
+
+ +**include_archived:** `typing.Optional[bool]` — Include archived attributes in the list. By default we return only non archived data attributes. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -8761,7 +8577,7 @@ client.news.items.list()
-
client.news.items.create(...) +
client.data_attributes.create(...)
@@ -8773,7 +8589,7 @@ client.news.items.list()
-You can create a news item +You can create a data attributes for a `contact` or a `company`.
@@ -8788,26 +8604,23 @@ You can create a news item
```python -from intercom import Intercom -from intercom.news import NewsfeedAssignment +from intercom import ( + CreateDataAttributeRequestOptions, + CreateDataAttributeRequestOptionsOptionsItem, + Intercom, +) client = Intercom( token="YOUR_TOKEN", ) -client.news.items.create( - title="Halloween is here!", - body="

New costumes in store for this spooky season

", - sender_id=991267734, - state="live", - deliver_silently=True, - labels=["Product", "Update", "New"], - reactions=["😆", "😅"], - newsfeed_assignments=[ - NewsfeedAssignment( - newsfeed_id=53, - published_at=1664638214, - ) - ], +client.data_attributes.create( + request=CreateDataAttributeRequestOptions( + options=[ + CreateDataAttributeRequestOptionsOptionsItem( + value="1-10", + ) + ], + ), ) ``` @@ -8824,7 +8637,7 @@ client.news.items.create(
-**title:** `str` — The title of the news item. +**request:** `CreateDataAttributeRequest`
@@ -8832,63 +8645,7 @@ client.news.items.create(
-**sender_id:** `int` — The id of the sender of the news item. Must be a teammate on the workspace. - -
-
- -
-
- -**body:** `typing.Optional[str]` — The news item body, which may contain HTML. - -
-
- -
-
- -**state:** `typing.Optional[NewsItemRequestState]` — News items will not be visible to your users in the assigned newsfeeds until they are set live. - -
-
- -
-
- -**deliver_silently:** `typing.Optional[bool]` — When set to `true`, the news item will appear in the messenger newsfeed without showing a notification badge. - -
-
- -
-
- -**labels:** `typing.Optional[typing.Sequence[str]]` — Label names displayed to users to categorize the news item. - -
-
- -
-
- -**reactions:** `typing.Optional[typing.Sequence[typing.Optional[str]]]` — Ordered list of emoji reactions to the news item. When empty, reactions are disabled. - -
-
- -
-
- -**newsfeed_assignments:** `typing.Optional[typing.Sequence[NewsfeedAssignment]]` — A list of newsfeed_assignments to assign to the specified newsfeed. - -
-
- -
-
- -**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -8900,7 +8657,7 @@ client.news.items.create(
-
client.news.items.find(...) +
client.data_attributes.update(...)
@@ -8912,7 +8669,12 @@ client.news.items.create(
-You can fetch the details of a single news item. + +You can update a data attribute. + +> 🚧 Updating the data type is not possible +> +> It is currently a dangerous action to execute changing a data attribute's type via the API. You will need to update the type via the UI instead.
@@ -8932,8 +8694,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.news.items.find( - news_item_id="123", +client.data_attributes.update( + data_attribute_id=1, + request={"description": "Trying to archieve", "archived": True}, ) ``` @@ -8950,7 +8713,15 @@ client.news.items.find(
-**news_item_id:** `str` — The unique identifier for the news item which is given by Intercom. +**data_attribute_id:** `int` — The data attribute id + +
+
+ +
+
+ +**request:** `UpdateDataAttributeRequestBody`
@@ -8970,11 +8741,12 @@ client.news.items.find(
-
client.news.items.update(...) +## Events +
client.events.list(...)
-#### 🔌 Usage +#### 📝 Description
@@ -8982,27 +8754,26 @@ client.news.items.find(
-```python -from intercom import Intercom -client = Intercom( - token="YOUR_TOKEN", -) -client.news.items.update( - news_item_id="123", - title="Christmas is here!", - body="

New gifts in store for the jolly season

", - sender_id=991267748, - reactions=["😝", "😂"], -) +> 🚧 +> +> Please note that you can only 'list' events that are less than 90 days old. Event counts and summaries will still include your events older than 90 days but you cannot 'list' these events individually if they are older than 90 days -``` +The events belonging to a customer can be listed by sending a GET request to `https://api.intercom.io/events` with a user or lead identifier along with a `type` parameter. The identifier parameter can be one of `user_id`, `email` or `intercom_user_id`. The `type` parameter value must be `user`. + +- `https://api.intercom.io/events?type=user&user_id={user_id}` +- `https://api.intercom.io/events?type=user&email={email}` +- `https://api.intercom.io/events?type=user&intercom_user_id={id}` (this call can be used to list leads) + +The `email` parameter value should be [url encoded](http://en.wikipedia.org/wiki/Percent-encoding) when sending. + +You can optionally define the result page size as well with the `per_page` parameter.
-#### ⚙️ Parameters +#### 🔌 Usage
@@ -9010,31 +8781,31 @@ client.news.items.update(
-**news_item_id:** `str` — The unique identifier for the news item which is given by Intercom. - -
-
+```python +from intercom import Intercom -
-
+client = Intercom( + token="YOUR_TOKEN", +) +client.events.list( + type="type", +) -**title:** `str` — The title of the news item. - +```
+
+
+ +#### ⚙️ Parameters
-**sender_id:** `int` — The id of the sender of the news item. Must be a teammate on the workspace. - -
-
-
-**body:** `typing.Optional[str]` — The news item body, which may contain HTML. +**type:** `str` — The value must be user
@@ -9042,7 +8813,7 @@ client.news.items.update(
-**state:** `typing.Optional[NewsItemRequestState]` — News items will not be visible to your users in the assigned newsfeeds until they are set live. +**user_id:** `typing.Optional[str]` — user_id query parameter
@@ -9050,7 +8821,7 @@ client.news.items.update(
-**deliver_silently:** `typing.Optional[bool]` — When set to `true`, the news item will appear in the messenger newsfeed without showing a notification badge. +**intercom_user_id:** `typing.Optional[str]` — intercom_user_id query parameter
@@ -9058,7 +8829,7 @@ client.news.items.update(
-**labels:** `typing.Optional[typing.Sequence[str]]` — Label names displayed to users to categorize the news item. +**email:** `typing.Optional[str]` — email query parameter
@@ -9066,7 +8837,7 @@ client.news.items.update(
-**reactions:** `typing.Optional[typing.Sequence[typing.Optional[str]]]` — Ordered list of emoji reactions to the news item. When empty, reactions are disabled. +**summary:** `typing.Optional[bool]` — summary flag
@@ -9074,7 +8845,7 @@ client.news.items.update(
-**newsfeed_assignments:** `typing.Optional[typing.Sequence[NewsfeedAssignment]]` — A list of newsfeed_assignments to assign to the specified newsfeed. +**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15
@@ -9094,7 +8865,7 @@ client.news.items.update(
-
client.news.items.delete(...) +
client.events.create(...)
@@ -9106,7 +8877,47 @@ client.news.items.update(
-You can delete a single news item. + +You will need an Access Token that has write permissions to send Events. Once you have a key you can submit events via POST to the Events resource, which is located at https://api.intercom.io/events, or you can send events using one of the client libraries. When working with the HTTP API directly a client should send the event with a `Content-Type` of `application/json`. + +When using the JavaScript API, [adding the code to your app](http://docs.intercom.io/configuring-Intercom/tracking-user-events-in-your-app) makes the Events API available. Once added, you can submit an event using the `trackEvent` method. This will associate the event with the Lead or currently logged-in user or logged-out visitor/lead and send it to Intercom. The final parameter is a map that can be used to send optional metadata about the event. + +With the Ruby client you pass a hash describing the event to `Intercom::Event.create`, or call the `track_user` method directly on the current user object (e.g. `user.track_event`). + +**NB: For the JSON object types, please note that we do not currently support nested JSON structure.** + +| Type | Description | Example | +| :-------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- | +| String | The value is a JSON String | `"source":"desktop"` | +| Number | The value is a JSON Number | `"load": 3.67` | +| Date | The key ends with the String `_date` and the value is a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time), assumed to be in the [UTC](http://en.wikipedia.org/wiki/Coordinated_Universal_Time) timezone. | `"contact_date": 1392036272` | +| Link | The value is a HTTP or HTTPS URI. | `"article": "https://example.org/ab1de.html"` | +| Rich Link | The value is a JSON object that contains `url` and `value` keys. | `"article": {"url": "https://example.org/ab1de.html", "value":"the dude abides"}` | +| Monetary Amount | The value is a JSON object that contains `amount` and `currency` keys. The `amount` key is a positive integer representing the amount in cents. The price in the example to the right denotes €349.99. | `"price": {"amount": 34999, "currency": "eur"}` | + +**Lead Events** + +When submitting events for Leads, you will need to specify the Lead's `id`. + +**Metadata behaviour** + +- We currently limit the number of tracked metadata keys to 10 per event. Once the quota is reached, we ignore any further keys we receive. The first 10 metadata keys are determined by the order in which they are sent in with the event. +- It is not possible to change the metadata keys once the event has been sent. A new event will need to be created with the new keys and you can archive the old one. +- There might be up to 24 hrs delay when you send a new metadata for an existing event. + +**Event de-duplication** + +The API may detect and ignore duplicate events. Each event is uniquely identified as a combination of the following data - the Workspace identifier, the Contact external identifier, the Data Event name and the Data Event created time. As a result, it is **strongly recommended** to send a second granularity Unix timestamp in the `created_at` field. + +Duplicated events are responded to using the normal `202 Accepted` code - an error is not thrown, however repeat requests will be counted against any rate limit that is in place. + +### HTTP API Responses + +- Successful responses to submitted events return `202 Accepted` with an empty body. +- Unauthorised access will be rejected with a `401 Unauthorized` or `403 Forbidden` response code. +- Events sent about users that cannot be found will return a `404 Not Found`. +- Event lists containing duplicate events will have those duplicates ignored. +- Server errors will return a `500` response code and may contain an error message in the body.
@@ -9121,13 +8932,17 @@ You can delete a single news item.
```python -from intercom import Intercom +from intercom import CreateDataEventRequestWithId, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.news.items.delete( - news_item_id="123", +client.events.create( + request=CreateDataEventRequestWithId( + id="8a88a590-e1c3-41e2-a502-e0649dbf721c", + event_name="invited-friend", + created_at=1671028894, + ), ) ``` @@ -9144,7 +8959,7 @@ client.news.items.delete(
-**news_item_id:** `str` — The unique identifier for the news item which is given by Intercom. +**request:** `CreateDataEventRequest`
@@ -9164,8 +8979,7 @@ client.news.items.delete(
-## News Feeds -
client.news.feeds.list_items(...) +
client.events.summaries(...)
@@ -9177,7 +8991,7 @@ client.news.items.delete(
-You can fetch a list of all news items that are live on a given newsfeed +Create event summaries for a user. Event summaries are used to track the number of times an event has occurred, the first time it occurred and the last time it occurred.
@@ -9197,9 +9011,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.news.feeds.list_items( - newsfeed_id="123", -) +client.events.summaries() ``` @@ -9215,7 +9027,15 @@ client.news.feeds.list_items(
-**newsfeed_id:** `str` — The unique identifier for the news feed item which is given by Intercom. +**user_id:** `typing.Optional[str]` — Your identifier for the user. + +
+
+ +
+
+ +**event_summaries:** `typing.Optional[CreateDataEventSummariesRequestEventSummaries]` — A list of event summaries for the user. Each event summary should contain the event name, the time the event occurred, and the number of times the event occurred. The event name should be a past tense 'verb-noun' combination, to improve readability, for example `updated-plan`.
@@ -9235,7 +9055,8 @@ client.news.feeds.list_items(
-
client.news.feeds.list() +## Jobs +
client.jobs.status(...)
@@ -9247,7 +9068,7 @@ client.news.feeds.list_items(
-You can fetch a list of all newsfeeds +Retrieve the status of job execution.
@@ -9267,7 +9088,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.news.feeds.list() +client.jobs.status( + job_id="job_id", +) ``` @@ -9283,6 +9106,14 @@ client.news.feeds.list()
+**job_id:** `str` — The unique identifier for the job which is given by Intercom + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -9295,7 +9126,8 @@ client.news.feeds.list()
-
client.news.feeds.find(...) +## Messages +
client.messages.create(...)
@@ -9307,7 +9139,17 @@ client.news.feeds.list()
-You can fetch the details of a single newsfeed +You can create a message that has been initiated by an admin. The conversation can be either an in-app message or an email. + +> 🚧 Sending for visitors +> +> There can be a short delay between when a contact is created and when a contact becomes available to be messaged through the API. A 404 Not Found error will be returned in this case. + +This will return the Message model that has been created. + +> 🚧 Retrieving Associated Conversations +> +> As this is a message, there will be no conversation present until the contact responds. Once they do, you will have to search for a contact's conversations with the id of the message.
@@ -9322,18 +9164,34 @@ You can fetch the details of a single newsfeed
```python -from intercom import Intercom +from intercom import ( + CreateMessageRequest_Email, + CreateMessageRequestFrom, + CreateMessageRequestTo, + Intercom, +) client = Intercom( token="YOUR_TOKEN", ) -client.news.feeds.find( - newsfeed_id="123", -) - -``` -
-
+client.messages.create( + request=CreateMessageRequest_Email( + subject="Thanks for everything", + body="Hello there", + template="plain", + from_=CreateMessageRequestFrom( + id=394051, + ), + to=CreateMessageRequestTo( + type="user", + id="536e564f316c83104c000020", + ), + ), +) + +``` + + @@ -9345,7 +9203,7 @@ client.news.feeds.find(
-**newsfeed_id:** `str` — The unique identifier for the news feed item which is given by Intercom. +**request:** `typing.Optional[CreateMessageRequest]`
@@ -9365,8 +9223,8 @@ client.news.feeds.find(
-## TicketTypes Attributes -
client.ticket_types.attributes.create(...) +## Segments +
client.segments.list(...)
@@ -9378,7 +9236,7 @@ client.news.feeds.find(
-You can create a new attribute for a ticket type. +You can fetch a list of all segments.
@@ -9398,13 +9256,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.ticket_types.attributes.create( - ticket_type_id="ticket_type_id", - name="Attribute Title", - description="Attribute Description", - data_type="string", - required_to_create=False, -) +client.segments.list() ``` @@ -9420,7 +9272,7 @@ client.ticket_types.attributes.create(
-**ticket_type_id:** `str` — The unique identifier for the ticket type which is given by Intercom. +**include_count:** `typing.Optional[bool]` — It includes the count of contacts that belong to each segment.
@@ -9428,79 +9280,69 @@ client.ticket_types.attributes.create(
-**name:** `str` — The name of the ticket type attribute +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
- -
-
- -**description:** `str` — The description of the attribute presented to the teammate or contact -
-
-
-**data_type:** `CreateTicketTypeAttributeRequestDataType` — The data type of the attribute -
+
+
client.segments.find(...)
-**required_to_create:** `typing.Optional[bool]` — Whether the attribute is required to be filled in when teammates are creating the ticket in Inbox. - -
-
+#### 📝 Description
-**required_to_create_for_contacts:** `typing.Optional[bool]` — Whether the attribute is required to be filled in when contacts are creating the ticket in Messenger. - -
-
-
-**visible_on_create:** `typing.Optional[bool]` — Whether the attribute is visible to teammates when creating a ticket in Inbox. - +You can fetch the details of a single segment. +
+
+#### 🔌 Usage +
-**visible_to_contacts:** `typing.Optional[bool]` — Whether the attribute is visible to contacts when creating a ticket in Messenger. - -
-
-
-**multiline:** `typing.Optional[bool]` — Whether the attribute allows multiple lines of text (only applicable to string attributes) - +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.segments.find( + segment_id="123", +) + +```
+ + + +#### ⚙️ Parameters
-**list_items:** `typing.Optional[str]` — A comma delimited list of items for the attribute value (only applicable to list attributes) - -
-
-
-**allow_multiple_values:** `typing.Optional[bool]` — Whether the attribute allows multiple files to be attached to it (only applicable to file attributes) +**segment_id:** `str` — The unique identified of a given segment.
@@ -9520,7 +9362,8 @@ client.ticket_types.attributes.create(
-
client.ticket_types.attributes.update(...) +## Subscription Types +
client.subscription_types.list()
@@ -9532,7 +9375,7 @@ client.ticket_types.attributes.create(
-You can update an existing attribute for a ticket type. +You can list all subscription types. A list of subscription type objects will be returned.
@@ -9552,11 +9395,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.ticket_types.attributes.update( - ticket_type_id="ticket_type_id", - attribute_id="attribute_id", - description="New Attribute Description", -) +client.subscription_types.list() ``` @@ -9572,95 +9411,76 @@ client.ticket_types.attributes.update(
-**ticket_type_id:** `str` — The unique identifier for the ticket type which is given by Intercom. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
- -
-
- -**attribute_id:** `str` — The unique identifier for the ticket type attribute which is given by Intercom. -
-
-
-**name:** `typing.Optional[str]` — The name of the ticket type attribute -
+
+## PhoneCallRedirects +
client.phone_call_redirects.create(...)
-**description:** `typing.Optional[str]` — The description of the attribute presented to the teammate or contact - -
-
+#### 📝 Description
-**required_to_create:** `typing.Optional[bool]` — Whether the attribute is required to be filled in when teammates are creating the ticket in Inbox. - -
-
-
-**required_to_create_for_contacts:** `typing.Optional[bool]` — Whether the attribute is required to be filled in when contacts are creating the ticket in Messenger. - +You can use the API to deflect phone calls to the Intercom Messenger. +Calling this endpoint will send an SMS with a link to the Messenger to the phone number specified. + +If custom attributes are specified, they will be added to the user or lead's custom data attributes.
- -
-
- -**visible_on_create:** `typing.Optional[bool]` — Whether the attribute is visible to teammates when creating a ticket in Inbox. -
+#### 🔌 Usage +
-**visible_to_contacts:** `typing.Optional[bool]` — Whether the attribute is visible to contacts when creating a ticket in Messenger. - -
-
-
-**multiline:** `typing.Optional[bool]` — Whether the attribute allows multiple lines of text (only applicable to string attributes) - -
-
+```python +from intercom import CreatePhoneSwitchRequest, Intercom -
-
+client = Intercom( + token="YOUR_TOKEN", +) +client.phone_call_redirects.create( + request=CreatePhoneSwitchRequest( + phone="+40241100100", + custom_attributes={"issue_type": "Billing", "priority": "High"}, + ), +) -**list_items:** `typing.Optional[str]` — A comma delimited list of items for the attribute value (only applicable to list attributes) - +``` +
+
+#### ⚙️ Parameters +
-**allow_multiple_values:** `typing.Optional[bool]` — Whether the attribute allows multiple files to be attached to it (only applicable to file attributes) - -
-
-
-**archived:** `typing.Optional[bool]` — Whether the attribute should be archived and not shown during creation of the ticket (it will still be present on previously created tickets) +**request:** `typing.Optional[CreatePhoneSwitchRequest]`
@@ -9680,8 +9500,8 @@ client.ticket_types.attributes.update(
-## Admins -
client.unstable.admins.identify_admin() +## Calls +
client.calls.list_calls(...)
@@ -9693,12 +9513,7 @@ client.ticket_types.attributes.update(
- -You can view the currently authorised admin along with the embedded app object (a "workspace" in legacy terminology). - -> 🚧 Single Sign On -> -> If you are building a custom "Log in with Intercom" flow for your site, and you call the `/me` endpoint to identify the logged-in user, you should not accept any sign-ins from users with unverified email addresses as it poses a potential impersonation security risk. +Retrieve a paginated list of calls.
@@ -9718,7 +9533,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.admins.identify_admin() +client.calls.list_calls() ``` @@ -9734,6 +9549,22 @@ client.unstable.admins.identify_admin()
+**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page + +
+
+ +
+
+ +**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 25. Max 25. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -9746,7 +9577,7 @@ client.unstable.admins.identify_admin()
-
client.unstable.admins.set_away_admin(...) +
client.calls.show_call(...)
@@ -9758,7 +9589,7 @@ client.unstable.admins.identify_admin()
-You can set an Admin as away for the Inbox. +Retrieve a single call by id.
@@ -9778,10 +9609,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.admins.set_away_admin( - id=1, - away_mode_enabled=True, - away_mode_reassign=True, +client.calls.show_call( + call_id="call_id", ) ``` @@ -9798,31 +9627,7 @@ client.unstable.admins.set_away_admin(
-**id:** `int` — The unique identifier of a given admin - -
-
- -
-
- -**away_mode_enabled:** `bool` — Set to "true" to change the status of the admin to away. - -
-
- -
-
- -**away_mode_reassign:** `bool` — Set to "true" to assign any new conversation replies to your default inbox. - -
-
- -
-
- -**away_status_reason_id:** `typing.Optional[int]` — The unique identifier of the away status reason +**call_id:** `str` — The id of the call to retrieve
@@ -9842,7 +9647,7 @@ client.unstable.admins.set_away_admin(
-
client.unstable.admins.list_activity_logs(...) +
client.calls.show_call_recording(...)
@@ -9854,7 +9659,7 @@ client.unstable.admins.set_away_admin(
-You can get a log of activities by all admins in an app. +Redirects to a signed URL for the call's recording if it exists.
@@ -9874,9 +9679,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.admins.list_activity_logs( - created_at_after="1677253093", - created_at_before="1677861493", +client.calls.show_call_recording( + call_id="call_id", ) ``` @@ -9893,15 +9697,7 @@ client.unstable.admins.list_activity_logs(
-**created_at_after:** `str` — The start date that you request data for. It must be formatted as a UNIX timestamp. - -
-
- -
-
- -**created_at_before:** `typing.Optional[str]` — The end date that you request data for. It must be formatted as a UNIX timestamp. +**call_id:** `str` — The id of the call
@@ -9921,7 +9717,7 @@ client.unstable.admins.list_activity_logs(
-
client.unstable.admins.list_admins() +
client.calls.show_call_transcript(...)
@@ -9933,7 +9729,7 @@ client.unstable.admins.list_activity_logs(
-You can fetch a list of admins for a given workspace. +Returns the transcript for the specified call as a downloadable text file.
@@ -9953,7 +9749,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.admins.list_admins() +client.calls.show_call_transcript( + call_id="call_id", +) ``` @@ -9969,6 +9767,14 @@ client.unstable.admins.list_admins()
+**call_id:** `str` — The id of the call + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -9981,7 +9787,7 @@ client.unstable.admins.list_admins()
-
client.unstable.admins.retrieve_admin(...) +
client.calls.list_calls_with_transcripts(...)
@@ -9993,7 +9799,8 @@ client.unstable.admins.list_admins()
-You can retrieve the details of a single admin. +Retrieve calls by a list of conversation ids and include transcripts when available. +A maximum of 20 `conversation_ids` can be provided. If none are provided or more than 20 are provided, a 400 error is returned.
@@ -10013,8 +9820,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.admins.retrieve_admin( - id=1, +client.calls.list_calls_with_transcripts( + conversation_ids=["64619700005694", "64619700005695"], ) ``` @@ -10031,7 +9838,7 @@ client.unstable.admins.retrieve_admin(
-**id:** `int` — The unique identifier of a given admin +**conversation_ids:** `typing.Sequence[str]` — A list of conversation ids to fetch calls for. Maximum 20.
@@ -10051,8 +9858,8 @@ client.unstable.admins.retrieve_admin(
-## AI Content -
client.unstable.ai_content.list_content_import_sources() +## Teams +
client.teams.list()
@@ -10064,7 +9871,7 @@ client.unstable.admins.retrieve_admin(
-You can retrieve a list of all content import sources for a workspace. +This will return a list of team objects for the App.
@@ -10084,7 +9891,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.ai_content.list_content_import_sources() +client.teams.list() ``` @@ -10112,7 +9919,7 @@ client.unstable.ai_content.list_content_import_sources()
-
client.unstable.ai_content.create_content_import_source(...) +
client.teams.find(...)
@@ -10124,7 +9931,7 @@ client.unstable.ai_content.list_content_import_sources()
-You can create a new content import source by sending a POST request to this endpoint. +You can fetch the details of a single team, containing an array of admins that belong to this team.
@@ -10144,8 +9951,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.ai_content.create_content_import_source( - url="https://www.example.com", +client.teams.find( + team_id="123", ) ``` @@ -10162,15 +9969,7 @@ client.unstable.ai_content.create_content_import_source(
-**url:** `str` — The URL of the content import source. - -
-
- -
-
- -**status:** `typing.Optional[CreateContentImportSourceRequestStatus]` — The status of the content import source. +**team_id:** `str` — The unique identifier of a given team.
@@ -10190,10 +9989,25 @@ client.unstable.ai_content.create_content_import_source(
-
client.unstable.ai_content.get_content_import_source(...) +## Ticket States +
client.ticket_states.list_ticket_states() +
+
+ +#### 📝 Description + +
+
+
+You can get a list of all ticket states for a workspace. +
+
+
+
+ #### 🔌 Usage
@@ -10208,9 +10022,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.ai_content.get_content_import_source( - id="id", -) +client.ticket_states.list_ticket_states() ```
@@ -10226,14 +10038,6 @@ client.unstable.ai_content.get_content_import_source(
-**id:** `str` — The unique identifier for the content import source which is given by Intercom. - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -10246,7 +10050,8 @@ client.unstable.ai_content.get_content_import_source(
-
client.unstable.ai_content.update_content_import_source(...) +## Ticket Types +
client.ticket_types.list()
@@ -10258,7 +10063,7 @@ client.unstable.ai_content.get_content_import_source(
-You can update an existing content import source. +You can get a list of all ticket types for a workspace.
@@ -10278,11 +10083,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.ai_content.update_content_import_source( - id="id", - sync_behavior="api", - url="https://www.example.com", -) +client.ticket_types.list() ``` @@ -10298,38 +10099,6 @@ client.unstable.ai_content.update_content_import_source(
-**id:** `str` — The unique identifier for the content import source which is given by Intercom. - -
-
- -
-
- -**sync_behavior:** `UpdateContentImportSourceRequestSyncBehavior` — If you intend to create or update External Pages via the API, this should be set to `api`. You can not change the value to or from api. - -
-
- -
-
- -**url:** `str` — The URL of the content import source. This may only be different from the existing value if the sync behavior is API. - -
-
- -
-
- -**status:** `typing.Optional[UpdateContentImportSourceRequestStatus]` — The status of the content import source. - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -10342,7 +10111,7 @@ client.unstable.ai_content.update_content_import_source(
-
client.unstable.ai_content.delete_content_import_source(...) +
client.ticket_types.create(...)
@@ -10354,7 +10123,11 @@ client.unstable.ai_content.update_content_import_source(
-You can delete a content import source by making a DELETE request this endpoint. This will also delete all external pages that were imported from this source. +You can create a new ticket type. +> 📘 Creating ticket types. +> +> Every ticket type will be created with two default attributes: _default_title_ and _default_description_. +> For the `icon` propery, use an emoji from [Twemoji Cheatsheet](https://twemoji-cheatsheet.vercel.app/)
@@ -10369,13 +10142,18 @@ You can delete a content import source by making a DELETE request this endpoint.
```python -from intercom import Intercom +from intercom import CreateTicketTypeRequest, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.ai_content.delete_content_import_source( - id="id", +client.ticket_types.create( + request=CreateTicketTypeRequest( + name="Customer Issue", + description="Customer Report Template", + category="Customer", + icon="🎟️", + ), ) ``` @@ -10392,7 +10170,7 @@ client.unstable.ai_content.delete_content_import_source(
-**id:** `str` — The unique identifier for the content import source which is given by Intercom. +**request:** `typing.Optional[CreateTicketTypeRequest]`
@@ -10412,7 +10190,7 @@ client.unstable.ai_content.delete_content_import_source(
-
client.unstable.ai_content.list_external_pages() +
client.ticket_types.get(...)
@@ -10424,7 +10202,7 @@ client.unstable.ai_content.delete_content_import_source(
-You can retrieve a list of all external pages for a workspace. +You can fetch the details of a single ticket type.
@@ -10444,7 +10222,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.ai_content.list_external_pages() +client.ticket_types.get( + ticket_type_id="ticket_type_id", +) ``` @@ -10460,6 +10240,14 @@ client.unstable.ai_content.list_external_pages()
+**ticket_type_id:** `str` — The unique identifier for the ticket type which is given by Intercom. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -10472,7 +10260,7 @@ client.unstable.ai_content.list_external_pages()
-
client.unstable.ai_content.create_external_page(...) +
client.ticket_types.update(...)
@@ -10484,7 +10272,12 @@ client.unstable.ai_content.list_external_pages()
-You can create a new external page by sending a POST request to this endpoint. If an external page already exists with the specified source_id and external_id, it will be updated instead. + +You can update a ticket type. + +> 📘 Updating a ticket type. +> +> For the `icon` propery, use an emoji from [Twemoji Cheatsheet](https://twemoji-cheatsheet.vercel.app/)
@@ -10504,12 +10297,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.ai_content.create_external_page( - title="Test", - html="

Test

", - url="https://www.example.com", - source_id=44, - external_id="abc1234", +client.ticket_types.update( + ticket_type_id="ticket_type_id", + name="Bug Report 2", ) ``` @@ -10526,7 +10316,7 @@ client.unstable.ai_content.create_external_page(
-**title:** `str` — The title of the external page. +**ticket_type_id:** `str` — The unique identifier for the ticket type which is given by Intercom.
@@ -10534,7 +10324,7 @@ client.unstable.ai_content.create_external_page(
-**html:** `str` — The body of the external page in HTML. +**name:** `typing.Optional[str]` — The name of the ticket type.
@@ -10542,7 +10332,7 @@ client.unstable.ai_content.create_external_page(
-**source_id:** `int` — The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. +**description:** `typing.Optional[str]` — The description of the ticket type.
@@ -10550,7 +10340,7 @@ client.unstable.ai_content.create_external_page(
-**external_id:** `str` — The identifier for the external page which was given by the source. Must be unique for the source. +**category:** `typing.Optional[UpdateTicketTypeRequestCategory]` — Category of the Ticket Type.
@@ -10558,7 +10348,7 @@ client.unstable.ai_content.create_external_page(
-**url:** `typing.Optional[str]` — The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. When a URL is not present, Fin will not reference the source. +**icon:** `typing.Optional[str]` — The icon of the ticket type.
@@ -10566,7 +10356,7 @@ client.unstable.ai_content.create_external_page(
-**ai_agent_availability:** `typing.Optional[bool]` — Whether the external page should be used to answer questions by AI Agent. Will not default when updating an existing external page. +**archived:** `typing.Optional[bool]` — The archived status of the ticket type.
@@ -10574,7 +10364,7 @@ client.unstable.ai_content.create_external_page(
-**ai_copilot_availability:** `typing.Optional[bool]` — Whether the external page should be used to answer questions by AI Copilot. Will not default when updating an existing external page. +**is_internal:** `typing.Optional[bool]` — Whether the tickets associated with this ticket type are intended for internal use only or will be shared with customers. This is currently a limited attribute.
@@ -10594,7 +10384,8 @@ client.unstable.ai_content.create_external_page(
-
client.unstable.ai_content.get_external_page(...) +## Tickets +
client.tickets.reply(...)
@@ -10606,7 +10397,7 @@ client.unstable.ai_content.create_external_page(
-You can retrieve an external page. +You can reply to a ticket with a message from an admin or on behalf of a contact, or with a note for admins.
@@ -10621,13 +10412,17 @@ You can retrieve an external page.
```python -from intercom import Intercom +from intercom import ContactReplyTicketIntercomUserIdRequest, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.ai_content.get_external_page( - id="id", +client.tickets.reply( + ticket_id="123", + request=ContactReplyTicketIntercomUserIdRequest( + body="Thanks again :)", + intercom_user_id="6762f2971bb69f9f2193bc49", + ), ) ``` @@ -10644,7 +10439,15 @@ client.unstable.ai_content.get_external_page(
-**id:** `str` — The unique identifier for the external page which is given by Intercom. +**ticket_id:** `str` + +
+
+ +
+
+ +**request:** `TicketsReplyRequestBody`
@@ -10664,7 +10467,7 @@ client.unstable.ai_content.get_external_page(
-
client.unstable.ai_content.update_external_page(...) +
client.tickets.create(...)
@@ -10676,7 +10479,7 @@ client.unstable.ai_content.get_external_page(
-You can update an existing external page (if it was created via the API). +You can create a new ticket.
@@ -10691,18 +10494,18 @@ You can update an existing external page (if it was created via the API).
```python -from intercom import Intercom +from intercom import CreateTicketRequestContactsItemId, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.ai_content.update_external_page( - id="id", - title="Test", - html="

Test

", - url="https://www.example.com", - source_id=47, - external_id="5678", +client.tickets.create( + ticket_type_id="1234", + contacts=[ + CreateTicketRequestContactsItemId( + id="6762f2d81bb69f9f2193bc54", + ) + ], ) ``` @@ -10719,7 +10522,7 @@ client.unstable.ai_content.update_external_page(
-**id:** `str` — The unique identifier for the external page which is given by Intercom. +**ticket_type_id:** `str` — The ID of the type of ticket you want to create
@@ -10727,7 +10530,7 @@ client.unstable.ai_content.update_external_page(
-**title:** `str` — The title of the external page. +**contacts:** `typing.Sequence[CreateTicketRequestContactsItem]` — The list of contacts (users or leads) affected by this ticket. Currently only one is allowed
@@ -10735,7 +10538,7 @@ client.unstable.ai_content.update_external_page(
-**html:** `str` — The body of the external page in HTML. +**skip_notifications:** `typing.Optional[bool]` — Option to disable notifications when a Ticket is created.
@@ -10743,7 +10546,13 @@ client.unstable.ai_content.update_external_page(
-**url:** `str` — The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. +**conversation_to_link_id:** `typing.Optional[str]` + +The ID of the conversation you want to link to the ticket. Here are the valid ways of linking two tickets: + - conversation | back-office ticket + - customer tickets | non-shared back-office ticket + - conversation | tracker ticket + - customer ticket | tracker ticket
@@ -10751,7 +10560,7 @@ client.unstable.ai_content.update_external_page(
-**source_id:** `int` — The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. +**company_id:** `typing.Optional[str]` — The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom
@@ -10759,7 +10568,7 @@ client.unstable.ai_content.update_external_page(
-**fin_availability:** `typing.Optional[bool]` — Whether the external page should be used to answer questions by Fin. +**created_at:** `typing.Optional[int]` — The time the ticket was created. If not provided, the current time will be used.
@@ -10767,7 +10576,7 @@ client.unstable.ai_content.update_external_page(
-**external_id:** `typing.Optional[str]` — The identifier for the external page which was given by the source. Must be unique for the source. +**assignment:** `typing.Optional[CreateTicketRequestAssignment]`
@@ -10787,7 +10596,7 @@ client.unstable.ai_content.update_external_page(
-
client.unstable.ai_content.delete_external_page(...) +
client.tickets.enqueue_create_ticket(...)
@@ -10799,7 +10608,7 @@ client.unstable.ai_content.update_external_page(
-Sending a DELETE request for an external page will remove it from the content library UI and from being used for AI answers. +Enqueues ticket creation for asynchronous processing, returning if the job was enqueued successfully to be processed. We attempt to perform a best-effort validation on inputs before tasks are enqueued. If the given parameters are incorrect, we won't enqueue the job.
@@ -10814,13 +10623,18 @@ Sending a DELETE request for an external page will remove it from the content li
```python -from intercom import Intercom +from intercom import CreateTicketRequestContactsItemId, Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.ai_content.delete_external_page( - id="id", +client.tickets.enqueue_create_ticket( + ticket_type_id="1234", + contacts=[ + CreateTicketRequestContactsItemId( + id="6762f2d81bb69f9f2193bc54", + ) + ], ) ``` @@ -10837,7 +10651,7 @@ client.unstable.ai_content.delete_external_page(
-**id:** `str` — The unique identifier for the external page which is given by Intercom. +**ticket_type_id:** `str` — The ID of the type of ticket you want to create
@@ -10845,68 +10659,57 @@ client.unstable.ai_content.delete_external_page(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**contacts:** `typing.Sequence[CreateTicketRequestContactsItem]` — The list of contacts (users or leads) affected by this ticket. Currently only one is allowed
-
-
+
+
+**skip_notifications:** `typing.Optional[bool]` — Option to disable notifications when a Ticket is created. +
-
-## Articles -
client.unstable.articles.list_articles()
-#### 📝 Description +**conversation_to_link_id:** `typing.Optional[str]` -
-
+The ID of the conversation you want to link to the ticket. Here are the valid ways of linking two tickets: + - conversation | back-office ticket + - customer tickets | non-shared back-office ticket + - conversation | tracker ticket + - customer ticket | tracker ticket + +
+
-You can fetch a list of all articles by making a GET request to `https://api.intercom.io/articles`. - -> 📘 How are the articles sorted and ordered? -> -> Articles will be returned in descending order on the `updated_at` attribute. This means if you need to iterate through results then we'll show the most recently updated articles first. -
-
+**company_id:** `typing.Optional[str]` — The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom +
-#### 🔌 Usage - -
-
-
-```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.unstable.articles.list_articles() - -``` -
-
+**created_at:** `typing.Optional[int]` — The time the ticket was created. If not provided, the current time will be used. +
-#### ⚙️ Parameters -
+**assignment:** `typing.Optional[CreateTicketRequestAssignment]` + +
+
+
@@ -10922,7 +10725,7 @@ client.unstable.articles.list_articles()
-
client.unstable.articles.create_article(...) +
client.tickets.get(...)
@@ -10934,7 +10737,7 @@ client.unstable.articles.list_articles()
-You can create a new article by making a POST request to `https://api.intercom.io/articles`. +You can fetch the details of a single ticket.
@@ -10954,8 +10757,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.articles.create_article( - request={"key": "value"}, +client.tickets.get( + ticket_id="ticket_id", ) ``` @@ -10972,7 +10775,7 @@ client.unstable.articles.create_article(
-**request:** `typing.Optional[typing.Any]` +**ticket_id:** `str` — The unique identifier for the ticket which is given by Intercom.
@@ -10992,7 +10795,7 @@ client.unstable.articles.create_article(
-
client.unstable.articles.retrieve_article(...) +
client.tickets.update(...)
@@ -11004,7 +10807,7 @@ client.unstable.articles.create_article(
-You can fetch the details of a single article by making a GET request to `https://api.intercom.io/articles/`. +You can update a ticket.
@@ -11024,8 +10827,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.articles.retrieve_article( - id=1, +client.tickets.update( + ticket_id="ticket_id", + ticket_state_id="123", ) ``` @@ -11042,7 +10846,7 @@ client.unstable.articles.retrieve_article(
-**id:** `int` — The unique identifier for the article which is given by Intercom. +**ticket_id:** `str` — The unique identifier for the ticket which is given by Intercom
@@ -11050,69 +10854,63 @@ client.unstable.articles.retrieve_article(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**ticket_attributes:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — The attributes set on the ticket.
- -
+
+
+**ticket_state_id:** `typing.Optional[str]` — The ID of the ticket state associated with the ticket type. +
-
-
client.unstable.articles.delete_article(...)
-#### 📝 Description - -
-
+**company_id:** `typing.Optional[str]` — The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company. + +
+
-You can delete a single article by making a DELETE request to `https://api.intercom.io/articles/`. -
-
+**open:** `typing.Optional[bool]` — Specify if a ticket is open. Set to false to close a ticket. Closing a ticket will also unsnooze it. +
-#### 🔌 Usage -
+**is_shared:** `typing.Optional[bool]` — Specify whether the ticket is visible to users. + +
+
+
-```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.unstable.articles.delete_article( - id=1, -) - -``` -
-
+**snoozed_until:** `typing.Optional[int]` — The time you want the ticket to reopen. + -#### ⚙️ Parameters -
+**admin_id:** `typing.Optional[int]` — The ID of the admin performing ticket update. Needed for workflows execution and attributing actions to specific admins. + +
+
+
-**id:** `int` — The unique identifier for the article which is given by Intercom. +**assignee_id:** `typing.Optional[str]` — The ID of the admin or team to which the ticket is assigned. Set this 0 to unassign it.
@@ -11132,7 +10930,7 @@ client.unstable.articles.delete_article(
-
client.unstable.articles.search_articles(...) +
client.tickets.delete_ticket(...)
@@ -11144,7 +10942,7 @@ client.unstable.articles.delete_article(
-You can search for articles by making a GET request to `https://api.intercom.io/articles/search`. +You can delete a ticket using the Intercom provided ID.
@@ -11164,9 +10962,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.articles.search_articles( - phrase="Getting started", - state="published", +client.tickets.delete_ticket( + ticket_id="ticket_id", ) ``` @@ -11183,31 +10980,7 @@ client.unstable.articles.search_articles(
-**phrase:** `typing.Optional[str]` — The phrase within your articles to search for. - -
-
- -
-
- -**state:** `typing.Optional[str]` — The state of the Articles returned. One of `published`, `draft` or `all`. - -
-
- -
-
- -**help_center_id:** `typing.Optional[int]` — The ID of the Help Center to search in. - -
-
- -
-
- -**highlight:** `typing.Optional[bool]` — Return a highlighted version of the matching content within your articles. Refer to the response schema for more details. +**ticket_id:** `str` — The unique identifier for the ticket which is given by Intercom.
@@ -11227,8 +11000,7 @@ client.unstable.articles.search_articles(
-## Away Status Reasons -
client.unstable.away_status_reasons.list_away_status_reasons() +
client.tickets.search(...)
@@ -11240,7 +11012,75 @@ client.unstable.articles.search_articles(
-Returns a list of all away status reasons configured for the workspace, including deleted ones. +You can search for multiple tickets by the value of their attributes in order to fetch exactly which ones you want. + +To search for tickets, you send a `POST` request to `https://api.intercom.io/tickets/search`. + +This will accept a query object in the body which will define your filters. +{% admonition type="warning" name="Optimizing search queries" %} + Search queries can be complex, so optimizing them can help the performance of your search. + Use the `AND` and `OR` operators to combine multiple filters to get the exact results you need and utilize + pagination to limit the number of results returned. The default is `20` results per page. + See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#example-search-conversations-request) for more details on how to use the `starting_after` param. +{% /admonition %} + +### Nesting & Limitations + +You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4). +There are some limitations to the amount of multiples there can be: +- There's a limit of max 2 nested filters +- There's a limit of max 15 filters for each AND or OR group + +### Accepted Fields + +Most keys listed as part of the Ticket model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foobar"`). +The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. + +| Field | Type | +| :---------------------------------------- | :--------------------------------------------------------------------------------------- | +| id | String | +| created_at | Date (UNIX timestamp) | +| updated_at | Date (UNIX timestamp) | +| _default_title_ | String | +| _default_description_ | String | +| category | String | +| ticket_type_id | String | +| contact_ids | String | +| teammate_ids | String | +| admin_assignee_id | String | +| team_assignee_id | String | +| open | Boolean | +| state | String | +| snoozed_until | Date (UNIX timestamp) | +| ticket_attribute.{id} | String or Boolean or Date (UNIX timestamp) or Float or Integer | + +{% admonition type="info" name="Searching by Category" %} +When searching for tickets by the **`category`** field, specific terms must be used instead of the category names: +* For **Customer** category tickets, use the term `request`. +* For **Back-office** category tickets, use the term `task`. +* For **Tracker** category tickets, use the term `tracker`. +{% /admonition %} + +### Accepted Operators + +{% admonition type="info" name="Searching based on `created_at`" %} + You may use the `<=` or `>=` operators to search by `created_at`. +{% /admonition %} + +The table below shows the operators you can use to define how you want to search for the value. The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates). + +| Operator | Valid Types | Description | +| :------- | :----------------------------- | :----------------------------------------------------------- | +| = | All | Equals | +| != | All | Doesn't Equal | +| IN | All | In Shortcut for `OR` queries Values most be in Array | +| NIN | All | Not In Shortcut for `OR !` queries Values must be in Array | +| > | Integer Date (UNIX Timestamp) | Greater (or equal) than | +| < | Integer Date (UNIX Timestamp) | Lower (or equal) than | +| ~ | String | Contains | +| !~ | String | Doesn't Contain | +| ^ | String | Starts With | +| $ | String | Ends With |
@@ -11255,12 +11095,36 @@ Returns a list of all away status reasons configured for the workspace, includin
```python -from intercom import Intercom +from intercom import ( + Intercom, + MultipleFilterSearchRequest, + SingleFilterSearchRequest, + StartingAfterPaging, +) client = Intercom( token="YOUR_TOKEN", ) -client.unstable.away_status_reasons.list_away_status_reasons() +response = client.tickets.search( + query=MultipleFilterSearchRequest( + operator="AND", + value=[ + SingleFilterSearchRequest( + field="created_at", + operator=">", + value="1306054154", + ) + ], + ), + pagination=StartingAfterPaging( + per_page=5, + ), +) +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -11276,23 +11140,53 @@ client.unstable.away_status_reasons.list_away_status_reasons()
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**query:** `SearchRequestQuery`
- -
- + +
+
+ +**pagination:** `typing.Optional[StartingAfterPaging]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+ + +
-## Unstable Export -
client.unstable.export.enqueue_a_new_reporting_data_export_job(...) +## Visitors +
client.visitors.find(...) +
+
+ +#### 📝 Description +
+
+
+ +You can fetch the details of a single visitor. +
+
+
+
+ #### 🔌 Usage
@@ -11307,14 +11201,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.export.enqueue_a_new_reporting_data_export_job( - dataset_id="conversation", - attribute_ids=[ - "conversation.id", - "conversation.first_user_conversation_part_created_at", - ], - start_time=1717490000, - end_time=1717510000, +client.visitors.find( + user_id="user_id", ) ``` @@ -11331,7 +11219,7 @@ client.unstable.export.enqueue_a_new_reporting_data_export_job(
-**dataset_id:** `str` +**user_id:** `str` — The user_id of the Visitor you want to retrieve.
@@ -11339,23 +11227,76 @@ client.unstable.export.enqueue_a_new_reporting_data_export_job(
-**attribute_ids:** `typing.Sequence[str]` +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+
+
+ + + + +
+ +
client.visitors.update(...) +
+
+ +#### 📝 Description
-**start_time:** `int` - +
+
+ +Sending a PUT request to `/visitors` will result in an update of an existing Visitor. + +**Option 1.** You can update a visitor by passing in the `user_id` of the visitor in the Request body. + +**Option 2.** You can update a visitor by passing in the `id` of the visitor in the Request body. +
+
+#### 🔌 Usage +
-**end_time:** `int` +
+
+ +```python +from intercom import Intercom, UpdateVisitorRequestWithUserId + +client = Intercom( + token="YOUR_TOKEN", +) +client.visitors.update( + request=UpdateVisitorRequestWithUserId( + user_id="fail", + name="Christian Fail", + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `UpdateVisitorRequest`
@@ -11375,10 +11316,28 @@ client.unstable.export.enqueue_a_new_reporting_data_export_job(
-
client.unstable.export.list_available_datasets_and_attributes() +
client.visitors.merge_to_contact(...) +
+
+ +#### 📝 Description + +
+
+
+You can merge a Visitor to a Contact of role type `lead` or `user`. + +> 📘 What happens upon a visitor being converted? +> +> If the User exists, then the Visitor will be merged into it, the Visitor deleted and the User returned. If the User does not exist, the Visitor will be converted to a User, with the User identifiers replacing it's Visitor identifiers. +
+
+
+
+ #### 🔌 Usage
@@ -11389,11 +11348,21 @@ client.unstable.export.enqueue_a_new_reporting_data_export_job( ```python from intercom import Intercom +from intercom.visitors import UserWithId, VisitorWithUserId client = Intercom( token="YOUR_TOKEN", ) -client.unstable.export.list_available_datasets_and_attributes() +client.visitors.merge_to_contact( + type="user", + user=UserWithId( + id="8a88a590-e1c3-41e2-a502-e0649dbf721c", + email="foo@bar.com", + ), + visitor=VisitorWithUserId( + user_id="3ecf64d0-9ed1-4e9f-88e1-da7d6e6782f3", + ), +) ```
@@ -11409,6 +11378,30 @@ client.unstable.export.list_available_datasets_and_attributes()
+**type:** `str` — Represents the role of the Contact model. Accepts `lead` or `user`. + +
+
+ +
+
+ +**user:** `ConvertVisitorRequestUser` — The unique identifiers retained after converting or merging. + +
+
+ +
+
+ +**visitor:** `ConvertVisitorRequestVisitor` — The unique identifiers to convert a single Visitor. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -11421,8 +11414,8 @@ client.unstable.export.list_available_datasets_and_attributes()
-## Help Center -
client.unstable.help_center.list_all_collections() +## HelpCenters Collections +
client.help_centers.collections.list(...)
@@ -11456,7 +11449,12 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.help_center.list_all_collections() +response = client.help_centers.collections.list() +for item in response: + yield item +# alternatively, you can paginate page-by-page +for page in response.iter_pages(): + yield page ```
@@ -11472,6 +11470,22 @@ client.unstable.help_center.list_all_collections()
+**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page + +
+
+ +
+
+ +**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15 + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -11484,7 +11498,7 @@ client.unstable.help_center.list_all_collections()
-
client.unstable.help_center.create_collection(...) +
client.help_centers.collections.create(...)
@@ -11516,7 +11530,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.help_center.create_collection( +client.help_centers.collections.create( name="collection 51", description="Missing required parameter", ) @@ -11587,7 +11601,7 @@ client.unstable.help_center.create_collection(
-
client.unstable.help_center.retrieve_collection(...) +
client.help_centers.collections.find(...)
@@ -11619,8 +11633,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.help_center.retrieve_collection( - id=1, +client.help_centers.collections.find( + collection_id=1, ) ``` @@ -11637,7 +11651,7 @@ client.unstable.help_center.retrieve_collection(
-**id:** `int` — The unique identifier for the collection which is given by Intercom. +**collection_id:** `int` — The unique identifier for the collection which is given by Intercom.
@@ -11657,7 +11671,7 @@ client.unstable.help_center.retrieve_collection(
-
client.unstable.help_center.update_collection(...) +
client.help_centers.collections.update(...)
@@ -11689,8 +11703,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.help_center.update_collection( - id=1, +client.help_centers.collections.update( + collection_id=1, name="Update collection name", ) @@ -11708,7 +11722,7 @@ client.unstable.help_center.update_collection(
-**id:** `int` — The unique identifier for the collection which is given by Intercom. +**collection_id:** `int` — The unique identifier for the collection which is given by Intercom.
@@ -11760,7 +11774,7 @@ client.unstable.help_center.update_collection(
-
client.unstable.help_center.delete_collection(...) +
client.help_centers.collections.delete(...)
@@ -11792,8 +11806,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.help_center.delete_collection( - id=1, +client.help_centers.collections.delete( + collection_id=1, ) ``` @@ -11810,7 +11824,7 @@ client.unstable.help_center.delete_collection(
-**id:** `int` — The unique identifier for the collection which is given by Intercom. +**collection_id:** `int` — The unique identifier for the collection which is given by Intercom.
@@ -11830,7 +11844,8 @@ client.unstable.help_center.delete_collection(
-
client.unstable.help_center.retrieve_help_center(...) +## News Items +
client.news.items.list()
@@ -11842,7 +11857,7 @@ client.unstable.help_center.delete_collection(
-You can fetch the details of a single Help Center by making a GET request to `https://api.intercom.io/help_center/help_center/`. +You can fetch a list of all news items
@@ -11862,9 +11877,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.help_center.retrieve_help_center( - id=1, -) +client.news.items.list() ``` @@ -11880,14 +11893,6 @@ client.unstable.help_center.retrieve_help_center(
-**id:** `int` — The unique identifier for the collection which is given by Intercom. - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -11900,7 +11905,7 @@ client.unstable.help_center.retrieve_help_center(
-
client.unstable.help_center.list_help_centers() +
client.news.items.create(...)
@@ -11912,7 +11917,7 @@ client.unstable.help_center.retrieve_help_center(
-You can list all Help Centers by making a GET request to `https://api.intercom.io/help_center/help_centers`. +You can create a news item
@@ -11928,11 +11933,26 @@ You can list all Help Centers by making a GET request to `https://api.intercom.i ```python from intercom import Intercom +from intercom.news import NewsfeedAssignment client = Intercom( token="YOUR_TOKEN", ) -client.unstable.help_center.list_help_centers() +client.news.items.create( + title="Halloween is here!", + body="

New costumes in store for this spooky season

", + sender_id=991267834, + state="live", + deliver_silently=True, + labels=["Product", "Update", "New"], + reactions=["😆", "😅"], + newsfeed_assignments=[ + NewsfeedAssignment( + newsfeed_id=53, + published_at=1664638214, + ) + ], +) ``` @@ -11948,83 +11968,23 @@ client.unstable.help_center.list_help_centers()
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**title:** `str` — The title of the news item.
- -
+
+
+**sender_id:** `int` — The id of the sender of the news item. Must be a teammate on the workspace. +
-
- -## Companies -
client.unstable.companies.retrieve_company(...) -
-
- -#### 📝 Description - -
-
- -
-
- -You can fetch a single company by passing in `company_id` or `name`. - - `https://api.intercom.io/companies?name={name}` - - `https://api.intercom.io/companies?company_id={company_id}` - -You can fetch all companies and filter by `segment_id` or `tag_id` as a query parameter. - - `https://api.intercom.io/companies?tag_id={tag_id}` - - `https://api.intercom.io/companies?segment_id={segment_id}` -
-
-
-
- -#### 🔌 Usage - -
-
- -
-
- -```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.unstable.companies.retrieve_company( - name="my company", - company_id="12345", - tag_id="678910", - segment_id="98765", -) - -``` -
-
-
-
- -#### ⚙️ Parameters - -
-
-**name:** `typing.Optional[str]` — The `name` of the company to filter by. +**body:** `typing.Optional[str]` — The news item body, which may contain HTML.
@@ -12032,7 +11992,7 @@ client.unstable.companies.retrieve_company(
-**company_id:** `typing.Optional[str]` — The `company_id` of the company to filter by. +**state:** `typing.Optional[NewsItemRequestState]` — News items will not be visible to your users in the assigned newsfeeds until they are set live.
@@ -12040,7 +12000,7 @@ client.unstable.companies.retrieve_company(
-**tag_id:** `typing.Optional[str]` — The `tag_id` of the company to filter by. +**deliver_silently:** `typing.Optional[bool]` — When set to `true`, the news item will appear in the messenger newsfeed without showing a notification badge.
@@ -12048,7 +12008,7 @@ client.unstable.companies.retrieve_company(
-**segment_id:** `typing.Optional[str]` — The `segment_id` of the company to filter by. +**labels:** `typing.Optional[typing.Sequence[str]]` — Label names displayed to users to categorize the news item.
@@ -12056,7 +12016,7 @@ client.unstable.companies.retrieve_company(
-**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page +**reactions:** `typing.Optional[typing.Sequence[typing.Optional[str]]]` — Ordered list of emoji reactions to the news item. When empty, reactions are disabled.
@@ -12064,7 +12024,7 @@ client.unstable.companies.retrieve_company(
-**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15 +**newsfeed_assignments:** `typing.Optional[typing.Sequence[NewsfeedAssignment]]` — A list of newsfeed_assignments to assign to the specified newsfeed.
@@ -12084,7 +12044,7 @@ client.unstable.companies.retrieve_company(
-
client.unstable.companies.create_or_update_company(...) +
client.news.items.find(...)
@@ -12096,15 +12056,7 @@ client.unstable.companies.retrieve_company(
-You can create or update a company. - -Companies will be only visible in Intercom when there is at least one associated user. - -Companies are looked up via `company_id` in a `POST` request, if not found via `company_id`, the new company will be created, if found, that company will be updated. - -{% admonition type="warning" name="Using `company_id`" %} - You can set a unique `company_id` value when creating a company. However, it is not possible to update `company_id`. Be sure to set a unique value once upon creation of the company. -{% /admonition %} +You can fetch the details of a single news item.
@@ -12124,8 +12076,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.companies.create_or_update_company( - request={"key": "value"}, +client.news.items.find( + news_item_id=1, ) ``` @@ -12142,7 +12094,7 @@ client.unstable.companies.create_or_update_company(
-**request:** `typing.Optional[typing.Any]` +**news_item_id:** `int` — The unique identifier for the news item which is given by Intercom.
@@ -12162,11 +12114,11 @@ client.unstable.companies.create_or_update_company(
-
client.unstable.companies.retrieve_a_company_by_id(...) +
client.news.items.update(...)
-#### 📝 Description +#### 🔌 Usage
@@ -12174,13 +12126,27 @@ client.unstable.companies.create_or_update_company(
-You can fetch a single company. +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.news.items.update( + news_item_id=1, + title="Christmas is here!", + body="

New gifts in store for the jolly season

", + sender_id=991267848, + reactions=["😝", "😂"], +) + +```
-#### 🔌 Usage +#### ⚙️ Parameters
@@ -12188,31 +12154,71 @@ You can fetch a single company.
-```python -from intercom import Intercom +**news_item_id:** `int` — The unique identifier for the news item which is given by Intercom. + +
+
-client = Intercom( - token="YOUR_TOKEN", -) -client.unstable.companies.retrieve_a_company_by_id( - id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", -) +
+
-``` +**title:** `str` — The title of the news item. +
+ +
+
+ +**sender_id:** `int` — The id of the sender of the news item. Must be a teammate on the workspace. +
-#### ⚙️ Parameters +
+
+ +**body:** `typing.Optional[str]` — The news item body, which may contain HTML. + +
+
+ +
+
+ +**state:** `typing.Optional[NewsItemRequestState]` — News items will not be visible to your users in the assigned newsfeeds until they are set live. + +
+
+**deliver_silently:** `typing.Optional[bool]` — When set to `true`, the news item will appear in the messenger newsfeed without showing a notification badge. + +
+
+
-**id:** `str` — The unique identifier for the company which is given by Intercom +**labels:** `typing.Optional[typing.Sequence[str]]` — Label names displayed to users to categorize the news item. + +
+
+ +
+
+ +**reactions:** `typing.Optional[typing.Sequence[typing.Optional[str]]]` — Ordered list of emoji reactions to the news item. When empty, reactions are disabled. + +
+
+ +
+
+ +**newsfeed_assignments:** `typing.Optional[typing.Sequence[NewsfeedAssignment]]` — A list of newsfeed_assignments to assign to the specified newsfeed.
@@ -12232,7 +12238,7 @@ client.unstable.companies.retrieve_a_company_by_id(
-
client.unstable.companies.update_company(...) +
client.news.items.delete(...)
@@ -12244,11 +12250,7 @@ client.unstable.companies.retrieve_a_company_by_id(
-You can update a single company using the Intercom provisioned `id`. - -{% admonition type="warning" name="Using `company_id`" %} - When updating a company it is not possible to update `company_id`. This can only be set once upon creation of the company. -{% /admonition %} +You can delete a single news item.
@@ -12268,8 +12270,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.companies.update_company( - id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +client.news.items.delete( + news_item_id=1, ) ``` @@ -12286,7 +12288,7 @@ client.unstable.companies.update_company(
-**id:** `str` — The unique identifier for the company which is given by Intercom +**news_item_id:** `int` — The unique identifier for the news item which is given by Intercom.
@@ -12306,7 +12308,8 @@ client.unstable.companies.update_company(
-
client.unstable.companies.delete_company(...) +## News Feeds +
client.news.feeds.list_items(...)
@@ -12318,7 +12321,7 @@ client.unstable.companies.update_company(
-You can delete a single company. +You can fetch a list of all news items that are live on a given newsfeed
@@ -12338,8 +12341,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.companies.delete_company( - id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +client.news.feeds.list_items( + newsfeed_id="123", ) ``` @@ -12356,7 +12359,7 @@ client.unstable.companies.delete_company(
-**id:** `str` — The unique identifier for the company which is given by Intercom +**newsfeed_id:** `str` — The unique identifier for the news feed item which is given by Intercom.
@@ -12376,7 +12379,7 @@ client.unstable.companies.delete_company(
-
client.unstable.companies.list_attached_contacts(...) +
client.news.feeds.list()
@@ -12388,7 +12391,7 @@ client.unstable.companies.delete_company(
-You can fetch a list of all contacts that belong to a company. +You can fetch a list of all newsfeeds
@@ -12408,9 +12411,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.companies.list_attached_contacts( - id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", -) +client.news.feeds.list() ``` @@ -12426,14 +12427,6 @@ client.unstable.companies.list_attached_contacts(
-**id:** `str` — The unique identifier for the company which is given by Intercom - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -12446,7 +12439,7 @@ client.unstable.companies.list_attached_contacts(
-
client.unstable.companies.list_attached_segments_for_companies(...) +
client.news.feeds.find(...)
@@ -12458,7 +12451,7 @@ client.unstable.companies.list_attached_contacts(
-You can fetch a list of all segments that belong to a company. +You can fetch the details of a single newsfeed
@@ -12478,8 +12471,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.companies.list_attached_segments_for_companies( - id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +client.news.feeds.find( + newsfeed_id="123", ) ``` @@ -12496,7 +12489,7 @@ client.unstable.companies.list_attached_segments_for_companies(
-**id:** `str` — The unique identifier for the company which is given by Intercom +**newsfeed_id:** `str` — The unique identifier for the news feed item which is given by Intercom.
@@ -12516,7 +12509,8 @@ client.unstable.companies.list_attached_segments_for_companies(
-
client.unstable.companies.list_all_companies(...) +## TicketTypes Attributes +
client.ticket_types.attributes.create(...)
@@ -12528,15 +12522,7 @@ client.unstable.companies.list_attached_segments_for_companies(
-You can list companies. The company list is sorted by the `last_request_at` field and by default is ordered descending, most recently requested first. - -Note that the API does not include companies who have no associated users in list responses. - -When using the Companies endpoint and the pages object to iterate through the returned companies, there is a limit of 10,000 Companies that can be returned. If you need to list or iterate on more than 10,000 Companies, please use the [Scroll API](https://developers.intercom.com/reference#iterating-over-all-companies). -{% admonition type="warning" name="Pagination" %} - You can use pagination to limit the number of results returned. The default is `20` results per page. - See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. -{% /admonition %} +You can create a new attribute for a ticket type.
@@ -12556,8 +12542,12 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.companies.list_all_companies( - order="desc", +client.ticket_types.attributes.create( + ticket_type_id="ticket_type_id", + name="Attribute Title", + description="Attribute Description", + data_type="string", + required_to_create=False, ) ``` @@ -12574,7 +12564,7 @@ client.unstable.companies.list_all_companies(
-**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page +**ticket_type_id:** `str` — The unique identifier for the ticket type which is given by Intercom.
@@ -12582,7 +12572,7 @@ client.unstable.companies.list_all_companies(
-**per_page:** `typing.Optional[int]` — How many results to return per page. Defaults to 15 +**name:** `str` — The name of the ticket type attribute
@@ -12590,7 +12580,7 @@ client.unstable.companies.list_all_companies(
-**order:** `typing.Optional[str]` — `asc` or `desc`. Return the companies in ascending or descending order. Defaults to desc +**description:** `str` — The description of the attribute presented to the teammate or contact
@@ -12598,81 +12588,63 @@ client.unstable.companies.list_all_companies(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**data_type:** `CreateTicketTypeAttributeRequestDataType` — The data type of the attribute
- -
+
+
+**required_to_create:** `typing.Optional[bool]` — Whether the attribute is required to be filled in when teammates are creating the ticket in Inbox. +
-
-
client.unstable.companies.scroll_over_all_companies(...)
-#### 📝 Description - -
-
+**required_to_create_for_contacts:** `typing.Optional[bool]` — Whether the attribute is required to be filled in when contacts are creating the ticket in Messenger. + +
+
- The `list all companies` functionality does not work well for huge datasets, and can result in errors and performance problems when paging deeply. The Scroll API provides an efficient mechanism for iterating over all companies in a dataset. - -- Each app can only have 1 scroll open at a time. You'll get an error message if you try to have more than one open per app. -- If the scroll isn't used for 1 minute, it expires and calls with that scroll param will fail -- If the end of the scroll is reached, "companies" will be empty and the scroll parameter will expire - -{% admonition type="info" name="Scroll Parameter" %} - You can get the first page of companies by simply sending a GET request to the scroll endpoint. - For subsequent requests you will need to use the scroll parameter from the response. -{% /admonition %} -{% admonition type="danger" name="Scroll network timeouts" %} - Since scroll is often used on large datasets network errors such as timeouts can be encountered. When this occurs you will see a HTTP 500 error with the following message: - "Request failed due to an internal network error. Please restart the scroll operation." - If this happens, you will need to restart your scroll query: It is not possible to continue from a specific point when using scroll. -{% /admonition %} -
-
+**visible_on_create:** `typing.Optional[bool]` — Whether the attribute is visible to teammates when creating a ticket in Inbox. +
-#### 🔌 Usage -
+**visible_to_contacts:** `typing.Optional[bool]` — Whether the attribute is visible to contacts when creating a ticket in Messenger. + +
+
+
-```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.unstable.companies.scroll_over_all_companies() - -``` -
-
+**multiline:** `typing.Optional[bool]` — Whether the attribute allows multiple lines of text (only applicable to string attributes) + -#### ⚙️ Parameters -
+**list_items:** `typing.Optional[str]` — A comma delimited list of items for the attribute value (only applicable to list attributes) + +
+
+
-**scroll_param:** `typing.Optional[str]` — +**allow_multiple_values:** `typing.Optional[bool]` — Whether the attribute allows multiple files to be attached to it (only applicable to file attributes)
@@ -12692,7 +12664,7 @@ client.unstable.companies.scroll_over_all_companies()
-
client.unstable.companies.attach_contact_to_a_company(...) +
client.ticket_types.attributes.update(...)
@@ -12704,7 +12676,7 @@ client.unstable.companies.scroll_over_all_companies()
-You can attach a company to a single contact. +You can update an existing attribute for a ticket type.
@@ -12724,9 +12696,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.companies.attach_contact_to_a_company( - id="id", - company_id="123", +client.ticket_types.attributes.update( + ticket_type_id="ticket_type_id", + attribute_id="attribute_id", + description="New Attribute Description", ) ``` @@ -12743,7 +12716,7 @@ client.unstable.companies.attach_contact_to_a_company(
-**id:** `str` — The unique identifier for the contact which is given by Intercom +**ticket_type_id:** `str` — The unique identifier for the ticket type which is given by Intercom.
@@ -12751,7 +12724,7 @@ client.unstable.companies.attach_contact_to_a_company(
-**company_id:** `str` — The unique identifier for the company which is given by Intercom +**attribute_id:** `str` — The unique identifier for the ticket type attribute which is given by Intercom.
@@ -12759,70 +12732,71 @@ client.unstable.companies.attach_contact_to_a_company(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**name:** `typing.Optional[str]` — The name of the ticket type attribute
- -
+
+
+**description:** `typing.Optional[str]` — The description of the attribute presented to the teammate or contact +
-
-
client.unstable.companies.detach_contact_from_a_company(...)
-#### 📝 Description +**required_to_create:** `typing.Optional[bool]` — Whether the attribute is required to be filled in when teammates are creating the ticket in Inbox. + +
+
+**required_to_create_for_contacts:** `typing.Optional[bool]` — Whether the attribute is required to be filled in when contacts are creating the ticket in Messenger. + +
+
+
-You can detach a company from a single contact. -
-
+**visible_on_create:** `typing.Optional[bool]` — Whether the attribute is visible to teammates when creating a ticket in Inbox. + -#### 🔌 Usage -
+**visible_to_contacts:** `typing.Optional[bool]` — Whether the attribute is visible to contacts when creating a ticket in Messenger. + +
+
+
-```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.unstable.companies.detach_contact_from_a_company( - contact_id="58a430d35458202d41b1e65b", - id="58a430d35458202d41b1e65b", -) - -``` -
-
+**multiline:** `typing.Optional[bool]` — Whether the attribute allows multiple lines of text (only applicable to string attributes) + -#### ⚙️ Parameters -
+**list_items:** `typing.Optional[str]` — A comma delimited list of items for the attribute value (only applicable to list attributes) + +
+
+
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**allow_multiple_values:** `typing.Optional[bool]` — Whether the attribute allows multiple files to be attached to it (only applicable to file attributes)
@@ -12830,7 +12804,7 @@ client.unstable.companies.detach_contact_from_a_company(
-**id:** `str` — The unique identifier for the company which is given by Intercom +**archived:** `typing.Optional[bool]` — Whether the attribute should be archived and not shown during creation of the ticket (it will still be present on previously created tickets)
@@ -12850,8 +12824,8 @@ client.unstable.companies.detach_contact_from_a_company(
-## Contacts -
client.unstable.contacts.list_companies_for_a_contact(...) +## Admins +
client.unstable.admins.identify_admin()
@@ -12863,7 +12837,12 @@ client.unstable.companies.detach_contact_from_a_company(
-You can fetch a list of companies that are associated to a contact. + +You can view the currently authorised admin along with the embedded app object (a "workspace" in legacy terminology). + +> 🚧 Single Sign On +> +> If you are building a custom "Log in with Intercom" flow for your site, and you call the `/me` endpoint to identify the logged-in user, you should not accept any sign-ins from users with unverified email addresses as it poses a potential impersonation security risk.
@@ -12883,9 +12862,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.list_companies_for_a_contact( - id="63a07ddf05a32042dffac965", -) +client.unstable.admins.identify_admin() ``` @@ -12901,14 +12878,6 @@ client.unstable.contacts.list_companies_for_a_contact(
-**id:** `str` — The unique identifier for the contact which is given by Intercom - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -12921,7 +12890,7 @@ client.unstable.contacts.list_companies_for_a_contact(
-
client.unstable.contacts.list_segments_for_a_contact(...) +
client.unstable.admins.set_away_admin(...)
@@ -12933,7 +12902,7 @@ client.unstable.contacts.list_companies_for_a_contact(
-You can fetch a list of segments that are associated to a contact. +You can set an Admin as away for the Inbox.
@@ -12953,8 +12922,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.list_segments_for_a_contact( - contact_id="63a07ddf05a32042dffac965", +client.unstable.admins.set_away_admin( + id=1, + away_mode_enabled=True, + away_mode_reassign=True, ) ``` @@ -12971,7 +12942,31 @@ client.unstable.contacts.list_segments_for_a_contact(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**id:** `int` — The unique identifier of a given admin + +
+
+ +
+
+ +**away_mode_enabled:** `bool` — Set to "true" to change the status of the admin to away. + +
+
+ +
+
+ +**away_mode_reassign:** `bool` — Set to "true" to assign any new conversation replies to your default inbox. + +
+
+ +
+
+ +**away_status_reason_id:** `typing.Optional[int]` — The unique identifier of the away status reason
@@ -12991,7 +12986,7 @@ client.unstable.contacts.list_segments_for_a_contact(
-
client.unstable.contacts.list_subscriptions_for_a_contact(...) +
client.unstable.admins.list_activity_logs(...)
@@ -13003,13 +12998,7 @@ client.unstable.contacts.list_segments_for_a_contact(
-You can fetch a list of subscription types that are attached to a contact. These can be subscriptions that a user has 'opted-in' to or has 'opted-out' from, depending on the subscription type. -This will return a list of Subscription Type objects that the contact is associated with. - -The data property will show a combined list of: - - 1.Opt-out subscription types that the user has opted-out from. - 2.Opt-in subscription types that the user has opted-in to receiving. +You can get a log of activities by all admins in an app.
@@ -13029,8 +13018,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.list_subscriptions_for_a_contact( - contact_id="63a07ddf05a32042dffac965", +client.unstable.admins.list_activity_logs( + created_at_after="1677253093", + created_at_before="1677861493", ) ``` @@ -13047,7 +13037,15 @@ client.unstable.contacts.list_subscriptions_for_a_contact(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**created_at_after:** `str` — The start date that you request data for. It must be formatted as a UNIX timestamp. + +
+
+ +
+
+ +**created_at_before:** `typing.Optional[str]` — The end date that you request data for. It must be formatted as a UNIX timestamp.
@@ -13067,7 +13065,7 @@ client.unstable.contacts.list_subscriptions_for_a_contact(
-
client.unstable.contacts.list_tags_for_a_contact(...) +
client.unstable.admins.list_admins()
@@ -13079,7 +13077,7 @@ client.unstable.contacts.list_subscriptions_for_a_contact(
-You can fetch a list of all tags that are attached to a specific contact. +You can fetch a list of admins for a given workspace.
@@ -13099,9 +13097,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.list_tags_for_a_contact( - contact_id="63a07ddf05a32042dffac965", -) +client.unstable.admins.list_admins() ``` @@ -13117,14 +13113,6 @@ client.unstable.contacts.list_tags_for_a_contact(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -13137,7 +13125,7 @@ client.unstable.contacts.list_tags_for_a_contact(
-
client.unstable.contacts.show_contact(...) +
client.unstable.admins.retrieve_admin(...)
@@ -13149,7 +13137,7 @@ client.unstable.contacts.list_tags_for_a_contact(
-You can fetch the details of a single contact. +You can retrieve the details of a single admin.
@@ -13169,8 +13157,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.show_contact( - id="63a07ddf05a32042dffac965", +client.unstable.admins.retrieve_admin( + id=1, ) ``` @@ -13187,7 +13175,7 @@ client.unstable.contacts.show_contact(
-**id:** `str` — id +**id:** `int` — The unique identifier of a given admin
@@ -13207,7 +13195,8 @@ client.unstable.contacts.show_contact(
-
client.unstable.contacts.update_contact(...) +## AI Content +
client.unstable.ai_content.list_content_import_sources()
@@ -13219,13 +13208,7 @@ client.unstable.contacts.show_contact(
-You can update an existing contact (ie. user or lead). - -{% admonition type="info" %} - This endpoint handles both **contact updates** and **custom object associations**. - - See _`update a contact with an association to a custom object instance`_ in the request/response examples to see the custom object association format. -{% /admonition %} +You can retrieve a list of all content import sources for a workspace.
@@ -13245,10 +13228,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.update_contact( - id="63a07ddf05a32042dffac965", - custom_attributes={"order": ["21"]}, -) +client.unstable.ai_content.list_content_import_sources() ``` @@ -13264,87 +13244,69 @@ client.unstable.contacts.update_contact(
-**id:** `str` — id +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
- -
-
- -**role:** `typing.Optional[str]` — The role of the contact. -
-
-
-**external_id:** `typing.Optional[str]` — A unique identifier for the contact which is given to Intercom -
+
+
client.unstable.ai_content.create_content_import_source(...)
-**email:** `typing.Optional[str]` — The contacts email - -
-
+#### 📝 Description
-**phone:** `typing.Optional[str]` — The contacts phone - -
-
-
-**name:** `typing.Optional[str]` — The contacts name - +You can create a new content import source by sending a POST request to this endpoint.
- -
-
- -**avatar:** `typing.Optional[str]` — An image URL containing the avatar of a contact -
+#### 🔌 Usage +
-**signed_up_at:** `typing.Optional[int]` — The time specified for when a contact signed up - -
-
-
-**last_seen_at:** `typing.Optional[int]` — The time when the contact was last seen (either where the Intercom Messenger was installed or when specified manually) - +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.ai_content.create_content_import_source( + url="https://www.example.com", +) + +``` +
+
+#### ⚙️ Parameters +
-**owner_id:** `typing.Optional[int]` — The id of an admin that has been assigned account ownership of the contact - -
-
-
-**unsubscribed_from_emails:** `typing.Optional[bool]` — Whether the contact is unsubscribed from emails +**url:** `str` — The URL of the content import source.
@@ -13352,7 +13314,7 @@ client.unstable.contacts.update_contact(
-**custom_attributes:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — The custom attributes which are set for the contact +**status:** `typing.Optional[CreateContentImportSourceRequestStatus]` — The status of the content import source.
@@ -13372,24 +13334,10 @@ client.unstable.contacts.update_contact(
-
client.unstable.contacts.delete_contact(...) -
-
- -#### 📝 Description - -
-
- +
client.unstable.ai_content.get_content_import_source(...)
-You can delete a single contact. -
-
-
-
- #### 🔌 Usage
@@ -13404,7 +13352,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.delete_contact( +client.unstable.ai_content.get_content_import_source( id="id", ) @@ -13422,7 +13370,7 @@ client.unstable.contacts.delete_contact(
-**id:** `str` — id +**id:** `str` — The unique identifier for the content import source which is given by Intercom.
@@ -13442,7 +13390,7 @@ client.unstable.contacts.delete_contact(
-
client.unstable.contacts.merge_contact(...) +
client.unstable.ai_content.update_content_import_source(...)
@@ -13454,7 +13402,7 @@ client.unstable.contacts.delete_contact(
-You can merge a contact with a `role` of `lead` into a contact with a `role` of `user`. +You can update an existing content import source.
@@ -13474,9 +13422,10 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.merge_contact( - from_="6762f0d51bb69f9f2193bb7f", - into="6762f0d51bb69f9f2193bb80", +client.unstable.ai_content.update_content_import_source( + id="id", + sync_behavior="api", + url="https://www.example.com", ) ``` @@ -13493,7 +13442,7 @@ client.unstable.contacts.merge_contact(
-**from_:** `typing.Optional[str]` — The unique identifier for the contact to merge away from. Must be a lead. +**id:** `str` — The unique identifier for the content import source which is given by Intercom.
@@ -13501,7 +13450,23 @@ client.unstable.contacts.merge_contact(
-**into:** `typing.Optional[str]` — The unique identifier for the contact to merge into. Must be a user. +**sync_behavior:** `UpdateContentImportSourceRequestSyncBehavior` — If you intend to create or update External Pages via the API, this should be set to `api`. You can not change the value to or from api. + +
+
+ +
+
+ +**url:** `str` — The URL of the content import source. This may only be different from the existing value if the sync behavior is API. + +
+
+ +
+
+ +**status:** `typing.Optional[UpdateContentImportSourceRequestStatus]` — The status of the content import source.
@@ -13521,7 +13486,7 @@ client.unstable.contacts.merge_contact(
-
client.unstable.contacts.search_contacts(...) +
client.unstable.ai_content.delete_content_import_source(...)
@@ -13533,106 +13498,7 @@ client.unstable.contacts.merge_contact(
-You can search for multiple contacts by the value of their attributes in order to fetch exactly who you want. - -To search for contacts, you need to send a `POST` request to `https://api.intercom.io/contacts/search`. - -This will accept a query object in the body which will define your filters in order to search for contacts. - -{% admonition type="warning" name="Optimizing search queries" %} - Search queries can be complex, so optimizing them can help the performance of your search. - Use the `AND` and `OR` operators to combine multiple filters to get the exact results you need and utilize - pagination to limit the number of results returned. The default is `50` results per page. - See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#example-search-conversations-request) for more details on how to use the `starting_after` param. -{% /admonition %} -### Contact Creation Delay - -If a contact has recently been created, there is a possibility that it will not yet be available when searching. This means that it may not appear in the response. This delay can take a few minutes. If you need to be instantly notified it is recommended to use webhooks and iterate to see if they match your search filters. - -### Nesting & Limitations - -You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4). -There are some limitations to the amount of multiple's there can be: -* There's a limit of max 2 nested filters -* There's a limit of max 15 filters for each AND or OR group - -### Searching for Timestamp Fields - -All timestamp fields (created_at, updated_at etc.) are indexed as Dates for Contact Search queries; Datetime queries are not currently supported. This means you can only query for timestamp fields by day - not hour, minute or second. -For example, if you search for all Contacts with a created_at value greater (>) than 1577869200 (the UNIX timestamp for January 1st, 2020 9:00 AM), that will be interpreted as 1577836800 (January 1st, 2020 12:00 AM). The search results will then include Contacts created from January 2nd, 2020 12:00 AM onwards. -If you'd like to get contacts created on January 1st, 2020 you should search with a created_at value equal (=) to 1577836800 (January 1st, 2020 12:00 AM). -This behaviour applies only to timestamps used in search queries. The search results will still contain the full UNIX timestamp and be sorted accordingly. - -### Accepted Fields - -Most key listed as part of the Contacts Model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). - -| Field | Type | -| ---------------------------------- | ------------------------------ | -| id | String | -| role | String
Accepts user or lead | -| name | String | -| avatar | String | -| owner_id | Integer | -| email | String | -| email_domain | String | -| phone | String | -| formatted_phone | String | -| external_id | String | -| created_at | Date (UNIX Timestamp) | -| signed_up_at | Date (UNIX Timestamp) | -| updated_at | Date (UNIX Timestamp) | -| last_seen_at | Date (UNIX Timestamp) | -| last_contacted_at | Date (UNIX Timestamp) | -| last_replied_at | Date (UNIX Timestamp) | -| last_email_opened_at | Date (UNIX Timestamp) | -| last_email_clicked_at | Date (UNIX Timestamp) | -| language_override | String | -| browser | String | -| browser_language | String | -| os | String | -| location.country | String | -| location.region | String | -| location.city | String | -| unsubscribed_from_emails | Boolean | -| marked_email_as_spam | Boolean | -| has_hard_bounced | Boolean | -| ios_last_seen_at | Date (UNIX Timestamp) | -| ios_app_version | String | -| ios_device | String | -| ios_app_device | String | -| ios_os_version | String | -| ios_app_name | String | -| ios_sdk_version | String | -| android_last_seen_at | Date (UNIX Timestamp) | -| android_app_version | String | -| android_device | String | -| android_app_name | String | -| andoid_sdk_version | String | -| segment_id | String | -| tag_id | String | -| custom_attributes.{attribute_name} | String | - -### Accepted Operators - -{% admonition type="warning" name="Searching based on `created_at`" %} - You cannot use the `<=` or `>=` operators to search by `created_at`. -{% /admonition %} - -The table below shows the operators you can use to define how you want to search for the value. The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates). - -| Operator | Valid Types | Description | -| :------- | :------------------------------- | :--------------------------------------------------------------- | -| = | All | Equals | -| != | All | Doesn't Equal | -| IN | All | In
Shortcut for `OR` queries
Values must be in Array | -| NIN | All | Not In
Shortcut for `OR !` queries
Values must be in Array | -| > | Integer
Date (UNIX Timestamp) | Greater than | -| < | Integer
Date (UNIX Timestamp) | Lower than | -| ~ | String | Contains | -| !~ | String | Doesn't Contain | -| ^ | String | Starts With | -| $ | String | Ends With | +You can delete a content import source by making a DELETE request this endpoint. This will also delete all external pages that were imported from this source.
@@ -13648,29 +13514,12 @@ The table below shows the operators you can use to define how you want to search ```python from intercom import Intercom -from intercom.unstable import ( - MultipleFilterSearchRequest, - SingleFilterSearchRequest, - StartingAfterPaging, -) client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.search_contacts( - query=MultipleFilterSearchRequest( - operator="AND", - value=[ - SingleFilterSearchRequest( - field="created_at", - operator=">", - value="1306054154", - ) - ], - ), - pagination=StartingAfterPaging( - per_page=5, - ), +client.unstable.ai_content.delete_content_import_source( + id="id", ) ``` @@ -13687,15 +13536,7 @@ client.unstable.contacts.search_contacts(
-**query:** `SearchRequestQuery` - -
-
- -
-
- -**pagination:** `typing.Optional[StartingAfterPaging]` +**id:** `str` — The unique identifier for the content import source which is given by Intercom.
@@ -13715,7 +13556,7 @@ client.unstable.contacts.search_contacts(
-
client.unstable.contacts.list_contacts() +
client.unstable.ai_content.list_external_pages()
@@ -13727,11 +13568,7 @@ client.unstable.contacts.search_contacts(
-You can fetch a list of all contacts (ie. users or leads) in your workspace. -{% admonition type="warning" name="Pagination" %} - You can use pagination to limit the number of results returned. The default is `50` results per page. - See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. -{% /admonition %} +You can retrieve a list of all external pages for a workspace.
@@ -13751,7 +13588,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.list_contacts() +client.unstable.ai_content.list_external_pages() ``` @@ -13779,7 +13616,7 @@ client.unstable.contacts.list_contacts()
-
client.unstable.contacts.create_contact(...) +
client.unstable.ai_content.create_external_page(...)
@@ -13791,7 +13628,7 @@ client.unstable.contacts.list_contacts()
-You can create a new contact (ie. user or lead). +You can create a new external page by sending a POST request to this endpoint. If an external page already exists with the specified source_id and external_id, it will be updated instead.
@@ -13811,8 +13648,12 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.create_contact( - request={"email": "joebloggs@intercom.io"}, +client.unstable.ai_content.create_external_page( + title="Test", + html="

Test

", + url="https://www.example.com", + source_id=44, + external_id="abc1234", ) ``` @@ -13829,7 +13670,55 @@ client.unstable.contacts.create_contact(
-**request:** `CreateContactRequestTwo` +**title:** `str` — The title of the external page. + +
+
+ +
+
+ +**html:** `str` — The body of the external page in HTML. + +
+
+ +
+
+ +**source_id:** `int` — The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. + +
+
+ +
+
+ +**external_id:** `str` — The identifier for the external page which was given by the source. Must be unique for the source. + +
+
+ +
+
+ +**url:** `typing.Optional[str]` — The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. When a URL is not present, Fin will not reference the source. + +
+
+ +
+
+ +**ai_agent_availability:** `typing.Optional[bool]` — Whether the external page should be used to answer questions by AI Agent. Will not default when updating an existing external page. + +
+
+ +
+
+ +**ai_copilot_availability:** `typing.Optional[bool]` — Whether the external page should be used to answer questions by AI Copilot. Will not default when updating an existing external page.
@@ -13849,7 +13738,7 @@ client.unstable.contacts.create_contact(
-
client.unstable.contacts.show_contact_by_external_id(...) +
client.unstable.ai_content.get_external_page(...)
@@ -13861,7 +13750,7 @@ client.unstable.contacts.create_contact(
-You can fetch the details of a single contact by external ID. Note that this endpoint only supports users and not leads. +You can retrieve an external page.
@@ -13881,8 +13770,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.show_contact_by_external_id( - external_id="cdd29344-5e0c-4ef0-ac56-f9ba2979bc27", +client.unstable.ai_content.get_external_page( + id="id", ) ``` @@ -13899,7 +13788,7 @@ client.unstable.contacts.show_contact_by_external_id(
-**external_id:** `str` — The external ID of the user that you want to retrieve +**id:** `str` — The unique identifier for the external page which is given by Intercom.
@@ -13919,7 +13808,7 @@ client.unstable.contacts.show_contact_by_external_id(
-
client.unstable.contacts.archive_contact(...) +
client.unstable.ai_content.update_external_page(...)
@@ -13931,7 +13820,7 @@ client.unstable.contacts.show_contact_by_external_id(
-You can archive a single contact. +You can update an existing external page (if it was created via the API).
@@ -13951,8 +13840,13 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.archive_contact( - id="63a07ddf05a32042dffac965", +client.unstable.ai_content.update_external_page( + id="id", + title="Test", + html="

Test

", + url="https://www.example.com", + source_id=47, + external_id="5678", ) ``` @@ -13969,7 +13863,55 @@ client.unstable.contacts.archive_contact(
-**id:** `str` — id +**id:** `str` — The unique identifier for the external page which is given by Intercom. + +
+
+ +
+
+ +**title:** `str` — The title of the external page. + +
+
+ +
+
+ +**html:** `str` — The body of the external page in HTML. + +
+
+ +
+
+ +**url:** `str` — The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. + +
+
+ +
+
+ +**source_id:** `int` — The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. + +
+
+ +
+
+ +**fin_availability:** `typing.Optional[bool]` — Whether the external page should be used to answer questions by Fin. + +
+
+ +
+
+ +**external_id:** `typing.Optional[str]` — The identifier for the external page which was given by the source. Must be unique for the source.
@@ -13989,7 +13931,7 @@ client.unstable.contacts.archive_contact(
-
client.unstable.contacts.unarchive_contact(...) +
client.unstable.ai_content.delete_external_page(...)
@@ -14001,7 +13943,7 @@ client.unstable.contacts.archive_contact(
-You can unarchive a single contact. +Sending a DELETE request for an external page will remove it from the content library UI and from being used for AI answers.
@@ -14021,8 +13963,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.unarchive_contact( - id="63a07ddf05a32042dffac965", +client.unstable.ai_content.delete_external_page( + id="id", ) ``` @@ -14039,7 +13981,7 @@ client.unstable.contacts.unarchive_contact(
-**id:** `str` — id +**id:** `str` — The unique identifier for the external page which is given by Intercom.
@@ -14059,7 +14001,8 @@ client.unstable.contacts.unarchive_contact(
-
client.unstable.contacts.block_contact(...) +## Articles +
client.unstable.articles.list_articles()
@@ -14071,7 +14014,11 @@ client.unstable.contacts.unarchive_contact(
-Block a single contact.
**Note:** conversations of the contact will also be archived during the process.
More details in [FAQ How do I block Inbox spam?](https://www.intercom.com/help/en/articles/8838656-inbox-faqs) +You can fetch a list of all articles by making a GET request to `https://api.intercom.io/articles`. + +> 📘 How are the articles sorted and ordered? +> +> Articles will be returned in descending order on the `updated_at` attribute. This means if you need to iterate through results then we'll show the most recently updated articles first.
@@ -14091,9 +14038,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.contacts.block_contact( - id="63a07ddf05a32042dffac965", -) +client.unstable.articles.list_articles() ``` @@ -14109,14 +14054,6 @@ client.unstable.contacts.block_contact(
-**id:** `str` — id - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -14129,8 +14066,7 @@ client.unstable.contacts.block_contact(
-## Notes -
client.unstable.notes.list_notes(...) +
client.unstable.articles.create_article(...)
@@ -14142,7 +14078,7 @@ client.unstable.contacts.block_contact(
-You can fetch a list of notes that are associated to a contact. +You can create a new article by making a POST request to `https://api.intercom.io/articles`.
@@ -14162,8 +14098,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.notes.list_notes( - id=1, +client.unstable.articles.create_article( + request={"key": "value"}, ) ``` @@ -14180,7 +14116,7 @@ client.unstable.notes.list_notes(
-**id:** `int` — The unique identifier of a contact. +**request:** `typing.Optional[typing.Any]`
@@ -14200,7 +14136,7 @@ client.unstable.notes.list_notes(
-
client.unstable.notes.create_note(...) +
client.unstable.articles.retrieve_article(...)
@@ -14212,7 +14148,7 @@ client.unstable.notes.list_notes(
-You can add a note to a single contact. +You can fetch the details of a single article by making a GET request to `https://api.intercom.io/articles/`.
@@ -14232,11 +14168,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.notes.create_note( +client.unstable.articles.retrieve_article( id=1, - body="Hello", - contact_id="123", - admin_id="123", ) ``` @@ -14253,31 +14186,7 @@ client.unstable.notes.create_note(
-**id:** `int` — The unique identifier of a given contact. - -
-
- -
-
- -**body:** `str` — The text of the note. - -
-
- -
-
- -**contact_id:** `typing.Optional[str]` — The unique identifier of a given contact. - -
-
- -
-
- -**admin_id:** `typing.Optional[str]` — The unique identifier of a given admin. +**id:** `int` — The unique identifier for the article which is given by Intercom.
@@ -14297,7 +14206,7 @@ client.unstable.notes.create_note(
-
client.unstable.notes.retrieve_note(...) +
client.unstable.articles.delete_article(...)
@@ -14309,7 +14218,7 @@ client.unstable.notes.create_note(
-You can fetch the details of a single note. +You can delete a single article by making a DELETE request to `https://api.intercom.io/articles/`.
@@ -14329,7 +14238,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.notes.retrieve_note( +client.unstable.articles.delete_article( id=1, ) @@ -14347,7 +14256,7 @@ client.unstable.notes.retrieve_note(
-**id:** `int` — The unique identifier of a given note +**id:** `int` — The unique identifier for the article which is given by Intercom.
@@ -14367,8 +14276,7 @@ client.unstable.notes.retrieve_note(
-## Subscription Types -
client.unstable.subscription_types.attach_subscription_type_to_contact(...) +
client.unstable.articles.search_articles(...)
@@ -14380,13 +14288,7 @@ client.unstable.notes.retrieve_note(
-You can add a specific subscription to a contact. In Intercom, we have two different subscription types based on user consent - opt-out and opt-in: - - 1.Attaching a contact to an opt-out subscription type will opt that user out from receiving messages related to that subscription type. - - 2.Attaching a contact to an opt-in subscription type will opt that user in to receiving messages related to that subscription type. - -This will return a subscription type model for the subscription type that was added to the contact. +You can search for articles by making a GET request to `https://api.intercom.io/articles/search`.
@@ -14406,10 +14308,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.subscription_types.attach_subscription_type_to_contact( - contact_id="63a07ddf05a32042dffac965", - id="invalid_id", - consent_type="opt_in", +client.unstable.articles.search_articles( + phrase="Getting started", + state="published", ) ``` @@ -14426,7 +14327,7 @@ client.unstable.subscription_types.attach_subscription_type_to_contact(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**phrase:** `typing.Optional[str]` — The phrase within your articles to search for.
@@ -14434,7 +14335,7 @@ client.unstable.subscription_types.attach_subscription_type_to_contact(
-**id:** `str` — The unique identifier for the subscription which is given by Intercom +**state:** `typing.Optional[str]` — The state of the Articles returned. One of `published`, `draft` or `all`.
@@ -14442,7 +14343,7 @@ client.unstable.subscription_types.attach_subscription_type_to_contact(
-**consent_type:** `str` — The consent_type of a subscription, opt_out or opt_in. +**help_center_id:** `typing.Optional[int]` — The ID of the Help Center to search in.
@@ -14450,11 +14351,19 @@ client.unstable.subscription_types.attach_subscription_type_to_contact(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**highlight:** `typing.Optional[bool]` — Return a highlighted version of the matching content within your articles. Refer to the response schema for more details.
- + +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
@@ -14462,7 +14371,8 @@ client.unstable.subscription_types.attach_subscription_type_to_contact(
-
client.unstable.subscription_types.detach_subscription_type_to_contact(...) +## Away Status Reasons +
client.unstable.away_status_reasons.list_away_status_reasons()
@@ -14474,7 +14384,7 @@ client.unstable.subscription_types.attach_subscription_type_to_contact(
-You can remove a specific subscription from a contact. This will return a subscription type model for the subscription type that was removed from the contact. +Returns a list of all away status reasons configured for the workspace, including deleted ones.
@@ -14494,10 +14404,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.subscription_types.detach_subscription_type_to_contact( - contact_id="63a07ddf05a32042dffac965", - id="37846", -) +client.unstable.away_status_reasons.list_away_status_reasons() ``` @@ -14513,51 +14420,105 @@ client.unstable.subscription_types.detach_subscription_type_to_contact(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
+ + + + +
+## Unstable Export +
client.unstable.export.enqueue_a_new_reporting_data_export_job(...)
-**id:** `str` — The unique identifier for the subscription type which is given by Intercom - +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.export.enqueue_a_new_reporting_data_export_job( + dataset_id="conversation", + attribute_ids=["conversation_id", "conversation_started_at"], + start_time=1717490000, + end_time=1717510000, +) + +``` +
+
+#### ⚙️ Parameters +
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +
+
+ +**dataset_id:** `str`
-
-
+
+
+**attribute_ids:** `typing.Sequence[str]` +
-
-
client.unstable.subscription_types.list_subscription_types()
-#### 📝 Description +**start_time:** `int` + +
+
+**end_time:** `int` + +
+
+
-You can list all subscription types. A list of subscription type objects will be returned. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+ + +
+ +
client.unstable.export.list_available_datasets_and_attributes() +
+
#### 🔌 Usage @@ -14573,7 +14534,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.subscription_types.list_subscription_types() +client.unstable.export.list_available_datasets_and_attributes() ```
@@ -14601,8 +14562,8 @@ client.unstable.subscription_types.list_subscription_types()
-## Tags -
client.unstable.tags.attach_tag_to_contact(...) +## Help Center +
client.unstable.help_center.list_all_collections()
@@ -14614,7 +14575,9 @@ client.unstable.subscription_types.list_subscription_types()
-You can tag a specific contact. This will return a tag object for the tag that was added to the contact. +You can fetch a list of all collections by making a GET request to `https://api.intercom.io/help_center/collections`. + +Collections will be returned in descending order on the `updated_at` attribute. This means if you need to iterate through results then we'll show the most recently updated collections first.
@@ -14634,10 +14597,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.tags.attach_tag_to_contact( - contact_id="63a07ddf05a32042dffac965", - id="123", -) +client.unstable.help_center.list_all_collections() ``` @@ -14653,22 +14613,6 @@ client.unstable.tags.attach_tag_to_contact(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom - -
-
- -
-
- -**id:** `str` — The unique identifier for the tag which is given by Intercom - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -14681,7 +14625,7 @@ client.unstable.tags.attach_tag_to_contact(
-
client.unstable.tags.detach_tag_from_contact(...) +
client.unstable.help_center.create_collection(...)
@@ -14693,7 +14637,7 @@ client.unstable.tags.attach_tag_to_contact(
-You can remove tag from a specific contact. This will return a tag object for the tag that was removed from the contact. +You can create a new collection by making a POST request to `https://api.intercom.io/help_center/collections.`
@@ -14713,9 +14657,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.tags.detach_tag_from_contact( - contact_id="63a07ddf05a32042dffac965", - id="7522907", +client.unstable.help_center.create_collection( + name="collection 51", + description="Missing required parameter", ) ``` @@ -14732,7 +14676,7 @@ client.unstable.tags.detach_tag_from_contact(
-**contact_id:** `str` — The unique identifier for the contact which is given by Intercom +**name:** `str` — The name of the collection. For multilingual collections, this will be the name of the default language's content.
@@ -14740,7 +14684,31 @@ client.unstable.tags.detach_tag_from_contact(
-**id:** `str` — The unique identifier for the tag which is given by Intercom +**description:** `typing.Optional[str]` — The description of the collection. For multilingual collections, this will be the description of the default language's content. + +
+
+ +
+
+ +**translated_content:** `typing.Optional[GroupTranslatedContent]` + +
+
+ +
+
+ +**parent_id:** `typing.Optional[str]` — The id of the parent collection. If `null` then it will be created as the first level collection. + +
+
+ +
+
+ +**help_center_id:** `typing.Optional[int]` — The id of the help center where the collection will be created. If `null` then it will be created in the default help center.
@@ -14760,7 +14728,7 @@ client.unstable.tags.detach_tag_from_contact(
-
client.unstable.tags.attach_tag_to_conversation(...) +
client.unstable.help_center.retrieve_collection(...)
@@ -14772,7 +14740,7 @@ client.unstable.tags.detach_tag_from_contact(
-You can tag a specific conversation. This will return a tag object for the tag that was added to the conversation. +You can fetch the details of a single collection by making a GET request to `https://api.intercom.io/help_center/collections/`.
@@ -14792,10 +14760,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.tags.attach_tag_to_conversation( - conversation_id="64619700005694", - id="7522907", - admin_id="780", +client.unstable.help_center.retrieve_collection( + id=1, ) ``` @@ -14812,23 +14778,7 @@ client.unstable.tags.attach_tag_to_conversation(
-**conversation_id:** `str` — conversation_id - -
-
- -
-
- -**id:** `str` — The unique identifier for the tag which is given by Intercom - -
-
- -
-
- -**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. +**id:** `int` — The unique identifier for the collection which is given by Intercom.
@@ -14848,7 +14798,7 @@ client.unstable.tags.attach_tag_to_conversation(
-
client.unstable.tags.detach_tag_from_conversation(...) +
client.unstable.help_center.update_collection(...)
@@ -14860,7 +14810,7 @@ client.unstable.tags.attach_tag_to_conversation(
-You can remove tag from a specific conversation. This will return a tag object for the tag that was removed from the conversation. +You can update the details of a single collection by making a PUT request to `https://api.intercom.io/collections/`.
@@ -14880,10 +14830,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.tags.detach_tag_from_conversation( - conversation_id="64619700005694", - id="7522907", - admin_id="123", +client.unstable.help_center.update_collection( + id=1, + name="Update collection name", ) ``` @@ -14900,7 +14849,7 @@ client.unstable.tags.detach_tag_from_conversation(
-**conversation_id:** `str` — conversation_id +**id:** `int` — The unique identifier for the collection which is given by Intercom.
@@ -14908,7 +14857,7 @@ client.unstable.tags.detach_tag_from_conversation(
-**id:** `str` — id +**name:** `typing.Optional[str]` — The name of the collection. For multilingual collections, this will be the name of the default language's content.
@@ -14916,7 +14865,23 @@ client.unstable.tags.detach_tag_from_conversation(
-**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. +**description:** `typing.Optional[str]` — The description of the collection. For multilingual collections, this will be the description of the default language's content. + +
+
+ +
+
+ +**translated_content:** `typing.Optional[GroupTranslatedContent]` + +
+
+ +
+
+ +**parent_id:** `typing.Optional[str]` — The id of the parent collection. If `null` then it will be updated as the first level collection.
@@ -14936,7 +14901,7 @@ client.unstable.tags.detach_tag_from_conversation(
-
client.unstable.tags.list_tags() +
client.unstable.help_center.delete_collection(...)
@@ -14948,7 +14913,7 @@ client.unstable.tags.detach_tag_from_conversation(
-You can fetch a list of all tags for a given workspace. +You can delete a single collection by making a DELETE request to `https://api.intercom.io/collections/`.
@@ -14968,7 +14933,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.tags.list_tags() +client.unstable.help_center.delete_collection( + id=1, +) ``` @@ -14984,6 +14951,14 @@ client.unstable.tags.list_tags()
+**id:** `int` — The unique identifier for the collection which is given by Intercom. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -14996,7 +14971,7 @@ client.unstable.tags.list_tags()
-
client.unstable.tags.create_tag(...) +
client.unstable.help_center.retrieve_help_center(...)
@@ -15008,19 +14983,7 @@ client.unstable.tags.list_tags()
-You can use this endpoint to perform the following operations: - - **1. Create a new tag:** You can create a new tag by passing in the tag name as specified in "Create or Update Tag Request Payload" described below. - - **2. Update an existing tag:** You can update an existing tag by passing the id of the tag as specified in "Create or Update Tag Request Payload" described below. - - **3. Tag Companies:** You can tag single company or a list of companies. You can tag a company by passing in the tag name and the company details as specified in "Tag Company Request Payload" described below. Also, if the tag doesn't exist then a new one will be created automatically. - - **4. Untag Companies:** You can untag a single company or a list of companies. You can untag a company by passing in the tag id and the company details as specified in "Untag Company Request Payload" described below. - - **5. Tag Multiple Users:** You can tag a list of users. You can tag the users by passing in the tag name and the user details as specified in "Tag Users Request Payload" described below. - -Each operation will return a tag object. +You can fetch the details of a single Help Center by making a GET request to `https://api.intercom.io/help_center/help_center/`.
@@ -15036,23 +14999,12 @@ Each operation will return a tag object. ```python from intercom import Intercom -from intercom.unstable import ( - TagMultipleUsersRequest, - TagMultipleUsersRequestUsersItem, -) client = Intercom( token="YOUR_TOKEN", ) -client.unstable.tags.create_tag( - request=TagMultipleUsersRequest( - name="test", - users=[ - TagMultipleUsersRequestUsersItem( - id="123", - ) - ], - ), +client.unstable.help_center.retrieve_help_center( + id=1, ) ``` @@ -15069,7 +15021,7 @@ client.unstable.tags.create_tag(
-**request:** `CreateTagRequestBody` +**id:** `int` — The unique identifier for the collection which is given by Intercom.
@@ -15089,7 +15041,7 @@ client.unstable.tags.create_tag(
-
client.unstable.tags.find_tag(...) +
client.unstable.help_center.list_help_centers()
@@ -15101,8 +15053,7 @@ client.unstable.tags.create_tag(
-You can fetch the details of tags that are on the workspace by their id. -This will return a tag object. +You can list all Help Centers by making a GET request to `https://api.intercom.io/help_center/help_centers`.
@@ -15122,9 +15073,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.tags.find_tag( - id="123", -) +client.unstable.help_center.list_help_centers() ``` @@ -15140,14 +15089,6 @@ client.unstable.tags.find_tag(
-**id:** `str` — The unique identifier of a given tag - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -15160,7 +15101,8 @@ client.unstable.tags.find_tag(
-
client.unstable.tags.delete_tag(...) +## Internal Articles +
client.unstable.internal_articles.list_internal_articles()
@@ -15172,7 +15114,7 @@ client.unstable.tags.find_tag(
-You can delete the details of tags that are on the workspace by passing in the id. +You can fetch a list of all internal articles by making a GET request to `https://api.intercom.io/internal_articles`.
@@ -15192,9 +15134,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.tags.delete_tag( - id="123", -) +client.unstable.internal_articles.list_internal_articles() ``` @@ -15210,14 +15150,6 @@ client.unstable.tags.delete_tag(
-**id:** `str` — The unique identifier of a given tag - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -15230,7 +15162,7 @@ client.unstable.tags.delete_tag(
-
client.unstable.tags.attach_tag_to_ticket(...) +
client.unstable.internal_articles.create_internal_article(...)
@@ -15242,7 +15174,7 @@ client.unstable.tags.delete_tag(
-You can tag a specific ticket. This will return a tag object for the tag that was added to the ticket. +You can create a new internal article by making a POST request to `https://api.intercom.io/internal_articles`.
@@ -15258,14 +15190,18 @@ You can tag a specific ticket. This will return a tag object for the tag that wa ```python from intercom import Intercom +from intercom.unstable import CreateInternalArticleRequest client = Intercom( token="YOUR_TOKEN", ) -client.unstable.tags.attach_tag_to_ticket( - ticket_id="64619700005694", - id="7522907", - admin_id="780", +client.unstable.internal_articles.create_internal_article( + request=CreateInternalArticleRequest( + title="Thanks for everything", + body="Body of the Internal Article", + author_id=1295, + owner_id=1295, + ), ) ``` @@ -15282,23 +15218,7 @@ client.unstable.tags.attach_tag_to_ticket(
-**ticket_id:** `str` — ticket_id - -
-
- -
-
- -**id:** `str` — The unique identifier for the tag which is given by Intercom - -
-
- -
-
- -**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. +**request:** `typing.Optional[CreateInternalArticleRequest]`
@@ -15318,7 +15238,7 @@ client.unstable.tags.attach_tag_to_ticket(
-
client.unstable.tags.detach_tag_from_ticket(...) +
client.unstable.internal_articles.retrieve_internal_article(...)
@@ -15330,7 +15250,7 @@ client.unstable.tags.attach_tag_to_ticket(
-You can remove tag from a specific ticket. This will return a tag object for the tag that was removed from the ticket. +You can fetch the details of a single internal article by making a GET request to `https://api.intercom.io/internal_articles/`.
@@ -15350,10 +15270,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.tags.detach_tag_from_ticket( - ticket_id="64619700005694", - id="7522907", - admin_id="123", +client.unstable.internal_articles.retrieve_internal_article( + id=1, ) ``` @@ -15370,23 +15288,7 @@ client.unstable.tags.detach_tag_from_ticket(
-**ticket_id:** `str` — ticket_id - -
-
- -
-
- -**id:** `str` — The unique identifier for the tag which is given by Intercom - -
-
- -
-
- -**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. +**id:** `int` — The unique identifier for the article which is given by Intercom.
@@ -15406,8 +15308,7 @@ client.unstable.tags.detach_tag_from_ticket(
-## Conversations -
client.unstable.conversations.list_conversations(...) +
client.unstable.internal_articles.update_internal_article(...)
@@ -15419,13 +15320,7 @@ client.unstable.tags.detach_tag_from_ticket(
-You can fetch a list of all conversations. - -You can optionally request the result page size and the cursor to start after to fetch the result. -{% admonition type="warning" name="Pagination" %} - You can use pagination to limit the number of results returned. The default is `20` results per page. - See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. -{% /admonition %} +You can update the details of a single internal article by making a PUT request to `https://api.intercom.io/internal_articles/`.
@@ -15445,7 +15340,11 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.list_conversations() +client.unstable.internal_articles.update_internal_article( + id=1, + title="Christmas is here!", + body="

New gifts in store for the jolly season

", +) ``` @@ -15461,7 +15360,7 @@ client.unstable.conversations.list_conversations()
-**per_page:** `typing.Optional[int]` — How many results per page +**id:** `int` — The unique identifier for the internal article which is given by Intercom.
@@ -15469,7 +15368,31 @@ client.unstable.conversations.list_conversations()
-**starting_after:** `typing.Optional[str]` — String used to get the next page of conversations. +**title:** `typing.Optional[str]` — The title of the article. + +
+
+ +
+
+ +**body:** `typing.Optional[str]` — The content of the article. + +
+
+ +
+
+ +**author_id:** `typing.Optional[int]` — The id of the author of the article. + +
+
+ +
+
+ +**owner_id:** `typing.Optional[int]` — The id of the author of the article.
@@ -15489,7 +15412,7 @@ client.unstable.conversations.list_conversations()
-
client.unstable.conversations.create_conversation(...) +
client.unstable.internal_articles.delete_internal_article(...)
@@ -15501,15 +15424,7 @@ client.unstable.conversations.list_conversations()
-You can create a conversation that has been initiated by a contact (ie. user or lead). -The conversation can be an in-app message only. - -{% admonition type="info" name="Sending for visitors" %} -You can also send a message from a visitor by specifying their `user_id` or `id` value in the `from` field, along with a `type` field value of `contact`. -This visitor will be automatically converted to a contact with a lead role once the conversation is created. -{% /admonition %} - -This will return the Message model that has been created. +You can delete a single internal article by making a DELETE request to `https://api.intercom.io/internal_articles/`.
@@ -15525,17 +15440,12 @@ This will return the Message model that has been created. ```python from intercom import Intercom -from intercom.unstable.conversations import CreateConversationRequestFrom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.create_conversation( - from_=CreateConversationRequestFrom( - type="user", - id="123_doesnt_exist", - ), - body="Hello there", +client.unstable.internal_articles.delete_internal_article( + id=1, ) ``` @@ -15552,23 +15462,7 @@ client.unstable.conversations.create_conversation(
-**from_:** `CreateConversationRequestFrom` - -
-
- -
-
- -**body:** `str` — The content of the message. HTML is not supported. - -
-
- -
-
- -**created_at:** `typing.Optional[int]` — The time the conversation was created as a UTC Unix timestamp. If not provided, the current time will be used. This field is only recommneded for migrating past conversations from another source into Intercom. +**id:** `int` — The unique identifier for the internal article which is given by Intercom.
@@ -15588,7 +15482,7 @@ client.unstable.conversations.create_conversation(
-
client.unstable.conversations.retrieve_conversation(...) +
client.unstable.internal_articles.search_internal_articles(...)
@@ -15600,16 +15494,7 @@ client.unstable.conversations.create_conversation(
- -You can fetch the details of a single conversation. - -This will return a single Conversation model with all its conversation parts. - -{% admonition type="warning" name="Hard limit of 500 parts" %} -The maximum number of conversation parts that can be returned via the API is 500. If you have more than that we will return the 500 most recent conversation parts. -{% /admonition %} - -For AI agent conversation metadata, please note that you need to have the agent enabled in your workspace, which is a [paid feature](https://www.intercom.com/help/en/articles/8205718-fin-resolutions#h_97f8c2e671). +You can search for internal articles by making a GET request to `https://api.intercom.io/internal_articles/search`.
@@ -15629,10 +15514,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.retrieve_conversation( - id=1, - display_as="plaintext", -) +client.unstable.internal_articles.search_internal_articles() ``` @@ -15648,15 +15530,7 @@ client.unstable.conversations.retrieve_conversation(
-**id:** `int` — The id of the conversation to target - -
-
- -
-
- -**display_as:** `typing.Optional[str]` — Set to plaintext to retrieve conversation messages in plain text. +**folder_id:** `typing.Optional[str]` — The ID of the folder to search in.
@@ -15676,7 +15550,8 @@ client.unstable.conversations.retrieve_conversation(
-
client.unstable.conversations.update_conversation(...) +## Companies +
client.unstable.companies.retrieve_company(...)
@@ -15688,18 +15563,17 @@ client.unstable.conversations.retrieve_conversation(
+You can fetch a single company by passing in `company_id` or `name`. -You can update an existing conversation. + `https://api.intercom.io/companies?name={name}` -{% admonition type="info" name="Replying and other actions" %} -If you want to reply to a coveration or take an action such as assign, unassign, open, close or snooze, take a look at the reply and manage endpoints. -{% /admonition %} + `https://api.intercom.io/companies?company_id={company_id}` -{% admonition type="info" %} - This endpoint handles both **conversation updates** and **custom object associations**. +You can fetch all companies and filter by `segment_id` or `tag_id` as a query parameter. - See _`update a conversation with an association to a custom object instance`_ in the request/response examples to see the custom object association format. -{% /admonition %} + `https://api.intercom.io/companies?tag_id={tag_id}` + + `https://api.intercom.io/companies?segment_id={segment_id}`
@@ -15719,12 +15593,11 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.update_conversation( - id=1, - display_as="plaintext", - read=True, - title="new conversation title", - custom_attributes={"issue_type": "Billing", "priority": "High"}, +client.unstable.companies.retrieve_company( + name="my company", + company_id="12345", + tag_id="678910", + segment_id="98765", ) ``` @@ -15741,7 +15614,7 @@ client.unstable.conversations.update_conversation(
-**id:** `int` — The id of the conversation to target +**name:** `typing.Optional[str]` — The `name` of the company to filter by.
@@ -15749,7 +15622,7 @@ client.unstable.conversations.update_conversation(
-**display_as:** `typing.Optional[str]` — Set to plaintext to retrieve conversation messages in plain text. +**company_id:** `typing.Optional[str]` — The `company_id` of the company to filter by.
@@ -15757,7 +15630,7 @@ client.unstable.conversations.update_conversation(
-**read:** `typing.Optional[bool]` — Mark a conversation as read within Intercom. +**tag_id:** `typing.Optional[str]` — The `tag_id` of the company to filter by.
@@ -15765,7 +15638,7 @@ client.unstable.conversations.update_conversation(
-**title:** `typing.Optional[str]` — The title given to the conversation +**segment_id:** `typing.Optional[str]` — The `segment_id` of the company to filter by.
@@ -15773,7 +15646,7 @@ client.unstable.conversations.update_conversation(
-**custom_attributes:** `typing.Optional[CustomAttributes]` +**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page
@@ -15781,7 +15654,7 @@ client.unstable.conversations.update_conversation(
-**company_id:** `typing.Optional[str]` — The ID of the company that the conversation is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company. +**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 15
@@ -15801,7 +15674,7 @@ client.unstable.conversations.update_conversation(
-
client.unstable.conversations.delete_conversation(...) +
client.unstable.companies.create_or_update_company(...)
@@ -15813,7 +15686,15 @@ client.unstable.conversations.update_conversation(
-You can delete a single conversation. +You can create or update a company. + +Companies will be only visible in Intercom when there is at least one associated user. + +Companies are looked up via `company_id` in a `POST` request, if not found via `company_id`, the new company will be created, if found, that company will be updated. + +{% admonition type="warning" name="Using `company_id`" %} + You can set a unique `company_id` value when creating a company. However, it is not possible to update `company_id`. Be sure to set a unique value once upon creation of the company. +{% /admonition %}
@@ -15833,8 +15714,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.delete_conversation( - id=1, +client.unstable.companies.create_or_update_company( + request={"key": "value"}, ) ``` @@ -15851,7 +15732,7 @@ client.unstable.conversations.delete_conversation(
-**id:** `int` — id +**request:** `typing.Optional[typing.Any]`
@@ -15871,7 +15752,7 @@ client.unstable.conversations.delete_conversation(
-
client.unstable.conversations.search_conversations(...) +
client.unstable.companies.retrieve_a_company_by_id(...)
@@ -15883,11 +15764,3728 @@ client.unstable.conversations.delete_conversation(
-You can search for multiple conversations by the value of their attributes in order to fetch exactly which ones you want. - -To search for conversations, you need to send a `POST` request to `https://api.intercom.io/conversations/search`. - -This will accept a query object in the body which will define your filters in order to search for conversations. +You can fetch a single company. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.companies.retrieve_a_company_by_id( + id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the company which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + + + +
+ +
client.unstable.companies.update_company(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can update a single company using the Intercom provisioned `id`. + +{% admonition type="warning" name="Using `company_id`" %} + When updating a company it is not possible to update `company_id`. This can only be set once upon creation of the company. +{% /admonition %} +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.companies.update_company( + id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the company which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.companies.delete_company(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can delete a single company. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.companies.delete_company( + id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the company which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.companies.list_attached_contacts(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch a list of all contacts that belong to a company. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.companies.list_attached_contacts( + id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the company which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.companies.list_attached_segments_for_companies(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch a list of all segments that belong to a company. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.companies.list_attached_segments_for_companies( + id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the company which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.companies.list_all_companies(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can list companies. The company list is sorted by the `last_request_at` field and by default is ordered descending, most recently requested first. + +Note that the API does not include companies who have no associated users in list responses. + +When using the Companies endpoint and the pages object to iterate through the returned companies, there is a limit of 10,000 Companies that can be returned. If you need to list or iterate on more than 10,000 Companies, please use the [Scroll API](https://developers.intercom.com/reference#iterating-over-all-companies). +{% admonition type="warning" name="Pagination" %} + You can use pagination to limit the number of results returned. The default is `20` results per page. + See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. +{% /admonition %} +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.companies.list_all_companies( + order="desc", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page + +
+
+ +
+
+ +**per_page:** `typing.Optional[int]` — How many results to return per page. Defaults to 15 + +
+
+ +
+
+ +**order:** `typing.Optional[str]` — `asc` or `desc`. Return the companies in ascending or descending order. Defaults to desc + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.companies.scroll_over_all_companies(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ + The `list all companies` functionality does not work well for huge datasets, and can result in errors and performance problems when paging deeply. The Scroll API provides an efficient mechanism for iterating over all companies in a dataset. + +- Each app can only have 1 scroll open at a time. You'll get an error message if you try to have more than one open per app. +- If the scroll isn't used for 1 minute, it expires and calls with that scroll param will fail +- If the end of the scroll is reached, "companies" will be empty and the scroll parameter will expire + +{% admonition type="info" name="Scroll Parameter" %} + You can get the first page of companies by simply sending a GET request to the scroll endpoint. + For subsequent requests you will need to use the scroll parameter from the response. +{% /admonition %} +{% admonition type="danger" name="Scroll network timeouts" %} + Since scroll is often used on large datasets network errors such as timeouts can be encountered. When this occurs you will see a HTTP 500 error with the following message: + "Request failed due to an internal network error. Please restart the scroll operation." + If this happens, you will need to restart your scroll query: It is not possible to continue from a specific point when using scroll. +{% /admonition %} +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.companies.scroll_over_all_companies() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**scroll_param:** `typing.Optional[str]` — + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.companies.attach_contact_to_a_company(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can attach a company to a single contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.companies.attach_contact_to_a_company( + id="id", + company_id="123", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ +**company_id:** `str` — The unique identifier for the company which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.companies.detach_contact_from_a_company(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can detach a company from a single contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.companies.detach_contact_from_a_company( + contact_id="58a430d35458202d41b1e65b", + id="58a430d35458202d41b1e65b", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the company which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Contacts +
client.unstable.contacts.list_companies_for_a_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch a list of companies that are associated to a contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.list_companies_for_a_contact( + id="63a07ddf05a32042dffac965", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.list_segments_for_a_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch a list of segments that are associated to a contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.list_segments_for_a_contact( + contact_id="63a07ddf05a32042dffac965", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.list_subscriptions_for_a_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch a list of subscription types that are attached to a contact. These can be subscriptions that a user has 'opted-in' to or has 'opted-out' from, depending on the subscription type. +This will return a list of Subscription Type objects that the contact is associated with. + +The data property will show a combined list of: + + 1.Opt-out subscription types that the user has opted-out from. + 2.Opt-in subscription types that the user has opted-in to receiving. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.list_subscriptions_for_a_contact( + contact_id="63a07ddf05a32042dffac965", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.list_tags_for_a_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch a list of all tags that are attached to a specific contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.list_tags_for_a_contact( + contact_id="63a07ddf05a32042dffac965", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.show_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch the details of a single contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.show_contact( + id="63a07ddf05a32042dffac965", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — id + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.update_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can update an existing contact (ie. user or lead). + +{% admonition type="info" %} + This endpoint handles both **contact updates** and **custom object associations**. + + See _`update a contact with an association to a custom object instance`_ in the request/response examples to see the custom object association format. +{% /admonition %} +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.update_contact( + id="63a07ddf05a32042dffac965", + custom_attributes={"order": ["21"]}, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — id + +
+
+ +
+
+ +**role:** `typing.Optional[str]` — The role of the contact. + +
+
+ +
+
+ +**external_id:** `typing.Optional[str]` — A unique identifier for the contact which is given to Intercom + +
+
+ +
+
+ +**email:** `typing.Optional[str]` — The contacts email + +
+
+ +
+
+ +**phone:** `typing.Optional[str]` — The contacts phone + +
+
+ +
+
+ +**name:** `typing.Optional[str]` — The contacts name + +
+
+ +
+
+ +**avatar:** `typing.Optional[str]` — An image URL containing the avatar of a contact + +
+
+ +
+
+ +**signed_up_at:** `typing.Optional[int]` — The time specified for when a contact signed up + +
+
+ +
+
+ +**last_seen_at:** `typing.Optional[int]` — The time when the contact was last seen (either where the Intercom Messenger was installed or when specified manually) + +
+
+ +
+
+ +**owner_id:** `typing.Optional[int]` — The id of an admin that has been assigned account ownership of the contact + +
+
+ +
+
+ +**unsubscribed_from_emails:** `typing.Optional[bool]` — Whether the contact is unsubscribed from emails + +
+
+ +
+
+ +**custom_attributes:** `typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]` — The custom attributes which are set for the contact + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.delete_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can delete a single contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.delete_contact( + id="id", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — id + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.merge_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can merge a contact with a `role` of `lead` into a contact with a `role` of `user`. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.merge_contact( + from_="6762f0d51bb69f9f2193bb7f", + into="6762f0d51bb69f9f2193bb80", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**from_:** `typing.Optional[str]` — The unique identifier for the contact to merge away from. Must be a lead. + +
+
+ +
+
+ +**into:** `typing.Optional[str]` — The unique identifier for the contact to merge into. Must be a user. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.search_contacts(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can search for multiple contacts by the value of their attributes in order to fetch exactly who you want. + +To search for contacts, you need to send a `POST` request to `https://api.intercom.io/contacts/search`. + +This will accept a query object in the body which will define your filters in order to search for contacts. + +{% admonition type="warning" name="Optimizing search queries" %} + Search queries can be complex, so optimizing them can help the performance of your search. + Use the `AND` and `OR` operators to combine multiple filters to get the exact results you need and utilize + pagination to limit the number of results returned. The default is `50` results per page. + See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#example-search-conversations-request) for more details on how to use the `starting_after` param. +{% /admonition %} +### Contact Creation Delay + +If a contact has recently been created, there is a possibility that it will not yet be available when searching. This means that it may not appear in the response. This delay can take a few minutes. If you need to be instantly notified it is recommended to use webhooks and iterate to see if they match your search filters. + +### Nesting & Limitations + +You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4). +There are some limitations to the amount of multiple's there can be: +* There's a limit of max 2 nested filters +* There's a limit of max 15 filters for each AND or OR group + +### Searching for Timestamp Fields + +All timestamp fields (created_at, updated_at etc.) are indexed as Dates for Contact Search queries; Datetime queries are not currently supported. This means you can only query for timestamp fields by day - not hour, minute or second. +For example, if you search for all Contacts with a created_at value greater (>) than 1577869200 (the UNIX timestamp for January 1st, 2020 9:00 AM), that will be interpreted as 1577836800 (January 1st, 2020 12:00 AM). The search results will then include Contacts created from January 2nd, 2020 12:00 AM onwards. +If you'd like to get contacts created on January 1st, 2020 you should search with a created_at value equal (=) to 1577836800 (January 1st, 2020 12:00 AM). +This behaviour applies only to timestamps used in search queries. The search results will still contain the full UNIX timestamp and be sorted accordingly. + +### Accepted Fields + +Most key listed as part of the Contacts Model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). + +| Field | Type | +| ---------------------------------- | ------------------------------ | +| id | String | +| role | String
Accepts user or lead | +| name | String | +| avatar | String | +| owner_id | Integer | +| email | String | +| email_domain | String | +| phone | String | +| formatted_phone | String | +| external_id | String | +| created_at | Date (UNIX Timestamp) | +| signed_up_at | Date (UNIX Timestamp) | +| updated_at | Date (UNIX Timestamp) | +| last_seen_at | Date (UNIX Timestamp) | +| last_contacted_at | Date (UNIX Timestamp) | +| last_replied_at | Date (UNIX Timestamp) | +| last_email_opened_at | Date (UNIX Timestamp) | +| last_email_clicked_at | Date (UNIX Timestamp) | +| language_override | String | +| browser | String | +| browser_language | String | +| os | String | +| location.country | String | +| location.region | String | +| location.city | String | +| unsubscribed_from_emails | Boolean | +| marked_email_as_spam | Boolean | +| has_hard_bounced | Boolean | +| ios_last_seen_at | Date (UNIX Timestamp) | +| ios_app_version | String | +| ios_device | String | +| ios_app_device | String | +| ios_os_version | String | +| ios_app_name | String | +| ios_sdk_version | String | +| android_last_seen_at | Date (UNIX Timestamp) | +| android_app_version | String | +| android_device | String | +| android_app_name | String | +| andoid_sdk_version | String | +| segment_id | String | +| tag_id | String | +| custom_attributes.{attribute_name} | String | + +### Accepted Operators + +{% admonition type="warning" name="Searching based on `created_at`" %} + You cannot use the `<=` or `>=` operators to search by `created_at`. +{% /admonition %} + +The table below shows the operators you can use to define how you want to search for the value. The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates). + +| Operator | Valid Types | Description | +| :------- | :------------------------------- | :--------------------------------------------------------------- | +| = | All | Equals | +| != | All | Doesn't Equal | +| IN | All | In
Shortcut for `OR` queries
Values must be in Array | +| NIN | All | Not In
Shortcut for `OR !` queries
Values must be in Array | +| > | Integer
Date (UNIX Timestamp) | Greater than | +| < | Integer
Date (UNIX Timestamp) | Lower than | +| ~ | String | Contains | +| !~ | String | Doesn't Contain | +| ^ | String | Starts With | +| $ | String | Ends With | +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom +from intercom.unstable import ( + MultipleFilterSearchRequest, + SingleFilterSearchRequest, + StartingAfterPaging, +) + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.search_contacts( + query=MultipleFilterSearchRequest( + operator="AND", + value=[ + SingleFilterSearchRequest( + field="created_at", + operator=">", + value="1306054154", + ) + ], + ), + pagination=StartingAfterPaging( + per_page=5, + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**query:** `SearchRequestQuery` + +
+
+ +
+
+ +**pagination:** `typing.Optional[StartingAfterPaging]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.list_contacts() +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch a list of all contacts (ie. users or leads) in your workspace. +{% admonition type="warning" name="Pagination" %} + You can use pagination to limit the number of results returned. The default is `50` results per page. + See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. +{% /admonition %} +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.list_contacts() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.create_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can create a new contact (ie. user or lead). +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.create_contact( + request={"email": "joebloggs@intercom.io"}, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CreateContactRequestTwo` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.show_contact_by_external_id(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch the details of a single contact by external ID. Note that this endpoint only supports users and not leads. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.show_contact_by_external_id( + external_id="cdd29344-5e0c-4ef0-ac56-f9ba2979bc27", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**external_id:** `str` — The external ID of the user that you want to retrieve + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.archive_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can archive a single contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.archive_contact( + id="63a07ddf05a32042dffac965", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — id + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.unarchive_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can unarchive a single contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.unarchive_contact( + id="63a07ddf05a32042dffac965", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — id + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.contacts.block_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Block a single contact.
**Note:** conversations of the contact will also be archived during the process.
More details in [FAQ How do I block Inbox spam?](https://www.intercom.com/help/en/articles/8838656-inbox-faqs) +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.contacts.block_contact( + id="63a07ddf05a32042dffac965", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — id + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Notes +
client.unstable.notes.list_notes(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch a list of notes that are associated to a contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.notes.list_notes( + id=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `int` — The unique identifier of a contact. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.notes.create_note(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can add a note to a single contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.notes.create_note( + id=1, + body="Hello", + contact_id="123", + admin_id="123", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `int` — The unique identifier of a given contact. + +
+
+ +
+
+ +**body:** `str` — The text of the note. + +
+
+ +
+
+ +**contact_id:** `typing.Optional[str]` — The unique identifier of a given contact. + +
+
+ +
+
+ +**admin_id:** `typing.Optional[str]` — The unique identifier of a given admin. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.notes.retrieve_note(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch the details of a single note. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.notes.retrieve_note( + id=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `int` — The unique identifier of a given note + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Subscription Types +
client.unstable.subscription_types.attach_subscription_type_to_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can add a specific subscription to a contact. In Intercom, we have two different subscription types based on user consent - opt-out and opt-in: + + 1.Attaching a contact to an opt-out subscription type will opt that user out from receiving messages related to that subscription type. + + 2.Attaching a contact to an opt-in subscription type will opt that user in to receiving messages related to that subscription type. + +This will return a subscription type model for the subscription type that was added to the contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.subscription_types.attach_subscription_type_to_contact( + contact_id="63a07ddf05a32042dffac965", + id="invalid_id", + consent_type="opt_in", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the subscription which is given by Intercom + +
+
+ +
+
+ +**consent_type:** `str` — The consent_type of a subscription, opt_out or opt_in. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.subscription_types.detach_subscription_type_to_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can remove a specific subscription from a contact. This will return a subscription type model for the subscription type that was removed from the contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.subscription_types.detach_subscription_type_to_contact( + contact_id="63a07ddf05a32042dffac965", + id="37846", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the subscription type which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.subscription_types.list_subscription_types() +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can list all subscription types. A list of subscription type objects will be returned. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.subscription_types.list_subscription_types() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Tags +
client.unstable.tags.attach_tag_to_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can tag a specific contact. This will return a tag object for the tag that was added to the contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.tags.attach_tag_to_contact( + contact_id="63a07ddf05a32042dffac965", + id="123", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the tag which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.tags.detach_tag_from_contact(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can remove tag from a specific contact. This will return a tag object for the tag that was removed from the contact. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.tags.detach_tag_from_contact( + contact_id="63a07ddf05a32042dffac965", + id="7522907", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**contact_id:** `str` — The unique identifier for the contact which is given by Intercom + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the tag which is given by Intercom + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.tags.attach_tag_to_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can tag a specific conversation. This will return a tag object for the tag that was added to the conversation. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.tags.attach_tag_to_conversation( + conversation_id="64619700005694", + id="7522907", + admin_id="780", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**conversation_id:** `str` — conversation_id + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the tag which is given by Intercom + +
+
+ +
+
+ +**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.tags.detach_tag_from_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can remove tag from a specific conversation. This will return a tag object for the tag that was removed from the conversation. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.tags.detach_tag_from_conversation( + conversation_id="64619700005694", + id="7522907", + admin_id="123", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**conversation_id:** `str` — conversation_id + +
+
+ +
+
+ +**id:** `str` — id + +
+
+ +
+
+ +**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.tags.list_tags() +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch a list of all tags for a given workspace. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.tags.list_tags() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.tags.create_tag(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can use this endpoint to perform the following operations: + + **1. Create a new tag:** You can create a new tag by passing in the tag name as specified in "Create or Update Tag Request Payload" described below. + + **2. Update an existing tag:** You can update an existing tag by passing the id of the tag as specified in "Create or Update Tag Request Payload" described below. + + **3. Tag Companies:** You can tag single company or a list of companies. You can tag a company by passing in the tag name and the company details as specified in "Tag Company Request Payload" described below. Also, if the tag doesn't exist then a new one will be created automatically. + + **4. Untag Companies:** You can untag a single company or a list of companies. You can untag a company by passing in the tag id and the company details as specified in "Untag Company Request Payload" described below. + + **5. Tag Multiple Users:** You can tag a list of users. You can tag the users by passing in the tag name and the user details as specified in "Tag Users Request Payload" described below. + +Each operation will return a tag object. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom +from intercom.unstable import ( + TagMultipleUsersRequest, + TagMultipleUsersRequestUsersItem, +) + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.tags.create_tag( + request=TagMultipleUsersRequest( + name="test", + users=[ + TagMultipleUsersRequestUsersItem( + id="123", + ) + ], + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CreateTagRequestBody` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.tags.find_tag(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch the details of tags that are on the workspace by their id. +This will return a tag object. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.tags.find_tag( + id="123", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The unique identifier of a given tag + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.tags.delete_tag(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can delete the details of tags that are on the workspace by passing in the id. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.tags.delete_tag( + id="123", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The unique identifier of a given tag + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.tags.attach_tag_to_ticket(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can tag a specific ticket. This will return a tag object for the tag that was added to the ticket. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.tags.attach_tag_to_ticket( + ticket_id="64619700005694", + id="7522907", + admin_id="780", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**ticket_id:** `str` — ticket_id + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the tag which is given by Intercom + +
+
+ +
+
+ +**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.tags.detach_tag_from_ticket(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can remove tag from a specific ticket. This will return a tag object for the tag that was removed from the ticket. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.tags.detach_tag_from_ticket( + ticket_id="64619700005694", + id="7522907", + admin_id="123", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**ticket_id:** `str` — ticket_id + +
+
+ +
+
+ +**id:** `str` — The unique identifier for the tag which is given by Intercom + +
+
+ +
+
+ +**admin_id:** `str` — The unique identifier for the admin which is given by Intercom. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Conversations +
client.unstable.conversations.list_conversations(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can fetch a list of all conversations. + +You can optionally request the result page size and the cursor to start after to fetch the result. +{% admonition type="warning" name="Pagination" %} + You can use pagination to limit the number of results returned. The default is `20` results per page. + See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#pagination-for-list-apis) for more details on how to use the `starting_after` param. +{% /admonition %} +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.list_conversations() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**per_page:** `typing.Optional[int]` — How many results per page + +
+
+ +
+
+ +**starting_after:** `typing.Optional[str]` — String used to get the next page of conversations. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.conversations.create_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can create a conversation that has been initiated by a contact (ie. user or lead). +The conversation can be an in-app message only. + +{% admonition type="info" name="Sending for visitors" %} +You can also send a message from a visitor by specifying their `user_id` or `id` value in the `from` field, along with a `type` field value of `contact`. +This visitor will be automatically converted to a contact with a lead role once the conversation is created. +{% /admonition %} + +This will return the Message model that has been created. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom +from intercom.unstable.conversations import CreateConversationRequestFrom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.create_conversation( + from_=CreateConversationRequestFrom( + type="user", + id="123_doesnt_exist", + ), + body="Hello there", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**from_:** `CreateConversationRequestFrom` + +
+
+ +
+
+ +**body:** `str` — The content of the message. HTML is not supported. + +
+
+ +
+
+ +**created_at:** `typing.Optional[int]` — The time the conversation was created as a UTC Unix timestamp. If not provided, the current time will be used. This field is only recommneded for migrating past conversations from another source into Intercom. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.conversations.retrieve_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ + +You can fetch the details of a single conversation. + +This will return a single Conversation model with all its conversation parts. + +{% admonition type="warning" name="Hard limit of 500 parts" %} +The maximum number of conversation parts that can be returned via the API is 500. If you have more than that we will return the 500 most recent conversation parts. +{% /admonition %} + +For AI agent conversation metadata, please note that you need to have the agent enabled in your workspace, which is a [paid feature](https://www.intercom.com/help/en/articles/8205718-fin-resolutions#h_97f8c2e671). +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.retrieve_conversation( + id=1, + display_as="plaintext", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `int` — The id of the conversation to target + +
+
+ +
+
+ +**display_as:** `typing.Optional[str]` — Set to plaintext to retrieve conversation messages in plain text. + +
+
+ +
+
+ +**include_translations:** `typing.Optional[bool]` — If set to true, conversation parts will be translated to the detected language of the conversation. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.conversations.update_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ + +You can update an existing conversation. + +{% admonition type="info" name="Replying and other actions" %} +If you want to reply to a coveration or take an action such as assign, unassign, open, close or snooze, take a look at the reply and manage endpoints. +{% /admonition %} + +{% admonition type="info" %} + This endpoint handles both **conversation updates** and **custom object associations**. + + See _`update a conversation with an association to a custom object instance`_ in the request/response examples to see the custom object association format. +{% /admonition %} +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.update_conversation( + id=1, + display_as="plaintext", + read=True, + title="new conversation title", + custom_attributes={"issue_type": "Billing", "priority": "High"}, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `int` — The id of the conversation to target + +
+
+ +
+
+ +**display_as:** `typing.Optional[str]` — Set to plaintext to retrieve conversation messages in plain text. + +
+
+ +
+
+ +**read:** `typing.Optional[bool]` — Mark a conversation as read within Intercom. + +
+
+ +
+
+ +**title:** `typing.Optional[str]` — The title given to the conversation + +
+
+ +
+
+ +**custom_attributes:** `typing.Optional[CustomAttributes]` + +
+
+ +
+
+ +**company_id:** `typing.Optional[str]` — The ID of the company that the conversation is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.conversations.delete_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can delete a single conversation. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.delete_conversation( + id=1, +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `int` — id + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.conversations.search_conversations(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can search for multiple conversations by the value of their attributes in order to fetch exactly which ones you want. + +To search for conversations, you need to send a `POST` request to `https://api.intercom.io/conversations/search`. + +This will accept a query object in the body which will define your filters in order to search for conversations. {% admonition type="warning" name="Optimizing search queries" %} Search queries can be complex, so optimizing them can help the performance of your search. Use the `AND` and `OR` operators to combine multiple filters to get the exact results you need and utilize @@ -15895,93 +19493,713 @@ This will accept a query object in the body which will define your filters in or See the [pagination section](https://developers.intercom.com/docs/build-an-integration/learn-more/rest-apis/pagination/#example-search-conversations-request) for more details on how to use the `starting_after` param. {% /admonition %} -### Nesting & Limitations +### Nesting & Limitations + +You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4). +There are some limitations to the amount of multiple's there can be: +- There's a limit of max 2 nested filters +- There's a limit of max 15 filters for each AND or OR group + +### Accepted Fields + +Most keys listed in the conversation model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). +The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. + +| Field | Type | +| :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | +| id | String | +| created_at | Date (UNIX timestamp) | +| updated_at | Date (UNIX timestamp) | +| source.type | String
Accepted fields are `conversation`, `email`, `facebook`, `instagram`, `phone_call`, `phone_switch`, `push`, `sms`, `twitter` and `whatsapp`. | +| source.id | String | +| source.delivered_as | String | +| source.subject | String | +| source.body | String | +| source.author.id | String | +| source.author.type | String | +| source.author.name | String | +| source.author.email | String | +| source.url | String | +| contact_ids | String | +| teammate_ids | String | +| admin_assignee_id | String | +| team_assignee_id | String | +| channel_initiated | String | +| open | Boolean | +| read | Boolean | +| state | String | +| waiting_since | Date (UNIX timestamp) | +| snoozed_until | Date (UNIX timestamp) | +| tag_ids | String | +| priority | String | +| statistics.time_to_assignment | Integer | +| statistics.time_to_admin_reply | Integer | +| statistics.time_to_first_close | Integer | +| statistics.time_to_last_close | Integer | +| statistics.median_time_to_reply | Integer | +| statistics.first_contact_reply_at | Date (UNIX timestamp) | +| statistics.first_assignment_at | Date (UNIX timestamp) | +| statistics.first_admin_reply_at | Date (UNIX timestamp) | +| statistics.first_close_at | Date (UNIX timestamp) | +| statistics.last_assignment_at | Date (UNIX timestamp) | +| statistics.last_assignment_admin_reply_at | Date (UNIX timestamp) | +| statistics.last_contact_reply_at | Date (UNIX timestamp) | +| statistics.last_admin_reply_at | Date (UNIX timestamp) | +| statistics.last_close_at | Date (UNIX timestamp) | +| statistics.last_closed_by_id | String | +| statistics.count_reopens | Integer | +| statistics.count_assignments | Integer | +| statistics.count_conversation_parts | Integer | +| conversation_rating.requested_at | Date (UNIX timestamp) | +| conversation_rating.replied_at | Date (UNIX timestamp) | +| conversation_rating.score | Integer | +| conversation_rating.remark | String | +| conversation_rating.contact_id | String | +| conversation_rating.admin_d | String | +| ai_agent_participated | Boolean | +| ai_agent.resolution_state | String | +| ai_agent.last_answer_type | String | +| ai_agent.rating | Integer | +| ai_agent.rating_remark | String | +| ai_agent.source_type | String | +| ai_agent.source_title | String | + +### Accepted Operators + +The table below shows the operators you can use to define how you want to search for the value. The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates). + +| Operator | Valid Types | Description | +| :------- | :----------------------------- | :----------------------------------------------------------- | +| = | All | Equals | +| != | All | Doesn't Equal | +| IN | All | In Shortcut for `OR` queries Values most be in Array | +| NIN | All | Not In Shortcut for `OR !` queries Values must be in Array | +| > | Integer Date (UNIX Timestamp) | Greater (or equal) than | +| < | Integer Date (UNIX Timestamp) | Lower (or equal) than | +| ~ | String | Contains | +| !~ | String | Doesn't Contain | +| ^ | String | Starts With | +| $ | String | Ends With | +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom +from intercom.unstable import ( + MultipleFilterSearchRequest, + SingleFilterSearchRequest, + StartingAfterPaging, +) + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.search_conversations( + query=MultipleFilterSearchRequest( + operator="AND", + value=[ + SingleFilterSearchRequest( + field="created_at", + operator=">", + value="1306054154", + ) + ], + ), + pagination=StartingAfterPaging( + per_page=5, + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**query:** `SearchRequestQuery` + +
+
+ +
+
+ +**pagination:** `typing.Optional[StartingAfterPaging]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.conversations.reply_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can reply to a conversation with a message from an admin or on behalf of a contact, or with a note for admins. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom +from intercom.unstable import ContactReplyIntercomUserIdRequest + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.reply_conversation( + id='123 or "last"', + request=ContactReplyIntercomUserIdRequest( + body="Thanks again :)", + intercom_user_id="6762f1661bb69f9f2193bbbf", + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The Intercom provisioned identifier for the conversation or the string "last" to reply to the last part of the conversation + +
+
+ +
+
+ +**request:** `ReplyConversationRequestBody` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.conversations.manage_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +For managing conversations you can: +- Close a conversation +- Snooze a conversation to reopen on a future date +- Open a conversation which is `snoozed` or `closed` +- Assign a conversation to an admin and/or team. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom +from intercom.unstable.conversations import ManageConversationRequestBody_Close + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.manage_conversation( + id="123", + request=ManageConversationRequestBody_Close( + admin_id="12345", + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The identifier for the conversation as given by Intercom. + +
+
+ +
+
+ +**request:** `ManageConversationRequestBody` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.conversations.attach_contact_to_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can add participants who are contacts to a conversation, on behalf of either another contact or an admin. + +{% admonition type="warning" name="Contacts without an email" %} +If you add a contact via the email parameter and there is no user/lead found on that workspace with he given email, then we will create a new contact with `role` set to `lead`. +{% /admonition %} +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom +from intercom.unstable.conversations import ( + AttachContactToConversationRequestCustomerIntercomUserId, +) + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.attach_contact_to_conversation( + id="123", + admin_id="12345", + customer=AttachContactToConversationRequestCustomerIntercomUserId( + intercom_user_id="6762f19e1bb69f9f2193bbd5", + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The identifier for the conversation as given by Intercom. + +
+
+ +
+
+ +**admin_id:** `typing.Optional[str]` — The `id` of the admin who is adding the new participant. + +
+
+ +
+
+ +**customer:** `typing.Optional[AttachContactToConversationRequestCustomer]` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.conversations.detach_contact_from_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can add participants who are contacts to a conversation, on behalf of either another contact or an admin. + +{% admonition type="warning" name="Contacts without an email" %} +If you add a contact via the email parameter and there is no user/lead found on that workspace with he given email, then we will create a new contact with `role` set to `lead`. +{% /admonition %} +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.detach_contact_from_conversation( + conversation_id="123", + contact_id="123", + admin_id="5017690", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**conversation_id:** `str` — The identifier for the conversation as given by Intercom. + +
+
+ +
+
+ +**contact_id:** `str` — The identifier for the contact as given by Intercom. + +
+
+ +
+
+ +**admin_id:** `str` — The `id` of the admin who is performing the action. + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.conversations.redact_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can redact a conversation part or the source message of a conversation (as seen in the source object). + +{% admonition type="info" name="Redacting parts and messages" %} +If you are redacting a conversation part, it must have a `body`. If you are redacting a source message, it must have been created by a contact. We will return a `conversation_part_not_redactable` error if these criteria are not met. +{% /admonition %} +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom +from intercom.unstable import RedactConversationRequest_ConversationPart + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.redact_conversation( + request=RedactConversationRequest_ConversationPart( + conversation_id="really_123_doesnt_exist", + conversation_part_id="really_123_doesnt_exist", + ), +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `RedactConversationRequest` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.conversations.convert_conversation_to_ticket(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +You can convert a conversation to a ticket. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.conversations.convert_conversation_to_ticket( + id=1, + ticket_type_id="54", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `int` — The id of the conversation to target + +
+
+ +
+
-You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4). -There are some limitations to the amount of multiple's there can be: -- There's a limit of max 2 nested filters -- There's a limit of max 15 filters for each AND or OR group +**ticket_type_id:** `str` — The ID of the type of ticket you want to convert the conversation to + +
+
-### Accepted Fields +
+
-Most keys listed in the conversation model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). -The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. +**attributes:** `typing.Optional[TicketRequestCustomAttributes]` + +
+
-| Field | Type | -| :---------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- | -| id | String | -| created_at | Date (UNIX timestamp) | -| updated_at | Date (UNIX timestamp) | -| source.type | String
Accepted fields are `conversation`, `email`, `facebook`, `instagram`, `phone_call`, `phone_switch`, `push`, `sms`, `twitter` and `whatsapp`. | -| source.id | String | -| source.delivered_as | String | -| source.subject | String | -| source.body | String | -| source.author.id | String | -| source.author.type | String | -| source.author.name | String | -| source.author.email | String | -| source.url | String | -| contact_ids | String | -| teammate_ids | String | -| admin_assignee_id | String | -| team_assignee_id | String | -| channel_initiated | String | -| open | Boolean | -| read | Boolean | -| state | String | -| waiting_since | Date (UNIX timestamp) | -| snoozed_until | Date (UNIX timestamp) | -| tag_ids | String | -| priority | String | -| statistics.time_to_assignment | Integer | -| statistics.time_to_admin_reply | Integer | -| statistics.time_to_first_close | Integer | -| statistics.time_to_last_close | Integer | -| statistics.median_time_to_reply | Integer | -| statistics.first_contact_reply_at | Date (UNIX timestamp) | -| statistics.first_assignment_at | Date (UNIX timestamp) | -| statistics.first_admin_reply_at | Date (UNIX timestamp) | -| statistics.first_close_at | Date (UNIX timestamp) | -| statistics.last_assignment_at | Date (UNIX timestamp) | -| statistics.last_assignment_admin_reply_at | Date (UNIX timestamp) | -| statistics.last_contact_reply_at | Date (UNIX timestamp) | -| statistics.last_admin_reply_at | Date (UNIX timestamp) | -| statistics.last_close_at | Date (UNIX timestamp) | -| statistics.last_closed_by_id | String | -| statistics.count_reopens | Integer | -| statistics.count_assignments | Integer | -| statistics.count_conversation_parts | Integer | -| conversation_rating.requested_at | Date (UNIX timestamp) | -| conversation_rating.replied_at | Date (UNIX timestamp) | -| conversation_rating.score | Integer | -| conversation_rating.remark | String | -| conversation_rating.contact_id | String | -| conversation_rating.admin_d | String | -| ai_agent_participated | Boolean | -| ai_agent.resolution_state | String | -| ai_agent.last_answer_type | String | -| ai_agent.rating | Integer | -| ai_agent.rating_remark | String | -| ai_agent.source_type | String | -| ai_agent.source_title | String | +
+
-### Accepted Operators +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
-The table below shows the operators you can use to define how you want to search for the value. The operator should be put in as a string (`"="`). The operator has to be compatible with the field's type (eg. you cannot search with `>` for a given string value as it's only compatible for integer's and dates). -| Operator | Valid Types | Description | -| :------- | :----------------------------- | :----------------------------------------------------------- | -| = | All | Equals | -| != | All | Doesn't Equal | -| IN | All | In Shortcut for `OR` queries Values most be in Array | -| NIN | All | Not In Shortcut for `OR !` queries Values must be in Array | -| > | Integer Date (UNIX Timestamp) | Greater (or equal) than | -| < | Integer Date (UNIX Timestamp) | Lower (or equal) than | -| ~ | String | Contains | -| !~ | String | Doesn't Contain | -| ^ | String | Starts With | -| $ | String | Ends With | +
+
+
+ +## Unstable CustomChannelEvents +
client.unstable.custom_channel_events.notify_new_conversation(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Notifies Intercom that a new conversation was created in your custom channel/platform. This triggers conversation creation and workflow automations within Intercom for your custom channel integration. +> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support.
@@ -15997,29 +20215,116 @@ The table below shows the operators you can use to define how you want to search ```python from intercom import Intercom -from intercom.unstable import ( - MultipleFilterSearchRequest, - SingleFilterSearchRequest, - StartingAfterPaging, -) +from intercom.unstable import CustomChannelContact client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.search_conversations( - query=MultipleFilterSearchRequest( - operator="AND", - value=[ - SingleFilterSearchRequest( - field="created_at", - operator=">", - value="1306054154", - ) - ], +client.unstable.custom_channel_events.notify_new_conversation( + event_id="evt_12345", + external_conversation_id="conv_67890", + contact=CustomChannelContact( + type="user", + external_id="user_001", + name="Jane Doe", + email="jane.doe@example.com", ), - pagination=StartingAfterPaging( - per_page=5, +) + +``` +
+
+ + + +#### ⚙️ Parameters + +
+
+ +
+
+ +**event_id:** `str` — Unique identifier for the event. + +
+
+ +
+
+ +**external_conversation_id:** `str` — Identifier for the conversation in your application. + +
+
+ +
+
+ +**contact:** `CustomChannelContact` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + + + +
+ +
client.unstable.custom_channel_events.notify_new_message(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Notifies Intercom that a new message was sent in a conversation on your custom channel/platform. This allows Intercom to process the message and trigger any relevant workflow automations. +> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom +from intercom.unstable import CustomChannelContact + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.custom_channel_events.notify_new_message( + event_id="evt_54321", + external_conversation_id="conv_98765", + contact=CustomChannelContact( + type="user", + external_id="user_002", + name="John Smith", + email="john.smith@example.com", ), + body="Hello, I need help with my order.", ) ``` @@ -16028,15 +20333,31 @@ client.unstable.conversations.search_conversations(
-#### ⚙️ Parameters - +#### ⚙️ Parameters + +
+
+ +
+
+ +**body:** `str` — The message content sent by the user. + +
+
+
+**event_id:** `str` — Unique identifier for the event. + +
+
+
-**query:** `SearchRequestQuery` +**external_conversation_id:** `str` — Identifier for the conversation in your application.
@@ -16044,7 +20365,7 @@ client.unstable.conversations.search_conversations(
-**pagination:** `typing.Optional[StartingAfterPaging]` +**contact:** `CustomChannelContact`
@@ -16064,7 +20385,7 @@ client.unstable.conversations.search_conversations(
-
client.unstable.conversations.reply_conversation(...) +
client.unstable.custom_channel_events.notify_quick_reply_selected(...)
@@ -16076,7 +20397,8 @@ client.unstable.conversations.search_conversations(
-You can reply to a conversation with a message from an admin or on behalf of a contact, or with a note for admins. +Notifies Intercom that a user selected a quick reply option in your custom channel/platform. This allows Intercom to process the response and trigger any relevant workflow automations. +> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support.
@@ -16092,17 +20414,21 @@ You can reply to a conversation with a message from an admin or on behalf of a c ```python from intercom import Intercom -from intercom.unstable import ContactReplyIntercomUserIdRequest +from intercom.unstable import CustomChannelContact client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.reply_conversation( - id='123 or "last"', - request=ContactReplyIntercomUserIdRequest( - body="Thanks again :)", - intercom_user_id="6762f1661bb69f9f2193bbbf", +client.unstable.custom_channel_events.notify_quick_reply_selected( + event_id="evt_67890", + external_conversation_id="conv_13579", + contact=CustomChannelContact( + type="user", + external_id="user_003", + name="Alice Example", + email="alice@example.com", ), + quick_reply_option_id="1234", ) ``` @@ -16119,7 +20445,7 @@ client.unstable.conversations.reply_conversation(
-**id:** `str` — The Intercom provisioned identifier for the conversation or the string "last" to reply to the last part of the conversation +**quick_reply_option_id:** `str` — Id of the selected quick reply option.
@@ -16127,7 +20453,23 @@ client.unstable.conversations.reply_conversation(
-**request:** `ReplyConversationRequestBody` +**event_id:** `str` — Unique identifier for the event. + +
+
+ +
+
+ +**external_conversation_id:** `str` — Identifier for the conversation in your application. + +
+
+ +
+
+ +**contact:** `CustomChannelContact`
@@ -16147,7 +20489,7 @@ client.unstable.conversations.reply_conversation(
-
client.unstable.conversations.manage_conversation(...) +
client.unstable.custom_channel_events.notify_attribute_collected(...)
@@ -16159,11 +20501,8 @@ client.unstable.conversations.reply_conversation(
-For managing conversations you can: -- Close a conversation -- Snooze a conversation to reopen on a future date -- Open a conversation which is `snoozed` or `closed` -- Assign a conversation to an admin and/or team. +Notifies Intercom that a user provided a response to an attribute collector in your custom channel/platform. This allows Intercom to process the attribute and trigger any relevant workflow automations. +> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support.
@@ -16179,15 +20518,23 @@ For managing conversations you can: ```python from intercom import Intercom -from intercom.unstable.conversations import ManageConversationRequestBody_Close +from intercom.unstable import CustomChannelAttribute, CustomChannelContact client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.manage_conversation( - id="123", - request=ManageConversationRequestBody_Close( - admin_id="12345", +client.unstable.custom_channel_events.notify_attribute_collected( + event_id="evt_24680", + external_conversation_id="conv_11223", + contact=CustomChannelContact( + type="user", + external_id="user_004", + name="Bob Example", + email="bob@example.com", + ), + attribute=CustomChannelAttribute( + id="shipping_address", + value="123 Main St, Springfield", ), ) @@ -16205,7 +20552,7 @@ client.unstable.conversations.manage_conversation(
-**id:** `str` — The identifier for the conversation as given by Intercom. +**attribute:** `CustomChannelAttribute`
@@ -16213,7 +20560,23 @@ client.unstable.conversations.manage_conversation(
-**request:** `ManageConversationRequestBody` +**event_id:** `str` — Unique identifier for the event. + +
+
+ +
+
+ +**external_conversation_id:** `str` — Identifier for the conversation in your application. + +
+
+ +
+
+ +**contact:** `CustomChannelContact`
@@ -16233,7 +20596,8 @@ client.unstable.conversations.manage_conversation(
-
client.unstable.conversations.attach_contact_to_conversation(...) +## Custom Object Instances +
client.unstable.custom_object_instances.get_custom_object_instances_by_external_id(...)
@@ -16245,11 +20609,7 @@ client.unstable.conversations.manage_conversation(
-You can add participants who are contacts to a conversation, on behalf of either another contact or an admin. - -{% admonition type="warning" name="Contacts without an email" %} -If you add a contact via the email parameter and there is no user/lead found on that workspace with he given email, then we will create a new contact with `role` set to `lead`. -{% /admonition %} +Fetch a Custom Object Instance by external_id.
@@ -16265,19 +20625,13 @@ If you add a contact via the email parameter and there is no user/lead found on ```python from intercom import Intercom -from intercom.unstable.conversations import ( - AttachContactToConversationRequestCustomerIntercomUserId, -) client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.attach_contact_to_conversation( - id="123", - admin_id="12345", - customer=AttachContactToConversationRequestCustomerIntercomUserId( - intercom_user_id="6762f19e1bb69f9f2193bbd5", - ), +client.unstable.custom_object_instances.get_custom_object_instances_by_external_id( + custom_object_type_identifier="Order", + external_id="external_id", ) ``` @@ -16294,15 +20648,7 @@ client.unstable.conversations.attach_contact_to_conversation(
-**id:** `str` — The identifier for the conversation as given by Intercom. - -
-
- -
-
- -**admin_id:** `typing.Optional[str]` — The `id` of the admin who is adding the new participant. +**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance.
@@ -16310,7 +20656,7 @@ client.unstable.conversations.attach_contact_to_conversation(
-**customer:** `typing.Optional[AttachContactToConversationRequestCustomer]` +**external_id:** `str`
@@ -16330,7 +20676,7 @@ client.unstable.conversations.attach_contact_to_conversation(
-
client.unstable.conversations.detach_contact_from_conversation(...) +
client.unstable.custom_object_instances.create_custom_object_instances(...)
@@ -16342,11 +20688,7 @@ client.unstable.conversations.attach_contact_to_conversation(
-You can add participants who are contacts to a conversation, on behalf of either another contact or an admin. - -{% admonition type="warning" name="Contacts without an email" %} -If you add a contact via the email parameter and there is no user/lead found on that workspace with he given email, then we will create a new contact with `role` set to `lead`. -{% /admonition %} +Create or update a custom object instance
@@ -16366,10 +20708,15 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.detach_contact_from_conversation( - conversation_id="123", - contact_id="123", - admin_id="5017690", +client.unstable.custom_object_instances.create_custom_object_instances( + custom_object_type_identifier="Order", + external_id="123", + external_created_at=1392036272, + external_updated_at=1392036272, + custom_attributes={ + "order_number": "ORDER-12345", + "total_amount": "custom_attributes", + }, ) ``` @@ -16386,7 +20733,7 @@ client.unstable.conversations.detach_contact_from_conversation(
-**conversation_id:** `str` — The identifier for the conversation as given by Intercom. +**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance.
@@ -16394,7 +20741,7 @@ client.unstable.conversations.detach_contact_from_conversation(
-**contact_id:** `str` — The identifier for the contact as given by Intercom. +**external_id:** `typing.Optional[str]` — A unique identifier for the Custom Object instance in the external system it originated from.
@@ -16402,7 +20749,23 @@ client.unstable.conversations.detach_contact_from_conversation(
-**admin_id:** `str` — The `id` of the admin who is performing the action. +**external_created_at:** `typing.Optional[int]` — The time when the Custom Object instance was created in the external system it originated from. + +
+
+ +
+
+ +**external_updated_at:** `typing.Optional[int]` — The time when the Custom Object instance was last updated in the external system it originated from. + +
+
+ +
+
+ +**custom_attributes:** `typing.Optional[typing.Dict[str, typing.Optional[str]]]` — The custom attributes which are set for the Custom Object instance.
@@ -16422,7 +20785,7 @@ client.unstable.conversations.detach_contact_from_conversation(
-
client.unstable.conversations.redact_conversation(...) +
client.unstable.custom_object_instances.delete_custom_object_instances_by_id(...)
@@ -16434,11 +20797,7 @@ client.unstable.conversations.detach_contact_from_conversation(
-You can redact a conversation part or the source message of a conversation (as seen in the source object). - -{% admonition type="info" name="Redacting parts and messages" %} -If you are redacting a conversation part, it must have a `body`. If you are redacting a source message, it must have been created by a contact. We will return a `conversation_part_not_redactable` error if these criteria are not met. -{% /admonition %} +Delete a single Custom Object instance by external_id.
@@ -16454,16 +20813,13 @@ If you are redacting a conversation part, it must have a `body`. If you are reda ```python from intercom import Intercom -from intercom.unstable import RedactConversationRequest_ConversationPart client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.redact_conversation( - request=RedactConversationRequest_ConversationPart( - conversation_id="really_123_doesnt_exist", - conversation_part_id="really_123_doesnt_exist", - ), +client.unstable.custom_object_instances.delete_custom_object_instances_by_id( + custom_object_type_identifier="Order", + external_id="external_id", ) ``` @@ -16480,7 +20836,15 @@ client.unstable.conversations.redact_conversation(
-**request:** `RedactConversationRequest` +**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance. + +
+
+ +
+
+ +**external_id:** `str`
@@ -16500,7 +20864,7 @@ client.unstable.conversations.redact_conversation(
-
client.unstable.conversations.convert_conversation_to_ticket(...) +
client.unstable.custom_object_instances.get_custom_object_instances_by_id(...)
@@ -16512,7 +20876,7 @@ client.unstable.conversations.redact_conversation(
-You can convert a conversation to a ticket. +Fetch a Custom Object Instance by id.
@@ -16532,9 +20896,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.conversations.convert_conversation_to_ticket( - id=1, - ticket_type_id="54", +client.unstable.custom_object_instances.get_custom_object_instances_by_id( + custom_object_type_identifier="Order", + id="id", ) ``` @@ -16551,15 +20915,7 @@ client.unstable.conversations.convert_conversation_to_ticket(
-**id:** `int` — The id of the conversation to target - -
-
- -
-
- -**ticket_type_id:** `str` — The ID of the type of ticket you want to convert the conversation to +**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance.
@@ -16567,7 +20923,7 @@ client.unstable.conversations.convert_conversation_to_ticket(
-**attributes:** `typing.Optional[TicketRequestCustomAttributes]` +**id:** `str` — The id or external_id of the custom object instance
@@ -16587,8 +20943,7 @@ client.unstable.conversations.convert_conversation_to_ticket(
-## Unstable CustomChannelEvents -
client.unstable.custom_channel_events.notify_new_conversation(...) +
client.unstable.custom_object_instances.delete_custom_object_instances_by_external_id(...)
@@ -16600,8 +20955,7 @@ client.unstable.conversations.convert_conversation_to_ticket(
-Notifies Intercom that a new conversation was created in your custom channel/platform. This triggers conversation creation and workflow automations within Intercom for your custom channel integration. -> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. +Delete a single Custom Object instance using the Intercom defined id.
@@ -16617,20 +20971,13 @@ Notifies Intercom that a new conversation was created in your custom channel/pla ```python from intercom import Intercom -from intercom.unstable import CustomChannelContact client = Intercom( token="YOUR_TOKEN", ) -client.unstable.custom_channel_events.notify_new_conversation( - event_id="evt_12345", - external_conversation_id="conv_67890", - contact=CustomChannelContact( - type="user", - external_id="user_001", - name="Jane Doe", - email="jane.doe@example.com", - ), +client.unstable.custom_object_instances.delete_custom_object_instances_by_external_id( + custom_object_type_identifier="Order", + id="id", ) ``` @@ -16647,15 +20994,7 @@ client.unstable.custom_channel_events.notify_new_conversation(
-**event_id:** `str` — Unique identifier for the event. - -
-
- -
-
- -**external_conversation_id:** `str` — Identifier for the conversation in your application. +**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance.
@@ -16663,7 +21002,7 @@ client.unstable.custom_channel_events.notify_new_conversation(
-**contact:** `CustomChannelContact` +**id:** `str` — The Intercom defined id of the custom object instance
@@ -16683,7 +21022,8 @@ client.unstable.custom_channel_events.notify_new_conversation(
-
client.unstable.custom_channel_events.notify_new_message(...) +## Data Attributes +
client.unstable.data_attributes.lis_data_attributes(...)
@@ -16695,8 +21035,7 @@ client.unstable.custom_channel_events.notify_new_conversation(
-Notifies Intercom that a new message was sent in a conversation on your custom channel/platform. This allows Intercom to process the message and trigger any relevant workflow automations. -> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. +You can fetch a list of all data attributes belonging to a workspace for contacts, companies or conversations.
@@ -16712,22 +21051,11 @@ Notifies Intercom that a new message was sent in a conversation on your custom c ```python from intercom import Intercom -from intercom.unstable import CustomChannelContact client = Intercom( token="YOUR_TOKEN", ) -client.unstable.custom_channel_events.notify_new_message( - event_id="evt_54321", - external_conversation_id="conv_98765", - contact=CustomChannelContact( - type="user", - external_id="user_002", - name="John Smith", - email="john.smith@example.com", - ), - body="Hello, I need help with my order.", -) +client.unstable.data_attributes.lis_data_attributes() ``` @@ -16743,23 +21071,7 @@ client.unstable.custom_channel_events.notify_new_message(
-**body:** `str` — The message content sent by the user. - -
-
- -
-
- -**event_id:** `str` — Unique identifier for the event. - -
-
- -
-
- -**external_conversation_id:** `str` — Identifier for the conversation in your application. +**model:** `typing.Optional[LisDataAttributesRequestModel]` — Specify the data attribute model to return.
@@ -16767,7 +21079,7 @@ client.unstable.custom_channel_events.notify_new_message(
-**contact:** `CustomChannelContact` +**include_archived:** `typing.Optional[bool]` — Include archived attributes in the list. By default we return only non archived data attributes.
@@ -16787,7 +21099,7 @@ client.unstable.custom_channel_events.notify_new_message(
-
client.unstable.custom_channel_events.notify_quick_reply_selected(...) +
client.unstable.data_attributes.create_data_attribute(...)
@@ -16799,8 +21111,7 @@ client.unstable.custom_channel_events.notify_new_message(
-Notifies Intercom that a user selected a quick reply option in your custom channel/platform. This allows Intercom to process the response and trigger any relevant workflow automations. -> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. +You can create a data attributes for a `contact` or a `company`.
@@ -16816,21 +21127,12 @@ Notifies Intercom that a user selected a quick reply option in your custom chann ```python from intercom import Intercom -from intercom.unstable import CustomChannelContact client = Intercom( token="YOUR_TOKEN", ) -client.unstable.custom_channel_events.notify_quick_reply_selected( - event_id="evt_67890", - external_conversation_id="conv_13579", - contact=CustomChannelContact( - type="user", - external_id="user_003", - name="Alice Example", - email="alice@example.com", - ), - quick_reply_option_id="1234", +client.unstable.data_attributes.create_data_attribute( + request={"key": "value"}, ) ``` @@ -16847,31 +21149,7 @@ client.unstable.custom_channel_events.notify_quick_reply_selected(
-**quick_reply_option_id:** `str` — Id of the selected quick reply option. - -
-
- -
-
- -**event_id:** `str` — Unique identifier for the event. - -
-
- -
-
- -**external_conversation_id:** `str` — Identifier for the conversation in your application. - -
-
- -
-
- -**contact:** `CustomChannelContact` +**request:** `typing.Optional[typing.Any]`
@@ -16891,7 +21169,7 @@ client.unstable.custom_channel_events.notify_quick_reply_selected(
-
client.unstable.custom_channel_events.notify_attribute_collected(...) +
client.unstable.data_attributes.update_data_attribute(...)
@@ -16903,8 +21181,12 @@ client.unstable.custom_channel_events.notify_quick_reply_selected(
-Notifies Intercom that a user provided a response to an attribute collector in your custom channel/platform. This allows Intercom to process the attribute and trigger any relevant workflow automations. -> **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + +You can update a data attribute. + +> 🚧 Updating the data type is not possible +> +> It is currently a dangerous action to execute changing a data attribute's type via the API. You will need to update the type via the UI instead.
@@ -16920,24 +21202,13 @@ Notifies Intercom that a user provided a response to an attribute collector in y ```python from intercom import Intercom -from intercom.unstable import CustomChannelAttribute, CustomChannelContact client = Intercom( token="YOUR_TOKEN", ) -client.unstable.custom_channel_events.notify_attribute_collected( - event_id="evt_24680", - external_conversation_id="conv_11223", - contact=CustomChannelContact( - type="user", - external_id="user_004", - name="Bob Example", - email="bob@example.com", - ), - attribute=CustomChannelAttribute( - id="shipping_address", - value="123 Main St, Springfield", - ), +client.unstable.data_attributes.update_data_attribute( + id=1, + request={"key": "value"}, ) ``` @@ -16954,23 +21225,7 @@ client.unstable.custom_channel_events.notify_attribute_collected(
-**attribute:** `CustomChannelAttribute` - -
-
- -
-
- -**event_id:** `str` — Unique identifier for the event. - -
-
- -
-
- -**external_conversation_id:** `str` — Identifier for the conversation in your application. +**id:** `int` — The data attribute id
@@ -16978,7 +21233,7 @@ client.unstable.custom_channel_events.notify_attribute_collected(
-**contact:** `CustomChannelContact` +**request:** `typing.Optional[typing.Any]`
@@ -16998,8 +21253,8 @@ client.unstable.custom_channel_events.notify_attribute_collected(
-## Custom Object Instances -
client.unstable.custom_object_instances.get_custom_object_instances_by_external_id(...) +## Data Events +
client.unstable.data_events.lis_data_events(...)
@@ -17011,7 +21266,20 @@ client.unstable.custom_channel_events.notify_attribute_collected(
-Fetch a Custom Object Instance by external_id. + +> 🚧 +> +> Please note that you can only 'list' events that are less than 90 days old. Event counts and summaries will still include your events older than 90 days but you cannot 'list' these events individually if they are older than 90 days + +The events belonging to a customer can be listed by sending a GET request to `https://api.intercom.io/events` with a user or lead identifier along with a `type` parameter. The identifier parameter can be one of `user_id`, `email` or `intercom_user_id`. The `type` parameter value must be `user`. + +- `https://api.intercom.io/events?type=user&user_id={user_id}` +- `https://api.intercom.io/events?type=user&email={email}` +- `https://api.intercom.io/events?type=user&intercom_user_id={id}` (this call can be used to list leads) + +The `email` parameter value should be [url encoded](http://en.wikipedia.org/wiki/Percent-encoding) when sending. + +You can optionally define the result page size as well with the `per_page` parameter.
@@ -17027,13 +21295,16 @@ Fetch a Custom Object Instance by external_id. ```python from intercom import Intercom +from intercom.unstable.data_events import LisDataEventsRequestFilterUserId client = Intercom( token="YOUR_TOKEN", ) -client.unstable.custom_object_instances.get_custom_object_instances_by_external_id( - custom_object_type_identifier="Order", - external_id="external_id", +client.unstable.data_events.lis_data_events( + filter=LisDataEventsRequestFilterUserId( + user_id="user_id", + ), + type="type", ) ``` @@ -17050,7 +21321,7 @@ client.unstable.custom_object_instances.get_custom_object_instances_by_external_
-**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance. +**filter:** `LisDataEventsRequestFilter`
@@ -17058,7 +21329,15 @@ client.unstable.custom_object_instances.get_custom_object_instances_by_external_
-**external_id:** `str` +**type:** `str` — The value must be user + +
+
+ +
+
+ +**summary:** `typing.Optional[bool]` — summary flag
@@ -17078,7 +21357,7 @@ client.unstable.custom_object_instances.get_custom_object_instances_by_external_
-
client.unstable.custom_object_instances.create_custom_object_instances(...) +
client.unstable.data_events.create_data_event(...)
@@ -17090,7 +21369,47 @@ client.unstable.custom_object_instances.get_custom_object_instances_by_external_
-Create or update a custom object instance + +You will need an Access Token that has write permissions to send Events. Once you have a key you can submit events via POST to the Events resource, which is located at https://api.intercom.io/events, or you can send events using one of the client libraries. When working with the HTTP API directly a client should send the event with a `Content-Type` of `application/json`. + +When using the JavaScript API, [adding the code to your app](http://docs.intercom.io/configuring-Intercom/tracking-user-events-in-your-app) makes the Events API available. Once added, you can submit an event using the `trackEvent` method. This will associate the event with the Lead or currently logged-in user or logged-out visitor/lead and send it to Intercom. The final parameter is a map that can be used to send optional metadata about the event. + +With the Ruby client you pass a hash describing the event to `Intercom::Event.create`, or call the `track_user` method directly on the current user object (e.g. `user.track_event`). + +**NB: For the JSON object types, please note that we do not currently support nested JSON structure.** + +| Type | Description | Example | +| :-------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- | +| String | The value is a JSON String | `"source":"desktop"` | +| Number | The value is a JSON Number | `"load": 3.67` | +| Date | The key ends with the String `_date` and the value is a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time), assumed to be in the [UTC](http://en.wikipedia.org/wiki/Coordinated_Universal_Time) timezone. | `"contact_date": 1392036272` | +| Link | The value is a HTTP or HTTPS URI. | `"article": "https://example.org/ab1de.html"` | +| Rich Link | The value is a JSON object that contains `url` and `value` keys. | `"article": {"url": "https://example.org/ab1de.html", "value":"the dude abides"}` | +| Monetary Amount | The value is a JSON object that contains `amount` and `currency` keys. The `amount` key is a positive integer representing the amount in cents. The price in the example to the right denotes €349.99. | `"price": {"amount": 34999, "currency": "eur"}` | + +**Lead Events** + +When submitting events for Leads, you will need to specify the Lead's `id`. + +**Metadata behaviour** + +- We currently limit the number of tracked metadata keys to 10 per event. Once the quota is reached, we ignore any further keys we receive. The first 10 metadata keys are determined by the order in which they are sent in with the event. +- It is not possible to change the metadata keys once the event has been sent. A new event will need to be created with the new keys and you can archive the old one. +- There might be up to 24 hrs delay when you send a new metadata for an existing event. + +**Event de-duplication** + +The API may detect and ignore duplicate events. Each event is uniquely identified as a combination of the following data - the Workspace identifier, the Contact external identifier, the Data Event name and the Data Event created time. As a result, it is **strongly recommended** to send a second granularity Unix timestamp in the `created_at` field. + +Duplicated events are responded to using the normal `202 Accepted` code - an error is not thrown, however repeat requests will be counted against any rate limit that is in place. + +### HTTP API Responses + +- Successful responses to submitted events return `202 Accepted` with an empty body. +- Unauthorised access will be rejected with a `401 Unauthorized` or `403 Forbidden` response code. +- Events sent about users that cannot be found will return a `404 Not Found`. +- Event lists containing duplicate events will have those duplicates ignored. +- Server errors will return a `500` response code and may contain an error message in the body.
@@ -17110,15 +21429,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.custom_object_instances.create_custom_object_instances( - custom_object_type_identifier="Order", - external_id="123", - external_created_at=1392036272, - external_updated_at=1392036272, - custom_attributes={ - "order_number": "ORDER-12345", - "total_amount": "custom_attributes", - }, +client.unstable.data_events.create_data_event( + request={"key": "value"}, ) ``` @@ -17135,39 +21447,7 @@ client.unstable.custom_object_instances.create_custom_object_instances(
-**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance. - -
-
- -
-
- -**external_id:** `typing.Optional[str]` — A unique identifier for the Custom Object instance in the external system it originated from. - -
-
- -
-
- -**external_created_at:** `typing.Optional[int]` — The time when the Custom Object instance was created in the external system it originated from. - -
-
- -
-
- -**external_updated_at:** `typing.Optional[int]` — The time when the Custom Object instance was last updated in the external system it originated from. - -
-
- -
-
- -**custom_attributes:** `typing.Optional[typing.Dict[str, typing.Optional[str]]]` — The custom attributes which are set for the Custom Object instance. +**request:** `CreateDataEventRequestTwo`
@@ -17187,7 +21467,7 @@ client.unstable.custom_object_instances.create_custom_object_instances(
-
client.unstable.custom_object_instances.delete_custom_object_instances_by_id(...) +
client.unstable.data_events.data_event_summaries(...)
@@ -17199,7 +21479,7 @@ client.unstable.custom_object_instances.create_custom_object_instances(
-Delete a single Custom Object instance by external_id. +Create event summaries for a user. Event summaries are used to track the number of times an event has occurred, the first time it occurred and the last time it occurred.
@@ -17219,10 +21499,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.custom_object_instances.delete_custom_object_instances_by_id( - custom_object_type_identifier="Order", - external_id="external_id", -) +client.unstable.data_events.data_event_summaries() ``` @@ -17238,7 +21515,7 @@ client.unstable.custom_object_instances.delete_custom_object_instances_by_id(
-**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance. +**user_id:** `typing.Optional[str]` — Your identifier for the user.
@@ -17246,7 +21523,7 @@ client.unstable.custom_object_instances.delete_custom_object_instances_by_id(
-**external_id:** `str` +**event_summaries:** `typing.Optional[CreateDataEventSummariesRequestEventSummaries]` — A list of event summaries for the user. Each event summary should contain the event name, the time the event occurred, and the number of times the event occurred. The event name should be a past tense 'verb-noun' combination, to improve readability, for example `updated-plan`.
@@ -17266,7 +21543,8 @@ client.unstable.custom_object_instances.delete_custom_object_instances_by_id(
-
client.unstable.custom_object_instances.get_custom_object_instances_by_id(...) +## Data Export +
client.unstable.data_export.create_data_export(...)
@@ -17278,7 +21556,21 @@ client.unstable.custom_object_instances.delete_custom_object_instances_by_id(
-Fetch a Custom Object Instance by id. +To create your export job, you need to send a `POST` request to the export endpoint `https://api.intercom.io/export/content/data`. + +The only parameters you need to provide are the range of dates that you want exported. + +>🚧 Limit of one active job +> +> You can only have one active job per workspace. You will receive a HTTP status code of 429 with the message Exceeded rate limit of 1 pending message data export jobs if you attempt to create a second concurrent job. + +>❗️ Updated_at not included +> +> It should be noted that the timeframe only includes messages sent during the time period and not messages that were only updated during this period. For example, if a message was updated yesterday but sent two days ago, you would need to set the created_at_after date before the message was sent to include that in your retrieval job. + +>📘 Date ranges are inclusive +> +> Requesting data for 2018-06-01 until 2018-06-30 will get all data for those days including those specified - e.g. 2018-06-01 00:00:00 until 2018-06-30 23:59:99.
@@ -17298,9 +21590,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.custom_object_instances.get_custom_object_instances_by_id( - custom_object_type_identifier="Order", - id="id", +client.unstable.data_export.create_data_export( + created_at_after=1734519776, + created_at_before=1734537776, ) ``` @@ -17317,7 +21609,7 @@ client.unstable.custom_object_instances.get_custom_object_instances_by_id(
-**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance. +**created_at_after:** `int` — The start date that you request data for. It must be formatted as a unix timestamp.
@@ -17325,7 +21617,7 @@ client.unstable.custom_object_instances.get_custom_object_instances_by_id(
-**id:** `str` — The id or external_id of the custom object instance +**created_at_before:** `int` — The end date that you request data for. It must be formatted as a unix timestamp.
@@ -17345,7 +21637,7 @@ client.unstable.custom_object_instances.get_custom_object_instances_by_id(
-
client.unstable.custom_object_instances.delete_custom_object_instances_by_external_id(...) +
client.unstable.data_export.get_data_export(...)
@@ -17357,7 +21649,11 @@ client.unstable.custom_object_instances.get_custom_object_instances_by_id(
-Delete a single Custom Object instance using the Intercom defined id. +You can view the status of your job by sending a `GET` request to the URL +`https://api.intercom.io/export/content/data/{job_identifier}` - the `{job_identifier}` is the value returned in the response when you first created the export job. More on it can be seen in the Export Job Model. + +> 🚧 Jobs expire after two days +> All jobs that have completed processing (and are thus available to download from the provided URL) will have an expiry limit of two days from when the export ob completed. After this, the data will no longer be available.
@@ -17377,9 +21673,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.custom_object_instances.delete_custom_object_instances_by_external_id( - custom_object_type_identifier="Order", - id="id", +client.unstable.data_export.get_data_export( + job_identifier="job_identifier", ) ``` @@ -17396,15 +21691,7 @@ client.unstable.custom_object_instances.delete_custom_object_instances_by_extern
-**custom_object_type_identifier:** `str` — The unique identifier of the custom object type that defines the structure of the custom object instance. - -
-
- -
-
- -**id:** `str` — The Intercom defined id of the custom object instance +**job_identifier:** `str` — job_identifier
@@ -17424,8 +21711,7 @@ client.unstable.custom_object_instances.delete_custom_object_instances_by_extern
-## Data Attributes -
client.unstable.data_attributes.lis_data_attributes(...) +
client.unstable.data_export.cancel_data_export(...)
@@ -17437,7 +21723,7 @@ client.unstable.custom_object_instances.delete_custom_object_instances_by_extern
-You can fetch a list of all data attributes belonging to a workspace for contacts, companies or conversations. +You can cancel your job
@@ -17457,7 +21743,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.data_attributes.lis_data_attributes() +client.unstable.data_export.cancel_data_export( + job_identifier="job_identifier", +) ``` @@ -17473,15 +21761,7 @@ client.unstable.data_attributes.lis_data_attributes()
-**model:** `typing.Optional[LisDataAttributesRequestModel]` — Specify the data attribute model to return. - -
-
- -
-
- -**include_archived:** `typing.Optional[bool]` — Include archived attributes in the list. By default we return only non archived data attributes. +**job_identifier:** `str` — job_identifier
@@ -17501,7 +21781,7 @@ client.unstable.data_attributes.lis_data_attributes()
-
client.unstable.data_attributes.create_data_attribute(...) +
client.unstable.data_export.download_data_export(...)
@@ -17513,7 +21793,13 @@ client.unstable.data_attributes.lis_data_attributes()
-You can create a data attributes for a `contact` or a `company`. +When a job has a status of complete, and thus a filled download_url, you can download your data by hitting that provided URL, formatted like so: https://api.intercom.io/download/content/data/xyz1234. + +Your exported message data will be streamed continuously back down to you in a gzipped CSV format. + +> 📘 Octet header required +> +> You will have to specify the header Accept: `application/octet-stream` when hitting this endpoint.
@@ -17533,12 +21819,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.data_attributes.create_data_attribute( - name="My Data Attribute", - model="contact", - data_type="string", - description="Just a plain old ring", - options=["options"], +client.unstable.data_export.download_data_export( + job_identifier="job_identifier", ) ``` @@ -17555,47 +21837,7 @@ client.unstable.data_attributes.create_data_attribute(
-**name:** `str` — The name of the data attribute. - -
-
- -
-
- -**model:** `CreateDataAttributeRequestModel` — The model that the data attribute belongs to. - -
-
- -
-
- -**data_type:** `CreateDataAttributeRequestDataType` — The type of data stored for this attribute. - -
-
- -
-
- -**description:** `typing.Optional[str]` — The readable description you see in the UI for the attribute. - -
-
- -
-
- -**options:** `typing.Optional[typing.Sequence[str]]` — To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - -
-
- -
-
- -**messenger_writable:** `typing.Optional[bool]` — Can this attribute be updated by the Messenger +**job_identifier:** `str` — job_identifier
@@ -17615,7 +21857,8 @@ client.unstable.data_attributes.create_data_attribute(
-
client.unstable.data_attributes.update_data_attribute(...) +## Jobs +
client.unstable.jobs.status(...)
@@ -17627,12 +21870,7 @@ client.unstable.data_attributes.create_data_attribute(
- -You can update a data attribute. - -> 🚧 Updating the data type is not possible -> -> It is currently a dangerous action to execute changing a data attribute's type via the API. You will need to update the type via the UI instead. +Retrieve the status of job execution.
@@ -17652,10 +21890,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.data_attributes.update_data_attribute( - id=1, - archived=True, - description="Trying to archieve", +client.unstable.jobs.status( + id="id", ) ``` @@ -17672,39 +21908,7 @@ client.unstable.data_attributes.update_data_attribute(
-**id:** `int` — The data attribute id - -
-
- -
-
- -**archived:** `typing.Optional[bool]` — Whether the attribute is to be archived or not. - -
-
- -
-
- -**description:** `typing.Optional[str]` — The readable description you see in the UI for the attribute. - -
-
- -
-
- -**options:** `typing.Optional[typing.Sequence[str]]` — To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - -
-
- -
-
- -**messenger_writable:** `typing.Optional[bool]` — Can this attribute be updated by the Messenger +**id:** `str` — The unique identifier for the job which is given by Intercom
@@ -17724,8 +21928,8 @@ client.unstable.data_attributes.update_data_attribute(
-## Data Events -
client.unstable.data_events.lis_data_events(...) +## Macros +
client.unstable.macros.list_macros(...)
@@ -17737,20 +21941,19 @@ client.unstable.data_attributes.update_data_attribute(
+You can fetch a list of all macros (saved replies) in your workspace for use in automating responses. -> 🚧 -> -> Please note that you can only 'list' events that are less than 90 days old. Event counts and summaries will still include your events older than 90 days but you cannot 'list' these events individually if they are older than 90 days +The macros are returned in descending order by updated_at. -The events belonging to a customer can be listed by sending a GET request to `https://api.intercom.io/events` with a user or lead identifier along with a `type` parameter. The identifier parameter can be one of `user_id`, `email` or `intercom_user_id`. The `type` parameter value must be `user`. +**Pagination** -- `https://api.intercom.io/events?type=user&user_id={user_id}` -- `https://api.intercom.io/events?type=user&email={email}` -- `https://api.intercom.io/events?type=user&intercom_user_id={id}` (this call can be used to list leads) +This endpoint uses cursor-based pagination via the `starting_after` parameter. The cursor is a Base64-encoded JSON array containing `[updated_at, id]` of the last item from the previous page. -The `email` parameter value should be [url encoded](http://en.wikipedia.org/wiki/Percent-encoding) when sending. +**Placeholder Transformation** -You can optionally define the result page size as well with the `per_page` parameter. +The API transforms Intercom placeholders to a more standard XML-like format: +- From: `{{user.name | fallback: 'there'}}` +- To: ``
@@ -17766,16 +21969,12 @@ You can optionally define the result page size as well with the `per_page` param ```python from intercom import Intercom -from intercom.unstable.data_events import LisDataEventsRequestFilterUserId client = Intercom( token="YOUR_TOKEN", ) -client.unstable.data_events.lis_data_events( - filter=LisDataEventsRequestFilterUserId( - user_id="user_id", - ), - type="type", +client.unstable.macros.list_macros( + starting_after="WzE3MTk0OTM3NTcuMCwgIjEyMyJd", ) ``` @@ -17792,7 +21991,7 @@ client.unstable.data_events.lis_data_events(
-**filter:** `LisDataEventsRequestFilter` +**per_page:** `typing.Optional[int]` — The number of results per page
@@ -17800,7 +21999,7 @@ client.unstable.data_events.lis_data_events(
-**type:** `str` — The value must be user +**starting_after:** `typing.Optional[str]` — Base64-encoded cursor containing [updated_at, id] for pagination
@@ -17808,7 +22007,7 @@ client.unstable.data_events.lis_data_events(
-**summary:** `typing.Optional[bool]` — summary flag +**updated_since:** `typing.Optional[int]` — Unix timestamp to filter macros updated after this time
@@ -17828,7 +22027,7 @@ client.unstable.data_events.lis_data_events(
-
client.unstable.data_events.create_data_event(...) +
client.unstable.macros.get_macro(...)
@@ -17840,47 +22039,23 @@ client.unstable.data_events.lis_data_events(
+You can fetch a single macro (saved reply) by its ID. The macro will only be returned if it is visible to the authenticated user based on its visibility settings. -You will need an Access Token that has write permissions to send Events. Once you have a key you can submit events via POST to the Events resource, which is located at https://api.intercom.io/events, or you can send events using one of the client libraries. When working with the HTTP API directly a client should send the event with a `Content-Type` of `application/json`. - -When using the JavaScript API, [adding the code to your app](http://docs.intercom.io/configuring-Intercom/tracking-user-events-in-your-app) makes the Events API available. Once added, you can submit an event using the `trackEvent` method. This will associate the event with the Lead or currently logged-in user or logged-out visitor/lead and send it to Intercom. The final parameter is a map that can be used to send optional metadata about the event. - -With the Ruby client you pass a hash describing the event to `Intercom::Event.create`, or call the `track_user` method directly on the current user object (e.g. `user.track_event`). - -**NB: For the JSON object types, please note that we do not currently support nested JSON structure.** - -| Type | Description | Example | -| :-------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------- | -| String | The value is a JSON String | `"source":"desktop"` | -| Number | The value is a JSON Number | `"load": 3.67` | -| Date | The key ends with the String `_date` and the value is a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time), assumed to be in the [UTC](http://en.wikipedia.org/wiki/Coordinated_Universal_Time) timezone. | `"contact_date": 1392036272` | -| Link | The value is a HTTP or HTTPS URI. | `"article": "https://example.org/ab1de.html"` | -| Rich Link | The value is a JSON object that contains `url` and `value` keys. | `"article": {"url": "https://example.org/ab1de.html", "value":"the dude abides"}` | -| Monetary Amount | The value is a JSON object that contains `amount` and `currency` keys. The `amount` key is a positive integer representing the amount in cents. The price in the example to the right denotes €349.99. | `"price": {"amount": 34999, "currency": "eur"}` | - -**Lead Events** - -When submitting events for Leads, you will need to specify the Lead's `id`. - -**Metadata behaviour** - -- We currently limit the number of tracked metadata keys to 10 per event. Once the quota is reached, we ignore any further keys we receive. The first 10 metadata keys are determined by the order in which they are sent in with the event. -- It is not possible to change the metadata keys once the event has been sent. A new event will need to be created with the new keys and you can archive the old one. -- There might be up to 24 hrs delay when you send a new metadata for an existing event. +**Visibility Rules** -**Event de-duplication** +A macro is returned based on its `visible_to` setting: +- `everyone`: Always visible to all team members +- `specific_teams`: Only visible if the authenticated user belongs to one of the teams specified in `visible_to_team_ids` -The API may detect and ignore duplicate events. Each event is uniquely identified as a combination of the following data - the Workspace identifier, the Contact external identifier, the Data Event name and the Data Event created time. As a result, it is **strongly recommended** to send a second granularity Unix timestamp in the `created_at` field. +If a macro exists but is not visible to the authenticated user, a 404 error is returned. -Duplicated events are responded to using the normal `202 Accepted` code - an error is not thrown, however repeat requests will be counted against any rate limit that is in place. +**Placeholder Transformation** -### HTTP API Responses +The API transforms Intercom placeholders to a more standard XML-like format in the `body` field: +- From: `{{user.name | fallback: 'there'}}` +- To: `` -- Successful responses to submitted events return `202 Accepted` with an empty body. -- Unauthorised access will be rejected with a `401 Unauthorized` or `403 Forbidden` response code. -- Events sent about users that cannot be found will return a `404 Not Found`. -- Event lists containing duplicate events will have those duplicates ignored. -- Server errors will return a `500` response code and may contain an error message in the body. +Default values in placeholders are HTML-escaped for security.
@@ -17900,8 +22075,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.data_events.create_data_event( - request={"key": "value"}, +client.unstable.macros.get_macro( + id="123", ) ``` @@ -17918,7 +22093,7 @@ client.unstable.data_events.create_data_event(
-**request:** `CreateDataEventRequestTwo` +**id:** `str` — The unique identifier of the macro
@@ -17938,7 +22113,8 @@ client.unstable.data_events.create_data_event(
-
client.unstable.data_events.data_event_summaries(...) +## Messages +
client.unstable.messages.create_message(...)
@@ -17950,7 +22126,17 @@ client.unstable.data_events.create_data_event(
-Create event summaries for a user. Event summaries are used to track the number of times an event has occurred, the first time it occurred and the last time it occurred. +You can create a message that has been initiated by an admin. The conversation can be either an in-app message, an email, sms or whatsapp. + +> 🚧 Sending for visitors +> +> There can be a short delay between when a contact is created and when a contact becomes available to be messaged through the API. A 404 Not Found error will be returned in this case. + +This will return the Message model that has been created. + +> 🚧 Retrieving Associated Conversations +> +> As this is a message, there will be no conversation present until the contact responds. Once they do, you will have to search for a contact's conversations with the id of the message.
@@ -17970,7 +22156,14 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.data_events.data_event_summaries() +client.unstable.messages.create_message( + request={ + "from": {"type": "admin", "id": "991267821"}, + "to": {"type": "user", "id": "6762f23b1bb69f9f2193bc1d"}, + "message_type": "sms", + "body": "heyy https://picsum.photos/200/300", + }, +) ``` @@ -17986,15 +22179,7 @@ client.unstable.data_events.data_event_summaries()
-**user_id:** `typing.Optional[str]` — Your identifier for the user. - -
-
- -
-
- -**event_summaries:** `typing.Optional[CreateDataEventSummariesRequestEventSummaries]` — A list of event summaries for the user. Each event summary should contain the event name, the time the event occurred, and the number of times the event occurred. The event name should be a past tense 'verb-noun' combination, to improve readability, for example `updated-plan`. +**request:** `CreateMessageRequestThree`
@@ -18014,8 +22199,7 @@ client.unstable.data_events.data_event_summaries()
-## Data Export -
client.unstable.data_export.create_data_export(...) +
client.unstable.messages.get_whats_app_message_status(...)
@@ -18027,21 +22211,11 @@ client.unstable.data_events.data_event_summaries()
-To create your export job, you need to send a `POST` request to the export endpoint `https://api.intercom.io/export/content/data`. - -The only parameters you need to provide are the range of dates that you want exported. - ->🚧 Limit of one active job -> -> You can only have one active job per workspace. You will receive a HTTP status code of 429 with the message Exceeded rate limit of 1 pending message data export jobs if you attempt to create a second concurrent job. +Retrieves statuses of messages sent from the Outbound module. Currently, this API only supports WhatsApp messages. ->❗️ Updated_at not included -> -> It should be noted that the timeframe only includes messages sent during the time period and not messages that were only updated during this period. For example, if a message was updated yesterday but sent two days ago, you would need to set the created_at_after date before the message was sent to include that in your retrieval job. ->📘 Date ranges are inclusive -> -> Requesting data for 2018-06-01 until 2018-06-30 will get all data for those days including those specified - e.g. 2018-06-01 00:00:00 until 2018-06-30 23:59:99. +This endpoint returns paginated status events for WhatsApp messages sent via the Outbound module, providing +information about delivery state and related message details.
@@ -18061,9 +22235,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.data_export.create_data_export( - created_at_after=1734519776, - created_at_before=1734537776, +client.unstable.messages.get_whats_app_message_status( + ruleset_id="ruleset_id", ) ``` @@ -18080,7 +22253,7 @@ client.unstable.data_export.create_data_export(
-**created_at_after:** `int` — The start date that you request data for. It must be formatted as a unix timestamp. +**ruleset_id:** `str` — The unique identifier for the set of messages to check status for
@@ -18088,7 +22261,15 @@ client.unstable.data_export.create_data_export(
-**created_at_before:** `int` — The end date that you request data for. It must be formatted as a unix timestamp. +**per_page:** `typing.Optional[int]` — Number of results per page (default 50, max 100) + +
+
+ +
+
+ +**starting_after:** `typing.Optional[str]` — Cursor for pagination, used to fetch the next page of results
@@ -18108,7 +22289,8 @@ client.unstable.data_export.create_data_export(
-
client.unstable.data_export.get_data_export(...) +## News +
client.unstable.news.list_news_items()
@@ -18120,11 +22302,7 @@ client.unstable.data_export.create_data_export(
-You can view the status of your job by sending a `GET` request to the URL -`https://api.intercom.io/export/content/data/{job_identifier}` - the `{job_identifier}` is the value returned in the response when you first created the export job. More on it can be seen in the Export Job Model. - -> 🚧 Jobs expire after two days -> All jobs that have completed processing (and are thus available to download from the provided URL) will have an expiry limit of two days from when the export ob completed. After this, the data will no longer be available. +You can fetch a list of all news items
@@ -18144,9 +22322,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.data_export.get_data_export( - job_identifier="job_identifier", -) +client.unstable.news.list_news_items() ``` @@ -18162,14 +22338,6 @@ client.unstable.data_export.get_data_export(
-**job_identifier:** `str` — job_identifier - -
-
- -
-
- **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -18182,7 +22350,7 @@ client.unstable.data_export.get_data_export(
-
client.unstable.data_export.cancel_data_export(...) +
client.unstable.news.create_news_item(...)
@@ -18194,7 +22362,7 @@ client.unstable.data_export.get_data_export(
-You can cancel your job +You can create a news item
@@ -18210,12 +22378,25 @@ You can cancel your job ```python from intercom import Intercom +from intercom.unstable.news import NewsfeedAssignment client = Intercom( token="YOUR_TOKEN", ) -client.unstable.data_export.cancel_data_export( - job_identifier="job_identifier", +client.unstable.news.create_news_item( + title="Halloween is here!", + body="

New costumes in store for this spooky season

", + sender_id=991267834, + state="live", + deliver_silently=True, + labels=["Product", "Update", "New"], + reactions=["😆", "😅"], + newsfeed_assignments=[ + NewsfeedAssignment( + newsfeed_id=53, + published_at=1664638214, + ) + ], ) ``` @@ -18232,7 +22413,7 @@ client.unstable.data_export.cancel_data_export(
-**job_identifier:** `str` — job_identifier +**title:** `str` — The title of the news item.
@@ -18240,75 +22421,55 @@ client.unstable.data_export.cancel_data_export(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**sender_id:** `int` — The id of the sender of the news item. Must be a teammate on the workspace.
- -
+
+
+**body:** `typing.Optional[str]` — The news item body, which may contain HTML. +
-
-
client.unstable.data_export.download_data_export(...)
-#### 📝 Description - -
-
+**state:** `typing.Optional[NewsItemRequestState]` — News items will not be visible to your users in the assigned newsfeeds until they are set live. + +
+
-When a job has a status of complete, and thus a filled download_url, you can download your data by hitting that provided URL, formatted like so: https://api.intercom.io/download/content/data/xyz1234. - -Your exported message data will be streamed continuously back down to you in a gzipped CSV format. - -> 📘 Octet header required -> -> You will have to specify the header Accept: `application/octet-stream` when hitting this endpoint. -
-
+**deliver_silently:** `typing.Optional[bool]` — When set to `true`, the news item will appear in the messenger newsfeed without showing a notification badge. +
-#### 🔌 Usage - -
-
-
-```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.unstable.data_export.download_data_export( - job_identifier="job_identifier", -) - -``` -
-
+**labels:** `typing.Optional[typing.Sequence[str]]` — Label names displayed to users to categorize the news item. +
-#### ⚙️ Parameters -
+**reactions:** `typing.Optional[typing.Sequence[typing.Optional[str]]]` — Ordered list of emoji reactions to the news item. When empty, reactions are disabled. + +
+
+
-**job_identifier:** `str` — job_identifier +**newsfeed_assignments:** `typing.Optional[typing.Sequence[NewsfeedAssignment]]` — A list of newsfeed_assignments to assign to the specified newsfeed.
@@ -18328,8 +22489,7 @@ client.unstable.data_export.download_data_export(
-## Jobs -
client.unstable.jobs.status(...) +
client.unstable.news.retrieve_news_item(...)
@@ -18341,7 +22501,7 @@ client.unstable.data_export.download_data_export(
-Retrieve the status of job execution. +You can fetch the details of a single news item.
@@ -18361,8 +22521,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.jobs.status( - id="id", +client.unstable.news.retrieve_news_item( + id=1, ) ``` @@ -18379,7 +22539,7 @@ client.unstable.jobs.status(
-**id:** `str` — The unique identifier for the job which is given by Intercom +**id:** `int` — The unique identifier for the news item which is given by Intercom.
@@ -18399,35 +22559,10 @@ client.unstable.jobs.status(
-## Messages -
client.unstable.messages.create_message(...) -
-
- -#### 📝 Description - -
-
- +
client.unstable.news.update_news_item(...)
-You can create a message that has been initiated by an admin. The conversation can be either an in-app message, an email, sms or whatsapp. - -> 🚧 Sending for visitors -> -> There can be a short delay between when a contact is created and when a contact becomes available to be messaged through the API. A 404 Not Found error will be returned in this case. - -This will return the Message model that has been created. - -> 🚧 Retrieving Associated Conversations -> -> As this is a message, there will be no conversation present until the contact responds. Once they do, you will have to search for a contact's conversations with the id of the message. -
-
-
-
- #### 🔌 Usage
@@ -18442,13 +22577,12 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.messages.create_message( - request={ - "from": {"type": "admin", "id": "991267821"}, - "to": {"type": "user", "id": "6762f23b1bb69f9f2193bc1d"}, - "message_type": "sms", - "body": "heyy https://picsum.photos/200/300", - }, +client.unstable.news.update_news_item( + id=1, + title="Christmas is here!", + body="

New gifts in store for the jolly season

", + sender_id=991267848, + reactions=["😝", "😂"], ) ``` @@ -18465,7 +22599,7 @@ client.unstable.messages.create_message(
-**request:** `CreateMessageRequestThree` +**id:** `int` — The unique identifier for the news item which is given by Intercom.
@@ -18473,73 +22607,47 @@ client.unstable.messages.create_message(
-**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. +**title:** `str` — The title of the news item.
-
-
- - - - -
-
client.unstable.messages.get_whats_app_message_status(...)
-#### 📝 Description - -
-
+**sender_id:** `int` — The id of the sender of the news item. Must be a teammate on the workspace. + +
+
-Retrieves statuses of messages sent from the Outbound module. Currently, this API only supports WhatsApp messages. - - -This endpoint returns paginated status events for WhatsApp messages sent via the Outbound module, providing -information about delivery state and related message details. -
-
+**body:** `typing.Optional[str]` — The news item body, which may contain HTML. +
-#### 🔌 Usage - -
-
-
-```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.unstable.messages.get_whats_app_message_status( - ruleset_id="ruleset_id", -) - -``` -
-
+**state:** `typing.Optional[NewsItemRequestState]` — News items will not be visible to your users in the assigned newsfeeds until they are set live. +
-#### ⚙️ Parameters -
+**deliver_silently:** `typing.Optional[bool]` — When set to `true`, the news item will appear in the messenger newsfeed without showing a notification badge. + +
+
+
-**ruleset_id:** `str` — The unique identifier for the set of messages to check status for +**labels:** `typing.Optional[typing.Sequence[str]]` — Label names displayed to users to categorize the news item.
@@ -18547,7 +22655,7 @@ client.unstable.messages.get_whats_app_message_status(
-**per_page:** `typing.Optional[int]` — Number of results per page (default 50, max 100) +**reactions:** `typing.Optional[typing.Sequence[typing.Optional[str]]]` — Ordered list of emoji reactions to the news item. When empty, reactions are disabled.
@@ -18555,7 +22663,7 @@ client.unstable.messages.get_whats_app_message_status(
-**starting_after:** `typing.Optional[str]` — Cursor for pagination, used to fetch the next page of results +**newsfeed_assignments:** `typing.Optional[typing.Sequence[NewsfeedAssignment]]` — A list of newsfeed_assignments to assign to the specified newsfeed.
@@ -18575,8 +22683,7 @@ client.unstable.messages.get_whats_app_message_status(
-## News -
client.unstable.news.list_news_items() +
client.unstable.news.delete_news_item(...)
@@ -18588,7 +22695,7 @@ client.unstable.messages.get_whats_app_message_status(
-You can fetch a list of all news items +You can delete a single news item.
@@ -18608,7 +22715,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.news.list_news_items() +client.unstable.news.delete_news_item( + id=1, +) ``` @@ -18624,6 +22733,14 @@ client.unstable.news.list_news_items()
+**id:** `int` — The unique identifier for the news item which is given by Intercom. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -18636,7 +22753,7 @@ client.unstable.news.list_news_items()
-
client.unstable.news.create_news_item(...) +
client.unstable.news.list_live_newsfeed_items(...)
@@ -18648,7 +22765,7 @@ client.unstable.news.list_news_items()
-You can create a news item +You can fetch a list of all news items that are live on a given newsfeed
@@ -18664,25 +22781,12 @@ You can create a news item ```python from intercom import Intercom -from intercom.unstable.news import NewsfeedAssignment client = Intercom( token="YOUR_TOKEN", ) -client.unstable.news.create_news_item( - title="Halloween is here!", - body="

New costumes in store for this spooky season

", - sender_id=991267834, - state="live", - deliver_silently=True, - labels=["Product", "Update", "New"], - reactions=["😆", "😅"], - newsfeed_assignments=[ - NewsfeedAssignment( - newsfeed_id=53, - published_at=1664638214, - ) - ], +client.unstable.news.list_live_newsfeed_items( + id="123", ) ``` @@ -18699,7 +22803,7 @@ client.unstable.news.create_news_item(
-**title:** `str` — The title of the news item. +**id:** `str` — The unique identifier for the news feed item which is given by Intercom.
@@ -18707,58 +22811,62 @@ client.unstable.news.create_news_item(
-**sender_id:** `int` — The id of the sender of the news item. Must be a teammate on the workspace. +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
+ +
-
-
-**body:** `typing.Optional[str]` — The news item body, which may contain HTML. -
+
+
client.unstable.news.list_newsfeeds()
-**state:** `typing.Optional[NewsItemRequestState]` — News items will not be visible to your users in the assigned newsfeeds until they are set live. - -
-
+#### 📝 Description
-**deliver_silently:** `typing.Optional[bool]` — When set to `true`, the news item will appear in the messenger newsfeed without showing a notification badge. - -
-
-
-**labels:** `typing.Optional[typing.Sequence[str]]` — Label names displayed to users to categorize the news item. - +You can fetch a list of all newsfeeds
+ + + +#### 🔌 Usage
-**reactions:** `typing.Optional[typing.Sequence[typing.Optional[str]]]` — Ordered list of emoji reactions to the news item. When empty, reactions are disabled. - -
-
-
-**newsfeed_assignments:** `typing.Optional[typing.Sequence[NewsfeedAssignment]]` — A list of newsfeed_assignments to assign to the specified newsfeed. - +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.news.list_newsfeeds() + +```
+ + + +#### ⚙️ Parameters + +
+
@@ -18775,7 +22883,7 @@ client.unstable.news.create_news_item(
-
client.unstable.news.retrieve_news_item(...) +
client.unstable.news.retrieve_newsfeed(...)
@@ -18787,7 +22895,7 @@ client.unstable.news.create_news_item(
-You can fetch the details of a single news item. +You can fetch the details of a single newsfeed
@@ -18807,8 +22915,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.news.retrieve_news_item( - id=1, +client.unstable.news.retrieve_newsfeed( + id="123", ) ``` @@ -18825,7 +22933,7 @@ client.unstable.news.retrieve_news_item(
-**id:** `int` — The unique identifier for the news item which is given by Intercom. +**id:** `str` — The unique identifier for the news feed item which is given by Intercom.
@@ -18845,11 +22953,12 @@ client.unstable.news.retrieve_news_item(
-
client.unstable.news.update_news_item(...) +## Segments +
client.unstable.segments.list_segments(...)
-#### 🔌 Usage +#### 📝 Description
@@ -18857,99 +22966,43 @@ client.unstable.news.retrieve_news_item(
-```python -from intercom import Intercom - -client = Intercom( - token="YOUR_TOKEN", -) -client.unstable.news.update_news_item( - id=1, - title="Christmas is here!", - body="

New gifts in store for the jolly season

", - sender_id=991267848, - reactions=["😝", "😂"], -) - -``` -
-
+You can fetch a list of all segments.
- -#### ⚙️ Parameters - -
-
- -
-
- -**id:** `int` — The unique identifier for the news item which is given by Intercom. -
-
-
- -**title:** `str` — The title of the news item. - -
-
+#### 🔌 Usage
-**sender_id:** `int` — The id of the sender of the news item. Must be a teammate on the workspace. - -
-
-
-**body:** `typing.Optional[str]` — The news item body, which may contain HTML. - -
-
+```python +from intercom import Intercom -
-
+client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.segments.list_segments() -**state:** `typing.Optional[NewsItemRequestState]` — News items will not be visible to your users in the assigned newsfeeds until they are set live. - +```
- -
-
- -**deliver_silently:** `typing.Optional[bool]` — When set to `true`, the news item will appear in the messenger newsfeed without showing a notification badge. -
-
-
- -**labels:** `typing.Optional[typing.Sequence[str]]` — Label names displayed to users to categorize the news item. - -
-
+#### ⚙️ Parameters
-**reactions:** `typing.Optional[typing.Sequence[typing.Optional[str]]]` — Ordered list of emoji reactions to the news item. When empty, reactions are disabled. - -
-
-
-**newsfeed_assignments:** `typing.Optional[typing.Sequence[NewsfeedAssignment]]` — A list of newsfeed_assignments to assign to the specified newsfeed. +**include_count:** `typing.Optional[bool]` — It includes the count of contacts that belong to each segment.
@@ -18969,7 +23022,7 @@ client.unstable.news.update_news_item(
-
client.unstable.news.delete_news_item(...) +
client.unstable.segments.retrieve_segment(...)
@@ -18981,7 +23034,7 @@ client.unstable.news.update_news_item(
-You can delete a single news item. +You can fetch the details of a single segment.
@@ -19001,8 +23054,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.news.delete_news_item( - id=1, +client.unstable.segments.retrieve_segment( + id="123", ) ``` @@ -19019,7 +23072,7 @@ client.unstable.news.delete_news_item(
-**id:** `int` — The unique identifier for the news item which is given by Intercom. +**id:** `str` — The unique identified of a given segment.
@@ -19039,7 +23092,8 @@ client.unstable.news.delete_news_item(
-
client.unstable.news.list_live_newsfeed_items(...) +## Switch +
client.unstable.switch.create_phone_switch(...)
@@ -19051,7 +23105,10 @@ client.unstable.news.delete_news_item(
-You can fetch a list of all news items that are live on a given newsfeed +You can use the API to deflect phone calls to the Intercom Messenger. +Calling this endpoint will send an SMS with a link to the Messenger to the phone number specified. + +If custom attributes are specified, they will be added to the user or lead's custom data attributes.
@@ -19071,8 +23128,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.news.list_live_newsfeed_items( - id="123", +client.unstable.switch.create_phone_switch( + request={"key": "value"}, ) ``` @@ -19089,7 +23146,7 @@ client.unstable.news.list_live_newsfeed_items(
-**id:** `str` — The unique identifier for the news feed item which is given by Intercom. +**request:** `typing.Optional[typing.Any]`
@@ -19109,7 +23166,8 @@ client.unstable.news.list_live_newsfeed_items(
-
client.unstable.news.list_newsfeeds() +## Unstable Calls +
client.unstable.calls.list_calls(...)
@@ -19121,7 +23179,7 @@ client.unstable.news.list_live_newsfeed_items(
-You can fetch a list of all newsfeeds +Retrieve a paginated list of calls.
@@ -19141,7 +23199,7 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.news.list_newsfeeds() +client.unstable.calls.list_calls() ``` @@ -19157,6 +23215,22 @@ client.unstable.news.list_newsfeeds()
+**page:** `typing.Optional[int]` — The page of results to fetch. Defaults to first page + +
+
+ +
+
+ +**per_page:** `typing.Optional[int]` — How many results to display per page. Defaults to 25. Max 25. + +
+
+ +
+
+ **request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration.
@@ -19169,7 +23243,7 @@ client.unstable.news.list_newsfeeds()
-
client.unstable.news.retrieve_newsfeed(...) +
client.unstable.calls.show_call(...)
@@ -19181,7 +23255,7 @@ client.unstable.news.list_newsfeeds()
-You can fetch the details of a single newsfeed +Retrieve a single call by id.
@@ -19201,8 +23275,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.news.retrieve_newsfeed( - id="123", +client.unstable.calls.show_call( + id="id", ) ``` @@ -19219,7 +23293,7 @@ client.unstable.news.retrieve_newsfeed(
-**id:** `str` — The unique identifier for the news feed item which is given by Intercom. +**id:** `str` — The id of the call to retrieve
@@ -19239,8 +23313,7 @@ client.unstable.news.retrieve_newsfeed(
-## Segments -
client.unstable.segments.list_segments(...) +
client.unstable.calls.show_call_recording(...)
@@ -19252,7 +23325,7 @@ client.unstable.news.retrieve_newsfeed(
-You can fetch a list of all segments. +Redirects to a signed URL for the call's recording if it exists.
@@ -19272,7 +23345,9 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.segments.list_segments() +client.unstable.calls.show_call_recording( + id="id", +) ``` @@ -19288,7 +23363,7 @@ client.unstable.segments.list_segments()
-**include_count:** `typing.Optional[bool]` — It includes the count of contacts that belong to each segment. +**id:** `str` — The id of the call
@@ -19308,7 +23383,7 @@ client.unstable.segments.list_segments()
-
client.unstable.segments.retrieve_segment(...) +
client.unstable.calls.show_call_transcript(...)
@@ -19320,7 +23395,7 @@ client.unstable.segments.list_segments()
-You can fetch the details of a single segment. +Returns the transcript for the specified call as a downloadable text file.
@@ -19340,8 +23415,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.segments.retrieve_segment( - id="123", +client.unstable.calls.show_call_transcript( + id="id", ) ``` @@ -19358,7 +23433,7 @@ client.unstable.segments.retrieve_segment(
-**id:** `str` — The unique identified of a given segment. +**id:** `str` — The id of the call
@@ -19378,8 +23453,7 @@ client.unstable.segments.retrieve_segment(
-## Switch -
client.unstable.switch.create_phone_switch(...) +
client.unstable.calls.list_calls_with_transcripts(...)
@@ -19391,10 +23465,8 @@ client.unstable.segments.retrieve_segment(
-You can use the API to deflect phone calls to the Intercom Messenger. -Calling this endpoint will send an SMS with a link to the Messenger to the phone number specified. - -If custom attributes are specified, they will be added to the user or lead's custom data attributes. +Retrieve calls by a list of conversation ids and include transcripts when available. +A maximum of 20 `conversation_ids` can be provided. If none are provided or more than 20 are provided, a 400 error is returned.
@@ -19414,8 +23486,8 @@ from intercom import Intercom client = Intercom( token="YOUR_TOKEN", ) -client.unstable.switch.create_phone_switch( - request={"key": "value"}, +client.unstable.calls.list_calls_with_transcripts( + conversation_ids=["64619700005694", "64619700005695"], ) ``` @@ -19432,7 +23504,7 @@ client.unstable.switch.create_phone_switch(
-**request:** `typing.Optional[typing.Any]` +**conversation_ids:** `typing.Sequence[str]` — A list of conversation ids to fetch calls for. Maximum 20.
@@ -21053,3 +25125,266 @@ client.unstable.visitors.convert_visitor(
+## Brands +
client.unstable.brands.list_brands() +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves all brands for the workspace, including the default brand. +The default brand id always matches the workspace +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.brands.list_brands() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.brands.retrieve_brand(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Fetches a specific brand by its unique identifier +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.brands.retrieve_brand( + id="id", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The unique identifier of the brand + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +## Emails +
client.unstable.emails.list_emails() +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Lists all sender email address settings for the workspace +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.emails.list_emails() + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ +
client.unstable.emails.retrieve_email(...) +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Fetches a specific email setting by its unique identifier +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from intercom import Intercom + +client = Intercom( + token="YOUR_TOKEN", +) +client.unstable.emails.retrieve_email( + id="id", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**id:** `str` — The unique identifier of the email setting + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ + +
+
+
+ diff --git a/src/intercom/__init__.py b/src/intercom/__init__.py index a38fa41..0fa9981 100644 --- a/src/intercom/__init__.py +++ b/src/intercom/__init__.py @@ -3,10 +3,6 @@ # isort: skip_file from .types import ( - ActionComponent, - ActionComponent_Sheet, - ActionComponent_Submit, - ActionComponent_Url, ActivityLog, ActivityLogActivityType, ActivityLogList, @@ -30,46 +26,26 @@ ArticleTranslatedContent, AssignConversationRequest, AssignConversationRequestType, - ButtonComponent, - ButtonComponentStyle, - CanvasObject, - CheckboxComponent, - CheckboxComponentSaveState, - CheckboxOption, + AwayStatusReason, + CallList, CloseConversationRequest, CollectionList, CompanyAttachedContacts, CompanyAttachedSegments, + CompanyData, CompanyList, CompanyScroll, - Component, - Component_Button, - Component_Checkbox, - Component_DataTable, - Component_Divider, - Component_Dropdown, - Component_Image, - Component_Input, - Component_List, - Component_SingleSelect, - Component_Spacer, - Component_Text, - Component_Textarea, - ConfigureRequest, - ConfigureRequestComponentId, - ConfigureRequestZero, - ConfigureResponse, - ConfigureResponseCanvas, ContactArchived, ContactAttachedCompanies, + ContactBlocked, ContactCompanies, - ContactCompany, ContactDeleted, ContactList, ContactLocation, ContactNotes, ContactReference, ContactReplyBaseRequest, + ContactReplyBaseRequestReplyOptionsItem, ContactReplyConversationRequest, ContactReplyEmailRequest, ContactReplyIntercomUserIdRequest, @@ -83,31 +59,50 @@ ContactSubscriptionTypes, ContactTags, ContactUnarchived, - ContentObject, ContentSourcesList, - Context, - ContextLocation, ConversationAttachmentFiles, + ConversationAttributeUpdatedByAdmin, + ConversationAttributeUpdatedByAdminAttribute, + ConversationAttributeUpdatedByAdminValue, + ConversationAttributeUpdatedByWorkflow, + ConversationAttributeUpdatedByWorkflowAttribute, + ConversationAttributeUpdatedByWorkflowValue, + ConversationAttributeUpdatedByWorkflowWorkflow, ConversationContacts, + ConversationDeleted, ConversationFirstContactReply, + ConversationList, ConversationPart, ConversationPartAuthor, + ConversationPartMetadata, + ConversationPartMetadataQuickReplyOptionsItem, + ConversationPartState, ConversationParts, ConversationRating, + ConversationResponseTime, ConversationSource, ConversationSourceType, ConversationStatistics, ConversationTeammates, + CreateArticleRequest, + CreateArticleRequestParentType, + CreateArticleRequestState, CreateContactRequest, CreateContactRequestTwo, CreateContactRequestWithEmail, CreateContactRequestWithExternalId, CreateContactRequestWithRole, + CreateDataAttributeRequest, + CreateDataAttributeRequestOne, + CreateDataAttributeRequestOneDataType, + CreateDataAttributeRequestOptions, + CreateDataAttributeRequestOptionsOptionsItem, CreateDataEventRequest, CreateDataEventRequestTwo, CreateDataEventRequestWithEmail, CreateDataEventRequestWithId, CreateDataEventRequestWithUserId, + CreateInternalArticleRequest, CreateMessageRequest, CreateMessageRequestFrom, CreateMessageRequestThree, @@ -117,16 +112,33 @@ CreateMessageRequestWithInapp, CreateMessageRequest_Email, CreateMessageRequest_Inapp, + CreateOrUpdateCompanyRequest, CreateOrUpdateTagRequest, + CreatePhoneSwitchRequest, CreateTicketReplyWithCommentRequest, - CreateTicketRequest, + CreateTicketRequestAssignment, + CreateTicketRequestBody, CreateTicketRequestContactsItem, CreateTicketRequestContactsItemEmail, CreateTicketRequestContactsItemExternalId, CreateTicketRequestContactsItemId, - CurrentCanvas, + CreateTicketTypeRequest, + CreateTicketTypeRequestCategory, CursorPages, + CustomActionFinished, + CustomActionFinishedAction, + CustomActionFinishedActionResult, + CustomActionStarted, + CustomActionStartedAction, CustomAttributes, + CustomAttributesValue, + CustomChannelAttribute, + CustomChannelBaseEvent, + CustomChannelContact, + CustomChannelContactType, + CustomChannelNotificationResponse, + CustomObjectInstanceDeleted, + CustomObjectInstanceList, CustomerRequest, CustomerRequestEmail, CustomerRequestIntercomUserId, @@ -137,53 +149,49 @@ DataEventSummary, DataEventSummaryItem, DataExportCsv, - DataTableComponent, - DataTableItem, + Datetime, DeletedArticleObject, DeletedCollectionObject, DeletedCompanyObject, + DeletedInternalArticleObject, DeletedObject, - DividerComponent, - DropdownComponent, - DropdownComponentSaveState, - DropdownOption, + EmailAddressHeader, + EmailMessageMetadata, Error, ErrorErrorsItem, - Event, + EventDetails, FileAttribute, GroupContent, GroupTranslatedContent, - ImageComponent, - ImageComponentAlign, - InitializeRequest, - InitializeResponse, - InputComponent, - InputComponentSaveState, + InternalArticleList, LinkedObject, LinkedObjectList, LinkedObjectType, - ListComponent, - ListComponentItemsItem, - ListItem, - ListItemWithImage, - ListItemWithoutImage, - LiveCanvasRequest, - LiveCanvasResponse, Metadata, MultipleFilterSearchRequest, MultipleFilterSearchRequestOperator, - MultipleOrSingleFilterSearchRequest, + MultipleFilterSearchRequestValue, NewsItemRequest, NewsItemRequestState, + NotFoundErrorBody, + NotFoundErrorBodyErrorsItem, NoteList, OffsetPages, OpenConversationRequest, + OperatorWorkflowEvent, + OperatorWorkflowEventEvent, + OperatorWorkflowEventWorkflow, PagesLink, - PaginatedConversationResponse, - PaginatedNewsItemResponse, - PaginatedNewsfeedResponse, + PaginatedResponse, + PaginatedResponseDataItem, + PaginatedResponseDataItem_NewsItem, + PaginatedResponseDataItem_Newsfeed, + PaginatedResponseType, PartAttachment, PhoneSwitch, + QuickReplyOption, + Recipient, + RecipientType, RedactConversationRequest, RedactConversationRequestConversationPart, RedactConversationRequestSource, @@ -191,27 +199,18 @@ RedactConversationRequest_Source, Reference, ReplyConversationRequest, - ResultsResponse, SearchRequest, SearchRequestQuery, SegmentList, - SheetActionComponent, SingleFilterSearchRequest, SingleFilterSearchRequestOperator, SingleFilterSearchRequestValue, - SingleSelectComponent, - SingleSelectComponentSaveState, - SingleSelectOption, + SingleFilterSearchRequestValueItem, SlaApplied, SlaAppliedSlaStatus, SnoozeConversationRequest, SocialProfile, - SpacerComponent, - SpacerComponentSize, StartingAfterPaging, - SubmitActionComponent, - SubmitRequest, - SubmitResponse, SubscriptionTypeList, TagCompanyRequest, TagCompanyRequestCompaniesItem, @@ -221,10 +220,6 @@ Tags, TeamList, TeamPriorityLevel, - TextAreaComponent, - TextComponent, - TextComponentAlign, - TextComponentStyle, TicketCustomAttributes, TicketList, TicketPartAuthor, @@ -233,6 +228,7 @@ TicketReply, TicketReplyPartType, TicketRequestCustomAttributes, + TicketStateList, TicketTypeAttribute, TicketTypeAttributeDataType, TicketTypeAttributeList, @@ -240,11 +236,15 @@ Translation, UntagCompanyRequest, UntagCompanyRequestCompaniesItem, + UpdateArticleRequestBody, + UpdateArticleRequestBodyParentType, + UpdateDataAttributeRequestBody, + UpdateDataAttributeRequestOptions, + UpdateDataAttributeRequestOptionsOptionsItem, UpdateVisitorRequest, UpdateVisitorRequestOne, UpdateVisitorRequestWithId, UpdateVisitorRequestWithUserId, - UrlActionComponent, Visitor, VisitorAvatar, VisitorCompanies, @@ -254,22 +254,42 @@ VisitorSocialProfiles, VisitorTags, VisitorTagsTagsItem, + WhatsappMessageStatusList, + WhatsappMessageStatusListEventsItem, + WhatsappMessageStatusListEventsItemStatus, + WhatsappMessageStatusListPages, + WhatsappMessageStatusListPagesNext, +) +from .errors import ( + BadRequestError, + ForbiddenError, + NotFoundError, + TooManyRequestsError, + UnauthorizedError, + UnprocessableEntityError, ) -from .errors import BadRequestError, ForbiddenError, NotFoundError, UnauthorizedError, UnprocessableEntityError from . import ( admins, ai_agent, + ai_content, ai_content_source, articles, + away_status_reasons, + calls, companies, contacts, conversations, + custom_channel_events, + custom_object_instances, data_attributes, data_events, data_export, events, + export, help_center, help_centers, + internal_articles, + jobs, messages, news, notes, @@ -278,13 +298,25 @@ subscription_types, tags, teams, + ticket_states, ticket_types, tickets, unstable, visitors, ) -from .admins import Admin, AdminAvatar +from .admins import Admin from .ai_agent import AiAgent, AiAgentSourceType +from .ai_content import ( + ContentImportSource, + ContentImportSourceStatus, + ContentImportSourceSyncBehavior, + ContentImportSourcesList, + CreateContentImportSourceRequestStatus, + ExternalPage, + ExternalPagesList, + UpdateContentImportSourceRequestStatus, + UpdateContentImportSourceRequestSyncBehavior, +) from .ai_content_source import ContentSource from .articles import ( Article, @@ -295,13 +327,12 @@ ArticleSearchHighlightsHighlightedSummaryItemItemType, ArticleSearchHighlightsHighlightedTitleItem, ArticleSearchHighlightsHighlightedTitleItemType, - CreateArticleRequestParentType, - CreateArticleRequestState, - SearchArticlesResponse, - SearchArticlesResponseData, - UpdateArticleRequestBodyParentType, - UpdateArticleRequestBodyState, + ArticleSearchResponse, + ArticleSearchResponseData, + InternalArticle, + UpdateArticleRequestState, ) +from .calls import Call, ListCallsWithTranscriptsResponse, ListCallsWithTranscriptsResponseDataItem from .client import AsyncIntercom, Intercom from .companies import ( CompaniesRetrieveResponse, @@ -312,7 +343,14 @@ CompanySegments, CompanyTags, ) -from .contacts import Contact +from .contacts import ( + Contact, + ContactsCreateResponse, + ContactsFindResponse, + ContactsMergeLeadInUserResponse, + ContactsUpdateResponse, + ShowContactByExternalIdResponse, +) from .conversations import ( AttachContactToConversationRequestCustomer, AttachContactToConversationRequestCustomerCustomer, @@ -329,20 +367,21 @@ CreateConversationRequestFrom, CreateConversationRequestFromType, ) -from .data_attributes import ( - CreateDataAttributeRequestDataType, - CreateDataAttributeRequestModel, - DataAttribute, - DataAttributeDataType, - DataAttributeModel, - DataAttributesListRequestModel, - UpdateDataAttributeRequestOptionsItem, -) +from .custom_object_instances import CustomObjectInstance +from .data_attributes import DataAttribute, DataAttributeDataType, DataAttributeModel, DataAttributesListRequestModel from .data_events import DataEvent -from .data_export import DataExport, DataExportStatus +from .data_export import DataExport, DataExportExportReportingDataResponse, DataExportStatus from .environment import IntercomEnvironment from .events import CreateDataEventSummariesRequestEventSummaries +from .export import ( + GetExportReportingDataGetDatasetsResponse, + GetExportReportingDataGetDatasetsResponseDataItem, + GetExportReportingDataGetDatasetsResponseDataItemAttributesItem, + PostExportReportingDataEnqueueResponse, +) from .help_center import Collection, HelpCenter, HelpCenterList +from .internal_articles import InternalArticleListItem, InternalArticleSearchResponse, InternalArticleSearchResponseData +from .jobs import Jobs, JobsStatus from .messages import Message, MessageMessageType from .news import NewsItem, NewsItemState, Newsfeed, NewsfeedAssignment from .notes import Note, NoteContact @@ -353,22 +392,31 @@ SubscriptionTypeContentTypesItem, SubscriptionTypeState, ) -from .tags import Tag, TagsCreateRequestBody +from .tags import Tag, TagBasic, TagsCreateRequestBody from .teams import Team -from .ticket_types import CreateTicketTypeRequestCategory, UpdateTicketTypeRequestBodyCategory +from .ticket_types import UpdateTicketTypeRequestCategory from .tickets import ( + DeleteTicketResponse, Ticket, TicketCategory, TicketContacts, TicketPart, TicketPartPreviousTicketState, TicketPartTicketState, - TicketTicketState, + TicketPartUpdatedAttributeData, + TicketPartUpdatedAttributeDataAttribute, + TicketPartUpdatedAttributeDataValue, + TicketPartUpdatedAttributeDataValueId, + TicketPartUpdatedAttributeDataValueLabel, + TicketState, + TicketStateCategory, + TicketStateDetailed, + TicketStateDetailedCategory, + TicketStateDetailedTicketTypes, TicketType, TicketTypeCategory, + TicketTypeTicketStates, TicketsReplyRequestBody, - UpdateTicketRequestAssignment, - UpdateTicketRequestState, ) from .version import __version__ from .visitors import ( @@ -382,10 +430,6 @@ ) __all__ = [ - "ActionComponent", - "ActionComponent_Sheet", - "ActionComponent_Submit", - "ActionComponent_Url", "ActivityLog", "ActivityLogActivityType", "ActivityLogList", @@ -393,7 +437,6 @@ "ActivityLogPerformedBy", "AddressableList", "Admin", - "AdminAvatar", "AdminList", "AdminPriorityLevel", "AdminReplyConversationRequest", @@ -417,6 +460,8 @@ "ArticleSearchHighlightsHighlightedSummaryItemItemType", "ArticleSearchHighlightsHighlightedTitleItem", "ArticleSearchHighlightsHighlightedTitleItemType", + "ArticleSearchResponse", + "ArticleSearchResponseData", "ArticleStatistics", "ArticleTranslatedContent", "AssignConversationRequest", @@ -426,13 +471,10 @@ "AttachContactToConversationRequestCustomerCustomer", "AttachContactToConversationRequestCustomerIntercomUserId", "AttachContactToConversationRequestCustomerUserId", + "AwayStatusReason", "BadRequestError", - "ButtonComponent", - "ButtonComponentStyle", - "CanvasObject", - "CheckboxComponent", - "CheckboxComponentSaveState", - "CheckboxOption", + "Call", + "CallList", "CloseConversationRequest", "Collection", "CollectionList", @@ -442,40 +484,24 @@ "Company", "CompanyAttachedContacts", "CompanyAttachedSegments", + "CompanyData", "CompanyList", "CompanyPlan", "CompanyScroll", "CompanySegments", "CompanyTags", - "Component", - "Component_Button", - "Component_Checkbox", - "Component_DataTable", - "Component_Divider", - "Component_Dropdown", - "Component_Image", - "Component_Input", - "Component_List", - "Component_SingleSelect", - "Component_Spacer", - "Component_Text", - "Component_Textarea", - "ConfigureRequest", - "ConfigureRequestComponentId", - "ConfigureRequestZero", - "ConfigureResponse", - "ConfigureResponseCanvas", "Contact", "ContactArchived", "ContactAttachedCompanies", + "ContactBlocked", "ContactCompanies", - "ContactCompany", "ContactDeleted", "ContactList", "ContactLocation", "ContactNotes", "ContactReference", "ContactReplyBaseRequest", + "ContactReplyBaseRequestReplyOptionsItem", "ContactReplyConversationRequest", "ContactReplyEmailRequest", "ContactReplyIntercomUserIdRequest", @@ -489,20 +515,38 @@ "ContactSubscriptionTypes", "ContactTags", "ContactUnarchived", - "ContentObject", + "ContactsCreateResponse", + "ContactsFindResponse", + "ContactsMergeLeadInUserResponse", + "ContactsUpdateResponse", + "ContentImportSource", + "ContentImportSourceStatus", + "ContentImportSourceSyncBehavior", + "ContentImportSourcesList", "ContentSource", "ContentSourcesList", - "Context", - "ContextLocation", "Conversation", "ConversationAttachmentFiles", + "ConversationAttributeUpdatedByAdmin", + "ConversationAttributeUpdatedByAdminAttribute", + "ConversationAttributeUpdatedByAdminValue", + "ConversationAttributeUpdatedByWorkflow", + "ConversationAttributeUpdatedByWorkflowAttribute", + "ConversationAttributeUpdatedByWorkflowValue", + "ConversationAttributeUpdatedByWorkflowWorkflow", "ConversationContacts", + "ConversationDeleted", "ConversationFirstContactReply", + "ConversationList", "ConversationPart", "ConversationPartAuthor", + "ConversationPartMetadata", + "ConversationPartMetadataQuickReplyOptionsItem", + "ConversationPartState", "ConversationParts", "ConversationPriority", "ConversationRating", + "ConversationResponseTime", "ConversationSource", "ConversationSourceType", "ConversationState", @@ -515,6 +559,7 @@ "ConversationsManageRequestBody_Snoozed", "ConvertVisitorRequestUser", "ConvertVisitorRequestVisitor", + "CreateArticleRequest", "CreateArticleRequestParentType", "CreateArticleRequestState", "CreateContactRequest", @@ -522,16 +567,21 @@ "CreateContactRequestWithEmail", "CreateContactRequestWithExternalId", "CreateContactRequestWithRole", + "CreateContentImportSourceRequestStatus", "CreateConversationRequestFrom", "CreateConversationRequestFromType", - "CreateDataAttributeRequestDataType", - "CreateDataAttributeRequestModel", + "CreateDataAttributeRequest", + "CreateDataAttributeRequestOne", + "CreateDataAttributeRequestOneDataType", + "CreateDataAttributeRequestOptions", + "CreateDataAttributeRequestOptionsOptionsItem", "CreateDataEventRequest", "CreateDataEventRequestTwo", "CreateDataEventRequestWithEmail", "CreateDataEventRequestWithId", "CreateDataEventRequestWithUserId", "CreateDataEventSummariesRequestEventSummaries", + "CreateInternalArticleRequest", "CreateMessageRequest", "CreateMessageRequestFrom", "CreateMessageRequestThree", @@ -541,17 +591,34 @@ "CreateMessageRequestWithInapp", "CreateMessageRequest_Email", "CreateMessageRequest_Inapp", + "CreateOrUpdateCompanyRequest", "CreateOrUpdateTagRequest", + "CreatePhoneSwitchRequest", "CreateTicketReplyWithCommentRequest", - "CreateTicketRequest", + "CreateTicketRequestAssignment", + "CreateTicketRequestBody", "CreateTicketRequestContactsItem", "CreateTicketRequestContactsItemEmail", "CreateTicketRequestContactsItemExternalId", "CreateTicketRequestContactsItemId", + "CreateTicketTypeRequest", "CreateTicketTypeRequestCategory", - "CurrentCanvas", "CursorPages", + "CustomActionFinished", + "CustomActionFinishedAction", + "CustomActionFinishedActionResult", + "CustomActionStarted", + "CustomActionStartedAction", "CustomAttributes", + "CustomAttributesValue", + "CustomChannelAttribute", + "CustomChannelBaseEvent", + "CustomChannelContact", + "CustomChannelContactType", + "CustomChannelNotificationResponse", + "CustomObjectInstance", + "CustomObjectInstanceDeleted", + "CustomObjectInstanceList", "CustomerRequest", "CustomerRequestEmail", "CustomerRequestIntercomUserId", @@ -568,50 +635,51 @@ "DataEventSummaryItem", "DataExport", "DataExportCsv", + "DataExportExportReportingDataResponse", "DataExportStatus", - "DataTableComponent", - "DataTableItem", + "Datetime", + "DeleteTicketResponse", "DeletedArticleObject", "DeletedCollectionObject", "DeletedCompanyObject", + "DeletedInternalArticleObject", "DeletedObject", - "DividerComponent", - "DropdownComponent", - "DropdownComponentSaveState", - "DropdownOption", + "EmailAddressHeader", + "EmailMessageMetadata", "Error", "ErrorErrorsItem", - "Event", + "EventDetails", + "ExternalPage", + "ExternalPagesList", "FileAttribute", "ForbiddenError", + "GetExportReportingDataGetDatasetsResponse", + "GetExportReportingDataGetDatasetsResponseDataItem", + "GetExportReportingDataGetDatasetsResponseDataItemAttributesItem", "GroupContent", "GroupTranslatedContent", "HelpCenter", "HelpCenterList", - "ImageComponent", - "ImageComponentAlign", - "InitializeRequest", - "InitializeResponse", - "InputComponent", - "InputComponentSaveState", "Intercom", "IntercomEnvironment", + "InternalArticle", + "InternalArticleList", + "InternalArticleListItem", + "InternalArticleSearchResponse", + "InternalArticleSearchResponseData", + "Jobs", + "JobsStatus", "LinkedObject", "LinkedObjectList", "LinkedObjectType", - "ListComponent", - "ListComponentItemsItem", - "ListItem", - "ListItemWithImage", - "ListItemWithoutImage", - "LiveCanvasRequest", - "LiveCanvasResponse", + "ListCallsWithTranscriptsResponse", + "ListCallsWithTranscriptsResponseDataItem", "Message", "MessageMessageType", "Metadata", "MultipleFilterSearchRequest", "MultipleFilterSearchRequestOperator", - "MultipleOrSingleFilterSearchRequest", + "MultipleFilterSearchRequestValue", "NewsItem", "NewsItemRequest", "NewsItemRequestState", @@ -619,17 +687,28 @@ "Newsfeed", "NewsfeedAssignment", "NotFoundError", + "NotFoundErrorBody", + "NotFoundErrorBodyErrorsItem", "Note", "NoteContact", "NoteList", "OffsetPages", "OpenConversationRequest", + "OperatorWorkflowEvent", + "OperatorWorkflowEventEvent", + "OperatorWorkflowEventWorkflow", "PagesLink", - "PaginatedConversationResponse", - "PaginatedNewsItemResponse", - "PaginatedNewsfeedResponse", + "PaginatedResponse", + "PaginatedResponseDataItem", + "PaginatedResponseDataItem_NewsItem", + "PaginatedResponseDataItem_Newsfeed", + "PaginatedResponseType", "PartAttachment", "PhoneSwitch", + "PostExportReportingDataEnqueueResponse", + "QuickReplyOption", + "Recipient", + "RecipientType", "RedactConversationRequest", "RedactConversationRequestConversationPart", "RedactConversationRequestSource", @@ -637,37 +716,28 @@ "RedactConversationRequest_Source", "Reference", "ReplyConversationRequest", - "ResultsResponse", - "SearchArticlesResponse", - "SearchArticlesResponseData", "SearchRequest", "SearchRequestQuery", "Segment", "SegmentList", "SegmentPersonType", - "SheetActionComponent", + "ShowContactByExternalIdResponse", "SingleFilterSearchRequest", "SingleFilterSearchRequestOperator", "SingleFilterSearchRequestValue", - "SingleSelectComponent", - "SingleSelectComponentSaveState", - "SingleSelectOption", + "SingleFilterSearchRequestValueItem", "SlaApplied", "SlaAppliedSlaStatus", "SnoozeConversationRequest", "SocialProfile", - "SpacerComponent", - "SpacerComponentSize", "StartingAfterPaging", - "SubmitActionComponent", - "SubmitRequest", - "SubmitResponse", "SubscriptionType", "SubscriptionTypeConsentType", "SubscriptionTypeContentTypesItem", "SubscriptionTypeList", "SubscriptionTypeState", "Tag", + "TagBasic", "TagCompanyRequest", "TagCompanyRequestCompaniesItem", "TagList", @@ -678,10 +748,6 @@ "Team", "TeamList", "TeamPriorityLevel", - "TextAreaComponent", - "TextComponent", - "TextComponentAlign", - "TextComponentStyle", "Ticket", "TicketCategory", "TicketContacts", @@ -692,34 +758,48 @@ "TicketPartAuthorType", "TicketPartPreviousTicketState", "TicketPartTicketState", + "TicketPartUpdatedAttributeData", + "TicketPartUpdatedAttributeDataAttribute", + "TicketPartUpdatedAttributeDataValue", + "TicketPartUpdatedAttributeDataValueId", + "TicketPartUpdatedAttributeDataValueLabel", "TicketParts", "TicketReply", "TicketReplyPartType", "TicketRequestCustomAttributes", - "TicketTicketState", + "TicketState", + "TicketStateCategory", + "TicketStateDetailed", + "TicketStateDetailedCategory", + "TicketStateDetailedTicketTypes", + "TicketStateList", "TicketType", "TicketTypeAttribute", "TicketTypeAttributeDataType", "TicketTypeAttributeList", "TicketTypeCategory", "TicketTypeList", + "TicketTypeTicketStates", "TicketsReplyRequestBody", + "TooManyRequestsError", "Translation", "UnauthorizedError", "UnprocessableEntityError", "UntagCompanyRequest", "UntagCompanyRequestCompaniesItem", + "UpdateArticleRequestBody", "UpdateArticleRequestBodyParentType", - "UpdateArticleRequestBodyState", - "UpdateDataAttributeRequestOptionsItem", - "UpdateTicketRequestAssignment", - "UpdateTicketRequestState", - "UpdateTicketTypeRequestBodyCategory", + "UpdateArticleRequestState", + "UpdateContentImportSourceRequestStatus", + "UpdateContentImportSourceRequestSyncBehavior", + "UpdateDataAttributeRequestBody", + "UpdateDataAttributeRequestOptions", + "UpdateDataAttributeRequestOptionsOptionsItem", + "UpdateTicketTypeRequestCategory", "UpdateVisitorRequest", "UpdateVisitorRequestOne", "UpdateVisitorRequestWithId", "UpdateVisitorRequestWithUserId", - "UrlActionComponent", "UserWithId", "UserWithUserId", "Visitor", @@ -734,20 +814,33 @@ "VisitorWithEmail", "VisitorWithId", "VisitorWithUserId", + "WhatsappMessageStatusList", + "WhatsappMessageStatusListEventsItem", + "WhatsappMessageStatusListEventsItemStatus", + "WhatsappMessageStatusListPages", + "WhatsappMessageStatusListPagesNext", "__version__", "admins", "ai_agent", + "ai_content", "ai_content_source", "articles", + "away_status_reasons", + "calls", "companies", "contacts", "conversations", + "custom_channel_events", + "custom_object_instances", "data_attributes", "data_events", "data_export", "events", + "export", "help_center", "help_centers", + "internal_articles", + "jobs", "messages", "news", "notes", @@ -756,6 +849,7 @@ "subscription_types", "tags", "teams", + "ticket_states", "ticket_types", "tickets", "unstable", diff --git a/src/intercom/admins/__init__.py b/src/intercom/admins/__init__.py index 6d2c427..54c16eb 100644 --- a/src/intercom/admins/__init__.py +++ b/src/intercom/admins/__init__.py @@ -2,6 +2,6 @@ # isort: skip_file -from .types import Admin, AdminAvatar +from .types import Admin -__all__ = ["Admin", "AdminAvatar"] +__all__ = ["Admin"] diff --git a/src/intercom/admins/client.py b/src/intercom/admins/client.py index e5c94bc..645c32e 100644 --- a/src/intercom/admins/client.py +++ b/src/intercom/admins/client.py @@ -29,7 +29,7 @@ def with_raw_response(self) -> RawAdminsClient: """ return self._raw_client - def identify(self, *, request_options: typing.Optional[RequestOptions] = None) -> AdminWithApp: + def identify(self, *, request_options: typing.Optional[RequestOptions] = None) -> typing.Optional[AdminWithApp]: """ You can view the currently authorised admin along with the embedded app object (a "workspace" in legacy terminology). @@ -45,7 +45,7 @@ def identify(self, *, request_options: typing.Optional[RequestOptions] = None) - Returns ------- - AdminWithApp + typing.Optional[AdminWithApp] Successful response Examples @@ -62,18 +62,19 @@ def identify(self, *, request_options: typing.Optional[RequestOptions] = None) - def away( self, - admin_id: str, + admin_id: int, *, away_mode_enabled: bool, away_mode_reassign: bool, + away_status_reason_id: typing.Optional[int] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> Admin: + ) -> typing.Optional[Admin]: """ You can set an Admin as away for the Inbox. Parameters ---------- - admin_id : str + admin_id : int The unique identifier of a given admin away_mode_enabled : bool @@ -82,12 +83,15 @@ def away( away_mode_reassign : bool Set to "true" to assign any new conversation replies to your default inbox. + away_status_reason_id : typing.Optional[int] + The unique identifier of the away status reason + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Admin + typing.Optional[Admin] Successful response Examples @@ -98,15 +102,17 @@ def away( token="YOUR_TOKEN", ) client.admins.away( - admin_id="admin_id", + admin_id=1, away_mode_enabled=True, away_mode_reassign=True, + away_status_reason_id=12345, ) """ _response = self._raw_client.away( admin_id, away_mode_enabled=away_mode_enabled, away_mode_reassign=away_mode_reassign, + away_status_reason_id=away_status_reason_id, request_options=request_options, ) return _response.data @@ -180,13 +186,13 @@ def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> Ad _response = self._raw_client.list(request_options=request_options) return _response.data - def find(self, admin_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Admin: + def find(self, admin_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> typing.Optional[Admin]: """ You can retrieve the details of a single admin. Parameters ---------- - admin_id : str + admin_id : int The unique identifier of a given admin request_options : typing.Optional[RequestOptions] @@ -194,7 +200,7 @@ def find(self, admin_id: str, *, request_options: typing.Optional[RequestOptions Returns ------- - Admin + typing.Optional[Admin] Admin found Examples @@ -205,7 +211,7 @@ def find(self, admin_id: str, *, request_options: typing.Optional[RequestOptions token="YOUR_TOKEN", ) client.admins.find( - admin_id="123", + admin_id=1, ) """ _response = self._raw_client.find(admin_id, request_options=request_options) @@ -227,7 +233,9 @@ def with_raw_response(self) -> AsyncRawAdminsClient: """ return self._raw_client - async def identify(self, *, request_options: typing.Optional[RequestOptions] = None) -> AdminWithApp: + async def identify( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.Optional[AdminWithApp]: """ You can view the currently authorised admin along with the embedded app object (a "workspace" in legacy terminology). @@ -243,7 +251,7 @@ async def identify(self, *, request_options: typing.Optional[RequestOptions] = N Returns ------- - AdminWithApp + typing.Optional[AdminWithApp] Successful response Examples @@ -268,18 +276,19 @@ async def main() -> None: async def away( self, - admin_id: str, + admin_id: int, *, away_mode_enabled: bool, away_mode_reassign: bool, + away_status_reason_id: typing.Optional[int] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> Admin: + ) -> typing.Optional[Admin]: """ You can set an Admin as away for the Inbox. Parameters ---------- - admin_id : str + admin_id : int The unique identifier of a given admin away_mode_enabled : bool @@ -288,12 +297,15 @@ async def away( away_mode_reassign : bool Set to "true" to assign any new conversation replies to your default inbox. + away_status_reason_id : typing.Optional[int] + The unique identifier of the away status reason + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Admin + typing.Optional[Admin] Successful response Examples @@ -309,9 +321,10 @@ async def away( async def main() -> None: await client.admins.away( - admin_id="admin_id", + admin_id=1, away_mode_enabled=True, away_mode_reassign=True, + away_status_reason_id=12345, ) @@ -321,6 +334,7 @@ async def main() -> None: admin_id, away_mode_enabled=away_mode_enabled, away_mode_reassign=away_mode_reassign, + away_status_reason_id=away_status_reason_id, request_options=request_options, ) return _response.data @@ -410,13 +424,15 @@ async def main() -> None: _response = await self._raw_client.list(request_options=request_options) return _response.data - async def find(self, admin_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Admin: + async def find( + self, admin_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.Optional[Admin]: """ You can retrieve the details of a single admin. Parameters ---------- - admin_id : str + admin_id : int The unique identifier of a given admin request_options : typing.Optional[RequestOptions] @@ -424,7 +440,7 @@ async def find(self, admin_id: str, *, request_options: typing.Optional[RequestO Returns ------- - Admin + typing.Optional[Admin] Admin found Examples @@ -440,7 +456,7 @@ async def find(self, admin_id: str, *, request_options: typing.Optional[RequestO async def main() -> None: await client.admins.find( - admin_id="123", + admin_id=1, ) diff --git a/src/intercom/admins/raw_client.py b/src/intercom/admins/raw_client.py index 122427b..4b59660 100644 --- a/src/intercom/admins/raw_client.py +++ b/src/intercom/admins/raw_client.py @@ -9,6 +9,7 @@ from ..core.jsonable_encoder import jsonable_encoder from ..core.request_options import RequestOptions from ..core.unchecked_base_model import construct_type +from ..errors.bad_request_error import BadRequestError from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError from ..types.activity_log_list import ActivityLogList @@ -25,7 +26,9 @@ class RawAdminsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def identify(self, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[AdminWithApp]: + def identify( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[typing.Optional[AdminWithApp]]: """ You can view the currently authorised admin along with the embedded app object (a "workspace" in legacy terminology). @@ -41,7 +44,7 @@ def identify(self, *, request_options: typing.Optional[RequestOptions] = None) - Returns ------- - HttpResponse[AdminWithApp] + HttpResponse[typing.Optional[AdminWithApp]] Successful response """ _response = self._client_wrapper.httpx_client.request( @@ -50,11 +53,13 @@ def identify(self, *, request_options: typing.Optional[RequestOptions] = None) - request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - AdminWithApp, + typing.Optional[AdminWithApp], construct_type( - type_=AdminWithApp, # type: ignore + type_=typing.Optional[AdminWithApp], # type: ignore object_=_response.json(), ), ) @@ -66,18 +71,19 @@ def identify(self, *, request_options: typing.Optional[RequestOptions] = None) - def away( self, - admin_id: str, + admin_id: int, *, away_mode_enabled: bool, away_mode_reassign: bool, + away_status_reason_id: typing.Optional[int] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[Admin]: + ) -> HttpResponse[typing.Optional[Admin]]: """ You can set an Admin as away for the Inbox. Parameters ---------- - admin_id : str + admin_id : int The unique identifier of a given admin away_mode_enabled : bool @@ -86,12 +92,15 @@ def away( away_mode_reassign : bool Set to "true" to assign any new conversation replies to your default inbox. + away_status_reason_id : typing.Optional[int] + The unique identifier of the away status reason + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - HttpResponse[Admin] + HttpResponse[typing.Optional[Admin]] Successful response """ _response = self._client_wrapper.httpx_client.request( @@ -100,6 +109,7 @@ def away( json={ "away_mode_enabled": away_mode_enabled, "away_mode_reassign": away_mode_reassign, + "away_status_reason_id": away_status_reason_id, }, headers={ "content-type": "application/json", @@ -108,15 +118,28 @@ def away( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Admin, + typing.Optional[Admin], construct_type( - type_=Admin, # type: ignore + type_=typing.Optional[Admin], # type: ignore object_=_response.json(), ), ) return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) if _response.status_code == 401: raise UnauthorizedError( headers=dict(_response.headers), @@ -250,13 +273,15 @@ def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> Ht raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - def find(self, admin_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Admin]: + def find( + self, admin_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[typing.Optional[Admin]]: """ You can retrieve the details of a single admin. Parameters ---------- - admin_id : str + admin_id : int The unique identifier of a given admin request_options : typing.Optional[RequestOptions] @@ -264,7 +289,7 @@ def find(self, admin_id: str, *, request_options: typing.Optional[RequestOptions Returns ------- - HttpResponse[Admin] + HttpResponse[typing.Optional[Admin]] Admin found """ _response = self._client_wrapper.httpx_client.request( @@ -273,11 +298,13 @@ def find(self, admin_id: str, *, request_options: typing.Optional[RequestOptions request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Admin, + typing.Optional[Admin], construct_type( - type_=Admin, # type: ignore + type_=typing.Optional[Admin], # type: ignore object_=_response.json(), ), ) @@ -316,7 +343,7 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def identify( self, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[AdminWithApp]: + ) -> AsyncHttpResponse[typing.Optional[AdminWithApp]]: """ You can view the currently authorised admin along with the embedded app object (a "workspace" in legacy terminology). @@ -332,7 +359,7 @@ async def identify( Returns ------- - AsyncHttpResponse[AdminWithApp] + AsyncHttpResponse[typing.Optional[AdminWithApp]] Successful response """ _response = await self._client_wrapper.httpx_client.request( @@ -341,11 +368,13 @@ async def identify( request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - AdminWithApp, + typing.Optional[AdminWithApp], construct_type( - type_=AdminWithApp, # type: ignore + type_=typing.Optional[AdminWithApp], # type: ignore object_=_response.json(), ), ) @@ -357,18 +386,19 @@ async def identify( async def away( self, - admin_id: str, + admin_id: int, *, away_mode_enabled: bool, away_mode_reassign: bool, + away_status_reason_id: typing.Optional[int] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[Admin]: + ) -> AsyncHttpResponse[typing.Optional[Admin]]: """ You can set an Admin as away for the Inbox. Parameters ---------- - admin_id : str + admin_id : int The unique identifier of a given admin away_mode_enabled : bool @@ -377,12 +407,15 @@ async def away( away_mode_reassign : bool Set to "true" to assign any new conversation replies to your default inbox. + away_status_reason_id : typing.Optional[int] + The unique identifier of the away status reason + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncHttpResponse[Admin] + AsyncHttpResponse[typing.Optional[Admin]] Successful response """ _response = await self._client_wrapper.httpx_client.request( @@ -391,6 +424,7 @@ async def away( json={ "away_mode_enabled": away_mode_enabled, "away_mode_reassign": away_mode_reassign, + "away_status_reason_id": away_status_reason_id, }, headers={ "content-type": "application/json", @@ -399,15 +433,28 @@ async def away( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Admin, + typing.Optional[Admin], construct_type( - type_=Admin, # type: ignore + type_=typing.Optional[Admin], # type: ignore object_=_response.json(), ), ) return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) if _response.status_code == 401: raise UnauthorizedError( headers=dict(_response.headers), @@ -542,14 +589,14 @@ async def list(self, *, request_options: typing.Optional[RequestOptions] = None) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def find( - self, admin_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[Admin]: + self, admin_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[typing.Optional[Admin]]: """ You can retrieve the details of a single admin. Parameters ---------- - admin_id : str + admin_id : int The unique identifier of a given admin request_options : typing.Optional[RequestOptions] @@ -557,7 +604,7 @@ async def find( Returns ------- - AsyncHttpResponse[Admin] + AsyncHttpResponse[typing.Optional[Admin]] Admin found """ _response = await self._client_wrapper.httpx_client.request( @@ -566,11 +613,13 @@ async def find( request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Admin, + typing.Optional[Admin], construct_type( - type_=Admin, # type: ignore + type_=typing.Optional[Admin], # type: ignore object_=_response.json(), ), ) diff --git a/src/intercom/admins/types/__init__.py b/src/intercom/admins/types/__init__.py index c0468bd..cd34677 100644 --- a/src/intercom/admins/types/__init__.py +++ b/src/intercom/admins/types/__init__.py @@ -3,6 +3,5 @@ # isort: skip_file from .admin import Admin -from .admin_avatar import AdminAvatar -__all__ = ["Admin", "AdminAvatar"] +__all__ = ["Admin"] diff --git a/src/intercom/admins/types/admin.py b/src/intercom/admins/types/admin.py index 3441e16..08d3ad0 100644 --- a/src/intercom/admins/types/admin.py +++ b/src/intercom/admins/types/admin.py @@ -6,7 +6,6 @@ from ...core.pydantic_utilities import IS_PYDANTIC_V2 from ...core.unchecked_base_model import UncheckedBaseModel from ...types.team_priority_level import TeamPriorityLevel -from .admin_avatar import AdminAvatar class Admin(UncheckedBaseModel): @@ -14,7 +13,7 @@ class Admin(UncheckedBaseModel): Admins are teammate accounts that have access to a workspace. """ - type: typing.Optional[typing.Literal["admin"]] = pydantic.Field(default=None) + type: typing.Optional[str] = pydantic.Field(default=None) """ String representing the object's type. Always has the value `admin`. """ @@ -49,6 +48,11 @@ class Admin(UncheckedBaseModel): Identifies if this admin is set to automatically reassign new conversations to the apps default inbox. """ + away_status_reason_id: typing.Optional[int] = pydantic.Field(default=None) + """ + The unique identifier of the away status reason + """ + has_inbox_seat: bool = pydantic.Field() """ Identifies if this admin has a paid inbox seat to restrict/allow features that require them. @@ -59,9 +63,9 @@ class Admin(UncheckedBaseModel): This object represents the avatar associated with the admin. """ - avatar: typing.Optional[AdminAvatar] = pydantic.Field(default=None) + avatar: typing.Optional[str] = pydantic.Field(default=None) """ - The avatar object associated with the admin + Image for the associated team or teammate """ team_priority_level: typing.Optional[TeamPriorityLevel] = None diff --git a/src/intercom/ai_agent/types/ai_agent.py b/src/intercom/ai_agent/types/ai_agent.py index be136a0..46f42cf 100644 --- a/src/intercom/ai_agent/types/ai_agent.py +++ b/src/intercom/ai_agent/types/ai_agent.py @@ -14,7 +14,7 @@ class AiAgent(UncheckedBaseModel): Data related to AI Agent involvement in the conversation. """ - source_type: AiAgentSourceType = pydantic.Field() + source_type: typing.Optional[AiAgentSourceType] = pydantic.Field(default=None) """ The type of the source that triggered AI Agent involvement in the conversation. """ @@ -44,6 +44,16 @@ class AiAgent(UncheckedBaseModel): The customer satisfaction rating remark given to AI Agent. """ + created_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time when the AI agent rating was created. + """ + + updated_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time when the AI agent rating was last updated. + """ + content_sources: typing.Optional[ContentSourcesList] = None if IS_PYDANTIC_V2: diff --git a/src/intercom/ai_content/__init__.py b/src/intercom/ai_content/__init__.py new file mode 100644 index 0000000..80c5656 --- /dev/null +++ b/src/intercom/ai_content/__init__.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import ( + ContentImportSource, + ContentImportSourceStatus, + ContentImportSourceSyncBehavior, + ContentImportSourcesList, + CreateContentImportSourceRequestStatus, + ExternalPage, + ExternalPagesList, + UpdateContentImportSourceRequestStatus, + UpdateContentImportSourceRequestSyncBehavior, +) + +__all__ = [ + "ContentImportSource", + "ContentImportSourceStatus", + "ContentImportSourceSyncBehavior", + "ContentImportSourcesList", + "CreateContentImportSourceRequestStatus", + "ExternalPage", + "ExternalPagesList", + "UpdateContentImportSourceRequestStatus", + "UpdateContentImportSourceRequestSyncBehavior", +] diff --git a/src/intercom/ai_content/client.py b/src/intercom/ai_content/client.py new file mode 100644 index 0000000..5536ba6 --- /dev/null +++ b/src/intercom/ai_content/client.py @@ -0,0 +1,979 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from .raw_client import AsyncRawAiContentClient, RawAiContentClient +from .types.content_import_source import ContentImportSource +from .types.content_import_sources_list import ContentImportSourcesList +from .types.create_content_import_source_request_status import CreateContentImportSourceRequestStatus +from .types.external_page import ExternalPage +from .types.external_pages_list import ExternalPagesList +from .types.update_content_import_source_request_status import UpdateContentImportSourceRequestStatus +from .types.update_content_import_source_request_sync_behavior import UpdateContentImportSourceRequestSyncBehavior + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class AiContentClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawAiContentClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawAiContentClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawAiContentClient + """ + return self._raw_client + + def list_content_import_sources( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> ContentImportSourcesList: + """ + You can retrieve a list of all content import sources for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentImportSourcesList + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.ai_content.list_content_import_sources() + """ + _response = self._raw_client.list_content_import_sources(request_options=request_options) + return _response.data + + def create_content_import_source( + self, + *, + url: str, + status: typing.Optional[CreateContentImportSourceRequestStatus] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ContentImportSource: + """ + You can create a new content import source by sending a POST request to this endpoint. + + Parameters + ---------- + url : str + The URL of the content import source. + + status : typing.Optional[CreateContentImportSourceRequestStatus] + The status of the content import source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentImportSource + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.ai_content.create_content_import_source( + url="https://www.example.com", + ) + """ + _response = self._raw_client.create_content_import_source( + url=url, status=status, request_options=request_options + ) + return _response.data + + def get_content_import_source( + self, source_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ContentImportSource: + """ + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentImportSource + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.ai_content.get_content_import_source( + source_id="source_id", + ) + """ + _response = self._raw_client.get_content_import_source(source_id, request_options=request_options) + return _response.data + + def update_content_import_source( + self, + source_id: str, + *, + sync_behavior: UpdateContentImportSourceRequestSyncBehavior, + url: str, + status: typing.Optional[UpdateContentImportSourceRequestStatus] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ContentImportSource: + """ + You can update an existing content import source. + + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + sync_behavior : UpdateContentImportSourceRequestSyncBehavior + If you intend to create or update External Pages via the API, this should be set to `api`. You can not change the value to or from api. + + url : str + The URL of the content import source. This may only be different from the existing value if the sync behavior is API. + + status : typing.Optional[UpdateContentImportSourceRequestStatus] + The status of the content import source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentImportSource + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.ai_content.update_content_import_source( + source_id="source_id", + sync_behavior="api", + url="https://www.example.com", + ) + """ + _response = self._raw_client.update_content_import_source( + source_id, sync_behavior=sync_behavior, url=url, status=status, request_options=request_options + ) + return _response.data + + def delete_content_import_source( + self, source_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + You can delete a content import source by making a DELETE request this endpoint. This will also delete all external pages that were imported from this source. + + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.ai_content.delete_content_import_source( + source_id="source_id", + ) + """ + _response = self._raw_client.delete_content_import_source(source_id, request_options=request_options) + return _response.data + + def list_external_pages(self, *, request_options: typing.Optional[RequestOptions] = None) -> ExternalPagesList: + """ + You can retrieve a list of all external pages for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ExternalPagesList + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.ai_content.list_external_pages() + """ + _response = self._raw_client.list_external_pages(request_options=request_options) + return _response.data + + def create_external_page( + self, + *, + title: str, + html: str, + source_id: int, + external_id: str, + url: typing.Optional[str] = OMIT, + ai_agent_availability: typing.Optional[bool] = OMIT, + ai_copilot_availability: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ExternalPage: + """ + You can create a new external page by sending a POST request to this endpoint. If an external page already exists with the specified source_id and external_id, it will be updated instead. + + Parameters + ---------- + title : str + The title of the external page. + + html : str + The body of the external page in HTML. + + source_id : int + The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. + + external_id : str + The identifier for the external page which was given by the source. Must be unique for the source. + + url : typing.Optional[str] + The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. When a URL is not present, Fin will not reference the source. + + ai_agent_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by AI Agent. Will not default when updating an existing external page. + + ai_copilot_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by AI Copilot. Will not default when updating an existing external page. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ExternalPage + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.ai_content.create_external_page( + title="Test", + html="

Test

", + url="https://www.example.com", + source_id=44, + external_id="abc1234", + ) + """ + _response = self._raw_client.create_external_page( + title=title, + html=html, + source_id=source_id, + external_id=external_id, + url=url, + ai_agent_availability=ai_agent_availability, + ai_copilot_availability=ai_copilot_availability, + request_options=request_options, + ) + return _response.data + + def get_external_page( + self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ExternalPage: + """ + You can retrieve an external page. + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ExternalPage + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.ai_content.get_external_page( + page_id="page_id", + ) + """ + _response = self._raw_client.get_external_page(page_id, request_options=request_options) + return _response.data + + def update_external_page( + self, + page_id: str, + *, + title: str, + html: str, + url: str, + source_id: int, + fin_availability: typing.Optional[bool] = OMIT, + external_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ExternalPage: + """ + You can update an existing external page (if it was created via the API). + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + title : str + The title of the external page. + + html : str + The body of the external page in HTML. + + url : str + The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. + + source_id : int + The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. + + fin_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by Fin. + + external_id : typing.Optional[str] + The identifier for the external page which was given by the source. Must be unique for the source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ExternalPage + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.ai_content.update_external_page( + page_id="page_id", + title="Test", + html="

Test

", + url="https://www.example.com", + source_id=47, + external_id="5678", + ) + """ + _response = self._raw_client.update_external_page( + page_id, + title=title, + html=html, + url=url, + source_id=source_id, + fin_availability=fin_availability, + external_id=external_id, + request_options=request_options, + ) + return _response.data + + def delete_external_page( + self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ExternalPage: + """ + Sending a DELETE request for an external page will remove it from the content library UI and from being used for AI answers. + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ExternalPage + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.ai_content.delete_external_page( + page_id="page_id", + ) + """ + _response = self._raw_client.delete_external_page(page_id, request_options=request_options) + return _response.data + + +class AsyncAiContentClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawAiContentClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawAiContentClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawAiContentClient + """ + return self._raw_client + + async def list_content_import_sources( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> ContentImportSourcesList: + """ + You can retrieve a list of all content import sources for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentImportSourcesList + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.ai_content.list_content_import_sources() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_content_import_sources(request_options=request_options) + return _response.data + + async def create_content_import_source( + self, + *, + url: str, + status: typing.Optional[CreateContentImportSourceRequestStatus] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ContentImportSource: + """ + You can create a new content import source by sending a POST request to this endpoint. + + Parameters + ---------- + url : str + The URL of the content import source. + + status : typing.Optional[CreateContentImportSourceRequestStatus] + The status of the content import source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentImportSource + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.ai_content.create_content_import_source( + url="https://www.example.com", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_content_import_source( + url=url, status=status, request_options=request_options + ) + return _response.data + + async def get_content_import_source( + self, source_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ContentImportSource: + """ + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentImportSource + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.ai_content.get_content_import_source( + source_id="source_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_content_import_source(source_id, request_options=request_options) + return _response.data + + async def update_content_import_source( + self, + source_id: str, + *, + sync_behavior: UpdateContentImportSourceRequestSyncBehavior, + url: str, + status: typing.Optional[UpdateContentImportSourceRequestStatus] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ContentImportSource: + """ + You can update an existing content import source. + + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + sync_behavior : UpdateContentImportSourceRequestSyncBehavior + If you intend to create or update External Pages via the API, this should be set to `api`. You can not change the value to or from api. + + url : str + The URL of the content import source. This may only be different from the existing value if the sync behavior is API. + + status : typing.Optional[UpdateContentImportSourceRequestStatus] + The status of the content import source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContentImportSource + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.ai_content.update_content_import_source( + source_id="source_id", + sync_behavior="api", + url="https://www.example.com", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update_content_import_source( + source_id, sync_behavior=sync_behavior, url=url, status=status, request_options=request_options + ) + return _response.data + + async def delete_content_import_source( + self, source_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + You can delete a content import source by making a DELETE request this endpoint. This will also delete all external pages that were imported from this source. + + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.ai_content.delete_content_import_source( + source_id="source_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_content_import_source(source_id, request_options=request_options) + return _response.data + + async def list_external_pages( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> ExternalPagesList: + """ + You can retrieve a list of all external pages for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ExternalPagesList + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.ai_content.list_external_pages() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_external_pages(request_options=request_options) + return _response.data + + async def create_external_page( + self, + *, + title: str, + html: str, + source_id: int, + external_id: str, + url: typing.Optional[str] = OMIT, + ai_agent_availability: typing.Optional[bool] = OMIT, + ai_copilot_availability: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ExternalPage: + """ + You can create a new external page by sending a POST request to this endpoint. If an external page already exists with the specified source_id and external_id, it will be updated instead. + + Parameters + ---------- + title : str + The title of the external page. + + html : str + The body of the external page in HTML. + + source_id : int + The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. + + external_id : str + The identifier for the external page which was given by the source. Must be unique for the source. + + url : typing.Optional[str] + The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. When a URL is not present, Fin will not reference the source. + + ai_agent_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by AI Agent. Will not default when updating an existing external page. + + ai_copilot_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by AI Copilot. Will not default when updating an existing external page. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ExternalPage + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.ai_content.create_external_page( + title="Test", + html="

Test

", + url="https://www.example.com", + source_id=44, + external_id="abc1234", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_external_page( + title=title, + html=html, + source_id=source_id, + external_id=external_id, + url=url, + ai_agent_availability=ai_agent_availability, + ai_copilot_availability=ai_copilot_availability, + request_options=request_options, + ) + return _response.data + + async def get_external_page( + self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ExternalPage: + """ + You can retrieve an external page. + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ExternalPage + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.ai_content.get_external_page( + page_id="page_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_external_page(page_id, request_options=request_options) + return _response.data + + async def update_external_page( + self, + page_id: str, + *, + title: str, + html: str, + url: str, + source_id: int, + fin_availability: typing.Optional[bool] = OMIT, + external_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ExternalPage: + """ + You can update an existing external page (if it was created via the API). + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + title : str + The title of the external page. + + html : str + The body of the external page in HTML. + + url : str + The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. + + source_id : int + The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. + + fin_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by Fin. + + external_id : typing.Optional[str] + The identifier for the external page which was given by the source. Must be unique for the source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ExternalPage + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.ai_content.update_external_page( + page_id="page_id", + title="Test", + html="

Test

", + url="https://www.example.com", + source_id=47, + external_id="5678", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update_external_page( + page_id, + title=title, + html=html, + url=url, + source_id=source_id, + fin_availability=fin_availability, + external_id=external_id, + request_options=request_options, + ) + return _response.data + + async def delete_external_page( + self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ExternalPage: + """ + Sending a DELETE request for an external page will remove it from the content library UI and from being used for AI answers. + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ExternalPage + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.ai_content.delete_external_page( + page_id="page_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_external_page(page_id, request_options=request_options) + return _response.data diff --git a/src/intercom/ai_content/raw_client.py b/src/intercom/ai_content/raw_client.py new file mode 100644 index 0000000..13be7f3 --- /dev/null +++ b/src/intercom/ai_content/raw_client.py @@ -0,0 +1,1243 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.jsonable_encoder import jsonable_encoder +from ..core.request_options import RequestOptions +from ..core.unchecked_base_model import construct_type +from ..errors.unauthorized_error import UnauthorizedError +from ..types.error import Error +from .types.content_import_source import ContentImportSource +from .types.content_import_sources_list import ContentImportSourcesList +from .types.create_content_import_source_request_status import CreateContentImportSourceRequestStatus +from .types.external_page import ExternalPage +from .types.external_pages_list import ExternalPagesList +from .types.update_content_import_source_request_status import UpdateContentImportSourceRequestStatus +from .types.update_content_import_source_request_sync_behavior import UpdateContentImportSourceRequestSyncBehavior + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawAiContentClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_content_import_sources( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ContentImportSourcesList]: + """ + You can retrieve a list of all content import sources for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ContentImportSourcesList] + successful + """ + _response = self._client_wrapper.httpx_client.request( + "ai/content_import_sources", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContentImportSourcesList, + construct_type( + type_=ContentImportSourcesList, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def create_content_import_source( + self, + *, + url: str, + status: typing.Optional[CreateContentImportSourceRequestStatus] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ContentImportSource]: + """ + You can create a new content import source by sending a POST request to this endpoint. + + Parameters + ---------- + url : str + The URL of the content import source. + + status : typing.Optional[CreateContentImportSourceRequestStatus] + The status of the content import source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ContentImportSource] + successful + """ + _response = self._client_wrapper.httpx_client.request( + "ai/content_import_sources", + method="POST", + json={ + "status": status, + "url": url, + "sync_behavior": "api", + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContentImportSource, + construct_type( + type_=ContentImportSource, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_content_import_source( + self, source_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ContentImportSource]: + """ + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ContentImportSource] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"ai/content_import_sources/{jsonable_encoder(source_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContentImportSource, + construct_type( + type_=ContentImportSource, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def update_content_import_source( + self, + source_id: str, + *, + sync_behavior: UpdateContentImportSourceRequestSyncBehavior, + url: str, + status: typing.Optional[UpdateContentImportSourceRequestStatus] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ContentImportSource]: + """ + You can update an existing content import source. + + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + sync_behavior : UpdateContentImportSourceRequestSyncBehavior + If you intend to create or update External Pages via the API, this should be set to `api`. You can not change the value to or from api. + + url : str + The URL of the content import source. This may only be different from the existing value if the sync behavior is API. + + status : typing.Optional[UpdateContentImportSourceRequestStatus] + The status of the content import source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ContentImportSource] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"ai/content_import_sources/{jsonable_encoder(source_id)}", + method="PUT", + json={ + "sync_behavior": sync_behavior, + "status": status, + "url": url, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContentImportSource, + construct_type( + type_=ContentImportSource, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def delete_content_import_source( + self, source_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[None]: + """ + You can delete a content import source by making a DELETE request this endpoint. This will also delete all external pages that were imported from this source. + + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[None] + """ + _response = self._client_wrapper.httpx_client.request( + f"ai/content_import_sources/{jsonable_encoder(source_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=None) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def list_external_pages( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ExternalPagesList]: + """ + You can retrieve a list of all external pages for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ExternalPagesList] + successful + """ + _response = self._client_wrapper.httpx_client.request( + "ai/external_pages", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ExternalPagesList, + construct_type( + type_=ExternalPagesList, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def create_external_page( + self, + *, + title: str, + html: str, + source_id: int, + external_id: str, + url: typing.Optional[str] = OMIT, + ai_agent_availability: typing.Optional[bool] = OMIT, + ai_copilot_availability: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ExternalPage]: + """ + You can create a new external page by sending a POST request to this endpoint. If an external page already exists with the specified source_id and external_id, it will be updated instead. + + Parameters + ---------- + title : str + The title of the external page. + + html : str + The body of the external page in HTML. + + source_id : int + The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. + + external_id : str + The identifier for the external page which was given by the source. Must be unique for the source. + + url : typing.Optional[str] + The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. When a URL is not present, Fin will not reference the source. + + ai_agent_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by AI Agent. Will not default when updating an existing external page. + + ai_copilot_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by AI Copilot. Will not default when updating an existing external page. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ExternalPage] + successful + """ + _response = self._client_wrapper.httpx_client.request( + "ai/external_pages", + method="POST", + json={ + "title": title, + "html": html, + "url": url, + "ai_agent_availability": ai_agent_availability, + "ai_copilot_availability": ai_copilot_availability, + "source_id": source_id, + "external_id": external_id, + "locale": "en", + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ExternalPage, + construct_type( + type_=ExternalPage, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_external_page( + self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ExternalPage]: + """ + You can retrieve an external page. + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ExternalPage] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"ai/external_pages/{jsonable_encoder(page_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ExternalPage, + construct_type( + type_=ExternalPage, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def update_external_page( + self, + page_id: str, + *, + title: str, + html: str, + url: str, + source_id: int, + fin_availability: typing.Optional[bool] = OMIT, + external_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ExternalPage]: + """ + You can update an existing external page (if it was created via the API). + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + title : str + The title of the external page. + + html : str + The body of the external page in HTML. + + url : str + The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. + + source_id : int + The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. + + fin_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by Fin. + + external_id : typing.Optional[str] + The identifier for the external page which was given by the source. Must be unique for the source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ExternalPage] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"ai/external_pages/{jsonable_encoder(page_id)}", + method="PUT", + json={ + "title": title, + "html": html, + "url": url, + "fin_availability": fin_availability, + "source_id": source_id, + "external_id": external_id, + "locale": "en", + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ExternalPage, + construct_type( + type_=ExternalPage, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def delete_external_page( + self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ExternalPage]: + """ + Sending a DELETE request for an external page will remove it from the content library UI and from being used for AI answers. + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ExternalPage] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"ai/external_pages/{jsonable_encoder(page_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ExternalPage, + construct_type( + type_=ExternalPage, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawAiContentClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_content_import_sources( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ContentImportSourcesList]: + """ + You can retrieve a list of all content import sources for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ContentImportSourcesList] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + "ai/content_import_sources", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContentImportSourcesList, + construct_type( + type_=ContentImportSourcesList, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def create_content_import_source( + self, + *, + url: str, + status: typing.Optional[CreateContentImportSourceRequestStatus] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ContentImportSource]: + """ + You can create a new content import source by sending a POST request to this endpoint. + + Parameters + ---------- + url : str + The URL of the content import source. + + status : typing.Optional[CreateContentImportSourceRequestStatus] + The status of the content import source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ContentImportSource] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + "ai/content_import_sources", + method="POST", + json={ + "status": status, + "url": url, + "sync_behavior": "api", + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContentImportSource, + construct_type( + type_=ContentImportSource, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_content_import_source( + self, source_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ContentImportSource]: + """ + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ContentImportSource] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"ai/content_import_sources/{jsonable_encoder(source_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContentImportSource, + construct_type( + type_=ContentImportSource, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def update_content_import_source( + self, + source_id: str, + *, + sync_behavior: UpdateContentImportSourceRequestSyncBehavior, + url: str, + status: typing.Optional[UpdateContentImportSourceRequestStatus] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ContentImportSource]: + """ + You can update an existing content import source. + + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + sync_behavior : UpdateContentImportSourceRequestSyncBehavior + If you intend to create or update External Pages via the API, this should be set to `api`. You can not change the value to or from api. + + url : str + The URL of the content import source. This may only be different from the existing value if the sync behavior is API. + + status : typing.Optional[UpdateContentImportSourceRequestStatus] + The status of the content import source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ContentImportSource] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"ai/content_import_sources/{jsonable_encoder(source_id)}", + method="PUT", + json={ + "sync_behavior": sync_behavior, + "status": status, + "url": url, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContentImportSource, + construct_type( + type_=ContentImportSource, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def delete_content_import_source( + self, source_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[None]: + """ + You can delete a content import source by making a DELETE request this endpoint. This will also delete all external pages that were imported from this source. + + Parameters + ---------- + source_id : str + The unique identifier for the content import source which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[None] + """ + _response = await self._client_wrapper.httpx_client.request( + f"ai/content_import_sources/{jsonable_encoder(source_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=None) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def list_external_pages( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ExternalPagesList]: + """ + You can retrieve a list of all external pages for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ExternalPagesList] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + "ai/external_pages", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ExternalPagesList, + construct_type( + type_=ExternalPagesList, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def create_external_page( + self, + *, + title: str, + html: str, + source_id: int, + external_id: str, + url: typing.Optional[str] = OMIT, + ai_agent_availability: typing.Optional[bool] = OMIT, + ai_copilot_availability: typing.Optional[bool] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ExternalPage]: + """ + You can create a new external page by sending a POST request to this endpoint. If an external page already exists with the specified source_id and external_id, it will be updated instead. + + Parameters + ---------- + title : str + The title of the external page. + + html : str + The body of the external page in HTML. + + source_id : int + The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. + + external_id : str + The identifier for the external page which was given by the source. Must be unique for the source. + + url : typing.Optional[str] + The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. When a URL is not present, Fin will not reference the source. + + ai_agent_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by AI Agent. Will not default when updating an existing external page. + + ai_copilot_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by AI Copilot. Will not default when updating an existing external page. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ExternalPage] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + "ai/external_pages", + method="POST", + json={ + "title": title, + "html": html, + "url": url, + "ai_agent_availability": ai_agent_availability, + "ai_copilot_availability": ai_copilot_availability, + "source_id": source_id, + "external_id": external_id, + "locale": "en", + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ExternalPage, + construct_type( + type_=ExternalPage, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_external_page( + self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ExternalPage]: + """ + You can retrieve an external page. + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ExternalPage] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"ai/external_pages/{jsonable_encoder(page_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ExternalPage, + construct_type( + type_=ExternalPage, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def update_external_page( + self, + page_id: str, + *, + title: str, + html: str, + url: str, + source_id: int, + fin_availability: typing.Optional[bool] = OMIT, + external_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ExternalPage]: + """ + You can update an existing external page (if it was created via the API). + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + title : str + The title of the external page. + + html : str + The body of the external page in HTML. + + url : str + The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. + + source_id : int + The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. + + fin_availability : typing.Optional[bool] + Whether the external page should be used to answer questions by Fin. + + external_id : typing.Optional[str] + The identifier for the external page which was given by the source. Must be unique for the source. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ExternalPage] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"ai/external_pages/{jsonable_encoder(page_id)}", + method="PUT", + json={ + "title": title, + "html": html, + "url": url, + "fin_availability": fin_availability, + "source_id": source_id, + "external_id": external_id, + "locale": "en", + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ExternalPage, + construct_type( + type_=ExternalPage, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def delete_external_page( + self, page_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ExternalPage]: + """ + Sending a DELETE request for an external page will remove it from the content library UI and from being used for AI answers. + + Parameters + ---------- + page_id : str + The unique identifier for the external page which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ExternalPage] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"ai/external_pages/{jsonable_encoder(page_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ExternalPage, + construct_type( + type_=ExternalPage, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/ai_content/types/__init__.py b/src/intercom/ai_content/types/__init__.py new file mode 100644 index 0000000..b2b7982 --- /dev/null +++ b/src/intercom/ai_content/types/__init__.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .content_import_source import ContentImportSource +from .content_import_source_status import ContentImportSourceStatus +from .content_import_source_sync_behavior import ContentImportSourceSyncBehavior +from .content_import_sources_list import ContentImportSourcesList +from .create_content_import_source_request_status import CreateContentImportSourceRequestStatus +from .external_page import ExternalPage +from .external_pages_list import ExternalPagesList +from .update_content_import_source_request_status import UpdateContentImportSourceRequestStatus +from .update_content_import_source_request_sync_behavior import UpdateContentImportSourceRequestSyncBehavior + +__all__ = [ + "ContentImportSource", + "ContentImportSourceStatus", + "ContentImportSourceSyncBehavior", + "ContentImportSourcesList", + "CreateContentImportSourceRequestStatus", + "ExternalPage", + "ExternalPagesList", + "UpdateContentImportSourceRequestStatus", + "UpdateContentImportSourceRequestSyncBehavior", +] diff --git a/src/intercom/ai_content/types/content_import_source.py b/src/intercom/ai_content/types/content_import_source.py new file mode 100644 index 0000000..474a4d2 --- /dev/null +++ b/src/intercom/ai_content/types/content_import_source.py @@ -0,0 +1,64 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .content_import_source_status import ContentImportSourceStatus +from .content_import_source_sync_behavior import ContentImportSourceSyncBehavior + + +class ContentImportSource(UncheckedBaseModel): + """ + An external source for External Pages that you add to your Fin Content Library. + """ + + type: typing.Literal["content_import_source"] = pydantic.Field(default="content_import_source") + """ + Always external_page + """ + + id: int = pydantic.Field() + """ + The unique identifier for the content import source which is given by Intercom. + """ + + last_synced_at: int = pydantic.Field() + """ + The time when the content import source was last synced. + """ + + sync_behavior: ContentImportSourceSyncBehavior = pydantic.Field() + """ + If you intend to create or update External Pages via the API, this should be set to `api`. + """ + + status: ContentImportSourceStatus = pydantic.Field() + """ + The status of the content import source. + """ + + url: str = pydantic.Field() + """ + The URL of the root of the external source. + """ + + created_at: int = pydantic.Field() + """ + The time when the content import source was created. + """ + + updated_at: int = pydantic.Field() + """ + The time when the content import source was last updated. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/ai_content/types/content_import_source_status.py b/src/intercom/ai_content/types/content_import_source_status.py new file mode 100644 index 0000000..389c3c8 --- /dev/null +++ b/src/intercom/ai_content/types/content_import_source_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ContentImportSourceStatus = typing.Union[typing.Literal["active", "deactivated"], typing.Any] diff --git a/src/intercom/ai_content/types/content_import_source_sync_behavior.py b/src/intercom/ai_content/types/content_import_source_sync_behavior.py new file mode 100644 index 0000000..97abd40 --- /dev/null +++ b/src/intercom/ai_content/types/content_import_source_sync_behavior.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ContentImportSourceSyncBehavior = typing.Union[typing.Literal["api", "automatic", "manual"], typing.Any] diff --git a/src/intercom/ai_content/types/content_import_sources_list.py b/src/intercom/ai_content/types/content_import_sources_list.py new file mode 100644 index 0000000..355cff5 --- /dev/null +++ b/src/intercom/ai_content/types/content_import_sources_list.py @@ -0,0 +1,40 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from ...types.pages_link import PagesLink +from .content_import_source import ContentImportSource + + +class ContentImportSourcesList(UncheckedBaseModel): + """ + This will return a list of the content import sources for the App. + """ + + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) + """ + The type of the object - `list`. + """ + + pages: typing.Optional[PagesLink] = None + total_count: typing.Optional[int] = pydantic.Field(default=None) + """ + A count of the total number of content import sources. + """ + + data: typing.Optional[typing.List[ContentImportSource]] = pydantic.Field(default=None) + """ + An array of Content Import Source objects + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/ai_content/types/create_content_import_source_request_status.py b/src/intercom/ai_content/types/create_content_import_source_request_status.py new file mode 100644 index 0000000..047dfd5 --- /dev/null +++ b/src/intercom/ai_content/types/create_content_import_source_request_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateContentImportSourceRequestStatus = typing.Union[typing.Literal["active", "deactivated"], typing.Any] diff --git a/src/intercom/ai_content/types/external_page.py b/src/intercom/ai_content/types/external_page.py new file mode 100644 index 0000000..bdb55e7 --- /dev/null +++ b/src/intercom/ai_content/types/external_page.py @@ -0,0 +1,92 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class ExternalPage(UncheckedBaseModel): + """ + External pages that you have added to your Fin Content Library. + """ + + type: typing.Literal["external_page"] = pydantic.Field(default="external_page") + """ + Always external_page + """ + + id: str = pydantic.Field() + """ + The unique identifier for the external page which is given by Intercom. + """ + + title: str = pydantic.Field() + """ + The title of the external page. + """ + + html: str = pydantic.Field() + """ + The body of the external page in HTML. + """ + + url: typing.Optional[str] = pydantic.Field(default=None) + """ + The URL of the external page. This will be used by Fin to link end users to the page it based its answer on. + """ + + ai_agent_availability: bool = pydantic.Field() + """ + Whether the external page should be used to answer questions by AI Agent. + """ + + ai_copilot_availability: bool = pydantic.Field() + """ + Whether the external page should be used to answer questions by AI Copilot. + """ + + fin_availability: typing.Optional[bool] = pydantic.Field(default=None) + """ + Deprecated. Use ai_agent_availability and ai_copilot_availability instead. + """ + + locale: typing.Literal["en"] = pydantic.Field(default="en") + """ + Always en + """ + + source_id: int = pydantic.Field() + """ + The unique identifier for the source of the external page which was given by Intercom. Every external page must be associated with a Content Import Source which represents the place it comes from and from which it inherits a default audience (configured in the UI). For a new source, make a POST request to the Content Import Source endpoint and an ID for the source will be returned in the response. + """ + + external_id: str = pydantic.Field() + """ + The identifier for the external page which was given by the source. Must be unique for the source. + """ + + created_at: int = pydantic.Field() + """ + The time when the external page was created. + """ + + updated_at: int = pydantic.Field() + """ + The time when the external page was last updated. + """ + + last_ingested_at: int = pydantic.Field() + """ + The time when the external page was last ingested. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/ai_content/types/external_pages_list.py b/src/intercom/ai_content/types/external_pages_list.py new file mode 100644 index 0000000..47b210a --- /dev/null +++ b/src/intercom/ai_content/types/external_pages_list.py @@ -0,0 +1,40 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from ...types.pages_link import PagesLink +from .external_page import ExternalPage + + +class ExternalPagesList(UncheckedBaseModel): + """ + This will return a list of external pages for the App. + """ + + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) + """ + The type of the object - `list`. + """ + + pages: typing.Optional[PagesLink] = None + total_count: typing.Optional[int] = pydantic.Field(default=None) + """ + A count of the total number of external pages. + """ + + data: typing.Optional[typing.List[ExternalPage]] = pydantic.Field(default=None) + """ + An array of External Page objects + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/ai_content/types/update_content_import_source_request_status.py b/src/intercom/ai_content/types/update_content_import_source_request_status.py new file mode 100644 index 0000000..080fcef --- /dev/null +++ b/src/intercom/ai_content/types/update_content_import_source_request_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +UpdateContentImportSourceRequestStatus = typing.Union[typing.Literal["active", "deactivated"], typing.Any] diff --git a/src/intercom/ai_content/types/update_content_import_source_request_sync_behavior.py b/src/intercom/ai_content/types/update_content_import_source_request_sync_behavior.py new file mode 100644 index 0000000..19fc0b0 --- /dev/null +++ b/src/intercom/ai_content/types/update_content_import_source_request_sync_behavior.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +UpdateContentImportSourceRequestSyncBehavior = typing.Union[typing.Literal["api", "automated", "manual"], typing.Any] diff --git a/src/intercom/ai_content_source/types/content_source.py b/src/intercom/ai_content_source/types/content_source.py index 7637acd..28316bc 100644 --- a/src/intercom/ai_content_source/types/content_source.py +++ b/src/intercom/ai_content_source/types/content_source.py @@ -12,22 +12,22 @@ class ContentSource(UncheckedBaseModel): The content source used by AI Agent in the conversation. """ - content_type: typing.Literal["custom_answer"] = pydantic.Field(default="custom_answer") + content_type: typing.Optional[typing.Literal["custom_answer"]] = pydantic.Field(default=None) """ The type of the content source. """ - url: str = pydantic.Field() + url: typing.Optional[str] = pydantic.Field(default=None) """ The internal URL linking to the content source for teammates. """ - title: str = pydantic.Field() + title: typing.Optional[str] = pydantic.Field(default=None) """ The title of the content source. """ - locale: str = pydantic.Field() + locale: typing.Optional[str] = pydantic.Field(default=None) """ The ISO 639 language code of the content source. """ diff --git a/src/intercom/articles/__init__.py b/src/intercom/articles/__init__.py index 143e0d6..5574118 100644 --- a/src/intercom/articles/__init__.py +++ b/src/intercom/articles/__init__.py @@ -11,12 +11,10 @@ ArticleSearchHighlightsHighlightedSummaryItemItemType, ArticleSearchHighlightsHighlightedTitleItem, ArticleSearchHighlightsHighlightedTitleItemType, - CreateArticleRequestParentType, - CreateArticleRequestState, - SearchArticlesResponse, - SearchArticlesResponseData, - UpdateArticleRequestBodyParentType, - UpdateArticleRequestBodyState, + ArticleSearchResponse, + ArticleSearchResponseData, + InternalArticle, + UpdateArticleRequestState, ) __all__ = [ @@ -28,10 +26,8 @@ "ArticleSearchHighlightsHighlightedSummaryItemItemType", "ArticleSearchHighlightsHighlightedTitleItem", "ArticleSearchHighlightsHighlightedTitleItemType", - "CreateArticleRequestParentType", - "CreateArticleRequestState", - "SearchArticlesResponse", - "SearchArticlesResponseData", - "UpdateArticleRequestBodyParentType", - "UpdateArticleRequestBodyState", + "ArticleSearchResponse", + "ArticleSearchResponseData", + "InternalArticle", + "UpdateArticleRequestState", ] diff --git a/src/intercom/articles/client.py b/src/intercom/articles/client.py index 0ac6720..769863c 100644 --- a/src/intercom/articles/client.py +++ b/src/intercom/articles/client.py @@ -6,15 +6,13 @@ from ..core.pagination import AsyncPager, SyncPager from ..core.request_options import RequestOptions from ..types.article_translated_content import ArticleTranslatedContent +from ..types.create_article_request import CreateArticleRequest from ..types.deleted_article_object import DeletedArticleObject from .raw_client import AsyncRawArticlesClient, RawArticlesClient from .types.article import Article from .types.article_list_item import ArticleListItem -from .types.create_article_request_parent_type import CreateArticleRequestParentType -from .types.create_article_request_state import CreateArticleRequestState -from .types.search_articles_response import SearchArticlesResponse -from .types.update_article_request_body_parent_type import UpdateArticleRequestBodyParentType -from .types.update_article_request_body_state import UpdateArticleRequestBodyState +from .types.article_search_response import ArticleSearchResponse +from .types.update_article_request_state import UpdateArticleRequestState # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -84,14 +82,7 @@ def list( def create( self, *, - title: str, - author_id: int, - description: typing.Optional[str] = OMIT, - body: typing.Optional[str] = OMIT, - state: typing.Optional[CreateArticleRequestState] = OMIT, - parent_id: typing.Optional[int] = OMIT, - parent_type: typing.Optional[CreateArticleRequestParentType] = OMIT, - translated_content: typing.Optional[ArticleTranslatedContent] = OMIT, + request: typing.Optional[CreateArticleRequest] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Article: """ @@ -99,28 +90,7 @@ def create( Parameters ---------- - title : str - The title of the article.For multilingual articles, this will be the title of the default language's content. - - author_id : int - The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. - - description : typing.Optional[str] - The description of the article. For multilingual articles, this will be the description of the default language's content. - - body : typing.Optional[str] - The content of the article. For multilingual articles, this will be the body of the default language's content. - - state : typing.Optional[CreateArticleRequestState] - Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. - - parent_id : typing.Optional[int] - The id of the article's parent collection or section. An article without this field stands alone. - - parent_type : typing.Optional[CreateArticleRequestParentType] - The type of parent, which can either be a `collection` or `section`. - - translated_content : typing.Optional[ArticleTranslatedContent] + request : typing.Optional[CreateArticleRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -132,50 +102,47 @@ def create( Examples -------- - from intercom import ArticleContent, ArticleTranslatedContent, Intercom + from intercom import ( + ArticleContent, + ArticleTranslatedContent, + CreateArticleRequest, + Intercom, + ) client = Intercom( token="YOUR_TOKEN", ) client.articles.create( - title="Thanks for everything", - description="Description of the Article", - body="Body of the Article", - author_id=991267407, - state="published", - parent_id=145, - parent_type="collection", - translated_content=ArticleTranslatedContent( - fr=ArticleContent( - title="Merci pour tout", - description="Description de l'article", - body="Corps de l'article", - author_id=991267407, - state="published", + request=CreateArticleRequest( + title="Thanks for everything", + description="Description of the Article", + body="Body of the Article", + author_id=991267497, + state="published", + parent_id=145, + parent_type="collection", + translated_content=ArticleTranslatedContent( + fr=ArticleContent( + title="Merci pour tout", + description="Description de l'article", + body="Corps de l'article", + author_id=991267497, + state="published", + ), ), ), ) """ - _response = self._raw_client.create( - title=title, - author_id=author_id, - description=description, - body=body, - state=state, - parent_id=parent_id, - parent_type=parent_type, - translated_content=translated_content, - request_options=request_options, - ) + _response = self._raw_client.create(request=request, request_options=request_options) return _response.data - def find(self, article_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Article: + def find(self, article_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> Article: """ You can fetch the details of a single article by making a GET request to `https://api.intercom.io/articles/`. Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -194,7 +161,7 @@ def find(self, article_id: str, *, request_options: typing.Optional[RequestOptio token="YOUR_TOKEN", ) client.articles.find( - article_id="123", + article_id=1, ) """ _response = self._raw_client.find(article_id, request_options=request_options) @@ -202,15 +169,15 @@ def find(self, article_id: str, *, request_options: typing.Optional[RequestOptio def update( self, - article_id: str, + article_id: int, *, title: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, body: typing.Optional[str] = OMIT, author_id: typing.Optional[int] = OMIT, - state: typing.Optional[UpdateArticleRequestBodyState] = OMIT, + state: typing.Optional[UpdateArticleRequestState] = OMIT, parent_id: typing.Optional[str] = OMIT, - parent_type: typing.Optional[UpdateArticleRequestBodyParentType] = OMIT, + parent_type: typing.Optional[str] = OMIT, translated_content: typing.Optional[ArticleTranslatedContent] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Article: @@ -219,7 +186,7 @@ def update( Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. title : typing.Optional[str] @@ -234,13 +201,13 @@ def update( author_id : typing.Optional[int] The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. - state : typing.Optional[UpdateArticleRequestBodyState] + state : typing.Optional[UpdateArticleRequestState] Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. parent_id : typing.Optional[str] The id of the article's parent collection or section. An article without this field stands alone. - parent_type : typing.Optional[UpdateArticleRequestBodyParentType] + parent_type : typing.Optional[str] The type of parent, which can either be a `collection` or `section`. translated_content : typing.Optional[ArticleTranslatedContent] @@ -261,7 +228,7 @@ def update( token="YOUR_TOKEN", ) client.articles.update( - article_id="123", + article_id=1, title="Christmas is here!", body="

New gifts in store for the jolly season

", ) @@ -281,14 +248,14 @@ def update( return _response.data def delete( - self, article_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, article_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> DeletedArticleObject: """ You can delete a single article by making a DELETE request to `https://api.intercom.io/articles/`. Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -307,7 +274,7 @@ def delete( token="YOUR_TOKEN", ) client.articles.delete( - article_id="123", + article_id=1, ) """ _response = self._raw_client.delete(article_id, request_options=request_options) @@ -321,7 +288,7 @@ def search( help_center_id: typing.Optional[int] = None, highlight: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> SearchArticlesResponse: + ) -> ArticleSearchResponse: """ You can search for articles by making a GET request to `https://api.intercom.io/articles/search`. @@ -344,7 +311,7 @@ def search( Returns ------- - SearchArticlesResponse + ArticleSearchResponse Search successful Examples @@ -442,14 +409,7 @@ async def main() -> None: async def create( self, *, - title: str, - author_id: int, - description: typing.Optional[str] = OMIT, - body: typing.Optional[str] = OMIT, - state: typing.Optional[CreateArticleRequestState] = OMIT, - parent_id: typing.Optional[int] = OMIT, - parent_type: typing.Optional[CreateArticleRequestParentType] = OMIT, - translated_content: typing.Optional[ArticleTranslatedContent] = OMIT, + request: typing.Optional[CreateArticleRequest] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Article: """ @@ -457,28 +417,7 @@ async def create( Parameters ---------- - title : str - The title of the article.For multilingual articles, this will be the title of the default language's content. - - author_id : int - The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. - - description : typing.Optional[str] - The description of the article. For multilingual articles, this will be the description of the default language's content. - - body : typing.Optional[str] - The content of the article. For multilingual articles, this will be the body of the default language's content. - - state : typing.Optional[CreateArticleRequestState] - Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. - - parent_id : typing.Optional[int] - The id of the article's parent collection or section. An article without this field stands alone. - - parent_type : typing.Optional[CreateArticleRequestParentType] - The type of parent, which can either be a `collection` or `section`. - - translated_content : typing.Optional[ArticleTranslatedContent] + request : typing.Optional[CreateArticleRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -492,7 +431,12 @@ async def create( -------- import asyncio - from intercom import ArticleContent, ArticleTranslatedContent, AsyncIntercom + from intercom import ( + ArticleContent, + ArticleTranslatedContent, + AsyncIntercom, + CreateArticleRequest, + ) client = AsyncIntercom( token="YOUR_TOKEN", @@ -501,20 +445,22 @@ async def create( async def main() -> None: await client.articles.create( - title="Thanks for everything", - description="Description of the Article", - body="Body of the Article", - author_id=991267407, - state="published", - parent_id=145, - parent_type="collection", - translated_content=ArticleTranslatedContent( - fr=ArticleContent( - title="Merci pour tout", - description="Description de l'article", - body="Corps de l'article", - author_id=991267407, - state="published", + request=CreateArticleRequest( + title="Thanks for everything", + description="Description of the Article", + body="Body of the Article", + author_id=991267497, + state="published", + parent_id=145, + parent_type="collection", + translated_content=ArticleTranslatedContent( + fr=ArticleContent( + title="Merci pour tout", + description="Description de l'article", + body="Corps de l'article", + author_id=991267497, + state="published", + ), ), ), ) @@ -522,26 +468,16 @@ async def main() -> None: asyncio.run(main()) """ - _response = await self._raw_client.create( - title=title, - author_id=author_id, - description=description, - body=body, - state=state, - parent_id=parent_id, - parent_type=parent_type, - translated_content=translated_content, - request_options=request_options, - ) + _response = await self._raw_client.create(request=request, request_options=request_options) return _response.data - async def find(self, article_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Article: + async def find(self, article_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> Article: """ You can fetch the details of a single article by making a GET request to `https://api.intercom.io/articles/`. Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -565,7 +501,7 @@ async def find(self, article_id: str, *, request_options: typing.Optional[Reques async def main() -> None: await client.articles.find( - article_id="123", + article_id=1, ) @@ -576,15 +512,15 @@ async def main() -> None: async def update( self, - article_id: str, + article_id: int, *, title: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, body: typing.Optional[str] = OMIT, author_id: typing.Optional[int] = OMIT, - state: typing.Optional[UpdateArticleRequestBodyState] = OMIT, + state: typing.Optional[UpdateArticleRequestState] = OMIT, parent_id: typing.Optional[str] = OMIT, - parent_type: typing.Optional[UpdateArticleRequestBodyParentType] = OMIT, + parent_type: typing.Optional[str] = OMIT, translated_content: typing.Optional[ArticleTranslatedContent] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Article: @@ -593,7 +529,7 @@ async def update( Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. title : typing.Optional[str] @@ -608,13 +544,13 @@ async def update( author_id : typing.Optional[int] The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. - state : typing.Optional[UpdateArticleRequestBodyState] + state : typing.Optional[UpdateArticleRequestState] Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. parent_id : typing.Optional[str] The id of the article's parent collection or section. An article without this field stands alone. - parent_type : typing.Optional[UpdateArticleRequestBodyParentType] + parent_type : typing.Optional[str] The type of parent, which can either be a `collection` or `section`. translated_content : typing.Optional[ArticleTranslatedContent] @@ -640,7 +576,7 @@ async def update( async def main() -> None: await client.articles.update( - article_id="123", + article_id=1, title="Christmas is here!", body="

New gifts in store for the jolly season

", ) @@ -663,14 +599,14 @@ async def main() -> None: return _response.data async def delete( - self, article_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, article_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> DeletedArticleObject: """ You can delete a single article by making a DELETE request to `https://api.intercom.io/articles/`. Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -694,7 +630,7 @@ async def delete( async def main() -> None: await client.articles.delete( - article_id="123", + article_id=1, ) @@ -711,7 +647,7 @@ async def search( help_center_id: typing.Optional[int] = None, highlight: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> SearchArticlesResponse: + ) -> ArticleSearchResponse: """ You can search for articles by making a GET request to `https://api.intercom.io/articles/search`. @@ -734,7 +670,7 @@ async def search( Returns ------- - SearchArticlesResponse + ArticleSearchResponse Search successful Examples diff --git a/src/intercom/articles/raw_client.py b/src/intercom/articles/raw_client.py index ee2643b..03e55e9 100644 --- a/src/intercom/articles/raw_client.py +++ b/src/intercom/articles/raw_client.py @@ -16,15 +16,13 @@ from ..errors.unauthorized_error import UnauthorizedError from ..types.article_list import ArticleList from ..types.article_translated_content import ArticleTranslatedContent +from ..types.create_article_request import CreateArticleRequest from ..types.deleted_article_object import DeletedArticleObject from ..types.error import Error from .types.article import Article from .types.article_list_item import ArticleListItem -from .types.create_article_request_parent_type import CreateArticleRequestParentType -from .types.create_article_request_state import CreateArticleRequestState -from .types.search_articles_response import SearchArticlesResponse -from .types.update_article_request_body_parent_type import UpdateArticleRequestBodyParentType -from .types.update_article_request_body_state import UpdateArticleRequestBodyState +from .types.article_search_response import ArticleSearchResponse +from .types.update_article_request_state import UpdateArticleRequestState # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -113,14 +111,7 @@ def list( def create( self, *, - title: str, - author_id: int, - description: typing.Optional[str] = OMIT, - body: typing.Optional[str] = OMIT, - state: typing.Optional[CreateArticleRequestState] = OMIT, - parent_id: typing.Optional[int] = OMIT, - parent_type: typing.Optional[CreateArticleRequestParentType] = OMIT, - translated_content: typing.Optional[ArticleTranslatedContent] = OMIT, + request: typing.Optional[CreateArticleRequest] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Article]: """ @@ -128,28 +119,7 @@ def create( Parameters ---------- - title : str - The title of the article.For multilingual articles, this will be the title of the default language's content. - - author_id : int - The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. - - description : typing.Optional[str] - The description of the article. For multilingual articles, this will be the description of the default language's content. - - body : typing.Optional[str] - The content of the article. For multilingual articles, this will be the body of the default language's content. - - state : typing.Optional[CreateArticleRequestState] - Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. - - parent_id : typing.Optional[int] - The id of the article's parent collection or section. An article without this field stands alone. - - parent_type : typing.Optional[CreateArticleRequestParentType] - The type of parent, which can either be a `collection` or `section`. - - translated_content : typing.Optional[ArticleTranslatedContent] + request : typing.Optional[CreateArticleRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -162,18 +132,9 @@ def create( _response = self._client_wrapper.httpx_client.request( "articles", method="POST", - json={ - "title": title, - "description": description, - "body": body, - "author_id": author_id, - "state": state, - "parent_id": parent_id, - "parent_type": parent_type, - "translated_content": convert_and_respect_annotation_metadata( - object_=translated_content, annotation=ArticleTranslatedContent, direction="write" - ), - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateArticleRequest, direction="write" + ), headers={ "content-type": "application/json", }, @@ -218,14 +179,14 @@ def create( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def find( - self, article_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, article_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[Article]: """ You can fetch the details of a single article by making a GET request to `https://api.intercom.io/articles/`. Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -280,15 +241,15 @@ def find( def update( self, - article_id: str, + article_id: int, *, title: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, body: typing.Optional[str] = OMIT, author_id: typing.Optional[int] = OMIT, - state: typing.Optional[UpdateArticleRequestBodyState] = OMIT, + state: typing.Optional[UpdateArticleRequestState] = OMIT, parent_id: typing.Optional[str] = OMIT, - parent_type: typing.Optional[UpdateArticleRequestBodyParentType] = OMIT, + parent_type: typing.Optional[str] = OMIT, translated_content: typing.Optional[ArticleTranslatedContent] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Article]: @@ -297,7 +258,7 @@ def update( Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. title : typing.Optional[str] @@ -312,13 +273,13 @@ def update( author_id : typing.Optional[int] The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. - state : typing.Optional[UpdateArticleRequestBodyState] + state : typing.Optional[UpdateArticleRequestState] Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. parent_id : typing.Optional[str] The id of the article's parent collection or section. An article without this field stands alone. - parent_type : typing.Optional[UpdateArticleRequestBodyParentType] + parent_type : typing.Optional[str] The type of parent, which can either be a `collection` or `section`. translated_content : typing.Optional[ArticleTranslatedContent] @@ -390,14 +351,14 @@ def update( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def delete( - self, article_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, article_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[DeletedArticleObject]: """ You can delete a single article by making a DELETE request to `https://api.intercom.io/articles/`. Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -458,7 +419,7 @@ def search( help_center_id: typing.Optional[int] = None, highlight: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[SearchArticlesResponse]: + ) -> HttpResponse[ArticleSearchResponse]: """ You can search for articles by making a GET request to `https://api.intercom.io/articles/search`. @@ -481,7 +442,7 @@ def search( Returns ------- - HttpResponse[SearchArticlesResponse] + HttpResponse[ArticleSearchResponse] Search successful """ _response = self._client_wrapper.httpx_client.request( @@ -498,9 +459,9 @@ def search( try: if 200 <= _response.status_code < 300: _data = typing.cast( - SearchArticlesResponse, + ArticleSearchResponse, construct_type( - type_=SearchArticlesResponse, # type: ignore + type_=ArticleSearchResponse, # type: ignore object_=_response.json(), ), ) @@ -608,14 +569,7 @@ async def _get_next(): async def create( self, *, - title: str, - author_id: int, - description: typing.Optional[str] = OMIT, - body: typing.Optional[str] = OMIT, - state: typing.Optional[CreateArticleRequestState] = OMIT, - parent_id: typing.Optional[int] = OMIT, - parent_type: typing.Optional[CreateArticleRequestParentType] = OMIT, - translated_content: typing.Optional[ArticleTranslatedContent] = OMIT, + request: typing.Optional[CreateArticleRequest] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Article]: """ @@ -623,28 +577,7 @@ async def create( Parameters ---------- - title : str - The title of the article.For multilingual articles, this will be the title of the default language's content. - - author_id : int - The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. - - description : typing.Optional[str] - The description of the article. For multilingual articles, this will be the description of the default language's content. - - body : typing.Optional[str] - The content of the article. For multilingual articles, this will be the body of the default language's content. - - state : typing.Optional[CreateArticleRequestState] - Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. - - parent_id : typing.Optional[int] - The id of the article's parent collection or section. An article without this field stands alone. - - parent_type : typing.Optional[CreateArticleRequestParentType] - The type of parent, which can either be a `collection` or `section`. - - translated_content : typing.Optional[ArticleTranslatedContent] + request : typing.Optional[CreateArticleRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -657,18 +590,9 @@ async def create( _response = await self._client_wrapper.httpx_client.request( "articles", method="POST", - json={ - "title": title, - "description": description, - "body": body, - "author_id": author_id, - "state": state, - "parent_id": parent_id, - "parent_type": parent_type, - "translated_content": convert_and_respect_annotation_metadata( - object_=translated_content, annotation=ArticleTranslatedContent, direction="write" - ), - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateArticleRequest, direction="write" + ), headers={ "content-type": "application/json", }, @@ -713,14 +637,14 @@ async def create( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def find( - self, article_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, article_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[Article]: """ You can fetch the details of a single article by making a GET request to `https://api.intercom.io/articles/`. Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -775,15 +699,15 @@ async def find( async def update( self, - article_id: str, + article_id: int, *, title: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, body: typing.Optional[str] = OMIT, author_id: typing.Optional[int] = OMIT, - state: typing.Optional[UpdateArticleRequestBodyState] = OMIT, + state: typing.Optional[UpdateArticleRequestState] = OMIT, parent_id: typing.Optional[str] = OMIT, - parent_type: typing.Optional[UpdateArticleRequestBodyParentType] = OMIT, + parent_type: typing.Optional[str] = OMIT, translated_content: typing.Optional[ArticleTranslatedContent] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Article]: @@ -792,7 +716,7 @@ async def update( Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. title : typing.Optional[str] @@ -807,13 +731,13 @@ async def update( author_id : typing.Optional[int] The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. - state : typing.Optional[UpdateArticleRequestBodyState] + state : typing.Optional[UpdateArticleRequestState] Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. parent_id : typing.Optional[str] The id of the article's parent collection or section. An article without this field stands alone. - parent_type : typing.Optional[UpdateArticleRequestBodyParentType] + parent_type : typing.Optional[str] The type of parent, which can either be a `collection` or `section`. translated_content : typing.Optional[ArticleTranslatedContent] @@ -885,14 +809,14 @@ async def update( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def delete( - self, article_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, article_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[DeletedArticleObject]: """ You can delete a single article by making a DELETE request to `https://api.intercom.io/articles/`. Parameters ---------- - article_id : str + article_id : int The unique identifier for the article which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -953,7 +877,7 @@ async def search( help_center_id: typing.Optional[int] = None, highlight: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[SearchArticlesResponse]: + ) -> AsyncHttpResponse[ArticleSearchResponse]: """ You can search for articles by making a GET request to `https://api.intercom.io/articles/search`. @@ -976,7 +900,7 @@ async def search( Returns ------- - AsyncHttpResponse[SearchArticlesResponse] + AsyncHttpResponse[ArticleSearchResponse] Search successful """ _response = await self._client_wrapper.httpx_client.request( @@ -993,9 +917,9 @@ async def search( try: if 200 <= _response.status_code < 300: _data = typing.cast( - SearchArticlesResponse, + ArticleSearchResponse, construct_type( - type_=SearchArticlesResponse, # type: ignore + type_=ArticleSearchResponse, # type: ignore object_=_response.json(), ), ) diff --git a/src/intercom/articles/types/__init__.py b/src/intercom/articles/types/__init__.py index acb8e03..07cb753 100644 --- a/src/intercom/articles/types/__init__.py +++ b/src/intercom/articles/types/__init__.py @@ -12,12 +12,10 @@ ) from .article_search_highlights_highlighted_title_item import ArticleSearchHighlightsHighlightedTitleItem from .article_search_highlights_highlighted_title_item_type import ArticleSearchHighlightsHighlightedTitleItemType -from .create_article_request_parent_type import CreateArticleRequestParentType -from .create_article_request_state import CreateArticleRequestState -from .search_articles_response import SearchArticlesResponse -from .search_articles_response_data import SearchArticlesResponseData -from .update_article_request_body_parent_type import UpdateArticleRequestBodyParentType -from .update_article_request_body_state import UpdateArticleRequestBodyState +from .article_search_response import ArticleSearchResponse +from .article_search_response_data import ArticleSearchResponseData +from .internal_article import InternalArticle +from .update_article_request_state import UpdateArticleRequestState __all__ = [ "Article", @@ -28,10 +26,8 @@ "ArticleSearchHighlightsHighlightedSummaryItemItemType", "ArticleSearchHighlightsHighlightedTitleItem", "ArticleSearchHighlightsHighlightedTitleItemType", - "CreateArticleRequestParentType", - "CreateArticleRequestState", - "SearchArticlesResponse", - "SearchArticlesResponseData", - "UpdateArticleRequestBodyParentType", - "UpdateArticleRequestBodyState", + "ArticleSearchResponse", + "ArticleSearchResponseData", + "InternalArticle", + "UpdateArticleRequestState", ] diff --git a/src/intercom/articles/types/article_search_highlights.py b/src/intercom/articles/types/article_search_highlights.py index 6ad1b7f..ca7efd5 100644 --- a/src/intercom/articles/types/article_search_highlights.py +++ b/src/intercom/articles/types/article_search_highlights.py @@ -14,17 +14,21 @@ class ArticleSearchHighlights(UncheckedBaseModel): The highlighted results of an Article search. In the examples provided my search query is always "my query". """ - article_id: str = pydantic.Field() + article_id: typing.Optional[str] = pydantic.Field(default=None) """ The ID of the corresponding article. """ - highlighted_title: typing.List[ArticleSearchHighlightsHighlightedTitleItem] = pydantic.Field() + highlighted_title: typing.Optional[typing.List[ArticleSearchHighlightsHighlightedTitleItem]] = pydantic.Field( + default=None + ) """ An Article title highlighted. """ - highlighted_summary: typing.List[typing.List[ArticleSearchHighlightsHighlightedSummaryItemItem]] = pydantic.Field() + highlighted_summary: typing.Optional[ + typing.List[typing.List[ArticleSearchHighlightsHighlightedSummaryItemItem]] + ] = pydantic.Field(default=None) """ An Article description and body text highlighted. """ diff --git a/src/intercom/articles/types/search_articles_response.py b/src/intercom/articles/types/article_search_response.py similarity index 70% rename from src/intercom/articles/types/search_articles_response.py rename to src/intercom/articles/types/article_search_response.py index aefa641..5c540b3 100644 --- a/src/intercom/articles/types/search_articles_response.py +++ b/src/intercom/articles/types/article_search_response.py @@ -6,25 +6,25 @@ from ...core.pydantic_utilities import IS_PYDANTIC_V2 from ...core.unchecked_base_model import UncheckedBaseModel from ...types.cursor_pages import CursorPages -from .search_articles_response_data import SearchArticlesResponseData +from .article_search_response_data import ArticleSearchResponseData -class SearchArticlesResponse(UncheckedBaseModel): +class ArticleSearchResponse(UncheckedBaseModel): """ The results of an Article search """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of the object - `list`. """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ The total number of Articles matching the search query """ - data: SearchArticlesResponseData = pydantic.Field() + data: typing.Optional[ArticleSearchResponseData] = pydantic.Field(default=None) """ An object containing the results of the search. """ diff --git a/src/intercom/articles/types/search_articles_response_data.py b/src/intercom/articles/types/article_search_response_data.py similarity index 94% rename from src/intercom/articles/types/search_articles_response_data.py rename to src/intercom/articles/types/article_search_response_data.py index dcc495d..741e1a7 100644 --- a/src/intercom/articles/types/search_articles_response_data.py +++ b/src/intercom/articles/types/article_search_response_data.py @@ -9,7 +9,7 @@ from .article_search_highlights import ArticleSearchHighlights -class SearchArticlesResponseData(UncheckedBaseModel): +class ArticleSearchResponseData(UncheckedBaseModel): """ An object containing the results of the search. """ diff --git a/src/intercom/articles/types/internal_article.py b/src/intercom/articles/types/internal_article.py new file mode 100644 index 0000000..3b83a54 --- /dev/null +++ b/src/intercom/articles/types/internal_article.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from ...internal_articles.types.internal_article_list_item import InternalArticleListItem + +InternalArticle = InternalArticleListItem diff --git a/src/intercom/articles/types/update_article_request_body_state.py b/src/intercom/articles/types/update_article_request_body_state.py deleted file mode 100644 index ecd45be..0000000 --- a/src/intercom/articles/types/update_article_request_body_state.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -UpdateArticleRequestBodyState = typing.Union[typing.Literal["published", "draft"], typing.Any] diff --git a/src/intercom/unstable/types/update_article_request_state.py b/src/intercom/articles/types/update_article_request_state.py similarity index 100% rename from src/intercom/unstable/types/update_article_request_state.py rename to src/intercom/articles/types/update_article_request_state.py diff --git a/src/intercom/away_status_reasons/__init__.py b/src/intercom/away_status_reasons/__init__.py new file mode 100644 index 0000000..5cde020 --- /dev/null +++ b/src/intercom/away_status_reasons/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/intercom/away_status_reasons/client.py b/src/intercom/away_status_reasons/client.py new file mode 100644 index 0000000..b8971ca --- /dev/null +++ b/src/intercom/away_status_reasons/client.py @@ -0,0 +1,104 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.away_status_reason import AwayStatusReason +from .raw_client import AsyncRawAwayStatusReasonsClient, RawAwayStatusReasonsClient + + +class AwayStatusReasonsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawAwayStatusReasonsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawAwayStatusReasonsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawAwayStatusReasonsClient + """ + return self._raw_client + + def list_away_status_reasons( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[AwayStatusReason]: + """ + Returns a list of all away status reasons configured for the workspace, including deleted ones. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[AwayStatusReason] + Successful response + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.away_status_reasons.list_away_status_reasons() + """ + _response = self._raw_client.list_away_status_reasons(request_options=request_options) + return _response.data + + +class AsyncAwayStatusReasonsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawAwayStatusReasonsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawAwayStatusReasonsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawAwayStatusReasonsClient + """ + return self._raw_client + + async def list_away_status_reasons( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.List[AwayStatusReason]: + """ + Returns a list of all away status reasons configured for the workspace, including deleted ones. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.List[AwayStatusReason] + Successful response + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.away_status_reasons.list_away_status_reasons() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_away_status_reasons(request_options=request_options) + return _response.data diff --git a/src/intercom/away_status_reasons/raw_client.py b/src/intercom/away_status_reasons/raw_client.py new file mode 100644 index 0000000..62fbd5c --- /dev/null +++ b/src/intercom/away_status_reasons/raw_client.py @@ -0,0 +1,117 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.request_options import RequestOptions +from ..core.unchecked_base_model import construct_type +from ..errors.unauthorized_error import UnauthorizedError +from ..types.away_status_reason import AwayStatusReason +from ..types.error import Error + + +class RawAwayStatusReasonsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_away_status_reasons( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[typing.List[AwayStatusReason]]: + """ + Returns a list of all away status reasons configured for the workspace, including deleted ones. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[typing.List[AwayStatusReason]] + Successful response + """ + _response = self._client_wrapper.httpx_client.request( + "away_status_reasons", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[AwayStatusReason], + construct_type( + type_=typing.List[AwayStatusReason], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawAwayStatusReasonsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_away_status_reasons( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[typing.List[AwayStatusReason]]: + """ + Returns a list of all away status reasons configured for the workspace, including deleted ones. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[typing.List[AwayStatusReason]] + Successful response + """ + _response = await self._client_wrapper.httpx_client.request( + "away_status_reasons", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.List[AwayStatusReason], + construct_type( + type_=typing.List[AwayStatusReason], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/calls/__init__.py b/src/intercom/calls/__init__.py new file mode 100644 index 0000000..bf542ca --- /dev/null +++ b/src/intercom/calls/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import Call, ListCallsWithTranscriptsResponse, ListCallsWithTranscriptsResponseDataItem + +__all__ = ["Call", "ListCallsWithTranscriptsResponse", "ListCallsWithTranscriptsResponseDataItem"] diff --git a/src/intercom/calls/client.py b/src/intercom/calls/client.py new file mode 100644 index 0000000..36f67dc --- /dev/null +++ b/src/intercom/calls/client.py @@ -0,0 +1,421 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.call_list import CallList +from .raw_client import AsyncRawCallsClient, RawCallsClient +from .types.call import Call +from .types.list_calls_with_transcripts_response import ListCallsWithTranscriptsResponse + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class CallsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawCallsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawCallsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawCallsClient + """ + return self._raw_client + + def list_calls( + self, + *, + page: typing.Optional[int] = None, + per_page: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CallList: + """ + Retrieve a paginated list of calls. + + Parameters + ---------- + page : typing.Optional[int] + The page of results to fetch. Defaults to first page + + per_page : typing.Optional[int] + How many results to display per page. Defaults to 25. Max 25. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CallList + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.calls.list_calls() + """ + _response = self._raw_client.list_calls(page=page, per_page=per_page, request_options=request_options) + return _response.data + + def show_call(self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Call: + """ + Retrieve a single call by id. + + Parameters + ---------- + call_id : str + The id of the call to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Call + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.calls.show_call( + call_id="call_id", + ) + """ + _response = self._raw_client.show_call(call_id, request_options=request_options) + return _response.data + + def show_call_recording(self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: + """ + Redirects to a signed URL for the call's recording if it exists. + + Parameters + ---------- + call_id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.calls.show_call_recording( + call_id="call_id", + ) + """ + _response = self._raw_client.show_call_recording(call_id, request_options=request_options) + return _response.data + + def show_call_transcript(self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> str: + """ + Returns the transcript for the specified call as a downloadable text file. + + Parameters + ---------- + call_id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + str + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.calls.show_call_transcript( + call_id="call_id", + ) + """ + _response = self._raw_client.show_call_transcript(call_id, request_options=request_options) + return _response.data + + def list_calls_with_transcripts( + self, *, conversation_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None + ) -> ListCallsWithTranscriptsResponse: + """ + Retrieve calls by a list of conversation ids and include transcripts when available. + A maximum of 20 `conversation_ids` can be provided. If none are provided or more than 20 are provided, a 400 error is returned. + + Parameters + ---------- + conversation_ids : typing.Sequence[str] + A list of conversation ids to fetch calls for. Maximum 20. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ListCallsWithTranscriptsResponse + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.calls.list_calls_with_transcripts( + conversation_ids=["64619700005694", "64619700005695"], + ) + """ + _response = self._raw_client.list_calls_with_transcripts( + conversation_ids=conversation_ids, request_options=request_options + ) + return _response.data + + +class AsyncCallsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawCallsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawCallsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawCallsClient + """ + return self._raw_client + + async def list_calls( + self, + *, + page: typing.Optional[int] = None, + per_page: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CallList: + """ + Retrieve a paginated list of calls. + + Parameters + ---------- + page : typing.Optional[int] + The page of results to fetch. Defaults to first page + + per_page : typing.Optional[int] + How many results to display per page. Defaults to 25. Max 25. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CallList + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.calls.list_calls() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_calls(page=page, per_page=per_page, request_options=request_options) + return _response.data + + async def show_call(self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Call: + """ + Retrieve a single call by id. + + Parameters + ---------- + call_id : str + The id of the call to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Call + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.calls.show_call( + call_id="call_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.show_call(call_id, request_options=request_options) + return _response.data + + async def show_call_recording( + self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Redirects to a signed URL for the call's recording if it exists. + + Parameters + ---------- + call_id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.calls.show_call_recording( + call_id="call_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.show_call_recording(call_id, request_options=request_options) + return _response.data + + async def show_call_transcript( + self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> str: + """ + Returns the transcript for the specified call as a downloadable text file. + + Parameters + ---------- + call_id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + str + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.calls.show_call_transcript( + call_id="call_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.show_call_transcript(call_id, request_options=request_options) + return _response.data + + async def list_calls_with_transcripts( + self, *, conversation_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None + ) -> ListCallsWithTranscriptsResponse: + """ + Retrieve calls by a list of conversation ids and include transcripts when available. + A maximum of 20 `conversation_ids` can be provided. If none are provided or more than 20 are provided, a 400 error is returned. + + Parameters + ---------- + conversation_ids : typing.Sequence[str] + A list of conversation ids to fetch calls for. Maximum 20. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ListCallsWithTranscriptsResponse + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.calls.list_calls_with_transcripts( + conversation_ids=["64619700005694", "64619700005695"], + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_calls_with_transcripts( + conversation_ids=conversation_ids, request_options=request_options + ) + return _response.data diff --git a/src/intercom/calls/raw_client.py b/src/intercom/calls/raw_client.py new file mode 100644 index 0000000..01accd2 --- /dev/null +++ b/src/intercom/calls/raw_client.py @@ -0,0 +1,603 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.jsonable_encoder import jsonable_encoder +from ..core.request_options import RequestOptions +from ..core.unchecked_base_model import construct_type +from ..errors.bad_request_error import BadRequestError +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.call_list import CallList +from ..types.error import Error +from .types.call import Call +from .types.list_calls_with_transcripts_response import ListCallsWithTranscriptsResponse + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawCallsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_calls( + self, + *, + page: typing.Optional[int] = None, + per_page: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[CallList]: + """ + Retrieve a paginated list of calls. + + Parameters + ---------- + page : typing.Optional[int] + The page of results to fetch. Defaults to first page + + per_page : typing.Optional[int] + How many results to display per page. Defaults to 25. Max 25. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[CallList] + successful + """ + _response = self._client_wrapper.httpx_client.request( + "calls", + method="GET", + params={ + "page": page, + "per_page": per_page, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CallList, + construct_type( + type_=CallList, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def show_call(self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Call]: + """ + Retrieve a single call by id. + + Parameters + ---------- + call_id : str + The id of the call to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Call] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(call_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Call, + construct_type( + type_=Call, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def show_call_recording( + self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[None]: + """ + Redirects to a signed URL for the call's recording if it exists. + + Parameters + ---------- + call_id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[None] + """ + _response = self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(call_id)}/recording", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=None) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def show_call_transcript( + self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[str]: + """ + Returns the transcript for the specified call as a downloadable text file. + + Parameters + ---------- + call_id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[str] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(call_id)}/transcript", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=_response.text) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def list_calls_with_transcripts( + self, *, conversation_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ListCallsWithTranscriptsResponse]: + """ + Retrieve calls by a list of conversation ids and include transcripts when available. + A maximum of 20 `conversation_ids` can be provided. If none are provided or more than 20 are provided, a 400 error is returned. + + Parameters + ---------- + conversation_ids : typing.Sequence[str] + A list of conversation ids to fetch calls for. Maximum 20. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ListCallsWithTranscriptsResponse] + successful + """ + _response = self._client_wrapper.httpx_client.request( + "calls/search", + method="POST", + json={ + "conversation_ids": conversation_ids, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ListCallsWithTranscriptsResponse, + construct_type( + type_=ListCallsWithTranscriptsResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawCallsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_calls( + self, + *, + page: typing.Optional[int] = None, + per_page: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[CallList]: + """ + Retrieve a paginated list of calls. + + Parameters + ---------- + page : typing.Optional[int] + The page of results to fetch. Defaults to first page + + per_page : typing.Optional[int] + How many results to display per page. Defaults to 25. Max 25. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[CallList] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + "calls", + method="GET", + params={ + "page": page, + "per_page": per_page, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CallList, + construct_type( + type_=CallList, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def show_call( + self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[Call]: + """ + Retrieve a single call by id. + + Parameters + ---------- + call_id : str + The id of the call to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Call] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(call_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Call, + construct_type( + type_=Call, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def show_call_recording( + self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[None]: + """ + Redirects to a signed URL for the call's recording if it exists. + + Parameters + ---------- + call_id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[None] + """ + _response = await self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(call_id)}/recording", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=None) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def show_call_transcript( + self, call_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[str]: + """ + Returns the transcript for the specified call as a downloadable text file. + + Parameters + ---------- + call_id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[str] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(call_id)}/transcript", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=_response.text) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def list_calls_with_transcripts( + self, *, conversation_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ListCallsWithTranscriptsResponse]: + """ + Retrieve calls by a list of conversation ids and include transcripts when available. + A maximum of 20 `conversation_ids` can be provided. If none are provided or more than 20 are provided, a 400 error is returned. + + Parameters + ---------- + conversation_ids : typing.Sequence[str] + A list of conversation ids to fetch calls for. Maximum 20. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ListCallsWithTranscriptsResponse] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + "calls/search", + method="POST", + json={ + "conversation_ids": conversation_ids, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ListCallsWithTranscriptsResponse, + construct_type( + type_=ListCallsWithTranscriptsResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/calls/types/__init__.py b/src/intercom/calls/types/__init__.py new file mode 100644 index 0000000..f0f25e4 --- /dev/null +++ b/src/intercom/calls/types/__init__.py @@ -0,0 +1,9 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .call import Call +from .list_calls_with_transcripts_response import ListCallsWithTranscriptsResponse +from .list_calls_with_transcripts_response_data_item import ListCallsWithTranscriptsResponseDataItem + +__all__ = ["Call", "ListCallsWithTranscriptsResponse", "ListCallsWithTranscriptsResponseDataItem"] diff --git a/src/intercom/calls/types/call.py b/src/intercom/calls/types/call.py new file mode 100644 index 0000000..7992287 --- /dev/null +++ b/src/intercom/calls/types/call.py @@ -0,0 +1,93 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from ...types.datetime import Datetime + + +class Call(UncheckedBaseModel): + """ + Represents a phone call in Intercom + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + String representing the object's type. Always has the value `call`. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the call. + """ + + conversation_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the conversation associated with the call, if any. + """ + + admin_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the admin associated with the call, if any. + """ + + contact_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the contact associated with the call, if any. + """ + + state: typing.Optional[str] = pydantic.Field(default=None) + """ + The current state of the call. + """ + + initiated_at: typing.Optional[Datetime] = None + answered_at: typing.Optional[Datetime] = None + ended_at: typing.Optional[Datetime] = None + created_at: typing.Optional[Datetime] = None + updated_at: typing.Optional[Datetime] = None + recording_url: typing.Optional[str] = pydantic.Field(default=None) + """ + API URL to download or redirect to the call recording if available. + """ + + call_type: typing.Optional[str] = pydantic.Field(default=None) + """ + The type of call. + """ + + direction: typing.Optional[str] = pydantic.Field(default=None) + """ + The direction of the call. + """ + + ended_reason: typing.Optional[str] = pydantic.Field(default=None) + """ + The reason for the call end, if applicable. + """ + + phone: typing.Optional[str] = pydantic.Field(default=None) + """ + The phone number involved in the call, in E.164 format. + """ + + fin_recording_url: typing.Optional[str] = pydantic.Field(default=None) + """ + API URL to the AI Agent (Fin) call recording if available. + """ + + fin_transcription_url: typing.Optional[str] = pydantic.Field(default=None) + """ + API URL to the AI Agent (Fin) call transcript if available. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/calls/types/list_calls_with_transcripts_response.py b/src/intercom/calls/types/list_calls_with_transcripts_response.py new file mode 100644 index 0000000..999c312 --- /dev/null +++ b/src/intercom/calls/types/list_calls_with_transcripts_response.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .list_calls_with_transcripts_response_data_item import ListCallsWithTranscriptsResponseDataItem + + +class ListCallsWithTranscriptsResponse(UncheckedBaseModel): + type: typing.Optional[str] = None + data: typing.Optional[typing.List[ListCallsWithTranscriptsResponseDataItem]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/calls/types/list_calls_with_transcripts_response_data_item.py b/src/intercom/calls/types/list_calls_with_transcripts_response_data_item.py new file mode 100644 index 0000000..b7ac00f --- /dev/null +++ b/src/intercom/calls/types/list_calls_with_transcripts_response_data_item.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from .call import Call + + +class ListCallsWithTranscriptsResponseDataItem(Call): + transcript: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = pydantic.Field( + default=None + ) + """ + The call transcript if available, otherwise an empty array. + """ + + transcript_status: typing.Optional[str] = pydantic.Field(default=None) + """ + The status of the transcript if available. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/client.py b/src/intercom/client.py index a652891..f11c3a1 100644 --- a/src/intercom/client.py +++ b/src/intercom/client.py @@ -5,17 +5,25 @@ import httpx from .admins.client import AdminsClient, AsyncAdminsClient +from .ai_content.client import AiContentClient, AsyncAiContentClient from .articles.client import ArticlesClient, AsyncArticlesClient +from .away_status_reasons.client import AsyncAwayStatusReasonsClient, AwayStatusReasonsClient +from .calls.client import AsyncCallsClient, CallsClient from .companies.client import AsyncCompaniesClient, CompaniesClient from .contacts.client import AsyncContactsClient, ContactsClient from .conversations.client import AsyncConversationsClient, ConversationsClient from .core.api_error import ApiError from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from .custom_channel_events.client import AsyncCustomChannelEventsClient, CustomChannelEventsClient +from .custom_object_instances.client import AsyncCustomObjectInstancesClient, CustomObjectInstancesClient from .data_attributes.client import AsyncDataAttributesClient, DataAttributesClient from .data_export.client import AsyncDataExportClient, DataExportClient from .environment import IntercomEnvironment from .events.client import AsyncEventsClient, EventsClient +from .export.client import AsyncExportClient, ExportClient from .help_centers.client import AsyncHelpCentersClient, HelpCentersClient +from .internal_articles.client import AsyncInternalArticlesClient, InternalArticlesClient +from .jobs.client import AsyncJobsClient, JobsClient from .messages.client import AsyncMessagesClient, MessagesClient from .news.client import AsyncNewsClient, NewsClient from .notes.client import AsyncNotesClient, NotesClient @@ -24,6 +32,7 @@ from .subscription_types.client import AsyncSubscriptionTypesClient, SubscriptionTypesClient from .tags.client import AsyncTagsClient, TagsClient from .teams.client import AsyncTeamsClient, TeamsClient +from .ticket_states.client import AsyncTicketStatesClient, TicketStatesClient from .ticket_types.client import AsyncTicketTypesClient, TicketTypesClient from .tickets.client import AsyncTicketsClient, TicketsClient from .unstable.client import AsyncUnstableClient, UnstableClient @@ -95,21 +104,30 @@ def __init__( timeout=_defaulted_timeout, ) self.admins = AdminsClient(client_wrapper=self._client_wrapper) + self.ai_content = AiContentClient(client_wrapper=self._client_wrapper) self.articles = ArticlesClient(client_wrapper=self._client_wrapper) + self.away_status_reasons = AwayStatusReasonsClient(client_wrapper=self._client_wrapper) + self.export = ExportClient(client_wrapper=self._client_wrapper) + self.data_export = DataExportClient(client_wrapper=self._client_wrapper) self.help_centers = HelpCentersClient(client_wrapper=self._client_wrapper) + self.internal_articles = InternalArticlesClient(client_wrapper=self._client_wrapper) self.companies = CompaniesClient(client_wrapper=self._client_wrapper) self.contacts = ContactsClient(client_wrapper=self._client_wrapper) self.notes = NotesClient(client_wrapper=self._client_wrapper) self.tags = TagsClient(client_wrapper=self._client_wrapper) self.conversations = ConversationsClient(client_wrapper=self._client_wrapper) + self.custom_channel_events = CustomChannelEventsClient(client_wrapper=self._client_wrapper) + self.custom_object_instances = CustomObjectInstancesClient(client_wrapper=self._client_wrapper) self.data_attributes = DataAttributesClient(client_wrapper=self._client_wrapper) self.events = EventsClient(client_wrapper=self._client_wrapper) - self.data_export = DataExportClient(client_wrapper=self._client_wrapper) + self.jobs = JobsClient(client_wrapper=self._client_wrapper) self.messages = MessagesClient(client_wrapper=self._client_wrapper) self.segments = SegmentsClient(client_wrapper=self._client_wrapper) self.subscription_types = SubscriptionTypesClient(client_wrapper=self._client_wrapper) self.phone_call_redirects = PhoneCallRedirectsClient(client_wrapper=self._client_wrapper) + self.calls = CallsClient(client_wrapper=self._client_wrapper) self.teams = TeamsClient(client_wrapper=self._client_wrapper) + self.ticket_states = TicketStatesClient(client_wrapper=self._client_wrapper) self.ticket_types = TicketTypesClient(client_wrapper=self._client_wrapper) self.tickets = TicketsClient(client_wrapper=self._client_wrapper) self.visitors = VisitorsClient(client_wrapper=self._client_wrapper) @@ -182,21 +200,30 @@ def __init__( timeout=_defaulted_timeout, ) self.admins = AsyncAdminsClient(client_wrapper=self._client_wrapper) + self.ai_content = AsyncAiContentClient(client_wrapper=self._client_wrapper) self.articles = AsyncArticlesClient(client_wrapper=self._client_wrapper) + self.away_status_reasons = AsyncAwayStatusReasonsClient(client_wrapper=self._client_wrapper) + self.export = AsyncExportClient(client_wrapper=self._client_wrapper) + self.data_export = AsyncDataExportClient(client_wrapper=self._client_wrapper) self.help_centers = AsyncHelpCentersClient(client_wrapper=self._client_wrapper) + self.internal_articles = AsyncInternalArticlesClient(client_wrapper=self._client_wrapper) self.companies = AsyncCompaniesClient(client_wrapper=self._client_wrapper) self.contacts = AsyncContactsClient(client_wrapper=self._client_wrapper) self.notes = AsyncNotesClient(client_wrapper=self._client_wrapper) self.tags = AsyncTagsClient(client_wrapper=self._client_wrapper) self.conversations = AsyncConversationsClient(client_wrapper=self._client_wrapper) + self.custom_channel_events = AsyncCustomChannelEventsClient(client_wrapper=self._client_wrapper) + self.custom_object_instances = AsyncCustomObjectInstancesClient(client_wrapper=self._client_wrapper) self.data_attributes = AsyncDataAttributesClient(client_wrapper=self._client_wrapper) self.events = AsyncEventsClient(client_wrapper=self._client_wrapper) - self.data_export = AsyncDataExportClient(client_wrapper=self._client_wrapper) + self.jobs = AsyncJobsClient(client_wrapper=self._client_wrapper) self.messages = AsyncMessagesClient(client_wrapper=self._client_wrapper) self.segments = AsyncSegmentsClient(client_wrapper=self._client_wrapper) self.subscription_types = AsyncSubscriptionTypesClient(client_wrapper=self._client_wrapper) self.phone_call_redirects = AsyncPhoneCallRedirectsClient(client_wrapper=self._client_wrapper) + self.calls = AsyncCallsClient(client_wrapper=self._client_wrapper) self.teams = AsyncTeamsClient(client_wrapper=self._client_wrapper) + self.ticket_states = AsyncTicketStatesClient(client_wrapper=self._client_wrapper) self.ticket_types = AsyncTicketTypesClient(client_wrapper=self._client_wrapper) self.tickets = AsyncTicketsClient(client_wrapper=self._client_wrapper) self.visitors = AsyncVisitorsClient(client_wrapper=self._client_wrapper) diff --git a/src/intercom/companies/client.py b/src/intercom/companies/client.py index d2d8f37..8469d96 100644 --- a/src/intercom/companies/client.py +++ b/src/intercom/companies/client.py @@ -7,6 +7,7 @@ from ..core.request_options import RequestOptions from ..types.company_attached_contacts import CompanyAttachedContacts from ..types.company_attached_segments import CompanyAttachedSegments +from ..types.create_or_update_company_request import CreateOrUpdateCompanyRequest from ..types.deleted_company_object import DeletedCompanyObject from .raw_client import AsyncRawCompaniesClient, RawCompaniesClient from .types.companies_retrieve_response import CompaniesRetrieveResponse @@ -111,15 +112,7 @@ def retrieve( def create_or_update( self, *, - name: typing.Optional[str] = OMIT, - company_id: typing.Optional[str] = OMIT, - plan: typing.Optional[str] = OMIT, - size: typing.Optional[int] = OMIT, - website: typing.Optional[str] = OMIT, - industry: typing.Optional[str] = OMIT, - custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, - remote_created_at: typing.Optional[int] = OMIT, - monthly_spend: typing.Optional[int] = OMIT, + request: typing.Optional[CreateOrUpdateCompanyRequest] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Company: """ @@ -135,32 +128,7 @@ def create_or_update( Parameters ---------- - name : typing.Optional[str] - The name of the Company - - company_id : typing.Optional[str] - The company id you have defined for the company. Can't be updated - - plan : typing.Optional[str] - The name of the plan you have associated with the company. - - size : typing.Optional[int] - The number of employees in this company. - - website : typing.Optional[str] - The URL for this company's website. Please note that the value specified here is not validated. Accepts any string. - - industry : typing.Optional[str] - The industry that this company operates in. - - custom_attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] - A hash of key/value pairs containing any other data about the company you want Intercom to store. - - remote_created_at : typing.Optional[int] - The time the company was created by you. - - monthly_spend : typing.Optional[int] - How much revenue the company generates for your business. Note that this will truncate floats. i.e. it only allow for whole integers, 155.98 will be truncated to 155. Note that this has an upper limit of 2**31-1 or 2147483647.. + request : typing.Optional[CreateOrUpdateCompanyRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -172,29 +140,20 @@ def create_or_update( Examples -------- - from intercom import Intercom + from intercom import CreateOrUpdateCompanyRequest, Intercom client = Intercom( token="YOUR_TOKEN", ) client.companies.create_or_update( - name="my company", - company_id="company_remote_id", - remote_created_at=1374138000, + request=CreateOrUpdateCompanyRequest( + name="my company", + company_id="company_remote_id", + remote_created_at=1374138000, + ), ) """ - _response = self._raw_client.create_or_update( - name=name, - company_id=company_id, - plan=plan, - size=size, - website=website, - industry=industry, - custom_attributes=custom_attributes, - remote_created_at=remote_created_at, - monthly_spend=monthly_spend, - request_options=request_options, - ) + _response = self._raw_client.create_or_update(request=request, request_options=request_options) return _response.data def find(self, company_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Company: @@ -297,12 +256,7 @@ def delete( return _response.data def list_attached_contacts( - self, - company_id: str, - *, - page: typing.Optional[int] = None, - per_page: typing.Optional[int] = None, - request_options: typing.Optional[RequestOptions] = None, + self, company_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> CompanyAttachedContacts: """ You can fetch a list of all contacts that belong to a company. @@ -312,12 +266,6 @@ def list_attached_contacts( company_id : str The unique identifier for the company which is given by Intercom - page : typing.Optional[int] - The page of results to fetch. Defaults to first page - - per_page : typing.Optional[int] - How many results to return per page. Defaults to 15 - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -337,9 +285,7 @@ def list_attached_contacts( company_id="5f4d3c1c-7b1b-4d7d-a97e-6095715c6632", ) """ - _response = self._raw_client.list_attached_contacts( - company_id, page=page, per_page=per_page, request_options=request_options - ) + _response = self._raw_client.list_attached_contacts(company_id, request_options=request_options) return _response.data def list_attached_segments( @@ -481,14 +427,14 @@ def scroll( return self._raw_client.scroll(scroll_param=scroll_param, request_options=request_options) def attach_contact( - self, contact_id: str, *, company_id: str, request_options: typing.Optional[RequestOptions] = None + self, contact_id: int, *, company_id: str, request_options: typing.Optional[RequestOptions] = None ) -> Company: """ You can attach a company to a single contact. Parameters ---------- - contact_id : str + contact_id : int The unique identifier for the contact which is given by Intercom company_id : str @@ -510,8 +456,8 @@ def attach_contact( token="YOUR_TOKEN", ) client.companies.attach_contact( - contact_id="contact_id", - company_id="667d608d8a68186f43bafd70", + contact_id=1, + company_id="6762f09a1bb69f9f2193bb34", ) """ _response = self._raw_client.attach_contact(contact_id, company_id=company_id, request_options=request_options) @@ -658,15 +604,7 @@ async def main() -> None: async def create_or_update( self, *, - name: typing.Optional[str] = OMIT, - company_id: typing.Optional[str] = OMIT, - plan: typing.Optional[str] = OMIT, - size: typing.Optional[int] = OMIT, - website: typing.Optional[str] = OMIT, - industry: typing.Optional[str] = OMIT, - custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, - remote_created_at: typing.Optional[int] = OMIT, - monthly_spend: typing.Optional[int] = OMIT, + request: typing.Optional[CreateOrUpdateCompanyRequest] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Company: """ @@ -682,32 +620,7 @@ async def create_or_update( Parameters ---------- - name : typing.Optional[str] - The name of the Company - - company_id : typing.Optional[str] - The company id you have defined for the company. Can't be updated - - plan : typing.Optional[str] - The name of the plan you have associated with the company. - - size : typing.Optional[int] - The number of employees in this company. - - website : typing.Optional[str] - The URL for this company's website. Please note that the value specified here is not validated. Accepts any string. - - industry : typing.Optional[str] - The industry that this company operates in. - - custom_attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] - A hash of key/value pairs containing any other data about the company you want Intercom to store. - - remote_created_at : typing.Optional[int] - The time the company was created by you. - - monthly_spend : typing.Optional[int] - How much revenue the company generates for your business. Note that this will truncate floats. i.e. it only allow for whole integers, 155.98 will be truncated to 155. Note that this has an upper limit of 2**31-1 or 2147483647.. + request : typing.Optional[CreateOrUpdateCompanyRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -721,7 +634,7 @@ async def create_or_update( -------- import asyncio - from intercom import AsyncIntercom + from intercom import AsyncIntercom, CreateOrUpdateCompanyRequest client = AsyncIntercom( token="YOUR_TOKEN", @@ -730,26 +643,17 @@ async def create_or_update( async def main() -> None: await client.companies.create_or_update( - name="my company", - company_id="company_remote_id", - remote_created_at=1374138000, + request=CreateOrUpdateCompanyRequest( + name="my company", + company_id="company_remote_id", + remote_created_at=1374138000, + ), ) asyncio.run(main()) """ - _response = await self._raw_client.create_or_update( - name=name, - company_id=company_id, - plan=plan, - size=size, - website=website, - industry=industry, - custom_attributes=custom_attributes, - remote_created_at=remote_created_at, - monthly_spend=monthly_spend, - request_options=request_options, - ) + _response = await self._raw_client.create_or_update(request=request, request_options=request_options) return _response.data async def find(self, company_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Company: @@ -876,12 +780,7 @@ async def main() -> None: return _response.data async def list_attached_contacts( - self, - company_id: str, - *, - page: typing.Optional[int] = None, - per_page: typing.Optional[int] = None, - request_options: typing.Optional[RequestOptions] = None, + self, company_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> CompanyAttachedContacts: """ You can fetch a list of all contacts that belong to a company. @@ -891,12 +790,6 @@ async def list_attached_contacts( company_id : str The unique identifier for the company which is given by Intercom - page : typing.Optional[int] - The page of results to fetch. Defaults to first page - - per_page : typing.Optional[int] - How many results to return per page. Defaults to 15 - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -924,9 +817,7 @@ async def main() -> None: asyncio.run(main()) """ - _response = await self._raw_client.list_attached_contacts( - company_id, page=page, per_page=per_page, request_options=request_options - ) + _response = await self._raw_client.list_attached_contacts(company_id, request_options=request_options) return _response.data async def list_attached_segments( @@ -1094,14 +985,14 @@ async def main() -> None: return await self._raw_client.scroll(scroll_param=scroll_param, request_options=request_options) async def attach_contact( - self, contact_id: str, *, company_id: str, request_options: typing.Optional[RequestOptions] = None + self, contact_id: int, *, company_id: str, request_options: typing.Optional[RequestOptions] = None ) -> Company: """ You can attach a company to a single contact. Parameters ---------- - contact_id : str + contact_id : int The unique identifier for the contact which is given by Intercom company_id : str @@ -1128,8 +1019,8 @@ async def attach_contact( async def main() -> None: await client.companies.attach_contact( - contact_id="contact_id", - company_id="667d608d8a68186f43bafd70", + contact_id=1, + company_id="6762f09a1bb69f9f2193bb34", ) diff --git a/src/intercom/companies/raw_client.py b/src/intercom/companies/raw_client.py index 25e0dd9..831b268 100644 --- a/src/intercom/companies/raw_client.py +++ b/src/intercom/companies/raw_client.py @@ -9,6 +9,7 @@ from ..core.jsonable_encoder import jsonable_encoder from ..core.pagination import AsyncPager, BaseHttpResponse, SyncPager from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata from ..core.unchecked_base_model import construct_type from ..errors.bad_request_error import BadRequestError from ..errors.not_found_error import NotFoundError @@ -17,6 +18,7 @@ from ..types.company_attached_segments import CompanyAttachedSegments from ..types.company_list import CompanyList from ..types.company_scroll import CompanyScroll +from ..types.create_or_update_company_request import CreateOrUpdateCompanyRequest from ..types.deleted_company_object import DeletedCompanyObject from ..types.error import Error from .types.companies_retrieve_response import CompaniesRetrieveResponse @@ -135,15 +137,7 @@ def retrieve( def create_or_update( self, *, - name: typing.Optional[str] = OMIT, - company_id: typing.Optional[str] = OMIT, - plan: typing.Optional[str] = OMIT, - size: typing.Optional[int] = OMIT, - website: typing.Optional[str] = OMIT, - industry: typing.Optional[str] = OMIT, - custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, - remote_created_at: typing.Optional[int] = OMIT, - monthly_spend: typing.Optional[int] = OMIT, + request: typing.Optional[CreateOrUpdateCompanyRequest] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Company]: """ @@ -159,32 +153,7 @@ def create_or_update( Parameters ---------- - name : typing.Optional[str] - The name of the Company - - company_id : typing.Optional[str] - The company id you have defined for the company. Can't be updated - - plan : typing.Optional[str] - The name of the plan you have associated with the company. - - size : typing.Optional[int] - The number of employees in this company. - - website : typing.Optional[str] - The URL for this company's website. Please note that the value specified here is not validated. Accepts any string. - - industry : typing.Optional[str] - The industry that this company operates in. - - custom_attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] - A hash of key/value pairs containing any other data about the company you want Intercom to store. - - remote_created_at : typing.Optional[int] - The time the company was created by you. - - monthly_spend : typing.Optional[int] - How much revenue the company generates for your business. Note that this will truncate floats. i.e. it only allow for whole integers, 155.98 will be truncated to 155. Note that this has an upper limit of 2**31-1 or 2147483647.. + request : typing.Optional[CreateOrUpdateCompanyRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -197,17 +166,9 @@ def create_or_update( _response = self._client_wrapper.httpx_client.request( "companies", method="POST", - json={ - "name": name, - "company_id": company_id, - "plan": plan, - "size": size, - "website": website, - "industry": industry, - "custom_attributes": custom_attributes, - "remote_created_at": remote_created_at, - "monthly_spend": monthly_spend, - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateOrUpdateCompanyRequest, direction="write" + ), headers={ "content-type": "application/json", }, @@ -439,12 +400,7 @@ def delete( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def list_attached_contacts( - self, - company_id: str, - *, - page: typing.Optional[int] = None, - per_page: typing.Optional[int] = None, - request_options: typing.Optional[RequestOptions] = None, + self, company_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[CompanyAttachedContacts]: """ You can fetch a list of all contacts that belong to a company. @@ -454,12 +410,6 @@ def list_attached_contacts( company_id : str The unique identifier for the company which is given by Intercom - page : typing.Optional[int] - The page of results to fetch. Defaults to first page - - per_page : typing.Optional[int] - How many results to return per page. Defaults to 15 - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -471,10 +421,6 @@ def list_attached_contacts( _response = self._client_wrapper.httpx_client.request( f"companies/{jsonable_encoder(company_id)}/contacts", method="GET", - params={ - "page": page, - "per_page": per_page, - }, request_options=request_options, ) try: @@ -703,11 +649,13 @@ def scroll( request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _parsed_response = typing.cast( - CompanyScroll, + typing.Optional[CompanyScroll], construct_type( - type_=CompanyScroll, # type: ignore + type_=typing.Optional[CompanyScroll], # type: ignore object_=_response.json(), ), ) @@ -738,14 +686,14 @@ def scroll( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def attach_contact( - self, contact_id: str, *, company_id: str, request_options: typing.Optional[RequestOptions] = None + self, contact_id: int, *, company_id: str, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[Company]: """ You can attach a company to a single contact. Parameters ---------- - contact_id : str + contact_id : int The unique identifier for the contact which is given by Intercom company_id : str @@ -993,15 +941,7 @@ async def retrieve( async def create_or_update( self, *, - name: typing.Optional[str] = OMIT, - company_id: typing.Optional[str] = OMIT, - plan: typing.Optional[str] = OMIT, - size: typing.Optional[int] = OMIT, - website: typing.Optional[str] = OMIT, - industry: typing.Optional[str] = OMIT, - custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, - remote_created_at: typing.Optional[int] = OMIT, - monthly_spend: typing.Optional[int] = OMIT, + request: typing.Optional[CreateOrUpdateCompanyRequest] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Company]: """ @@ -1017,32 +957,7 @@ async def create_or_update( Parameters ---------- - name : typing.Optional[str] - The name of the Company - - company_id : typing.Optional[str] - The company id you have defined for the company. Can't be updated - - plan : typing.Optional[str] - The name of the plan you have associated with the company. - - size : typing.Optional[int] - The number of employees in this company. - - website : typing.Optional[str] - The URL for this company's website. Please note that the value specified here is not validated. Accepts any string. - - industry : typing.Optional[str] - The industry that this company operates in. - - custom_attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] - A hash of key/value pairs containing any other data about the company you want Intercom to store. - - remote_created_at : typing.Optional[int] - The time the company was created by you. - - monthly_spend : typing.Optional[int] - How much revenue the company generates for your business. Note that this will truncate floats. i.e. it only allow for whole integers, 155.98 will be truncated to 155. Note that this has an upper limit of 2**31-1 or 2147483647.. + request : typing.Optional[CreateOrUpdateCompanyRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1055,17 +970,9 @@ async def create_or_update( _response = await self._client_wrapper.httpx_client.request( "companies", method="POST", - json={ - "name": name, - "company_id": company_id, - "plan": plan, - "size": size, - "website": website, - "industry": industry, - "custom_attributes": custom_attributes, - "remote_created_at": remote_created_at, - "monthly_spend": monthly_spend, - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateOrUpdateCompanyRequest, direction="write" + ), headers={ "content-type": "application/json", }, @@ -1297,12 +1204,7 @@ async def delete( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def list_attached_contacts( - self, - company_id: str, - *, - page: typing.Optional[int] = None, - per_page: typing.Optional[int] = None, - request_options: typing.Optional[RequestOptions] = None, + self, company_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[CompanyAttachedContacts]: """ You can fetch a list of all contacts that belong to a company. @@ -1312,12 +1214,6 @@ async def list_attached_contacts( company_id : str The unique identifier for the company which is given by Intercom - page : typing.Optional[int] - The page of results to fetch. Defaults to first page - - per_page : typing.Optional[int] - How many results to return per page. Defaults to 15 - request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1329,10 +1225,6 @@ async def list_attached_contacts( _response = await self._client_wrapper.httpx_client.request( f"companies/{jsonable_encoder(company_id)}/contacts", method="GET", - params={ - "page": page, - "per_page": per_page, - }, request_options=request_options, ) try: @@ -1564,11 +1456,13 @@ async def scroll( request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _parsed_response = typing.cast( - CompanyScroll, + typing.Optional[CompanyScroll], construct_type( - type_=CompanyScroll, # type: ignore + type_=typing.Optional[CompanyScroll], # type: ignore object_=_response.json(), ), ) @@ -1602,14 +1496,14 @@ async def _get_next(): raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def attach_contact( - self, contact_id: str, *, company_id: str, request_options: typing.Optional[RequestOptions] = None + self, contact_id: int, *, company_id: str, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[Company]: """ You can attach a company to a single contact. Parameters ---------- - contact_id : str + contact_id : int The unique identifier for the contact which is given by Intercom company_id : str diff --git a/src/intercom/companies/types/companies_retrieve_response.py b/src/intercom/companies/types/companies_retrieve_response.py index 36d2ec8..e894a25 100644 --- a/src/intercom/companies/types/companies_retrieve_response.py +++ b/src/intercom/companies/types/companies_retrieve_response.py @@ -49,8 +49,8 @@ class Config: class CompaniesRetrieveResponse_List(UncheckedBaseModel): type: typing.Literal["list"] = "list" pages: typing.Optional[OffsetPages] = None - total_count: int - data: typing.List[Company] + total_count: typing.Optional[int] = None + data: typing.Optional[typing.List[Company]] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/intercom/companies/types/company_plan.py b/src/intercom/companies/types/company_plan.py index 8588123..613cb83 100644 --- a/src/intercom/companies/types/company_plan.py +++ b/src/intercom/companies/types/company_plan.py @@ -8,7 +8,7 @@ class CompanyPlan(UncheckedBaseModel): - type: typing.Optional[typing.Literal["plan"]] = pydantic.Field(default=None) + type: typing.Optional[str] = pydantic.Field(default=None) """ Value is always "plan" """ diff --git a/src/intercom/contacts/__init__.py b/src/intercom/contacts/__init__.py index 1877e8a..a40ff20 100644 --- a/src/intercom/contacts/__init__.py +++ b/src/intercom/contacts/__init__.py @@ -2,6 +2,20 @@ # isort: skip_file -from .types import Contact +from .types import ( + Contact, + ContactsCreateResponse, + ContactsFindResponse, + ContactsMergeLeadInUserResponse, + ContactsUpdateResponse, + ShowContactByExternalIdResponse, +) -__all__ = ["Contact"] +__all__ = [ + "Contact", + "ContactsCreateResponse", + "ContactsFindResponse", + "ContactsMergeLeadInUserResponse", + "ContactsUpdateResponse", + "ShowContactByExternalIdResponse", +] diff --git a/src/intercom/contacts/client.py b/src/intercom/contacts/client.py index d24425c..4cfbd31 100644 --- a/src/intercom/contacts/client.py +++ b/src/intercom/contacts/client.py @@ -8,6 +8,7 @@ from ..core.request_options import RequestOptions from ..subscription_types.types.subscription_type import SubscriptionType from ..types.contact_archived import ContactArchived +from ..types.contact_blocked import ContactBlocked from ..types.contact_deleted import ContactDeleted from ..types.contact_segments import ContactSegments from ..types.contact_unarchived import ContactUnarchived @@ -18,6 +19,11 @@ from ..types.tag_list import TagList from .raw_client import AsyncRawContactsClient, RawContactsClient from .types.contact import Contact +from .types.contacts_create_response import ContactsCreateResponse +from .types.contacts_find_response import ContactsFindResponse +from .types.contacts_merge_lead_in_user_response import ContactsMergeLeadInUserResponse +from .types.contacts_update_response import ContactsUpdateResponse +from .types.show_contact_by_external_id_response import ShowContactByExternalIdResponse # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -284,21 +290,21 @@ def list_attached_tags( _response = self._raw_client.list_attached_tags(contact_id, request_options=request_options) return _response.data - def find(self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Contact: + def find(self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> ContactsFindResponse: """ You can fetch the details of a single contact. Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Contact + ContactsFindResponse successful Examples @@ -331,10 +337,16 @@ def update( unsubscribed_from_emails: typing.Optional[bool] = OMIT, custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> Contact: + ) -> ContactsUpdateResponse: """ You can update an existing contact (ie. user or lead). + {% admonition type="info" %} + This endpoint handles both **contact updates** and **custom object associations**. + + See _`update a contact with an association to a custom object instance`_ in the request/response examples to see the custom object association format. + {% /admonition %} + Parameters ---------- contact_id : str @@ -378,7 +390,7 @@ def update( Returns ------- - Contact + ContactsUpdateResponse successful Examples @@ -418,7 +430,7 @@ def delete(self, contact_id: str, *, request_options: typing.Optional[RequestOpt Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -443,17 +455,21 @@ def delete(self, contact_id: str, *, request_options: typing.Optional[RequestOpt return _response.data def merge_lead_in_user( - self, *, lead_id: str, contact_id: str, request_options: typing.Optional[RequestOptions] = None - ) -> Contact: + self, + *, + lead_id: typing.Optional[str] = OMIT, + contact_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ContactsMergeLeadInUserResponse: """ You can merge a contact with a `role` of `lead` into a contact with a `role` of `user`. Parameters ---------- - lead_id : str + lead_id : typing.Optional[str] The unique identifier for the contact to merge away from. Must be a lead. - contact_id : str + contact_id : typing.Optional[str] The unique identifier for the contact to merge into. Must be a user. request_options : typing.Optional[RequestOptions] @@ -461,7 +477,7 @@ def merge_lead_in_user( Returns ------- - Contact + ContactsMergeLeadInUserResponse successful Examples @@ -472,8 +488,8 @@ def merge_lead_in_user( token="YOUR_TOKEN", ) client.contacts.merge_lead_in_user( - lead_id="667d60ac8a68186f43bafdbb", - contact_id="667d60ac8a68186f43bafdbc", + lead_id="6762f0d51bb69f9f2193bb7f", + contact_id="6762f0d51bb69f9f2193bb80", ) """ _response = self._raw_client.merge_lead_in_user( @@ -692,7 +708,7 @@ def list( def create( self, *, request: CreateContactRequest, request_options: typing.Optional[RequestOptions] = None - ) -> Contact: + ) -> ContactsCreateResponse: """ You can create a new contact (ie. user or lead). @@ -705,7 +721,7 @@ def create( Returns ------- - Contact + ContactsCreateResponse successful Examples @@ -724,6 +740,39 @@ def create( _response = self._raw_client.create(request=request, request_options=request_options) return _response.data + def show_contact_by_external_id( + self, external_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ShowContactByExternalIdResponse: + """ + You can fetch the details of a single contact by external ID. Note that this endpoint only supports users and not leads. + + Parameters + ---------- + external_id : str + The external ID of the user that you want to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ShowContactByExternalIdResponse + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.contacts.show_contact_by_external_id( + external_id="cdd29344-5e0c-4ef0-ac56-f9ba2979bc27", + ) + """ + _response = self._raw_client.show_contact_by_external_id(external_id, request_options=request_options) + return _response.data + def archive(self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> ContactArchived: """ You can archive a single contact. @@ -731,7 +780,7 @@ def archive(self, contact_id: str, *, request_options: typing.Optional[RequestOp Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -764,7 +813,7 @@ def unarchive( Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -788,6 +837,39 @@ def unarchive( _response = self._raw_client.unarchive(contact_id, request_options=request_options) return _response.data + def block_contact( + self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ContactBlocked: + """ + Block a single contact.
**Note:** conversations of the contact will also be archived during the process.
More details in [FAQ How do I block Inbox spam?](https://www.intercom.com/help/en/articles/8838656-inbox-faqs) + + Parameters + ---------- + contact_id : str + contact_id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContactBlocked + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.contacts.block_contact( + contact_id="63a07ddf05a32042dffac965", + ) + """ + _response = self._raw_client.block_contact(contact_id, request_options=request_options) + return _response.data + class AsyncContactsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -1101,21 +1183,23 @@ async def main() -> None: _response = await self._raw_client.list_attached_tags(contact_id, request_options=request_options) return _response.data - async def find(self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Contact: + async def find( + self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ContactsFindResponse: """ You can fetch the details of a single contact. Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Contact + ContactsFindResponse successful Examples @@ -1156,10 +1240,16 @@ async def update( unsubscribed_from_emails: typing.Optional[bool] = OMIT, custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> Contact: + ) -> ContactsUpdateResponse: """ You can update an existing contact (ie. user or lead). + {% admonition type="info" %} + This endpoint handles both **contact updates** and **custom object associations**. + + See _`update a contact with an association to a custom object instance`_ in the request/response examples to see the custom object association format. + {% /admonition %} + Parameters ---------- contact_id : str @@ -1203,7 +1293,7 @@ async def update( Returns ------- - Contact + ContactsUpdateResponse successful Examples @@ -1253,7 +1343,7 @@ async def delete( Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1286,17 +1376,21 @@ async def main() -> None: return _response.data async def merge_lead_in_user( - self, *, lead_id: str, contact_id: str, request_options: typing.Optional[RequestOptions] = None - ) -> Contact: + self, + *, + lead_id: typing.Optional[str] = OMIT, + contact_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> ContactsMergeLeadInUserResponse: """ You can merge a contact with a `role` of `lead` into a contact with a `role` of `user`. Parameters ---------- - lead_id : str + lead_id : typing.Optional[str] The unique identifier for the contact to merge away from. Must be a lead. - contact_id : str + contact_id : typing.Optional[str] The unique identifier for the contact to merge into. Must be a user. request_options : typing.Optional[RequestOptions] @@ -1304,7 +1398,7 @@ async def merge_lead_in_user( Returns ------- - Contact + ContactsMergeLeadInUserResponse successful Examples @@ -1320,8 +1414,8 @@ async def merge_lead_in_user( async def main() -> None: await client.contacts.merge_lead_in_user( - lead_id="667d60ac8a68186f43bafdbb", - contact_id="667d60ac8a68186f43bafdbc", + lead_id="6762f0d51bb69f9f2193bb7f", + contact_id="6762f0d51bb69f9f2193bb80", ) @@ -1561,7 +1655,7 @@ async def main() -> None: async def create( self, *, request: CreateContactRequest, request_options: typing.Optional[RequestOptions] = None - ) -> Contact: + ) -> ContactsCreateResponse: """ You can create a new contact (ie. user or lead). @@ -1574,7 +1668,7 @@ async def create( Returns ------- - Contact + ContactsCreateResponse successful Examples @@ -1601,6 +1695,47 @@ async def main() -> None: _response = await self._raw_client.create(request=request, request_options=request_options) return _response.data + async def show_contact_by_external_id( + self, external_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ShowContactByExternalIdResponse: + """ + You can fetch the details of a single contact by external ID. Note that this endpoint only supports users and not leads. + + Parameters + ---------- + external_id : str + The external ID of the user that you want to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ShowContactByExternalIdResponse + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.contacts.show_contact_by_external_id( + external_id="cdd29344-5e0c-4ef0-ac56-f9ba2979bc27", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.show_contact_by_external_id(external_id, request_options=request_options) + return _response.data + async def archive( self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None ) -> ContactArchived: @@ -1610,7 +1745,7 @@ async def archive( Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1651,7 +1786,7 @@ async def unarchive( Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1682,3 +1817,44 @@ async def main() -> None: """ _response = await self._raw_client.unarchive(contact_id, request_options=request_options) return _response.data + + async def block_contact( + self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> ContactBlocked: + """ + Block a single contact.
**Note:** conversations of the contact will also be archived during the process.
More details in [FAQ How do I block Inbox spam?](https://www.intercom.com/help/en/articles/8838656-inbox-faqs) + + Parameters + ---------- + contact_id : str + contact_id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ContactBlocked + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.contacts.block_contact( + contact_id="63a07ddf05a32042dffac965", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.block_contact(contact_id, request_options=request_options) + return _response.data diff --git a/src/intercom/contacts/raw_client.py b/src/intercom/contacts/raw_client.py index db4c3d4..0eb6338 100644 --- a/src/intercom/contacts/raw_client.py +++ b/src/intercom/contacts/raw_client.py @@ -17,6 +17,7 @@ from ..subscription_types.types.subscription_type import SubscriptionType from ..types.contact_archived import ContactArchived from ..types.contact_attached_companies import ContactAttachedCompanies +from ..types.contact_blocked import ContactBlocked from ..types.contact_deleted import ContactDeleted from ..types.contact_list import ContactList from ..types.contact_segments import ContactSegments @@ -28,6 +29,11 @@ from ..types.subscription_type_list import SubscriptionTypeList from ..types.tag_list import TagList from .types.contact import Contact +from .types.contacts_create_response import ContactsCreateResponse +from .types.contacts_find_response import ContactsFindResponse +from .types.contacts_merge_lead_in_user_response import ContactsMergeLeadInUserResponse +from .types.contacts_update_response import ContactsUpdateResponse +from .types.show_contact_by_external_id_response import ShowContactByExternalIdResponse # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -466,21 +472,21 @@ def list_attached_tags( def find( self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[Contact]: + ) -> HttpResponse[ContactsFindResponse]: """ You can fetch the details of a single contact. Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - HttpResponse[Contact] + HttpResponse[ContactsFindResponse] successful """ _response = self._client_wrapper.httpx_client.request( @@ -491,9 +497,9 @@ def find( try: if 200 <= _response.status_code < 300: _data = typing.cast( - Contact, + ContactsFindResponse, construct_type( - type_=Contact, # type: ignore + type_=ContactsFindResponse, # type: ignore object_=_response.json(), ), ) @@ -530,10 +536,16 @@ def update( unsubscribed_from_emails: typing.Optional[bool] = OMIT, custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[Contact]: + ) -> HttpResponse[ContactsUpdateResponse]: """ You can update an existing contact (ie. user or lead). + {% admonition type="info" %} + This endpoint handles both **contact updates** and **custom object associations**. + + See _`update a contact with an association to a custom object instance`_ in the request/response examples to see the custom object association format. + {% /admonition %} + Parameters ---------- contact_id : str @@ -577,7 +589,7 @@ def update( Returns ------- - HttpResponse[Contact] + HttpResponse[ContactsUpdateResponse] successful """ _response = self._client_wrapper.httpx_client.request( @@ -605,9 +617,9 @@ def update( try: if 200 <= _response.status_code < 300: _data = typing.cast( - Contact, + ContactsUpdateResponse, construct_type( - type_=Contact, # type: ignore + type_=ContactsUpdateResponse, # type: ignore object_=_response.json(), ), ) @@ -637,7 +649,7 @@ def delete( Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -679,17 +691,21 @@ def delete( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def merge_lead_in_user( - self, *, lead_id: str, contact_id: str, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[Contact]: + self, + *, + lead_id: typing.Optional[str] = OMIT, + contact_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[ContactsMergeLeadInUserResponse]: """ You can merge a contact with a `role` of `lead` into a contact with a `role` of `user`. Parameters ---------- - lead_id : str + lead_id : typing.Optional[str] The unique identifier for the contact to merge away from. Must be a lead. - contact_id : str + contact_id : typing.Optional[str] The unique identifier for the contact to merge into. Must be a user. request_options : typing.Optional[RequestOptions] @@ -697,7 +713,7 @@ def merge_lead_in_user( Returns ------- - HttpResponse[Contact] + HttpResponse[ContactsMergeLeadInUserResponse] successful """ _response = self._client_wrapper.httpx_client.request( @@ -716,9 +732,9 @@ def merge_lead_in_user( try: if 200 <= _response.status_code < 300: _data = typing.cast( - Contact, + ContactsMergeLeadInUserResponse, construct_type( - type_=Contact, # type: ignore + type_=ContactsMergeLeadInUserResponse, # type: ignore object_=_response.json(), ), ) @@ -1003,7 +1019,7 @@ def list( def create( self, *, request: CreateContactRequest, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[Contact]: + ) -> HttpResponse[ContactsCreateResponse]: """ You can create a new contact (ie. user or lead). @@ -1016,7 +1032,7 @@ def create( Returns ------- - HttpResponse[Contact] + HttpResponse[ContactsCreateResponse] successful """ _response = self._client_wrapper.httpx_client.request( @@ -1034,9 +1050,59 @@ def create( try: if 200 <= _response.status_code < 300: _data = typing.cast( - Contact, + ContactsCreateResponse, + construct_type( + type_=ContactsCreateResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def show_contact_by_external_id( + self, external_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ShowContactByExternalIdResponse]: + """ + You can fetch the details of a single contact by external ID. Note that this endpoint only supports users and not leads. + + Parameters + ---------- + external_id : str + The external ID of the user that you want to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ShowContactByExternalIdResponse] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"contacts/find_by_external_id/{jsonable_encoder(external_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ShowContactByExternalIdResponse, construct_type( - type_=Contact, # type: ignore + type_=ShowContactByExternalIdResponse, # type: ignore object_=_response.json(), ), ) @@ -1066,7 +1132,7 @@ def archive( Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1105,7 +1171,7 @@ def unarchive( Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1135,6 +1201,45 @@ def unarchive( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def block_contact( + self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ContactBlocked]: + """ + Block a single contact.
**Note:** conversations of the contact will also be archived during the process.
More details in [FAQ How do I block Inbox spam?](https://www.intercom.com/help/en/articles/8838656-inbox-faqs) + + Parameters + ---------- + contact_id : str + contact_id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ContactBlocked] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"contacts/{jsonable_encoder(contact_id)}/block", + method="POST", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContactBlocked, + construct_type( + type_=ContactBlocked, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + class AsyncRawContactsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -1572,21 +1677,21 @@ async def list_attached_tags( async def find( self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[Contact]: + ) -> AsyncHttpResponse[ContactsFindResponse]: """ You can fetch the details of a single contact. Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncHttpResponse[Contact] + AsyncHttpResponse[ContactsFindResponse] successful """ _response = await self._client_wrapper.httpx_client.request( @@ -1597,9 +1702,9 @@ async def find( try: if 200 <= _response.status_code < 300: _data = typing.cast( - Contact, + ContactsFindResponse, construct_type( - type_=Contact, # type: ignore + type_=ContactsFindResponse, # type: ignore object_=_response.json(), ), ) @@ -1636,10 +1741,16 @@ async def update( unsubscribed_from_emails: typing.Optional[bool] = OMIT, custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[Contact]: + ) -> AsyncHttpResponse[ContactsUpdateResponse]: """ You can update an existing contact (ie. user or lead). + {% admonition type="info" %} + This endpoint handles both **contact updates** and **custom object associations**. + + See _`update a contact with an association to a custom object instance`_ in the request/response examples to see the custom object association format. + {% /admonition %} + Parameters ---------- contact_id : str @@ -1683,7 +1794,7 @@ async def update( Returns ------- - AsyncHttpResponse[Contact] + AsyncHttpResponse[ContactsUpdateResponse] successful """ _response = await self._client_wrapper.httpx_client.request( @@ -1711,9 +1822,9 @@ async def update( try: if 200 <= _response.status_code < 300: _data = typing.cast( - Contact, + ContactsUpdateResponse, construct_type( - type_=Contact, # type: ignore + type_=ContactsUpdateResponse, # type: ignore object_=_response.json(), ), ) @@ -1743,7 +1854,7 @@ async def delete( Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1785,17 +1896,21 @@ async def delete( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def merge_lead_in_user( - self, *, lead_id: str, contact_id: str, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[Contact]: + self, + *, + lead_id: typing.Optional[str] = OMIT, + contact_id: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[ContactsMergeLeadInUserResponse]: """ You can merge a contact with a `role` of `lead` into a contact with a `role` of `user`. Parameters ---------- - lead_id : str + lead_id : typing.Optional[str] The unique identifier for the contact to merge away from. Must be a lead. - contact_id : str + contact_id : typing.Optional[str] The unique identifier for the contact to merge into. Must be a user. request_options : typing.Optional[RequestOptions] @@ -1803,7 +1918,7 @@ async def merge_lead_in_user( Returns ------- - AsyncHttpResponse[Contact] + AsyncHttpResponse[ContactsMergeLeadInUserResponse] successful """ _response = await self._client_wrapper.httpx_client.request( @@ -1822,9 +1937,9 @@ async def merge_lead_in_user( try: if 200 <= _response.status_code < 300: _data = typing.cast( - Contact, + ContactsMergeLeadInUserResponse, construct_type( - type_=Contact, # type: ignore + type_=ContactsMergeLeadInUserResponse, # type: ignore object_=_response.json(), ), ) @@ -2115,7 +2230,7 @@ async def _get_next(): async def create( self, *, request: CreateContactRequest, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[Contact]: + ) -> AsyncHttpResponse[ContactsCreateResponse]: """ You can create a new contact (ie. user or lead). @@ -2128,7 +2243,7 @@ async def create( Returns ------- - AsyncHttpResponse[Contact] + AsyncHttpResponse[ContactsCreateResponse] successful """ _response = await self._client_wrapper.httpx_client.request( @@ -2146,9 +2261,59 @@ async def create( try: if 200 <= _response.status_code < 300: _data = typing.cast( - Contact, + ContactsCreateResponse, + construct_type( + type_=ContactsCreateResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def show_contact_by_external_id( + self, external_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ShowContactByExternalIdResponse]: + """ + You can fetch the details of a single contact by external ID. Note that this endpoint only supports users and not leads. + + Parameters + ---------- + external_id : str + The external ID of the user that you want to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ShowContactByExternalIdResponse] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"contacts/find_by_external_id/{jsonable_encoder(external_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ShowContactByExternalIdResponse, construct_type( - type_=Contact, # type: ignore + type_=ShowContactByExternalIdResponse, # type: ignore object_=_response.json(), ), ) @@ -2178,7 +2343,7 @@ async def archive( Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2217,7 +2382,7 @@ async def unarchive( Parameters ---------- contact_id : str - id + contact_id request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -2246,3 +2411,42 @@ async def unarchive( except JSONDecodeError: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def block_contact( + self, contact_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ContactBlocked]: + """ + Block a single contact.
**Note:** conversations of the contact will also be archived during the process.
More details in [FAQ How do I block Inbox spam?](https://www.intercom.com/help/en/articles/8838656-inbox-faqs) + + Parameters + ---------- + contact_id : str + contact_id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ContactBlocked] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"contacts/{jsonable_encoder(contact_id)}/block", + method="POST", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ContactBlocked, + construct_type( + type_=ContactBlocked, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/contacts/types/__init__.py b/src/intercom/contacts/types/__init__.py index 729415d..ca3c76f 100644 --- a/src/intercom/contacts/types/__init__.py +++ b/src/intercom/contacts/types/__init__.py @@ -3,5 +3,17 @@ # isort: skip_file from .contact import Contact +from .contacts_create_response import ContactsCreateResponse +from .contacts_find_response import ContactsFindResponse +from .contacts_merge_lead_in_user_response import ContactsMergeLeadInUserResponse +from .contacts_update_response import ContactsUpdateResponse +from .show_contact_by_external_id_response import ShowContactByExternalIdResponse -__all__ = ["Contact"] +__all__ = [ + "Contact", + "ContactsCreateResponse", + "ContactsFindResponse", + "ContactsMergeLeadInUserResponse", + "ContactsUpdateResponse", + "ShowContactByExternalIdResponse", +] diff --git a/src/intercom/contacts/types/contact.py b/src/intercom/contacts/types/contact.py index d926cdb..ec6f0af 100644 --- a/src/intercom/contacts/types/contact.py +++ b/src/intercom/contacts/types/contact.py @@ -14,7 +14,7 @@ class Contact(UncheckedBaseModel): """ - Contact are the objects that represent your leads and users in Intercom. + Contacts represent your leads and users in Intercom. """ type: typing.Optional[typing.Literal["contact"]] = pydantic.Field(default=None) @@ -22,7 +22,7 @@ class Contact(UncheckedBaseModel): The type of object. """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier for the contact which is given by Intercom. """ @@ -32,12 +32,12 @@ class Contact(UncheckedBaseModel): The unique identifier for the contact which is provided by the Client. """ - workspace_id: str = pydantic.Field() + workspace_id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the workspace which the contact belongs to. """ - role: str = pydantic.Field() + role: typing.Optional[str] = pydantic.Field(default=None) """ The role of the contact. """ @@ -57,11 +57,6 @@ class Contact(UncheckedBaseModel): The contacts phone. """ - formatted_phone: typing.Optional[str] = pydantic.Field(default=None) - """ - The contacts phone number normalized to the E164 format - """ - name: typing.Optional[str] = pydantic.Field(default=None) """ The contacts name. @@ -72,27 +67,27 @@ class Contact(UncheckedBaseModel): The id of an admin that has been assigned account ownership of the contact. """ - has_hard_bounced: bool = pydantic.Field() + has_hard_bounced: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the contact has had an email sent to them hard bounce. """ - marked_email_as_spam: bool = pydantic.Field() + marked_email_as_spam: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the contact has marked an email sent to them as spam. """ - unsubscribed_from_emails: bool = pydantic.Field() + unsubscribed_from_emails: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the contact is unsubscribed from emails. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ (UNIX timestamp) The time when the contact was created. """ - updated_at: int = pydantic.Field() + updated_at: typing.Optional[int] = pydantic.Field(default=None) """ (UNIX timestamp) The time when the contact was last updated. """ @@ -225,8 +220,8 @@ class Contact(UncheckedBaseModel): tags: typing.Optional[ContactTags] = None notes: typing.Optional[ContactNotes] = None companies: typing.Optional[ContactCompanies] = None - location: ContactLocation - social_profiles: ContactSocialProfiles + location: typing.Optional[ContactLocation] = None + social_profiles: typing.Optional[ContactSocialProfiles] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/intercom/contacts/types/contacts_create_response.py b/src/intercom/contacts/types/contacts_create_response.py new file mode 100644 index 0000000..7496002 --- /dev/null +++ b/src/intercom/contacts/types/contacts_create_response.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from .contact import Contact + + +class ContactsCreateResponse(Contact): + enabled_push_messaging: typing.Optional[bool] = pydantic.Field(default=None) + """ + If the user has enabled push messaging. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/contacts/types/contacts_find_response.py b/src/intercom/contacts/types/contacts_find_response.py new file mode 100644 index 0000000..4b797d4 --- /dev/null +++ b/src/intercom/contacts/types/contacts_find_response.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from .contact import Contact + + +class ContactsFindResponse(Contact): + enabled_push_messaging: typing.Optional[bool] = pydantic.Field(default=None) + """ + If the user has enabled push messaging. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/contacts/types/contacts_merge_lead_in_user_response.py b/src/intercom/contacts/types/contacts_merge_lead_in_user_response.py new file mode 100644 index 0000000..18d1697 --- /dev/null +++ b/src/intercom/contacts/types/contacts_merge_lead_in_user_response.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from .contact import Contact + + +class ContactsMergeLeadInUserResponse(Contact): + enabled_push_messaging: typing.Optional[bool] = pydantic.Field(default=None) + """ + If the user has enabled push messaging. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/contacts/types/contacts_update_response.py b/src/intercom/contacts/types/contacts_update_response.py new file mode 100644 index 0000000..6dcec36 --- /dev/null +++ b/src/intercom/contacts/types/contacts_update_response.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from .contact import Contact + + +class ContactsUpdateResponse(Contact): + enabled_push_messaging: typing.Optional[bool] = pydantic.Field(default=None) + """ + If the user has enabled push messaging. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/contacts/types/show_contact_by_external_id_response.py b/src/intercom/contacts/types/show_contact_by_external_id_response.py new file mode 100644 index 0000000..016134a --- /dev/null +++ b/src/intercom/contacts/types/show_contact_by_external_id_response.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from .contact import Contact + + +class ShowContactByExternalIdResponse(Contact): + enabled_push_messaging: typing.Optional[bool] = pydantic.Field(default=None) + """ + If the user has enabled push messaging. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/conversations/client.py b/src/intercom/conversations/client.py index 7f4d1bb..835e78b 100644 --- a/src/intercom/conversations/client.py +++ b/src/intercom/conversations/client.py @@ -7,6 +7,7 @@ from ..core.request_options import RequestOptions from ..messages.types.message import Message from ..tickets.types.ticket import Ticket +from ..types.conversation_deleted import ConversationDeleted from ..types.custom_attributes import CustomAttributes from ..types.redact_conversation_request import RedactConversationRequest from ..types.reply_conversation_request import ReplyConversationRequest @@ -134,7 +135,7 @@ def create( client.conversations.create( from_=CreateConversationRequestFrom( type="user", - id="667d60d18a68186f43bafddd", + id="6762f11b1bb69f9f2193bba3", ), body="Hello there", ) @@ -146,9 +147,10 @@ def create( def find( self, - conversation_id: str, + conversation_id: int, *, display_as: typing.Optional[str] = None, + include_translations: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Conversation: """ @@ -165,12 +167,15 @@ def find( Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target display_as : typing.Optional[str] Set to plaintext to retrieve conversation messages in plain text. + include_translations : typing.Optional[bool] + If set to true, conversation parts will be translated to the detected language of the conversation. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -187,20 +192,27 @@ def find( token="YOUR_TOKEN", ) client.conversations.find( - conversation_id="123", + conversation_id=1, display_as="plaintext", ) """ - _response = self._raw_client.find(conversation_id, display_as=display_as, request_options=request_options) + _response = self._raw_client.find( + conversation_id, + display_as=display_as, + include_translations=include_translations, + request_options=request_options, + ) return _response.data def update( self, - conversation_id: str, + conversation_id: int, *, display_as: typing.Optional[str] = None, read: typing.Optional[bool] = OMIT, + title: typing.Optional[str] = OMIT, custom_attributes: typing.Optional[CustomAttributes] = OMIT, + company_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Conversation: """ @@ -211,9 +223,15 @@ def update( If you want to reply to a coveration or take an action such as assign, unassign, open, close or snooze, take a look at the reply and manage endpoints. {% /admonition %} + {% admonition type="info" %} + This endpoint handles both **conversation updates** and **custom object associations**. + + See _`update a conversation with an association to a custom object instance`_ in the request/response examples to see the custom object association format. + {% /admonition %} + Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target display_as : typing.Optional[str] @@ -222,15 +240,21 @@ def update( read : typing.Optional[bool] Mark a conversation as read within Intercom. + title : typing.Optional[str] + The title given to the conversation + custom_attributes : typing.Optional[CustomAttributes] + company_id : typing.Optional[str] + The ID of the company that the conversation is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company. + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- Conversation - conversation found + update a conversation with an association to a custom object instance Examples -------- @@ -240,9 +264,10 @@ def update( token="YOUR_TOKEN", ) client.conversations.update( - conversation_id="123", + conversation_id=1, display_as="plaintext", read=True, + title="new conversation title", custom_attributes={"issue_type": "Billing", "priority": "High"}, ) """ @@ -250,11 +275,46 @@ def update( conversation_id, display_as=display_as, read=read, + title=title, custom_attributes=custom_attributes, + company_id=company_id, request_options=request_options, ) return _response.data + def delete_conversation( + self, conversation_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> ConversationDeleted: + """ + You can delete a single conversation. + + Parameters + ---------- + conversation_id : int + id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ConversationDeleted + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.conversations.delete_conversation( + conversation_id=1, + ) + """ + _response = self._raw_client.delete_conversation(conversation_id, request_options=request_options) + return _response.data + def search( self, *, @@ -284,7 +344,7 @@ def search( ### Accepted Fields - Most keys listed as part of the The conversation model is searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). + Most keys listed in the conversation model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. | Field | Type | @@ -448,7 +508,7 @@ def reply( conversation_id='123 or "last"', request=ContactReplyIntercomUserIdRequest( body="Thanks again :)", - intercom_user_id="667d60f18a68186f43bafdf4", + intercom_user_id="6762f1571bb69f9f2193bbbb", ), ) """ @@ -502,45 +562,6 @@ def manage( _response = self._raw_client.manage(conversation_id, request=request, request_options=request_options) return _response.data - def run_assignment_rules( - self, conversation_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> Conversation: - """ - {% admonition type="danger" name="Deprecation of Run Assignment Rules" %} - Run assignment rules is now deprecated in version 2.12 and future versions and will be permanently removed on December 31, 2026. After this date, any requests made to this endpoint will fail. - {% /admonition %} - You can let a conversation be automatically assigned following assignment rules. - {% admonition type="warning" name="When using workflows" %} - It is not possible to use this endpoint with Workflows. - {% /admonition %} - - Parameters - ---------- - conversation_id : str - The identifier for the conversation as given by Intercom. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - Conversation - Assign a conversation using assignment rules - - Examples - -------- - from intercom import Intercom - - client = Intercom( - token="YOUR_TOKEN", - ) - client.conversations.run_assignment_rules( - conversation_id="123", - ) - """ - _response = self._raw_client.run_assignment_rules(conversation_id, request_options=request_options) - return _response.data - def attach_contact_as_admin( self, conversation_id: str, @@ -588,7 +609,7 @@ def attach_contact_as_admin( conversation_id="123", admin_id="12345", customer=AttachContactToConversationRequestCustomerIntercomUserId( - intercom_user_id="667d61168a68186f43bafe0d", + intercom_user_id="6762f19b1bb69f9f2193bbd4", ), ) """ @@ -690,18 +711,18 @@ def redact_conversation_part( def convert_to_ticket( self, - conversation_id: str, + conversation_id: int, *, ticket_type_id: str, attributes: typing.Optional[TicketRequestCustomAttributes] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> Ticket: + ) -> typing.Optional[Ticket]: """ You can convert a conversation to a ticket. Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target ticket_type_id : str @@ -714,7 +735,7 @@ def convert_to_ticket( Returns ------- - Ticket + typing.Optional[Ticket] successful Examples @@ -725,8 +746,8 @@ def convert_to_ticket( token="YOUR_TOKEN", ) client.conversations.convert_to_ticket( - conversation_id="123", - ticket_type_id="79", + conversation_id=1, + ticket_type_id="53", ) """ _response = self._raw_client.convert_to_ticket( @@ -734,6 +755,35 @@ def convert_to_ticket( ) return _response.data + def run_assignment_rules( + self, conversation_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Parameters + ---------- + conversation_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.conversations.run_assignment_rules( + conversation_id="conversation_id", + ) + """ + _response = self._raw_client.run_assignment_rules(conversation_id, request_options=request_options) + return _response.data + class AsyncConversationsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -862,7 +912,7 @@ async def main() -> None: await client.conversations.create( from_=CreateConversationRequestFrom( type="user", - id="667d60d18a68186f43bafddd", + id="6762f11b1bb69f9f2193bba3", ), body="Hello there", ) @@ -877,9 +927,10 @@ async def main() -> None: async def find( self, - conversation_id: str, + conversation_id: int, *, display_as: typing.Optional[str] = None, + include_translations: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Conversation: """ @@ -896,12 +947,15 @@ async def find( Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target display_as : typing.Optional[str] Set to plaintext to retrieve conversation messages in plain text. + include_translations : typing.Optional[bool] + If set to true, conversation parts will be translated to the detected language of the conversation. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -923,23 +977,30 @@ async def find( async def main() -> None: await client.conversations.find( - conversation_id="123", + conversation_id=1, display_as="plaintext", ) asyncio.run(main()) """ - _response = await self._raw_client.find(conversation_id, display_as=display_as, request_options=request_options) + _response = await self._raw_client.find( + conversation_id, + display_as=display_as, + include_translations=include_translations, + request_options=request_options, + ) return _response.data async def update( self, - conversation_id: str, + conversation_id: int, *, display_as: typing.Optional[str] = None, read: typing.Optional[bool] = OMIT, + title: typing.Optional[str] = OMIT, custom_attributes: typing.Optional[CustomAttributes] = OMIT, + company_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Conversation: """ @@ -950,9 +1011,15 @@ async def update( If you want to reply to a coveration or take an action such as assign, unassign, open, close or snooze, take a look at the reply and manage endpoints. {% /admonition %} + {% admonition type="info" %} + This endpoint handles both **conversation updates** and **custom object associations**. + + See _`update a conversation with an association to a custom object instance`_ in the request/response examples to see the custom object association format. + {% /admonition %} + Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target display_as : typing.Optional[str] @@ -961,15 +1028,21 @@ async def update( read : typing.Optional[bool] Mark a conversation as read within Intercom. + title : typing.Optional[str] + The title given to the conversation + custom_attributes : typing.Optional[CustomAttributes] + company_id : typing.Optional[str] + The ID of the company that the conversation is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company. + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- Conversation - conversation found + update a conversation with an association to a custom object instance Examples -------- @@ -984,9 +1057,10 @@ async def update( async def main() -> None: await client.conversations.update( - conversation_id="123", + conversation_id=1, display_as="plaintext", read=True, + title="new conversation title", custom_attributes={"issue_type": "Billing", "priority": "High"}, ) @@ -997,11 +1071,54 @@ async def main() -> None: conversation_id, display_as=display_as, read=read, + title=title, custom_attributes=custom_attributes, + company_id=company_id, request_options=request_options, ) return _response.data + async def delete_conversation( + self, conversation_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> ConversationDeleted: + """ + You can delete a single conversation. + + Parameters + ---------- + conversation_id : int + id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ConversationDeleted + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.conversations.delete_conversation( + conversation_id=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_conversation(conversation_id, request_options=request_options) + return _response.data + async def search( self, *, @@ -1031,7 +1148,7 @@ async def search( ### Accepted Fields - Most keys listed as part of the The conversation model is searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). + Most keys listed in the conversation model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. | Field | Type | @@ -1209,7 +1326,7 @@ async def main() -> None: conversation_id='123 or "last"', request=ContactReplyIntercomUserIdRequest( body="Thanks again :)", - intercom_user_id="667d60f18a68186f43bafdf4", + intercom_user_id="6762f1571bb69f9f2193bbbb", ), ) @@ -1274,53 +1391,6 @@ async def main() -> None: _response = await self._raw_client.manage(conversation_id, request=request, request_options=request_options) return _response.data - async def run_assignment_rules( - self, conversation_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> Conversation: - """ - {% admonition type="danger" name="Deprecation of Run Assignment Rules" %} - Run assignment rules is now deprecated in version 2.12 and future versions and will be permanently removed on December 31, 2026. After this date, any requests made to this endpoint will fail. - {% /admonition %} - You can let a conversation be automatically assigned following assignment rules. - {% admonition type="warning" name="When using workflows" %} - It is not possible to use this endpoint with Workflows. - {% /admonition %} - - Parameters - ---------- - conversation_id : str - The identifier for the conversation as given by Intercom. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - Conversation - Assign a conversation using assignment rules - - Examples - -------- - import asyncio - - from intercom import AsyncIntercom - - client = AsyncIntercom( - token="YOUR_TOKEN", - ) - - - async def main() -> None: - await client.conversations.run_assignment_rules( - conversation_id="123", - ) - - - asyncio.run(main()) - """ - _response = await self._raw_client.run_assignment_rules(conversation_id, request_options=request_options) - return _response.data - async def attach_contact_as_admin( self, conversation_id: str, @@ -1373,7 +1443,7 @@ async def main() -> None: conversation_id="123", admin_id="12345", customer=AttachContactToConversationRequestCustomerIntercomUserId( - intercom_user_id="667d61168a68186f43bafe0d", + intercom_user_id="6762f19b1bb69f9f2193bbd4", ), ) @@ -1494,18 +1564,18 @@ async def main() -> None: async def convert_to_ticket( self, - conversation_id: str, + conversation_id: int, *, ticket_type_id: str, attributes: typing.Optional[TicketRequestCustomAttributes] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> Ticket: + ) -> typing.Optional[Ticket]: """ You can convert a conversation to a ticket. Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target ticket_type_id : str @@ -1518,7 +1588,7 @@ async def convert_to_ticket( Returns ------- - Ticket + typing.Optional[Ticket] successful Examples @@ -1534,8 +1604,8 @@ async def convert_to_ticket( async def main() -> None: await client.conversations.convert_to_ticket( - conversation_id="123", - ticket_type_id="79", + conversation_id=1, + ticket_type_id="53", ) @@ -1545,3 +1615,40 @@ async def main() -> None: conversation_id, ticket_type_id=ticket_type_id, attributes=attributes, request_options=request_options ) return _response.data + + async def run_assignment_rules( + self, conversation_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Parameters + ---------- + conversation_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.conversations.run_assignment_rules( + conversation_id="conversation_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.run_assignment_rules(conversation_id, request_options=request_options) + return _response.data diff --git a/src/intercom/conversations/raw_client.py b/src/intercom/conversations/raw_client.py index ced03b9..3aa2a33 100644 --- a/src/intercom/conversations/raw_client.py +++ b/src/intercom/conversations/raw_client.py @@ -18,9 +18,10 @@ from ..errors.unprocessable_entity_error import UnprocessableEntityError from ..messages.types.message import Message from ..tickets.types.ticket import Ticket +from ..types.conversation_deleted import ConversationDeleted +from ..types.conversation_list import ConversationList from ..types.custom_attributes import CustomAttributes from ..types.error import Error -from ..types.paginated_conversation_response import PaginatedConversationResponse from ..types.redact_conversation_request import RedactConversationRequest from ..types.reply_conversation_request import ReplyConversationRequest from ..types.search_request_query import SearchRequestQuery @@ -83,9 +84,9 @@ def list( try: if 200 <= _response.status_code < 300: _parsed_response = typing.cast( - PaginatedConversationResponse, + ConversationList, construct_type( - type_=PaginatedConversationResponse, # type: ignore + type_=ConversationList, # type: ignore object_=_response.json(), ), ) @@ -233,9 +234,10 @@ def create( def find( self, - conversation_id: str, + conversation_id: int, *, display_as: typing.Optional[str] = None, + include_translations: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Conversation]: """ @@ -252,12 +254,15 @@ def find( Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target display_as : typing.Optional[str] Set to plaintext to retrieve conversation messages in plain text. + include_translations : typing.Optional[bool] + If set to true, conversation parts will be translated to the detected language of the conversation. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -271,6 +276,7 @@ def find( method="GET", params={ "display_as": display_as, + "include_translations": include_translations, }, request_options=request_options, ) @@ -324,11 +330,13 @@ def find( def update( self, - conversation_id: str, + conversation_id: int, *, display_as: typing.Optional[str] = None, read: typing.Optional[bool] = OMIT, + title: typing.Optional[str] = OMIT, custom_attributes: typing.Optional[CustomAttributes] = OMIT, + company_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Conversation]: """ @@ -339,9 +347,15 @@ def update( If you want to reply to a coveration or take an action such as assign, unassign, open, close or snooze, take a look at the reply and manage endpoints. {% /admonition %} + {% admonition type="info" %} + This endpoint handles both **conversation updates** and **custom object associations**. + + See _`update a conversation with an association to a custom object instance`_ in the request/response examples to see the custom object association format. + {% /admonition %} + Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target display_as : typing.Optional[str] @@ -350,15 +364,21 @@ def update( read : typing.Optional[bool] Mark a conversation as read within Intercom. + title : typing.Optional[str] + The title given to the conversation + custom_attributes : typing.Optional[CustomAttributes] + company_id : typing.Optional[str] + The ID of the company that the conversation is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company. + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- HttpResponse[Conversation] - conversation found + update a conversation with an association to a custom object instance """ _response = self._client_wrapper.httpx_client.request( f"conversations/{jsonable_encoder(conversation_id)}", @@ -368,7 +388,11 @@ def update( }, json={ "read": read, - "custom_attributes": custom_attributes, + "title": title, + "custom_attributes": convert_and_respect_annotation_metadata( + object_=custom_attributes, annotation=CustomAttributes, direction="write" + ), + "company_id": company_id, }, headers={ "content-type": "application/json", @@ -424,6 +448,67 @@ def update( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def delete_conversation( + self, conversation_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ConversationDeleted]: + """ + You can delete a single conversation. + + Parameters + ---------- + conversation_id : int + id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ConversationDeleted] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"conversations/{jsonable_encoder(conversation_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ConversationDeleted, + construct_type( + type_=ConversationDeleted, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def search( self, *, @@ -453,7 +538,7 @@ def search( ### Accepted Fields - Most keys listed as part of the The conversation model is searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). + Most keys listed in the conversation model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. | Field | Type | @@ -566,9 +651,9 @@ def search( try: if 200 <= _response.status_code < 300: _parsed_response = typing.cast( - PaginatedConversationResponse, + ConversationList, construct_type( - type_=PaginatedConversationResponse, # type: ignore + type_=ConversationList, # type: ignore object_=_response.json(), ), ) @@ -765,84 +850,6 @@ def manage( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - def run_assignment_rules( - self, conversation_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[Conversation]: - """ - {% admonition type="danger" name="Deprecation of Run Assignment Rules" %} - Run assignment rules is now deprecated in version 2.12 and future versions and will be permanently removed on December 31, 2026. After this date, any requests made to this endpoint will fail. - {% /admonition %} - You can let a conversation be automatically assigned following assignment rules. - {% admonition type="warning" name="When using workflows" %} - It is not possible to use this endpoint with Workflows. - {% /admonition %} - - Parameters - ---------- - conversation_id : str - The identifier for the conversation as given by Intercom. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - HttpResponse[Conversation] - Assign a conversation using assignment rules - """ - _response = self._client_wrapper.httpx_client.request( - f"conversations/{jsonable_encoder(conversation_id)}/run_assignment_rules", - method="POST", - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - Conversation, - construct_type( - type_=Conversation, # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 401: - raise UnauthorizedError( - headers=dict(_response.headers), - body=typing.cast( - Error, - construct_type( - type_=Error, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 403: - raise ForbiddenError( - headers=dict(_response.headers), - body=typing.cast( - Error, - construct_type( - type_=Error, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 404: - raise NotFoundError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - construct_type( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - def attach_contact_as_admin( self, conversation_id: str, @@ -1117,18 +1124,18 @@ def redact_conversation_part( def convert_to_ticket( self, - conversation_id: str, + conversation_id: int, *, ticket_type_id: str, attributes: typing.Optional[TicketRequestCustomAttributes] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[Ticket]: + ) -> HttpResponse[typing.Optional[Ticket]]: """ You can convert a conversation to a ticket. Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target ticket_type_id : str @@ -1141,7 +1148,7 @@ def convert_to_ticket( Returns ------- - HttpResponse[Ticket] + HttpResponse[typing.Optional[Ticket]] successful """ _response = self._client_wrapper.httpx_client.request( @@ -1158,11 +1165,13 @@ def convert_to_ticket( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Ticket, + typing.Optional[Ticket], construct_type( - type_=Ticket, # type: ignore + type_=typing.Optional[Ticket], # type: ignore object_=_response.json(), ), ) @@ -1183,6 +1192,34 @@ def convert_to_ticket( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def run_assignment_rules( + self, conversation_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[None]: + """ + Parameters + ---------- + conversation_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[None] + """ + _response = self._client_wrapper.httpx_client.request( + f"conversations/{jsonable_encoder(conversation_id)}/run_assignment_rules", + method="POST", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=None) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + class AsyncRawConversationsClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): @@ -1232,9 +1269,9 @@ async def list( try: if 200 <= _response.status_code < 300: _parsed_response = typing.cast( - PaginatedConversationResponse, + ConversationList, construct_type( - type_=PaginatedConversationResponse, # type: ignore + type_=ConversationList, # type: ignore object_=_response.json(), ), ) @@ -1385,9 +1422,10 @@ async def create( async def find( self, - conversation_id: str, + conversation_id: int, *, display_as: typing.Optional[str] = None, + include_translations: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Conversation]: """ @@ -1404,12 +1442,15 @@ async def find( Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target display_as : typing.Optional[str] Set to plaintext to retrieve conversation messages in plain text. + include_translations : typing.Optional[bool] + If set to true, conversation parts will be translated to the detected language of the conversation. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1423,6 +1464,7 @@ async def find( method="GET", params={ "display_as": display_as, + "include_translations": include_translations, }, request_options=request_options, ) @@ -1476,11 +1518,13 @@ async def find( async def update( self, - conversation_id: str, + conversation_id: int, *, display_as: typing.Optional[str] = None, read: typing.Optional[bool] = OMIT, + title: typing.Optional[str] = OMIT, custom_attributes: typing.Optional[CustomAttributes] = OMIT, + company_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Conversation]: """ @@ -1491,9 +1535,15 @@ async def update( If you want to reply to a coveration or take an action such as assign, unassign, open, close or snooze, take a look at the reply and manage endpoints. {% /admonition %} + {% admonition type="info" %} + This endpoint handles both **conversation updates** and **custom object associations**. + + See _`update a conversation with an association to a custom object instance`_ in the request/response examples to see the custom object association format. + {% /admonition %} + Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target display_as : typing.Optional[str] @@ -1502,15 +1552,21 @@ async def update( read : typing.Optional[bool] Mark a conversation as read within Intercom. + title : typing.Optional[str] + The title given to the conversation + custom_attributes : typing.Optional[CustomAttributes] + company_id : typing.Optional[str] + The ID of the company that the conversation is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company. + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- AsyncHttpResponse[Conversation] - conversation found + update a conversation with an association to a custom object instance """ _response = await self._client_wrapper.httpx_client.request( f"conversations/{jsonable_encoder(conversation_id)}", @@ -1520,7 +1576,11 @@ async def update( }, json={ "read": read, - "custom_attributes": custom_attributes, + "title": title, + "custom_attributes": convert_and_respect_annotation_metadata( + object_=custom_attributes, annotation=CustomAttributes, direction="write" + ), + "company_id": company_id, }, headers={ "content-type": "application/json", @@ -1576,6 +1636,67 @@ async def update( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + async def delete_conversation( + self, conversation_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ConversationDeleted]: + """ + You can delete a single conversation. + + Parameters + ---------- + conversation_id : int + id + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ConversationDeleted] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"conversations/{jsonable_encoder(conversation_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ConversationDeleted, + construct_type( + type_=ConversationDeleted, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + async def search( self, *, @@ -1605,7 +1726,7 @@ async def search( ### Accepted Fields - Most keys listed as part of the The conversation model is searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). + Most keys listed in the conversation model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foorbar"`). The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. | Field | Type | @@ -1718,9 +1839,9 @@ async def search( try: if 200 <= _response.status_code < 300: _parsed_response = typing.cast( - PaginatedConversationResponse, + ConversationList, construct_type( - type_=PaginatedConversationResponse, # type: ignore + type_=ConversationList, # type: ignore object_=_response.json(), ), ) @@ -1920,84 +2041,6 @@ async def manage( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - async def run_assignment_rules( - self, conversation_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[Conversation]: - """ - {% admonition type="danger" name="Deprecation of Run Assignment Rules" %} - Run assignment rules is now deprecated in version 2.12 and future versions and will be permanently removed on December 31, 2026. After this date, any requests made to this endpoint will fail. - {% /admonition %} - You can let a conversation be automatically assigned following assignment rules. - {% admonition type="warning" name="When using workflows" %} - It is not possible to use this endpoint with Workflows. - {% /admonition %} - - Parameters - ---------- - conversation_id : str - The identifier for the conversation as given by Intercom. - - request_options : typing.Optional[RequestOptions] - Request-specific configuration. - - Returns - ------- - AsyncHttpResponse[Conversation] - Assign a conversation using assignment rules - """ - _response = await self._client_wrapper.httpx_client.request( - f"conversations/{jsonable_encoder(conversation_id)}/run_assignment_rules", - method="POST", - request_options=request_options, - ) - try: - if 200 <= _response.status_code < 300: - _data = typing.cast( - Conversation, - construct_type( - type_=Conversation, # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 401: - raise UnauthorizedError( - headers=dict(_response.headers), - body=typing.cast( - Error, - construct_type( - type_=Error, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 403: - raise ForbiddenError( - headers=dict(_response.headers), - body=typing.cast( - Error, - construct_type( - type_=Error, # type: ignore - object_=_response.json(), - ), - ), - ) - if _response.status_code == 404: - raise NotFoundError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - construct_type( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - async def attach_contact_as_admin( self, conversation_id: str, @@ -2272,18 +2315,18 @@ async def redact_conversation_part( async def convert_to_ticket( self, - conversation_id: str, + conversation_id: int, *, ticket_type_id: str, attributes: typing.Optional[TicketRequestCustomAttributes] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[Ticket]: + ) -> AsyncHttpResponse[typing.Optional[Ticket]]: """ You can convert a conversation to a ticket. Parameters ---------- - conversation_id : str + conversation_id : int The id of the conversation to target ticket_type_id : str @@ -2296,7 +2339,7 @@ async def convert_to_ticket( Returns ------- - AsyncHttpResponse[Ticket] + AsyncHttpResponse[typing.Optional[Ticket]] successful """ _response = await self._client_wrapper.httpx_client.request( @@ -2313,11 +2356,13 @@ async def convert_to_ticket( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Ticket, + typing.Optional[Ticket], construct_type( - type_=Ticket, # type: ignore + type_=typing.Optional[Ticket], # type: ignore object_=_response.json(), ), ) @@ -2337,3 +2382,31 @@ async def convert_to_ticket( except JSONDecodeError: raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def run_assignment_rules( + self, conversation_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[None]: + """ + Parameters + ---------- + conversation_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[None] + """ + _response = await self._client_wrapper.httpx_client.request( + f"conversations/{jsonable_encoder(conversation_id)}/run_assignment_rules", + method="POST", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=None) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/conversations/types/conversation.py b/src/intercom/conversations/types/conversation.py index 342e1dd..8429784 100644 --- a/src/intercom/conversations/types/conversation.py +++ b/src/intercom/conversations/types/conversation.py @@ -26,12 +26,12 @@ class Conversation(UncheckedBaseModel): Conversations are how you can communicate with users in Intercom. They are created when a contact replies to an outbound message, or when one admin directly sends a message to a single contact. """ - type: typing.Optional[typing.Literal["conversation"]] = pydantic.Field(default=None) + type: typing.Optional[str] = pydantic.Field(default=None) """ Always conversation. """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id representing the conversation. """ @@ -41,12 +41,12 @@ class Conversation(UncheckedBaseModel): The title given to the conversation. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ The time the conversation was created. """ - updated_at: int = pydantic.Field() + updated_at: typing.Optional[int] = pydantic.Field(default=None) """ The last time the conversation was updated. """ @@ -61,17 +61,17 @@ class Conversation(UncheckedBaseModel): If set this is the time in the future when this conversation will be marked as open. i.e. it will be in a snoozed state until this time. i.e. it will be in a snoozed state until this time. """ - open: bool = pydantic.Field() + open: typing.Optional[bool] = pydantic.Field(default=None) """ Indicates whether a conversation is open (true) or closed (false). """ - state: ConversationState = pydantic.Field() + state: typing.Optional[ConversationState] = pydantic.Field(default=None) """ Can be set to "open", "closed" or "snoozed". """ - read: bool = pydantic.Field() + read: typing.Optional[bool] = pydantic.Field(default=None) """ Indicates whether a conversation has been read. """ @@ -91,12 +91,17 @@ class Conversation(UncheckedBaseModel): The id of the team assigned to the conversation. If it's not assigned to a team it will return null. """ + company_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The ID of the company that the conversation is associated with. The unique identifier for the company which is given by Intercom. + """ + tags: typing.Optional[Tags] = None conversation_rating: typing.Optional[ConversationRating] = None - source: ConversationSource - contacts: ConversationContacts - teammates: ConversationTeammates - custom_attributes: CustomAttributes + source: typing.Optional[ConversationSource] = None + contacts: typing.Optional[ConversationContacts] = None + teammates: typing.Optional[ConversationTeammates] = None + custom_attributes: typing.Optional[CustomAttributes] = None first_contact_reply: typing.Optional[ConversationFirstContactReply] = None sla_applied: typing.Optional[SlaApplied] = None statistics: typing.Optional[ConversationStatistics] = None diff --git a/src/intercom/core/client_wrapper.py b/src/intercom/core/client_wrapper.py index 9590225..99c57dd 100644 --- a/src/intercom/core/client_wrapper.py +++ b/src/intercom/core/client_wrapper.py @@ -20,10 +20,10 @@ def __init__( def get_headers(self) -> typing.Dict[str, str]: headers: typing.Dict[str, str] = { - "User-Agent": "python-intercom/4.0.0", + "User-Agent": "python-intercom/5.0.0", "X-Fern-Language": "Python", "X-Fern-SDK-Name": "python-intercom", - "X-Fern-SDK-Version": "4.0.0", + "X-Fern-SDK-Version": "5.0.0", } headers["Authorization"] = f"Bearer {self._get_token()}" return headers diff --git a/src/intercom/custom_channel_events/__init__.py b/src/intercom/custom_channel_events/__init__.py new file mode 100644 index 0000000..5cde020 --- /dev/null +++ b/src/intercom/custom_channel_events/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/intercom/custom_channel_events/client.py b/src/intercom/custom_channel_events/client.py new file mode 100644 index 0000000..7a98364 --- /dev/null +++ b/src/intercom/custom_channel_events/client.py @@ -0,0 +1,553 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.custom_channel_attribute import CustomChannelAttribute +from ..types.custom_channel_contact import CustomChannelContact +from ..types.custom_channel_notification_response import CustomChannelNotificationResponse +from .raw_client import AsyncRawCustomChannelEventsClient, RawCustomChannelEventsClient + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class CustomChannelEventsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawCustomChannelEventsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawCustomChannelEventsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawCustomChannelEventsClient + """ + return self._raw_client + + def notify_new_conversation( + self, + *, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomChannelNotificationResponse: + """ + Notifies Intercom that a new conversation was created in your custom channel/platform. This triggers conversation creation and workflow automations within Intercom for your custom channel integration. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomChannelNotificationResponse + Successfully notified Intercom + + Examples + -------- + from intercom import CustomChannelContact, Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.custom_channel_events.notify_new_conversation( + event_id="event_id", + external_conversation_id="external_conversation_id", + contact=CustomChannelContact( + type="user", + external_id="external_id", + ), + ) + """ + _response = self._raw_client.notify_new_conversation( + event_id=event_id, + external_conversation_id=external_conversation_id, + contact=contact, + request_options=request_options, + ) + return _response.data + + def notify_new_message( + self, + *, + body: str, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomChannelNotificationResponse: + """ + Notifies Intercom that a new message was sent in a conversation on your custom channel/platform. This allows Intercom to process the message and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + body : str + The message content sent by the user. + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomChannelNotificationResponse + Successfully notified Intercom + + Examples + -------- + from intercom import CustomChannelContact, Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.custom_channel_events.notify_new_message( + body="body", + event_id="event_id", + external_conversation_id="external_conversation_id", + contact=CustomChannelContact( + type="user", + external_id="external_id", + ), + ) + """ + _response = self._raw_client.notify_new_message( + body=body, + event_id=event_id, + external_conversation_id=external_conversation_id, + contact=contact, + request_options=request_options, + ) + return _response.data + + def notify_quick_reply_selected( + self, + *, + quick_reply_option_id: str, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomChannelNotificationResponse: + """ + Notifies Intercom that a user selected a quick reply option in your custom channel/platform. This allows Intercom to process the response and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + quick_reply_option_id : str + Id of the selected quick reply option. + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomChannelNotificationResponse + Successfully notified Intercom + + Examples + -------- + from intercom import CustomChannelContact, Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.custom_channel_events.notify_quick_reply_selected( + event_id="evt_67890", + external_conversation_id="conv_13579", + contact=CustomChannelContact( + type="user", + external_id="user_003", + name="Alice Example", + email="alice@example.com", + ), + quick_reply_option_id="1234", + ) + """ + _response = self._raw_client.notify_quick_reply_selected( + quick_reply_option_id=quick_reply_option_id, + event_id=event_id, + external_conversation_id=external_conversation_id, + contact=contact, + request_options=request_options, + ) + return _response.data + + def notify_attribute_collected( + self, + *, + attribute: CustomChannelAttribute, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomChannelNotificationResponse: + """ + Notifies Intercom that a user provided a response to an attribute collector in your custom channel/platform. This allows Intercom to process the attribute and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + attribute : CustomChannelAttribute + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomChannelNotificationResponse + Successfully notified Intercom + + Examples + -------- + from intercom import CustomChannelAttribute, CustomChannelContact, Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.custom_channel_events.notify_attribute_collected( + attribute=CustomChannelAttribute( + id="id", + value="value", + ), + event_id="event_id", + external_conversation_id="external_conversation_id", + contact=CustomChannelContact( + type="user", + external_id="external_id", + ), + ) + """ + _response = self._raw_client.notify_attribute_collected( + attribute=attribute, + event_id=event_id, + external_conversation_id=external_conversation_id, + contact=contact, + request_options=request_options, + ) + return _response.data + + +class AsyncCustomChannelEventsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawCustomChannelEventsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawCustomChannelEventsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawCustomChannelEventsClient + """ + return self._raw_client + + async def notify_new_conversation( + self, + *, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomChannelNotificationResponse: + """ + Notifies Intercom that a new conversation was created in your custom channel/platform. This triggers conversation creation and workflow automations within Intercom for your custom channel integration. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomChannelNotificationResponse + Successfully notified Intercom + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom, CustomChannelContact + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.custom_channel_events.notify_new_conversation( + event_id="event_id", + external_conversation_id="external_conversation_id", + contact=CustomChannelContact( + type="user", + external_id="external_id", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.notify_new_conversation( + event_id=event_id, + external_conversation_id=external_conversation_id, + contact=contact, + request_options=request_options, + ) + return _response.data + + async def notify_new_message( + self, + *, + body: str, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomChannelNotificationResponse: + """ + Notifies Intercom that a new message was sent in a conversation on your custom channel/platform. This allows Intercom to process the message and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + body : str + The message content sent by the user. + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomChannelNotificationResponse + Successfully notified Intercom + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom, CustomChannelContact + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.custom_channel_events.notify_new_message( + body="body", + event_id="event_id", + external_conversation_id="external_conversation_id", + contact=CustomChannelContact( + type="user", + external_id="external_id", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.notify_new_message( + body=body, + event_id=event_id, + external_conversation_id=external_conversation_id, + contact=contact, + request_options=request_options, + ) + return _response.data + + async def notify_quick_reply_selected( + self, + *, + quick_reply_option_id: str, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomChannelNotificationResponse: + """ + Notifies Intercom that a user selected a quick reply option in your custom channel/platform. This allows Intercom to process the response and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + quick_reply_option_id : str + Id of the selected quick reply option. + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomChannelNotificationResponse + Successfully notified Intercom + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom, CustomChannelContact + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.custom_channel_events.notify_quick_reply_selected( + event_id="evt_67890", + external_conversation_id="conv_13579", + contact=CustomChannelContact( + type="user", + external_id="user_003", + name="Alice Example", + email="alice@example.com", + ), + quick_reply_option_id="1234", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.notify_quick_reply_selected( + quick_reply_option_id=quick_reply_option_id, + event_id=event_id, + external_conversation_id=external_conversation_id, + contact=contact, + request_options=request_options, + ) + return _response.data + + async def notify_attribute_collected( + self, + *, + attribute: CustomChannelAttribute, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomChannelNotificationResponse: + """ + Notifies Intercom that a user provided a response to an attribute collector in your custom channel/platform. This allows Intercom to process the attribute and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + attribute : CustomChannelAttribute + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomChannelNotificationResponse + Successfully notified Intercom + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom, CustomChannelAttribute, CustomChannelContact + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.custom_channel_events.notify_attribute_collected( + attribute=CustomChannelAttribute( + id="id", + value="value", + ), + event_id="event_id", + external_conversation_id="external_conversation_id", + contact=CustomChannelContact( + type="user", + external_id="external_id", + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.notify_attribute_collected( + attribute=attribute, + event_id=event_id, + external_conversation_id=external_conversation_id, + contact=contact, + request_options=request_options, + ) + return _response.data diff --git a/src/intercom/custom_channel_events/raw_client.py b/src/intercom/custom_channel_events/raw_client.py new file mode 100644 index 0000000..2860258 --- /dev/null +++ b/src/intercom/custom_channel_events/raw_client.py @@ -0,0 +1,904 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata +from ..core.unchecked_base_model import construct_type +from ..errors.bad_request_error import BadRequestError +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..errors.unprocessable_entity_error import UnprocessableEntityError +from ..types.custom_channel_attribute import CustomChannelAttribute +from ..types.custom_channel_contact import CustomChannelContact +from ..types.custom_channel_notification_response import CustomChannelNotificationResponse +from ..types.error import Error + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawCustomChannelEventsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def notify_new_conversation( + self, + *, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[CustomChannelNotificationResponse]: + """ + Notifies Intercom that a new conversation was created in your custom channel/platform. This triggers conversation creation and workflow automations within Intercom for your custom channel integration. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[CustomChannelNotificationResponse] + Successfully notified Intercom + """ + _response = self._client_wrapper.httpx_client.request( + "custom_channel_events/notify_new_conversation", + method="POST", + json={ + "event_id": event_id, + "external_conversation_id": external_conversation_id, + "contact": convert_and_respect_annotation_metadata( + object_=contact, annotation=CustomChannelContact, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomChannelNotificationResponse, + construct_type( + type_=CustomChannelNotificationResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def notify_new_message( + self, + *, + body: str, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[CustomChannelNotificationResponse]: + """ + Notifies Intercom that a new message was sent in a conversation on your custom channel/platform. This allows Intercom to process the message and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + body : str + The message content sent by the user. + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[CustomChannelNotificationResponse] + Successfully notified Intercom + """ + _response = self._client_wrapper.httpx_client.request( + "custom_channel_events/notify_new_message", + method="POST", + json={ + "body": body, + "event_id": event_id, + "external_conversation_id": external_conversation_id, + "contact": convert_and_respect_annotation_metadata( + object_=contact, annotation=CustomChannelContact, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomChannelNotificationResponse, + construct_type( + type_=CustomChannelNotificationResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def notify_quick_reply_selected( + self, + *, + quick_reply_option_id: str, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[CustomChannelNotificationResponse]: + """ + Notifies Intercom that a user selected a quick reply option in your custom channel/platform. This allows Intercom to process the response and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + quick_reply_option_id : str + Id of the selected quick reply option. + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[CustomChannelNotificationResponse] + Successfully notified Intercom + """ + _response = self._client_wrapper.httpx_client.request( + "custom_channel_events/notify_quick_reply_selected", + method="POST", + json={ + "quick_reply_option_id": quick_reply_option_id, + "event_id": event_id, + "external_conversation_id": external_conversation_id, + "contact": convert_and_respect_annotation_metadata( + object_=contact, annotation=CustomChannelContact, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomChannelNotificationResponse, + construct_type( + type_=CustomChannelNotificationResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def notify_attribute_collected( + self, + *, + attribute: CustomChannelAttribute, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[CustomChannelNotificationResponse]: + """ + Notifies Intercom that a user provided a response to an attribute collector in your custom channel/platform. This allows Intercom to process the attribute and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + attribute : CustomChannelAttribute + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[CustomChannelNotificationResponse] + Successfully notified Intercom + """ + _response = self._client_wrapper.httpx_client.request( + "custom_channel_events/notify_attribute_collected", + method="POST", + json={ + "attribute": convert_and_respect_annotation_metadata( + object_=attribute, annotation=CustomChannelAttribute, direction="write" + ), + "event_id": event_id, + "external_conversation_id": external_conversation_id, + "contact": convert_and_respect_annotation_metadata( + object_=contact, annotation=CustomChannelContact, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomChannelNotificationResponse, + construct_type( + type_=CustomChannelNotificationResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawCustomChannelEventsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def notify_new_conversation( + self, + *, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[CustomChannelNotificationResponse]: + """ + Notifies Intercom that a new conversation was created in your custom channel/platform. This triggers conversation creation and workflow automations within Intercom for your custom channel integration. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[CustomChannelNotificationResponse] + Successfully notified Intercom + """ + _response = await self._client_wrapper.httpx_client.request( + "custom_channel_events/notify_new_conversation", + method="POST", + json={ + "event_id": event_id, + "external_conversation_id": external_conversation_id, + "contact": convert_and_respect_annotation_metadata( + object_=contact, annotation=CustomChannelContact, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomChannelNotificationResponse, + construct_type( + type_=CustomChannelNotificationResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def notify_new_message( + self, + *, + body: str, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[CustomChannelNotificationResponse]: + """ + Notifies Intercom that a new message was sent in a conversation on your custom channel/platform. This allows Intercom to process the message and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + body : str + The message content sent by the user. + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[CustomChannelNotificationResponse] + Successfully notified Intercom + """ + _response = await self._client_wrapper.httpx_client.request( + "custom_channel_events/notify_new_message", + method="POST", + json={ + "body": body, + "event_id": event_id, + "external_conversation_id": external_conversation_id, + "contact": convert_and_respect_annotation_metadata( + object_=contact, annotation=CustomChannelContact, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomChannelNotificationResponse, + construct_type( + type_=CustomChannelNotificationResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def notify_quick_reply_selected( + self, + *, + quick_reply_option_id: str, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[CustomChannelNotificationResponse]: + """ + Notifies Intercom that a user selected a quick reply option in your custom channel/platform. This allows Intercom to process the response and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + quick_reply_option_id : str + Id of the selected quick reply option. + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[CustomChannelNotificationResponse] + Successfully notified Intercom + """ + _response = await self._client_wrapper.httpx_client.request( + "custom_channel_events/notify_quick_reply_selected", + method="POST", + json={ + "quick_reply_option_id": quick_reply_option_id, + "event_id": event_id, + "external_conversation_id": external_conversation_id, + "contact": convert_and_respect_annotation_metadata( + object_=contact, annotation=CustomChannelContact, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomChannelNotificationResponse, + construct_type( + type_=CustomChannelNotificationResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def notify_attribute_collected( + self, + *, + attribute: CustomChannelAttribute, + event_id: str, + external_conversation_id: str, + contact: CustomChannelContact, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[CustomChannelNotificationResponse]: + """ + Notifies Intercom that a user provided a response to an attribute collector in your custom channel/platform. This allows Intercom to process the attribute and trigger any relevant workflow automations. + > **Note:** This endpoint is currently under managed availability. Please reach out to your accounts team to discuss access and tailored, hands-on support. + + Parameters + ---------- + attribute : CustomChannelAttribute + + event_id : str + Unique identifier for the event. + + external_conversation_id : str + Identifier for the conversation in your application. + + contact : CustomChannelContact + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[CustomChannelNotificationResponse] + Successfully notified Intercom + """ + _response = await self._client_wrapper.httpx_client.request( + "custom_channel_events/notify_attribute_collected", + method="POST", + json={ + "attribute": convert_and_respect_annotation_metadata( + object_=attribute, annotation=CustomChannelAttribute, direction="write" + ), + "event_id": event_id, + "external_conversation_id": external_conversation_id, + "contact": convert_and_respect_annotation_metadata( + object_=contact, annotation=CustomChannelContact, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomChannelNotificationResponse, + construct_type( + type_=CustomChannelNotificationResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 422: + raise UnprocessableEntityError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/custom_object_instances/__init__.py b/src/intercom/custom_object_instances/__init__.py new file mode 100644 index 0000000..84e0f61 --- /dev/null +++ b/src/intercom/custom_object_instances/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import CustomObjectInstance + +__all__ = ["CustomObjectInstance"] diff --git a/src/intercom/custom_object_instances/client.py b/src/intercom/custom_object_instances/client.py new file mode 100644 index 0000000..319b09f --- /dev/null +++ b/src/intercom/custom_object_instances/client.py @@ -0,0 +1,556 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.custom_object_instance_deleted import CustomObjectInstanceDeleted +from .raw_client import AsyncRawCustomObjectInstancesClient, RawCustomObjectInstancesClient +from .types.custom_object_instance import CustomObjectInstance + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class CustomObjectInstancesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawCustomObjectInstancesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawCustomObjectInstancesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawCustomObjectInstancesClient + """ + return self._raw_client + + def get_custom_object_instances_by_external_id( + self, + custom_object_type_identifier: str, + *, + external_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[CustomObjectInstance]: + """ + Fetch a Custom Object Instance by external_id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[CustomObjectInstance] + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.custom_object_instances.get_custom_object_instances_by_external_id( + custom_object_type_identifier="Order", + external_id="external_id", + ) + """ + _response = self._raw_client.get_custom_object_instances_by_external_id( + custom_object_type_identifier, external_id=external_id, request_options=request_options + ) + return _response.data + + def create_custom_object_instances( + self, + custom_object_type_identifier: str, + *, + external_id: typing.Optional[str] = OMIT, + external_created_at: typing.Optional[int] = OMIT, + external_updated_at: typing.Optional[int] = OMIT, + custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[CustomObjectInstance]: + """ + Create or update a custom object instance + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : typing.Optional[str] + A unique identifier for the Custom Object instance in the external system it originated from. + + external_created_at : typing.Optional[int] + The time when the Custom Object instance was created in the external system it originated from. + + external_updated_at : typing.Optional[int] + The time when the Custom Object instance was last updated in the external system it originated from. + + custom_attributes : typing.Optional[typing.Dict[str, typing.Optional[str]]] + The custom attributes which are set for the Custom Object instance. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[CustomObjectInstance] + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.custom_object_instances.create_custom_object_instances( + custom_object_type_identifier="Order", + external_id="123", + external_created_at=1392036272, + external_updated_at=1392036272, + custom_attributes={ + "order_number": "ORDER-12345", + "total_amount": "custom_attributes", + }, + ) + """ + _response = self._raw_client.create_custom_object_instances( + custom_object_type_identifier, + external_id=external_id, + external_created_at=external_created_at, + external_updated_at=external_updated_at, + custom_attributes=custom_attributes, + request_options=request_options, + ) + return _response.data + + def delete_custom_object_instances_by_id( + self, + custom_object_type_identifier: str, + *, + external_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomObjectInstanceDeleted: + """ + Delete a single Custom Object instance by external_id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomObjectInstanceDeleted + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.custom_object_instances.delete_custom_object_instances_by_id( + custom_object_type_identifier="Order", + external_id="external_id", + ) + """ + _response = self._raw_client.delete_custom_object_instances_by_id( + custom_object_type_identifier, external_id=external_id, request_options=request_options + ) + return _response.data + + def get_custom_object_instances_by_id( + self, + custom_object_type_identifier: str, + custom_object_instance_id: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[CustomObjectInstance]: + """ + Fetch a Custom Object Instance by id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + custom_object_instance_id : str + The id or external_id of the custom object instance + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[CustomObjectInstance] + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.custom_object_instances.get_custom_object_instances_by_id( + custom_object_type_identifier="Order", + custom_object_instance_id="custom_object_instance_id", + ) + """ + _response = self._raw_client.get_custom_object_instances_by_id( + custom_object_type_identifier, custom_object_instance_id, request_options=request_options + ) + return _response.data + + def delete_custom_object_instances_by_external_id( + self, + custom_object_type_identifier: str, + custom_object_instance_id: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomObjectInstanceDeleted: + """ + Delete a single Custom Object instance using the Intercom defined id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + custom_object_instance_id : str + The Intercom defined id of the custom object instance + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomObjectInstanceDeleted + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.custom_object_instances.delete_custom_object_instances_by_external_id( + custom_object_type_identifier="Order", + custom_object_instance_id="custom_object_instance_id", + ) + """ + _response = self._raw_client.delete_custom_object_instances_by_external_id( + custom_object_type_identifier, custom_object_instance_id, request_options=request_options + ) + return _response.data + + +class AsyncCustomObjectInstancesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawCustomObjectInstancesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawCustomObjectInstancesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawCustomObjectInstancesClient + """ + return self._raw_client + + async def get_custom_object_instances_by_external_id( + self, + custom_object_type_identifier: str, + *, + external_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[CustomObjectInstance]: + """ + Fetch a Custom Object Instance by external_id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[CustomObjectInstance] + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.custom_object_instances.get_custom_object_instances_by_external_id( + custom_object_type_identifier="Order", + external_id="external_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_custom_object_instances_by_external_id( + custom_object_type_identifier, external_id=external_id, request_options=request_options + ) + return _response.data + + async def create_custom_object_instances( + self, + custom_object_type_identifier: str, + *, + external_id: typing.Optional[str] = OMIT, + external_created_at: typing.Optional[int] = OMIT, + external_updated_at: typing.Optional[int] = OMIT, + custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[CustomObjectInstance]: + """ + Create or update a custom object instance + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : typing.Optional[str] + A unique identifier for the Custom Object instance in the external system it originated from. + + external_created_at : typing.Optional[int] + The time when the Custom Object instance was created in the external system it originated from. + + external_updated_at : typing.Optional[int] + The time when the Custom Object instance was last updated in the external system it originated from. + + custom_attributes : typing.Optional[typing.Dict[str, typing.Optional[str]]] + The custom attributes which are set for the Custom Object instance. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[CustomObjectInstance] + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.custom_object_instances.create_custom_object_instances( + custom_object_type_identifier="Order", + external_id="123", + external_created_at=1392036272, + external_updated_at=1392036272, + custom_attributes={ + "order_number": "ORDER-12345", + "total_amount": "custom_attributes", + }, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_custom_object_instances( + custom_object_type_identifier, + external_id=external_id, + external_created_at=external_created_at, + external_updated_at=external_updated_at, + custom_attributes=custom_attributes, + request_options=request_options, + ) + return _response.data + + async def delete_custom_object_instances_by_id( + self, + custom_object_type_identifier: str, + *, + external_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomObjectInstanceDeleted: + """ + Delete a single Custom Object instance by external_id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomObjectInstanceDeleted + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.custom_object_instances.delete_custom_object_instances_by_id( + custom_object_type_identifier="Order", + external_id="external_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_custom_object_instances_by_id( + custom_object_type_identifier, external_id=external_id, request_options=request_options + ) + return _response.data + + async def get_custom_object_instances_by_id( + self, + custom_object_type_identifier: str, + custom_object_instance_id: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> typing.Optional[CustomObjectInstance]: + """ + Fetch a Custom Object Instance by id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + custom_object_instance_id : str + The id or external_id of the custom object instance + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[CustomObjectInstance] + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.custom_object_instances.get_custom_object_instances_by_id( + custom_object_type_identifier="Order", + custom_object_instance_id="custom_object_instance_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_custom_object_instances_by_id( + custom_object_type_identifier, custom_object_instance_id, request_options=request_options + ) + return _response.data + + async def delete_custom_object_instances_by_external_id( + self, + custom_object_type_identifier: str, + custom_object_instance_id: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> CustomObjectInstanceDeleted: + """ + Delete a single Custom Object instance using the Intercom defined id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + custom_object_instance_id : str + The Intercom defined id of the custom object instance + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CustomObjectInstanceDeleted + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.custom_object_instances.delete_custom_object_instances_by_external_id( + custom_object_type_identifier="Order", + custom_object_instance_id="custom_object_instance_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_custom_object_instances_by_external_id( + custom_object_type_identifier, custom_object_instance_id, request_options=request_options + ) + return _response.data diff --git a/src/intercom/custom_object_instances/raw_client.py b/src/intercom/custom_object_instances/raw_client.py new file mode 100644 index 0000000..939322e --- /dev/null +++ b/src/intercom/custom_object_instances/raw_client.py @@ -0,0 +1,773 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.jsonable_encoder import jsonable_encoder +from ..core.request_options import RequestOptions +from ..core.unchecked_base_model import construct_type +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.custom_object_instance_deleted import CustomObjectInstanceDeleted +from ..types.error import Error +from .types.custom_object_instance import CustomObjectInstance + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawCustomObjectInstancesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def get_custom_object_instances_by_external_id( + self, + custom_object_type_identifier: str, + *, + external_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[typing.Optional[CustomObjectInstance]]: + """ + Fetch a Custom Object Instance by external_id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[typing.Optional[CustomObjectInstance]] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"custom_object_instances/{jsonable_encoder(custom_object_type_identifier)}", + method="GET", + params={ + "external_id": external_id, + }, + request_options=request_options, + ) + try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[CustomObjectInstance], + construct_type( + type_=typing.Optional[CustomObjectInstance], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def create_custom_object_instances( + self, + custom_object_type_identifier: str, + *, + external_id: typing.Optional[str] = OMIT, + external_created_at: typing.Optional[int] = OMIT, + external_updated_at: typing.Optional[int] = OMIT, + custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[typing.Optional[CustomObjectInstance]]: + """ + Create or update a custom object instance + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : typing.Optional[str] + A unique identifier for the Custom Object instance in the external system it originated from. + + external_created_at : typing.Optional[int] + The time when the Custom Object instance was created in the external system it originated from. + + external_updated_at : typing.Optional[int] + The time when the Custom Object instance was last updated in the external system it originated from. + + custom_attributes : typing.Optional[typing.Dict[str, typing.Optional[str]]] + The custom attributes which are set for the Custom Object instance. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[typing.Optional[CustomObjectInstance]] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"custom_object_instances/{jsonable_encoder(custom_object_type_identifier)}", + method="POST", + json={ + "external_id": external_id, + "external_created_at": external_created_at, + "external_updated_at": external_updated_at, + "custom_attributes": custom_attributes, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[CustomObjectInstance], + construct_type( + type_=typing.Optional[CustomObjectInstance], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def delete_custom_object_instances_by_id( + self, + custom_object_type_identifier: str, + *, + external_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[CustomObjectInstanceDeleted]: + """ + Delete a single Custom Object instance by external_id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[CustomObjectInstanceDeleted] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"custom_object_instances/{jsonable_encoder(custom_object_type_identifier)}", + method="DELETE", + params={ + "external_id": external_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomObjectInstanceDeleted, + construct_type( + type_=CustomObjectInstanceDeleted, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_custom_object_instances_by_id( + self, + custom_object_type_identifier: str, + custom_object_instance_id: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[typing.Optional[CustomObjectInstance]]: + """ + Fetch a Custom Object Instance by id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + custom_object_instance_id : str + The id or external_id of the custom object instance + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[typing.Optional[CustomObjectInstance]] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"custom_object_instances/{jsonable_encoder(custom_object_type_identifier)}/{jsonable_encoder(custom_object_instance_id)}", + method="GET", + request_options=request_options, + ) + try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[CustomObjectInstance], + construct_type( + type_=typing.Optional[CustomObjectInstance], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def delete_custom_object_instances_by_external_id( + self, + custom_object_type_identifier: str, + custom_object_instance_id: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[CustomObjectInstanceDeleted]: + """ + Delete a single Custom Object instance using the Intercom defined id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + custom_object_instance_id : str + The Intercom defined id of the custom object instance + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[CustomObjectInstanceDeleted] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"custom_object_instances/{jsonable_encoder(custom_object_type_identifier)}/{jsonable_encoder(custom_object_instance_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomObjectInstanceDeleted, + construct_type( + type_=CustomObjectInstanceDeleted, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawCustomObjectInstancesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def get_custom_object_instances_by_external_id( + self, + custom_object_type_identifier: str, + *, + external_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[typing.Optional[CustomObjectInstance]]: + """ + Fetch a Custom Object Instance by external_id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[typing.Optional[CustomObjectInstance]] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"custom_object_instances/{jsonable_encoder(custom_object_type_identifier)}", + method="GET", + params={ + "external_id": external_id, + }, + request_options=request_options, + ) + try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[CustomObjectInstance], + construct_type( + type_=typing.Optional[CustomObjectInstance], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def create_custom_object_instances( + self, + custom_object_type_identifier: str, + *, + external_id: typing.Optional[str] = OMIT, + external_created_at: typing.Optional[int] = OMIT, + external_updated_at: typing.Optional[int] = OMIT, + custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[str]]] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[typing.Optional[CustomObjectInstance]]: + """ + Create or update a custom object instance + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : typing.Optional[str] + A unique identifier for the Custom Object instance in the external system it originated from. + + external_created_at : typing.Optional[int] + The time when the Custom Object instance was created in the external system it originated from. + + external_updated_at : typing.Optional[int] + The time when the Custom Object instance was last updated in the external system it originated from. + + custom_attributes : typing.Optional[typing.Dict[str, typing.Optional[str]]] + The custom attributes which are set for the Custom Object instance. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[typing.Optional[CustomObjectInstance]] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"custom_object_instances/{jsonable_encoder(custom_object_type_identifier)}", + method="POST", + json={ + "external_id": external_id, + "external_created_at": external_created_at, + "external_updated_at": external_updated_at, + "custom_attributes": custom_attributes, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[CustomObjectInstance], + construct_type( + type_=typing.Optional[CustomObjectInstance], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def delete_custom_object_instances_by_id( + self, + custom_object_type_identifier: str, + *, + external_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[CustomObjectInstanceDeleted]: + """ + Delete a single Custom Object instance by external_id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + external_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[CustomObjectInstanceDeleted] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"custom_object_instances/{jsonable_encoder(custom_object_type_identifier)}", + method="DELETE", + params={ + "external_id": external_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomObjectInstanceDeleted, + construct_type( + type_=CustomObjectInstanceDeleted, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_custom_object_instances_by_id( + self, + custom_object_type_identifier: str, + custom_object_instance_id: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[typing.Optional[CustomObjectInstance]]: + """ + Fetch a Custom Object Instance by id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + custom_object_instance_id : str + The id or external_id of the custom object instance + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[typing.Optional[CustomObjectInstance]] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"custom_object_instances/{jsonable_encoder(custom_object_type_identifier)}/{jsonable_encoder(custom_object_instance_id)}", + method="GET", + request_options=request_options, + ) + try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[CustomObjectInstance], + construct_type( + type_=typing.Optional[CustomObjectInstance], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def delete_custom_object_instances_by_external_id( + self, + custom_object_type_identifier: str, + custom_object_instance_id: str, + *, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[CustomObjectInstanceDeleted]: + """ + Delete a single Custom Object instance using the Intercom defined id. + + Parameters + ---------- + custom_object_type_identifier : str + The unique identifier of the custom object type that defines the structure of the custom object instance. + + custom_object_instance_id : str + The Intercom defined id of the custom object instance + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[CustomObjectInstanceDeleted] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"custom_object_instances/{jsonable_encoder(custom_object_type_identifier)}/{jsonable_encoder(custom_object_instance_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CustomObjectInstanceDeleted, + construct_type( + type_=CustomObjectInstanceDeleted, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/custom_object_instances/types/__init__.py b/src/intercom/custom_object_instances/types/__init__.py new file mode 100644 index 0000000..027829d --- /dev/null +++ b/src/intercom/custom_object_instances/types/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .custom_object_instance import CustomObjectInstance + +__all__ = ["CustomObjectInstance"] diff --git a/src/intercom/custom_object_instances/types/custom_object_instance.py b/src/intercom/custom_object_instances/types/custom_object_instance.py new file mode 100644 index 0000000..8285b26 --- /dev/null +++ b/src/intercom/custom_object_instances/types/custom_object_instance.py @@ -0,0 +1,62 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class CustomObjectInstance(UncheckedBaseModel): + """ + A Custom Object Instance represents an instance of a custom object type. This allows you to create and set custom attributes to store data about your customers that is not already captured by Intercom. The parent object includes recommended default attributes and you can add your own custom attributes. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The Intercom defined id representing the custom object instance. + """ + + external_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id you have defined for the custom object instance. + """ + + external_created_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time when the Custom Object instance was created in the external system it originated from. + """ + + external_updated_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time when the Custom Object instance was last updated in the external system it originated from. + """ + + created_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time the attribute was created as a UTC Unix timestamp + """ + + updated_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time the attribute was last updated as a UTC Unix timestamp + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + The identifier of the custom object type that defines the structure of the custom object instance. + """ + + custom_attributes: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + The custom attributes you have set on the custom object instance. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/data_attributes/__init__.py b/src/intercom/data_attributes/__init__.py index 28a61e8..c5b8e39 100644 --- a/src/intercom/data_attributes/__init__.py +++ b/src/intercom/data_attributes/__init__.py @@ -2,22 +2,6 @@ # isort: skip_file -from .types import ( - CreateDataAttributeRequestDataType, - CreateDataAttributeRequestModel, - DataAttribute, - DataAttributeDataType, - DataAttributeModel, - DataAttributesListRequestModel, - UpdateDataAttributeRequestOptionsItem, -) +from .types import DataAttribute, DataAttributeDataType, DataAttributeModel, DataAttributesListRequestModel -__all__ = [ - "CreateDataAttributeRequestDataType", - "CreateDataAttributeRequestModel", - "DataAttribute", - "DataAttributeDataType", - "DataAttributeModel", - "DataAttributesListRequestModel", - "UpdateDataAttributeRequestOptionsItem", -] +__all__ = ["DataAttribute", "DataAttributeDataType", "DataAttributeModel", "DataAttributesListRequestModel"] diff --git a/src/intercom/data_attributes/client.py b/src/intercom/data_attributes/client.py index b762c06..e6e688f 100644 --- a/src/intercom/data_attributes/client.py +++ b/src/intercom/data_attributes/client.py @@ -4,13 +4,12 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.request_options import RequestOptions +from ..types.create_data_attribute_request import CreateDataAttributeRequest from ..types.data_attribute_list import DataAttributeList +from ..types.update_data_attribute_request_body import UpdateDataAttributeRequestBody from .raw_client import AsyncRawDataAttributesClient, RawDataAttributesClient -from .types.create_data_attribute_request_data_type import CreateDataAttributeRequestDataType -from .types.create_data_attribute_request_model import CreateDataAttributeRequestModel from .types.data_attribute import DataAttribute from .types.data_attributes_list_request_model import DataAttributesListRequestModel -from .types.update_data_attribute_request_options_item import UpdateDataAttributeRequestOptionsItem # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -72,38 +71,14 @@ def list( return _response.data def create( - self, - *, - name: str, - model: CreateDataAttributeRequestModel, - data_type: CreateDataAttributeRequestDataType, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, - request_options: typing.Optional[RequestOptions] = None, + self, *, request: CreateDataAttributeRequest, request_options: typing.Optional[RequestOptions] = None ) -> DataAttribute: """ You can create a data attributes for a `contact` or a `company`. Parameters ---------- - name : str - The name of the data attribute. - - model : CreateDataAttributeRequestModel - The model that the data attribute belongs to. - - data_type : CreateDataAttributeRequestDataType - The type of data stored for this attribute. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : CreateDataAttributeRequest request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -115,36 +90,25 @@ def create( Examples -------- - from intercom import Intercom + from intercom import CreateDataAttributeRequestOne, Intercom client = Intercom( token="YOUR_TOKEN", ) client.data_attributes.create( - name="Mithril Shirt", - model="company", - data_type="string", + request=CreateDataAttributeRequestOne( + data_type="string", + ), ) """ - _response = self._raw_client.create( - name=name, - model=model, - data_type=data_type, - description=description, - options=options, - messenger_writable=messenger_writable, - request_options=request_options, - ) + _response = self._raw_client.create(request=request, request_options=request_options) return _response.data def update( self, - data_attribute_id: str, + data_attribute_id: int, *, - archived: typing.Optional[bool] = OMIT, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[UpdateDataAttributeRequestOptionsItem]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, + request: UpdateDataAttributeRequestBody, request_options: typing.Optional[RequestOptions] = None, ) -> DataAttribute: """ @@ -157,20 +121,10 @@ def update( Parameters ---------- - data_attribute_id : str + data_attribute_id : int The data attribute id - archived : typing.Optional[bool] - Whether the attribute is to be archived or not. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[UpdateDataAttributeRequestOptionsItem]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : UpdateDataAttributeRequestBody request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -182,34 +136,30 @@ def update( Examples -------- - from intercom import Intercom - from intercom.data_attributes import UpdateDataAttributeRequestOptionsItem + from intercom import ( + Intercom, + UpdateDataAttributeRequestOptions, + UpdateDataAttributeRequestOptionsOptionsItem, + ) client = Intercom( token="YOUR_TOKEN", ) client.data_attributes.update( - data_attribute_id="1", - archived=False, - description="Just a plain old ring", - options=[ - UpdateDataAttributeRequestOptionsItem( - value="1-10", - ), - UpdateDataAttributeRequestOptionsItem( - value="11-20", - ), - ], + data_attribute_id=1, + request=UpdateDataAttributeRequestOptions( + options=[ + UpdateDataAttributeRequestOptionsOptionsItem( + value="1-10", + ), + UpdateDataAttributeRequestOptionsOptionsItem( + value="11-20", + ), + ], + ), ) """ - _response = self._raw_client.update( - data_attribute_id, - archived=archived, - description=description, - options=options, - messenger_writable=messenger_writable, - request_options=request_options, - ) + _response = self._raw_client.update(data_attribute_id, request=request, request_options=request_options) return _response.data @@ -277,38 +227,14 @@ async def main() -> None: return _response.data async def create( - self, - *, - name: str, - model: CreateDataAttributeRequestModel, - data_type: CreateDataAttributeRequestDataType, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, - request_options: typing.Optional[RequestOptions] = None, + self, *, request: CreateDataAttributeRequest, request_options: typing.Optional[RequestOptions] = None ) -> DataAttribute: """ You can create a data attributes for a `contact` or a `company`. Parameters ---------- - name : str - The name of the data attribute. - - model : CreateDataAttributeRequestModel - The model that the data attribute belongs to. - - data_type : CreateDataAttributeRequestDataType - The type of data stored for this attribute. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : CreateDataAttributeRequest request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -322,7 +248,7 @@ async def create( -------- import asyncio - from intercom import AsyncIntercom + from intercom import AsyncIntercom, CreateDataAttributeRequestOne client = AsyncIntercom( token="YOUR_TOKEN", @@ -331,33 +257,22 @@ async def create( async def main() -> None: await client.data_attributes.create( - name="Mithril Shirt", - model="company", - data_type="string", + request=CreateDataAttributeRequestOne( + data_type="string", + ), ) asyncio.run(main()) """ - _response = await self._raw_client.create( - name=name, - model=model, - data_type=data_type, - description=description, - options=options, - messenger_writable=messenger_writable, - request_options=request_options, - ) + _response = await self._raw_client.create(request=request, request_options=request_options) return _response.data async def update( self, - data_attribute_id: str, + data_attribute_id: int, *, - archived: typing.Optional[bool] = OMIT, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[UpdateDataAttributeRequestOptionsItem]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, + request: UpdateDataAttributeRequestBody, request_options: typing.Optional[RequestOptions] = None, ) -> DataAttribute: """ @@ -370,20 +285,10 @@ async def update( Parameters ---------- - data_attribute_id : str + data_attribute_id : int The data attribute id - archived : typing.Optional[bool] - Whether the attribute is to be archived or not. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[UpdateDataAttributeRequestOptionsItem]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : UpdateDataAttributeRequestBody request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -397,8 +302,11 @@ async def update( -------- import asyncio - from intercom import AsyncIntercom - from intercom.data_attributes import UpdateDataAttributeRequestOptionsItem + from intercom import ( + AsyncIntercom, + UpdateDataAttributeRequestOptions, + UpdateDataAttributeRequestOptionsOptionsItem, + ) client = AsyncIntercom( token="YOUR_TOKEN", @@ -407,28 +315,21 @@ async def update( async def main() -> None: await client.data_attributes.update( - data_attribute_id="1", - archived=False, - description="Just a plain old ring", - options=[ - UpdateDataAttributeRequestOptionsItem( - value="1-10", - ), - UpdateDataAttributeRequestOptionsItem( - value="11-20", - ), - ], + data_attribute_id=1, + request=UpdateDataAttributeRequestOptions( + options=[ + UpdateDataAttributeRequestOptionsOptionsItem( + value="1-10", + ), + UpdateDataAttributeRequestOptionsOptionsItem( + value="11-20", + ), + ], + ), ) asyncio.run(main()) """ - _response = await self._raw_client.update( - data_attribute_id, - archived=archived, - description=description, - options=options, - messenger_writable=messenger_writable, - request_options=request_options, - ) + _response = await self._raw_client.update(data_attribute_id, request=request, request_options=request_options) return _response.data diff --git a/src/intercom/data_attributes/raw_client.py b/src/intercom/data_attributes/raw_client.py index 8170eed..941d4d8 100644 --- a/src/intercom/data_attributes/raw_client.py +++ b/src/intercom/data_attributes/raw_client.py @@ -14,13 +14,12 @@ from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError from ..errors.unprocessable_entity_error import UnprocessableEntityError +from ..types.create_data_attribute_request import CreateDataAttributeRequest from ..types.data_attribute_list import DataAttributeList from ..types.error import Error -from .types.create_data_attribute_request_data_type import CreateDataAttributeRequestDataType -from .types.create_data_attribute_request_model import CreateDataAttributeRequestModel +from ..types.update_data_attribute_request_body import UpdateDataAttributeRequestBody from .types.data_attribute import DataAttribute from .types.data_attributes_list_request_model import DataAttributesListRequestModel -from .types.update_data_attribute_request_options_item import UpdateDataAttributeRequestOptionsItem # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -92,38 +91,14 @@ def list( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def create( - self, - *, - name: str, - model: CreateDataAttributeRequestModel, - data_type: CreateDataAttributeRequestDataType, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, - request_options: typing.Optional[RequestOptions] = None, + self, *, request: CreateDataAttributeRequest, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[DataAttribute]: """ You can create a data attributes for a `contact` or a `company`. Parameters ---------- - name : str - The name of the data attribute. - - model : CreateDataAttributeRequestModel - The model that the data attribute belongs to. - - data_type : CreateDataAttributeRequestDataType - The type of data stored for this attribute. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : CreateDataAttributeRequest request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -136,14 +111,9 @@ def create( _response = self._client_wrapper.httpx_client.request( "data_attributes", method="POST", - json={ - "name": name, - "model": model, - "data_type": data_type, - "description": description, - "options": options, - "messenger_writable": messenger_writable, - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateDataAttributeRequest, direction="write" + ), headers={ "content-type": "application/json", }, @@ -189,12 +159,9 @@ def create( def update( self, - data_attribute_id: str, + data_attribute_id: int, *, - archived: typing.Optional[bool] = OMIT, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[UpdateDataAttributeRequestOptionsItem]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, + request: UpdateDataAttributeRequestBody, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[DataAttribute]: """ @@ -207,20 +174,10 @@ def update( Parameters ---------- - data_attribute_id : str + data_attribute_id : int The data attribute id - archived : typing.Optional[bool] - Whether the attribute is to be archived or not. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[UpdateDataAttributeRequestOptionsItem]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : UpdateDataAttributeRequestBody request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -233,16 +190,9 @@ def update( _response = self._client_wrapper.httpx_client.request( f"data_attributes/{jsonable_encoder(data_attribute_id)}", method="PUT", - json={ - "archived": archived, - "description": description, - "options": convert_and_respect_annotation_metadata( - object_=options, - annotation=typing.Sequence[UpdateDataAttributeRequestOptionsItem], - direction="write", - ), - "messenger_writable": messenger_writable, - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=UpdateDataAttributeRequestBody, direction="write" + ), headers={ "content-type": "application/json", }, @@ -375,38 +325,14 @@ async def list( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def create( - self, - *, - name: str, - model: CreateDataAttributeRequestModel, - data_type: CreateDataAttributeRequestDataType, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, - request_options: typing.Optional[RequestOptions] = None, + self, *, request: CreateDataAttributeRequest, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[DataAttribute]: """ You can create a data attributes for a `contact` or a `company`. Parameters ---------- - name : str - The name of the data attribute. - - model : CreateDataAttributeRequestModel - The model that the data attribute belongs to. - - data_type : CreateDataAttributeRequestDataType - The type of data stored for this attribute. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : CreateDataAttributeRequest request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -419,14 +345,9 @@ async def create( _response = await self._client_wrapper.httpx_client.request( "data_attributes", method="POST", - json={ - "name": name, - "model": model, - "data_type": data_type, - "description": description, - "options": options, - "messenger_writable": messenger_writable, - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateDataAttributeRequest, direction="write" + ), headers={ "content-type": "application/json", }, @@ -472,12 +393,9 @@ async def create( async def update( self, - data_attribute_id: str, + data_attribute_id: int, *, - archived: typing.Optional[bool] = OMIT, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[UpdateDataAttributeRequestOptionsItem]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, + request: UpdateDataAttributeRequestBody, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[DataAttribute]: """ @@ -490,20 +408,10 @@ async def update( Parameters ---------- - data_attribute_id : str + data_attribute_id : int The data attribute id - archived : typing.Optional[bool] - Whether the attribute is to be archived or not. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[UpdateDataAttributeRequestOptionsItem]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : UpdateDataAttributeRequestBody request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -516,16 +424,9 @@ async def update( _response = await self._client_wrapper.httpx_client.request( f"data_attributes/{jsonable_encoder(data_attribute_id)}", method="PUT", - json={ - "archived": archived, - "description": description, - "options": convert_and_respect_annotation_metadata( - object_=options, - annotation=typing.Sequence[UpdateDataAttributeRequestOptionsItem], - direction="write", - ), - "messenger_writable": messenger_writable, - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=UpdateDataAttributeRequestBody, direction="write" + ), headers={ "content-type": "application/json", }, diff --git a/src/intercom/data_attributes/types/__init__.py b/src/intercom/data_attributes/types/__init__.py index 9ce733d..b0fb969 100644 --- a/src/intercom/data_attributes/types/__init__.py +++ b/src/intercom/data_attributes/types/__init__.py @@ -2,20 +2,9 @@ # isort: skip_file -from .create_data_attribute_request_data_type import CreateDataAttributeRequestDataType -from .create_data_attribute_request_model import CreateDataAttributeRequestModel from .data_attribute import DataAttribute from .data_attribute_data_type import DataAttributeDataType from .data_attribute_model import DataAttributeModel from .data_attributes_list_request_model import DataAttributesListRequestModel -from .update_data_attribute_request_options_item import UpdateDataAttributeRequestOptionsItem -__all__ = [ - "CreateDataAttributeRequestDataType", - "CreateDataAttributeRequestModel", - "DataAttribute", - "DataAttributeDataType", - "DataAttributeModel", - "DataAttributesListRequestModel", - "UpdateDataAttributeRequestOptionsItem", -] +__all__ = ["DataAttribute", "DataAttributeDataType", "DataAttributeModel", "DataAttributesListRequestModel"] diff --git a/src/intercom/data_attributes/types/create_data_attribute_request_model.py b/src/intercom/data_attributes/types/create_data_attribute_request_model.py deleted file mode 100644 index cc5c9b6..0000000 --- a/src/intercom/data_attributes/types/create_data_attribute_request_model.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -CreateDataAttributeRequestModel = typing.Union[typing.Literal["contact", "company"], typing.Any] diff --git a/src/intercom/data_export/__init__.py b/src/intercom/data_export/__init__.py index 0b3cdcb..65c77cb 100644 --- a/src/intercom/data_export/__init__.py +++ b/src/intercom/data_export/__init__.py @@ -2,6 +2,6 @@ # isort: skip_file -from .types import DataExport, DataExportStatus +from .types import DataExport, DataExportExportReportingDataResponse, DataExportStatus -__all__ = ["DataExport", "DataExportStatus"] +__all__ = ["DataExport", "DataExportExportReportingDataResponse", "DataExportStatus"] diff --git a/src/intercom/data_export/client.py b/src/intercom/data_export/client.py index 5d8d8be..1ca3b35 100644 --- a/src/intercom/data_export/client.py +++ b/src/intercom/data_export/client.py @@ -6,6 +6,7 @@ from ..core.request_options import RequestOptions from .raw_client import AsyncRawDataExportClient, RawDataExportClient from .types.data_export import DataExport +from .types.data_export_export_reporting_data_response import DataExportExportReportingDataResponse # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -26,6 +27,85 @@ def with_raw_response(self) -> RawDataExportClient: """ return self._raw_client + def export_reporting_data( + self, + job_identifier: str, + *, + app_id: str, + client_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> DataExportExportReportingDataResponse: + """ + Parameters + ---------- + job_identifier : str + Unique identifier of the job. + + app_id : str + The Intercom defined code of the workspace the company is associated to. + + client_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DataExportExportReportingDataResponse + Job status returned successfully + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.data_export.export_reporting_data( + job_identifier="job_identifier", + app_id="app_id", + client_id="client_id", + ) + """ + _response = self._raw_client.export_reporting_data( + job_identifier, app_id=app_id, client_id=client_id, request_options=request_options + ) + return _response.data + + def download_reporting_data_export( + self, job_identifier: str, *, app_id: str, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Parameters + ---------- + job_identifier : str + + app_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.data_export.download_reporting_data_export( + job_identifier="job_identifier", + app_id="app_id", + ) + """ + _response = self._raw_client.download_reporting_data_export( + job_identifier, app_id=app_id, request_options=request_options + ) + return _response.data + def create( self, *, created_at_after: int, created_at_before: int, request_options: typing.Optional[RequestOptions] = None ) -> DataExport: @@ -70,8 +150,8 @@ def create( token="YOUR_TOKEN", ) client.data_export.create( - created_at_after=1719474967, - created_at_before=1719492967, + created_at_after=1734519776, + created_at_before=1734537776, ) """ _response = self._raw_client.create( @@ -197,6 +277,101 @@ def with_raw_response(self) -> AsyncRawDataExportClient: """ return self._raw_client + async def export_reporting_data( + self, + job_identifier: str, + *, + app_id: str, + client_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> DataExportExportReportingDataResponse: + """ + Parameters + ---------- + job_identifier : str + Unique identifier of the job. + + app_id : str + The Intercom defined code of the workspace the company is associated to. + + client_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DataExportExportReportingDataResponse + Job status returned successfully + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.data_export.export_reporting_data( + job_identifier="job_identifier", + app_id="app_id", + client_id="client_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.export_reporting_data( + job_identifier, app_id=app_id, client_id=client_id, request_options=request_options + ) + return _response.data + + async def download_reporting_data_export( + self, job_identifier: str, *, app_id: str, request_options: typing.Optional[RequestOptions] = None + ) -> None: + """ + Parameters + ---------- + job_identifier : str + + app_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.data_export.download_reporting_data_export( + job_identifier="job_identifier", + app_id="app_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.download_reporting_data_export( + job_identifier, app_id=app_id, request_options=request_options + ) + return _response.data + async def create( self, *, created_at_after: int, created_at_before: int, request_options: typing.Optional[RequestOptions] = None ) -> DataExport: @@ -246,8 +421,8 @@ async def create( async def main() -> None: await client.data_export.create( - created_at_after=1719474967, - created_at_before=1719492967, + created_at_after=1734519776, + created_at_before=1734537776, ) diff --git a/src/intercom/data_export/raw_client.py b/src/intercom/data_export/raw_client.py index b58e193..36ffc4b 100644 --- a/src/intercom/data_export/raw_client.py +++ b/src/intercom/data_export/raw_client.py @@ -9,7 +9,9 @@ from ..core.jsonable_encoder import jsonable_encoder from ..core.request_options import RequestOptions from ..core.unchecked_base_model import construct_type +from ..errors.not_found_error import NotFoundError from .types.data_export import DataExport +from .types.data_export_export_reporting_data_response import DataExportExportReportingDataResponse # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -19,6 +21,112 @@ class RawDataExportClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper + def export_reporting_data( + self, + job_identifier: str, + *, + app_id: str, + client_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[DataExportExportReportingDataResponse]: + """ + Parameters + ---------- + job_identifier : str + Unique identifier of the job. + + app_id : str + The Intercom defined code of the workspace the company is associated to. + + client_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DataExportExportReportingDataResponse] + Job status returned successfully + """ + _response = self._client_wrapper.httpx_client.request( + f"export/reporting_data/{jsonable_encoder(job_identifier)}", + method="GET", + params={ + "app_id": app_id, + "client_id": client_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DataExportExportReportingDataResponse, + construct_type( + type_=DataExportExportReportingDataResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def download_reporting_data_export( + self, job_identifier: str, *, app_id: str, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[None]: + """ + Parameters + ---------- + job_identifier : str + + app_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[None] + """ + _response = self._client_wrapper.httpx_client.request( + f"download/reporting_data/{jsonable_encoder(job_identifier)}", + method="GET", + params={ + "app_id": app_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=None) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + def create( self, *, created_at_after: int, created_at_before: int, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[DataExport]: @@ -207,6 +315,112 @@ class AsyncRawDataExportClient: def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper + async def export_reporting_data( + self, + job_identifier: str, + *, + app_id: str, + client_id: str, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[DataExportExportReportingDataResponse]: + """ + Parameters + ---------- + job_identifier : str + Unique identifier of the job. + + app_id : str + The Intercom defined code of the workspace the company is associated to. + + client_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DataExportExportReportingDataResponse] + Job status returned successfully + """ + _response = await self._client_wrapper.httpx_client.request( + f"export/reporting_data/{jsonable_encoder(job_identifier)}", + method="GET", + params={ + "app_id": app_id, + "client_id": client_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DataExportExportReportingDataResponse, + construct_type( + type_=DataExportExportReportingDataResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def download_reporting_data_export( + self, job_identifier: str, *, app_id: str, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[None]: + """ + Parameters + ---------- + job_identifier : str + + app_id : str + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[None] + """ + _response = await self._client_wrapper.httpx_client.request( + f"download/reporting_data/{jsonable_encoder(job_identifier)}", + method="GET", + params={ + "app_id": app_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=None) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + async def create( self, *, created_at_after: int, created_at_before: int, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[DataExport]: diff --git a/src/intercom/data_export/types/__init__.py b/src/intercom/data_export/types/__init__.py index 6689b22..85cc72f 100644 --- a/src/intercom/data_export/types/__init__.py +++ b/src/intercom/data_export/types/__init__.py @@ -3,6 +3,7 @@ # isort: skip_file from .data_export import DataExport +from .data_export_export_reporting_data_response import DataExportExportReportingDataResponse from .data_export_status import DataExportStatus -__all__ = ["DataExport", "DataExportStatus"] +__all__ = ["DataExport", "DataExportExportReportingDataResponse", "DataExportStatus"] diff --git a/src/intercom/data_export/types/data_export.py b/src/intercom/data_export/types/data_export.py index 357e29e..adad4b0 100644 --- a/src/intercom/data_export/types/data_export.py +++ b/src/intercom/data_export/types/data_export.py @@ -13,22 +13,22 @@ class DataExport(UncheckedBaseModel): The data export api is used to view all message sent & viewed in a given timeframe. """ - job_identifier: str = pydantic.Field() + job_identfier: typing.Optional[str] = pydantic.Field(default=None) """ The identifier for your job. """ - status: DataExportStatus = pydantic.Field() + status: typing.Optional[DataExportStatus] = pydantic.Field(default=None) """ The current state of your job. """ - download_expires_at: str = pydantic.Field() + download_expires_at: typing.Optional[str] = pydantic.Field(default=None) """ The time after which you will not be able to access the data. """ - download_url: str = pydantic.Field() + download_url: typing.Optional[str] = pydantic.Field(default=None) """ The location where you can download your data. """ diff --git a/src/intercom/data_export/types/data_export_export_reporting_data_response.py b/src/intercom/data_export/types/data_export_export_reporting_data_response.py new file mode 100644 index 0000000..0a245c6 --- /dev/null +++ b/src/intercom/data_export/types/data_export_export_reporting_data_response.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class DataExportExportReportingDataResponse(UncheckedBaseModel): + job_identifier: typing.Optional[str] = None + status: typing.Optional[str] = None + download_url: typing.Optional[str] = None + download_expires_at: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/errors/__init__.py b/src/intercom/errors/__init__.py index 3b7a374..f72a312 100644 --- a/src/intercom/errors/__init__.py +++ b/src/intercom/errors/__init__.py @@ -5,7 +5,15 @@ from .bad_request_error import BadRequestError from .forbidden_error import ForbiddenError from .not_found_error import NotFoundError +from .too_many_requests_error import TooManyRequestsError from .unauthorized_error import UnauthorizedError from .unprocessable_entity_error import UnprocessableEntityError -__all__ = ["BadRequestError", "ForbiddenError", "NotFoundError", "UnauthorizedError", "UnprocessableEntityError"] +__all__ = [ + "BadRequestError", + "ForbiddenError", + "NotFoundError", + "TooManyRequestsError", + "UnauthorizedError", + "UnprocessableEntityError", +] diff --git a/src/intercom/errors/too_many_requests_error.py b/src/intercom/errors/too_many_requests_error.py new file mode 100644 index 0000000..a0743ee --- /dev/null +++ b/src/intercom/errors/too_many_requests_error.py @@ -0,0 +1,11 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.api_error import ApiError +from ..types.error import Error + + +class TooManyRequestsError(ApiError): + def __init__(self, body: Error, headers: typing.Optional[typing.Dict[str, str]] = None): + super().__init__(status_code=429, headers=headers, body=body) diff --git a/src/intercom/export/__init__.py b/src/intercom/export/__init__.py new file mode 100644 index 0000000..ae35bc3 --- /dev/null +++ b/src/intercom/export/__init__.py @@ -0,0 +1,17 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import ( + GetExportReportingDataGetDatasetsResponse, + GetExportReportingDataGetDatasetsResponseDataItem, + GetExportReportingDataGetDatasetsResponseDataItemAttributesItem, + PostExportReportingDataEnqueueResponse, +) + +__all__ = [ + "GetExportReportingDataGetDatasetsResponse", + "GetExportReportingDataGetDatasetsResponseDataItem", + "GetExportReportingDataGetDatasetsResponseDataItemAttributesItem", + "PostExportReportingDataEnqueueResponse", +] diff --git a/src/intercom/export/client.py b/src/intercom/export/client.py new file mode 100644 index 0000000..ffec252 --- /dev/null +++ b/src/intercom/export/client.py @@ -0,0 +1,214 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from .raw_client import AsyncRawExportClient, RawExportClient +from .types.get_export_reporting_data_get_datasets_response import GetExportReportingDataGetDatasetsResponse +from .types.post_export_reporting_data_enqueue_response import PostExportReportingDataEnqueueResponse + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class ExportClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawExportClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawExportClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawExportClient + """ + return self._raw_client + + def enqueue_a_new_reporting_data_export_job( + self, + *, + dataset_id: str, + attribute_ids: typing.Sequence[str], + start_time: int, + end_time: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> PostExportReportingDataEnqueueResponse: + """ + Parameters + ---------- + dataset_id : str + + attribute_ids : typing.Sequence[str] + + start_time : int + + end_time : int + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + PostExportReportingDataEnqueueResponse + Job enqueued successfully + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.export.enqueue_a_new_reporting_data_export_job( + dataset_id="conversation", + attribute_ids=["conversation_id", "conversation_started_at"], + start_time=1717490000, + end_time=1717510000, + ) + """ + _response = self._raw_client.enqueue_a_new_reporting_data_export_job( + dataset_id=dataset_id, + attribute_ids=attribute_ids, + start_time=start_time, + end_time=end_time, + request_options=request_options, + ) + return _response.data + + def list_available_datasets_and_attributes( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetExportReportingDataGetDatasetsResponse: + """ + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetExportReportingDataGetDatasetsResponse + List of datasets + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.export.list_available_datasets_and_attributes() + """ + _response = self._raw_client.list_available_datasets_and_attributes(request_options=request_options) + return _response.data + + +class AsyncExportClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawExportClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawExportClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawExportClient + """ + return self._raw_client + + async def enqueue_a_new_reporting_data_export_job( + self, + *, + dataset_id: str, + attribute_ids: typing.Sequence[str], + start_time: int, + end_time: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> PostExportReportingDataEnqueueResponse: + """ + Parameters + ---------- + dataset_id : str + + attribute_ids : typing.Sequence[str] + + start_time : int + + end_time : int + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + PostExportReportingDataEnqueueResponse + Job enqueued successfully + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.export.enqueue_a_new_reporting_data_export_job( + dataset_id="conversation", + attribute_ids=["conversation_id", "conversation_started_at"], + start_time=1717490000, + end_time=1717510000, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.enqueue_a_new_reporting_data_export_job( + dataset_id=dataset_id, + attribute_ids=attribute_ids, + start_time=start_time, + end_time=end_time, + request_options=request_options, + ) + return _response.data + + async def list_available_datasets_and_attributes( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> GetExportReportingDataGetDatasetsResponse: + """ + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + GetExportReportingDataGetDatasetsResponse + List of datasets + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.export.list_available_datasets_and_attributes() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_available_datasets_and_attributes(request_options=request_options) + return _response.data diff --git a/src/intercom/export/raw_client.py b/src/intercom/export/raw_client.py new file mode 100644 index 0000000..cc1a959 --- /dev/null +++ b/src/intercom/export/raw_client.py @@ -0,0 +1,279 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.request_options import RequestOptions +from ..core.unchecked_base_model import construct_type +from ..errors.bad_request_error import BadRequestError +from ..errors.too_many_requests_error import TooManyRequestsError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.error import Error +from .types.get_export_reporting_data_get_datasets_response import GetExportReportingDataGetDatasetsResponse +from .types.post_export_reporting_data_enqueue_response import PostExportReportingDataEnqueueResponse + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawExportClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def enqueue_a_new_reporting_data_export_job( + self, + *, + dataset_id: str, + attribute_ids: typing.Sequence[str], + start_time: int, + end_time: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[PostExportReportingDataEnqueueResponse]: + """ + Parameters + ---------- + dataset_id : str + + attribute_ids : typing.Sequence[str] + + start_time : int + + end_time : int + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[PostExportReportingDataEnqueueResponse] + Job enqueued successfully + """ + _response = self._client_wrapper.httpx_client.request( + "export/reporting_data/enqueue", + method="POST", + json={ + "dataset_id": dataset_id, + "attribute_ids": attribute_ids, + "start_time": start_time, + "end_time": end_time, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + PostExportReportingDataEnqueueResponse, + construct_type( + type_=PostExportReportingDataEnqueueResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def list_available_datasets_and_attributes( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[GetExportReportingDataGetDatasetsResponse]: + """ + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[GetExportReportingDataGetDatasetsResponse] + List of datasets + """ + _response = self._client_wrapper.httpx_client.request( + "export/reporting_data/get_datasets", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetExportReportingDataGetDatasetsResponse, + construct_type( + type_=GetExportReportingDataGetDatasetsResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawExportClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def enqueue_a_new_reporting_data_export_job( + self, + *, + dataset_id: str, + attribute_ids: typing.Sequence[str], + start_time: int, + end_time: int, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[PostExportReportingDataEnqueueResponse]: + """ + Parameters + ---------- + dataset_id : str + + attribute_ids : typing.Sequence[str] + + start_time : int + + end_time : int + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[PostExportReportingDataEnqueueResponse] + Job enqueued successfully + """ + _response = await self._client_wrapper.httpx_client.request( + "export/reporting_data/enqueue", + method="POST", + json={ + "dataset_id": dataset_id, + "attribute_ids": attribute_ids, + "start_time": start_time, + "end_time": end_time, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + PostExportReportingDataEnqueueResponse, + construct_type( + type_=PostExportReportingDataEnqueueResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def list_available_datasets_and_attributes( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[GetExportReportingDataGetDatasetsResponse]: + """ + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[GetExportReportingDataGetDatasetsResponse] + List of datasets + """ + _response = await self._client_wrapper.httpx_client.request( + "export/reporting_data/get_datasets", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + GetExportReportingDataGetDatasetsResponse, + construct_type( + type_=GetExportReportingDataGetDatasetsResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/export/types/__init__.py b/src/intercom/export/types/__init__.py new file mode 100644 index 0000000..8026b50 --- /dev/null +++ b/src/intercom/export/types/__init__.py @@ -0,0 +1,17 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .get_export_reporting_data_get_datasets_response import GetExportReportingDataGetDatasetsResponse +from .get_export_reporting_data_get_datasets_response_data_item import GetExportReportingDataGetDatasetsResponseDataItem +from .get_export_reporting_data_get_datasets_response_data_item_attributes_item import ( + GetExportReportingDataGetDatasetsResponseDataItemAttributesItem, +) +from .post_export_reporting_data_enqueue_response import PostExportReportingDataEnqueueResponse + +__all__ = [ + "GetExportReportingDataGetDatasetsResponse", + "GetExportReportingDataGetDatasetsResponseDataItem", + "GetExportReportingDataGetDatasetsResponseDataItemAttributesItem", + "PostExportReportingDataEnqueueResponse", +] diff --git a/src/intercom/export/types/get_export_reporting_data_get_datasets_response.py b/src/intercom/export/types/get_export_reporting_data_get_datasets_response.py new file mode 100644 index 0000000..b61cffc --- /dev/null +++ b/src/intercom/export/types/get_export_reporting_data_get_datasets_response.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .get_export_reporting_data_get_datasets_response_data_item import GetExportReportingDataGetDatasetsResponseDataItem + + +class GetExportReportingDataGetDatasetsResponse(UncheckedBaseModel): + type: typing.Optional[str] = None + data: typing.Optional[typing.List[GetExportReportingDataGetDatasetsResponseDataItem]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/export/types/get_export_reporting_data_get_datasets_response_data_item.py b/src/intercom/export/types/get_export_reporting_data_get_datasets_response_data_item.py new file mode 100644 index 0000000..206ba68 --- /dev/null +++ b/src/intercom/export/types/get_export_reporting_data_get_datasets_response_data_item.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .get_export_reporting_data_get_datasets_response_data_item_attributes_item import ( + GetExportReportingDataGetDatasetsResponseDataItemAttributesItem, +) + + +class GetExportReportingDataGetDatasetsResponseDataItem(UncheckedBaseModel): + id: typing.Optional[str] = None + name: typing.Optional[str] = None + description: typing.Optional[str] = None + default_time_attribute_id: typing.Optional[str] = None + attributes: typing.Optional[typing.List[GetExportReportingDataGetDatasetsResponseDataItemAttributesItem]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/admins/types/admin_avatar.py b/src/intercom/export/types/get_export_reporting_data_get_datasets_response_data_item_attributes_item.py similarity index 72% rename from src/intercom/admins/types/admin_avatar.py rename to src/intercom/export/types/get_export_reporting_data_get_datasets_response_data_item_attributes_item.py index 547330c..593af9d 100644 --- a/src/intercom/admins/types/admin_avatar.py +++ b/src/intercom/export/types/get_export_reporting_data_get_datasets_response_data_item_attributes_item.py @@ -7,15 +7,9 @@ from ...core.unchecked_base_model import UncheckedBaseModel -class AdminAvatar(UncheckedBaseModel): - """ - The avatar object associated with the admin - """ - - image_url: str = pydantic.Field() - """ - URL of the admin's avatar image - """ +class GetExportReportingDataGetDatasetsResponseDataItemAttributesItem(UncheckedBaseModel): + id: typing.Optional[str] = None + name: typing.Optional[str] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/intercom/export/types/post_export_reporting_data_enqueue_response.py b/src/intercom/export/types/post_export_reporting_data_enqueue_response.py new file mode 100644 index 0000000..5a6f7f1 --- /dev/null +++ b/src/intercom/export/types/post_export_reporting_data_enqueue_response.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class PostExportReportingDataEnqueueResponse(UncheckedBaseModel): + job_identifier: typing.Optional[str] = None + status: typing.Optional[str] = None + download_url: typing.Optional[str] = None + download_expires_at: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/help_center/types/help_center.py b/src/intercom/help_center/types/help_center.py index dfaa8f2..204d3b9 100644 --- a/src/intercom/help_center/types/help_center.py +++ b/src/intercom/help_center/types/help_center.py @@ -12,17 +12,17 @@ class HelpCenter(UncheckedBaseModel): Help Centers contain collections """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier for the Help Center which is given by Intercom. """ - workspace_id: str = pydantic.Field() + workspace_id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the workspace which the Help Center belongs to. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ The time when the Help Center was created. """ @@ -32,21 +32,31 @@ class HelpCenter(UncheckedBaseModel): The time when the Help Center was last updated. """ - identifier: str = pydantic.Field() + identifier: typing.Optional[str] = pydantic.Field(default=None) """ The identifier of the Help Center. This is used in the URL of the Help Center. """ - website_turned_on: bool = pydantic.Field() + website_turned_on: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the Help Center is turned on or not. This is controlled in your Help Center settings. """ - display_name: str = pydantic.Field() + display_name: typing.Optional[str] = pydantic.Field(default=None) """ The display name of the Help Center only seen by teammates. """ + url: typing.Optional[str] = pydantic.Field(default=None) + """ + The URL for the help center, if you have a custom domain then this will show the URL using the custom domain. + """ + + custom_domain: typing.Optional[str] = pydantic.Field(default=None) + """ + Custom domain configured for the help center + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/help_center/types/help_center_list.py b/src/intercom/help_center/types/help_center_list.py index 8dbd44f..2e74669 100644 --- a/src/intercom/help_center/types/help_center_list.py +++ b/src/intercom/help_center/types/help_center_list.py @@ -13,12 +13,12 @@ class HelpCenterList(UncheckedBaseModel): A list of Help Centers belonging to the App """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of the object - `list`. """ - data: typing.List[HelpCenter] = pydantic.Field() + data: typing.Optional[typing.List[HelpCenter]] = pydantic.Field(default=None) """ An array of Help Center objects """ diff --git a/src/intercom/help_centers/client.py b/src/intercom/help_centers/client.py index 2563f0b..b4227b5 100644 --- a/src/intercom/help_centers/client.py +++ b/src/intercom/help_centers/client.py @@ -26,14 +26,14 @@ def with_raw_response(self) -> RawHelpCentersClient: """ return self._raw_client - def find(self, help_center_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HelpCenter: + def find(self, help_center_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> HelpCenter: """ You can fetch the details of a single Help Center by making a GET request to `https://api.intercom.io/help_center/help_center/`. Parameters ---------- - help_center_id : str - The unique identifier for the Help Center which is given by Intercom. + help_center_id : int + The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -51,7 +51,7 @@ def find(self, help_center_id: str, *, request_options: typing.Optional[RequestO token="YOUR_TOKEN", ) client.help_centers.find( - help_center_id="123", + help_center_id=1, ) """ _response = self._raw_client.find(help_center_id, request_options=request_options) @@ -116,14 +116,14 @@ def with_raw_response(self) -> AsyncRawHelpCentersClient: """ return self._raw_client - async def find(self, help_center_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HelpCenter: + async def find(self, help_center_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> HelpCenter: """ You can fetch the details of a single Help Center by making a GET request to `https://api.intercom.io/help_center/help_center/`. Parameters ---------- - help_center_id : str - The unique identifier for the Help Center which is given by Intercom. + help_center_id : int + The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -146,7 +146,7 @@ async def find(self, help_center_id: str, *, request_options: typing.Optional[Re async def main() -> None: await client.help_centers.find( - help_center_id="123", + help_center_id=1, ) diff --git a/src/intercom/help_centers/collections/client.py b/src/intercom/help_centers/collections/client.py index f7b7c7e..e0d0d90 100644 --- a/src/intercom/help_centers/collections/client.py +++ b/src/intercom/help_centers/collections/client.py @@ -131,13 +131,13 @@ def create( ) return _response.data - def find(self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Collection: + def find(self, collection_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> Collection: """ You can fetch the details of a single collection by making a GET request to `https://api.intercom.io/help_center/collections/`. Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -156,7 +156,7 @@ def find(self, collection_id: str, *, request_options: typing.Optional[RequestOp token="YOUR_TOKEN", ) client.help_centers.collections.find( - collection_id="123", + collection_id=1, ) """ _response = self._raw_client.find(collection_id, request_options=request_options) @@ -164,7 +164,7 @@ def find(self, collection_id: str, *, request_options: typing.Optional[RequestOp def update( self, - collection_id: str, + collection_id: int, *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, @@ -177,7 +177,7 @@ def update( Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. name : typing.Optional[str] @@ -207,7 +207,7 @@ def update( token="YOUR_TOKEN", ) client.help_centers.collections.update( - collection_id="123", + collection_id=1, name="Update collection name", ) """ @@ -222,14 +222,14 @@ def update( return _response.data def delete( - self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, collection_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> DeletedCollectionObject: """ You can delete a single collection by making a DELETE request to `https://api.intercom.io/collections/`. Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -248,7 +248,7 @@ def delete( token="YOUR_TOKEN", ) client.help_centers.collections.delete( - collection_id="123", + collection_id=1, ) """ _response = self._raw_client.delete(collection_id, request_options=request_options) @@ -389,13 +389,13 @@ async def main() -> None: ) return _response.data - async def find(self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Collection: + async def find(self, collection_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> Collection: """ You can fetch the details of a single collection by making a GET request to `https://api.intercom.io/help_center/collections/`. Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -419,7 +419,7 @@ async def find(self, collection_id: str, *, request_options: typing.Optional[Req async def main() -> None: await client.help_centers.collections.find( - collection_id="123", + collection_id=1, ) @@ -430,7 +430,7 @@ async def main() -> None: async def update( self, - collection_id: str, + collection_id: int, *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, @@ -443,7 +443,7 @@ async def update( Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. name : typing.Optional[str] @@ -478,7 +478,7 @@ async def update( async def main() -> None: await client.help_centers.collections.update( - collection_id="123", + collection_id=1, name="Update collection name", ) @@ -496,14 +496,14 @@ async def main() -> None: return _response.data async def delete( - self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, collection_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> DeletedCollectionObject: """ You can delete a single collection by making a DELETE request to `https://api.intercom.io/collections/`. Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -527,7 +527,7 @@ async def delete( async def main() -> None: await client.help_centers.collections.delete( - collection_id="123", + collection_id=1, ) diff --git a/src/intercom/help_centers/collections/raw_client.py b/src/intercom/help_centers/collections/raw_client.py index 98fed1c..409ad67 100644 --- a/src/intercom/help_centers/collections/raw_client.py +++ b/src/intercom/help_centers/collections/raw_client.py @@ -195,14 +195,14 @@ def create( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def find( - self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, collection_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[Collection]: """ You can fetch the details of a single collection by making a GET request to `https://api.intercom.io/help_center/collections/`. Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -257,7 +257,7 @@ def find( def update( self, - collection_id: str, + collection_id: int, *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, @@ -270,7 +270,7 @@ def update( Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. name : typing.Optional[str] @@ -347,14 +347,14 @@ def update( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def delete( - self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, collection_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[DeletedCollectionObject]: """ You can delete a single collection by making a DELETE request to `https://api.intercom.io/collections/`. Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -582,14 +582,14 @@ async def create( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def find( - self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, collection_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[Collection]: """ You can fetch the details of a single collection by making a GET request to `https://api.intercom.io/help_center/collections/`. Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -644,7 +644,7 @@ async def find( async def update( self, - collection_id: str, + collection_id: int, *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, @@ -657,7 +657,7 @@ async def update( Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. name : typing.Optional[str] @@ -734,14 +734,14 @@ async def update( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def delete( - self, collection_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, collection_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[DeletedCollectionObject]: """ You can delete a single collection by making a DELETE request to `https://api.intercom.io/collections/`. Parameters ---------- - collection_id : str + collection_id : int The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] diff --git a/src/intercom/help_centers/raw_client.py b/src/intercom/help_centers/raw_client.py index 165c20c..cd42797 100644 --- a/src/intercom/help_centers/raw_client.py +++ b/src/intercom/help_centers/raw_client.py @@ -22,15 +22,15 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper def find( - self, help_center_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, help_center_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[HelpCenter]: """ You can fetch the details of a single Help Center by making a GET request to `https://api.intercom.io/help_center/help_center/`. Parameters ---------- - help_center_id : str - The unique identifier for the Help Center which is given by Intercom. + help_center_id : int + The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -160,15 +160,15 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper async def find( - self, help_center_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, help_center_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[HelpCenter]: """ You can fetch the details of a single Help Center by making a GET request to `https://api.intercom.io/help_center/help_center/`. Parameters ---------- - help_center_id : str - The unique identifier for the Help Center which is given by Intercom. + help_center_id : int + The unique identifier for the collection which is given by Intercom. request_options : typing.Optional[RequestOptions] Request-specific configuration. diff --git a/src/intercom/internal_articles/__init__.py b/src/intercom/internal_articles/__init__.py new file mode 100644 index 0000000..7c622b6 --- /dev/null +++ b/src/intercom/internal_articles/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import InternalArticleListItem, InternalArticleSearchResponse, InternalArticleSearchResponseData + +__all__ = ["InternalArticleListItem", "InternalArticleSearchResponse", "InternalArticleSearchResponseData"] diff --git a/src/intercom/internal_articles/client.py b/src/intercom/internal_articles/client.py new file mode 100644 index 0000000..c697e2b --- /dev/null +++ b/src/intercom/internal_articles/client.py @@ -0,0 +1,549 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..articles.types.internal_article import InternalArticle +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.create_internal_article_request import CreateInternalArticleRequest +from ..types.deleted_internal_article_object import DeletedInternalArticleObject +from ..types.internal_article_list import InternalArticleList +from .raw_client import AsyncRawInternalArticlesClient, RawInternalArticlesClient +from .types.internal_article_search_response import InternalArticleSearchResponse + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class InternalArticlesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawInternalArticlesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawInternalArticlesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawInternalArticlesClient + """ + return self._raw_client + + def list_internal_articles(self, *, request_options: typing.Optional[RequestOptions] = None) -> InternalArticleList: + """ + You can fetch a list of all internal articles by making a GET request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticleList + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.internal_articles.list_internal_articles() + """ + _response = self._raw_client.list_internal_articles(request_options=request_options) + return _response.data + + def create_internal_article( + self, + *, + request: typing.Optional[CreateInternalArticleRequest] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> InternalArticle: + """ + You can create a new internal article by making a POST request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request : typing.Optional[CreateInternalArticleRequest] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + internal article created + + Examples + -------- + from intercom import CreateInternalArticleRequest, Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.internal_articles.create_internal_article( + request=CreateInternalArticleRequest( + title="Thanks for everything", + body="Body of the Article", + author_id=991266252, + owner_id=991266252, + ), + ) + """ + _response = self._raw_client.create_internal_article(request=request, request_options=request_options) + return _response.data + + def retrieve_internal_article( + self, internal_article_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> InternalArticle: + """ + You can fetch the details of a single internal article by making a GET request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + Internal article found + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.internal_articles.retrieve_internal_article( + internal_article_id=1, + ) + """ + _response = self._raw_client.retrieve_internal_article(internal_article_id, request_options=request_options) + return _response.data + + def update_internal_article( + self, + internal_article_id: int, + *, + title: typing.Optional[str] = OMIT, + body: typing.Optional[str] = OMIT, + author_id: typing.Optional[int] = OMIT, + owner_id: typing.Optional[int] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> InternalArticle: + """ + You can update the details of a single internal article by making a PUT request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the internal article which is given by Intercom. + + title : typing.Optional[str] + The title of the article. + + body : typing.Optional[str] + The content of the article. + + author_id : typing.Optional[int] + The id of the author of the article. + + owner_id : typing.Optional[int] + The id of the author of the article. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.internal_articles.update_internal_article( + internal_article_id=1, + title="Christmas is here!", + body="

New gifts in store for the jolly season

", + ) + """ + _response = self._raw_client.update_internal_article( + internal_article_id, + title=title, + body=body, + author_id=author_id, + owner_id=owner_id, + request_options=request_options, + ) + return _response.data + + def delete_internal_article( + self, internal_article_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> DeletedInternalArticleObject: + """ + You can delete a single internal article by making a DELETE request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the internal article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeletedInternalArticleObject + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.internal_articles.delete_internal_article( + internal_article_id=1, + ) + """ + _response = self._raw_client.delete_internal_article(internal_article_id, request_options=request_options) + return _response.data + + def search_internal_articles( + self, *, folder_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> InternalArticleSearchResponse: + """ + You can search for internal articles by making a GET request to `https://api.intercom.io/internal_articles/search`. + + Parameters + ---------- + folder_id : typing.Optional[str] + The ID of the folder to search in. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticleSearchResponse + Search successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.internal_articles.search_internal_articles() + """ + _response = self._raw_client.search_internal_articles(folder_id=folder_id, request_options=request_options) + return _response.data + + +class AsyncInternalArticlesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawInternalArticlesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawInternalArticlesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawInternalArticlesClient + """ + return self._raw_client + + async def list_internal_articles( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> InternalArticleList: + """ + You can fetch a list of all internal articles by making a GET request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticleList + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.internal_articles.list_internal_articles() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_internal_articles(request_options=request_options) + return _response.data + + async def create_internal_article( + self, + *, + request: typing.Optional[CreateInternalArticleRequest] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> InternalArticle: + """ + You can create a new internal article by making a POST request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request : typing.Optional[CreateInternalArticleRequest] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + internal article created + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom, CreateInternalArticleRequest + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.internal_articles.create_internal_article( + request=CreateInternalArticleRequest( + title="Thanks for everything", + body="Body of the Article", + author_id=991266252, + owner_id=991266252, + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_internal_article(request=request, request_options=request_options) + return _response.data + + async def retrieve_internal_article( + self, internal_article_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> InternalArticle: + """ + You can fetch the details of a single internal article by making a GET request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + Internal article found + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.internal_articles.retrieve_internal_article( + internal_article_id=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.retrieve_internal_article( + internal_article_id, request_options=request_options + ) + return _response.data + + async def update_internal_article( + self, + internal_article_id: int, + *, + title: typing.Optional[str] = OMIT, + body: typing.Optional[str] = OMIT, + author_id: typing.Optional[int] = OMIT, + owner_id: typing.Optional[int] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> InternalArticle: + """ + You can update the details of a single internal article by making a PUT request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the internal article which is given by Intercom. + + title : typing.Optional[str] + The title of the article. + + body : typing.Optional[str] + The content of the article. + + author_id : typing.Optional[int] + The id of the author of the article. + + owner_id : typing.Optional[int] + The id of the author of the article. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.internal_articles.update_internal_article( + internal_article_id=1, + title="Christmas is here!", + body="

New gifts in store for the jolly season

", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update_internal_article( + internal_article_id, + title=title, + body=body, + author_id=author_id, + owner_id=owner_id, + request_options=request_options, + ) + return _response.data + + async def delete_internal_article( + self, internal_article_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> DeletedInternalArticleObject: + """ + You can delete a single internal article by making a DELETE request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the internal article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeletedInternalArticleObject + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.internal_articles.delete_internal_article( + internal_article_id=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_internal_article(internal_article_id, request_options=request_options) + return _response.data + + async def search_internal_articles( + self, *, folder_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> InternalArticleSearchResponse: + """ + You can search for internal articles by making a GET request to `https://api.intercom.io/internal_articles/search`. + + Parameters + ---------- + folder_id : typing.Optional[str] + The ID of the folder to search in. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticleSearchResponse + Search successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.internal_articles.search_internal_articles() + + + asyncio.run(main()) + """ + _response = await self._raw_client.search_internal_articles( + folder_id=folder_id, request_options=request_options + ) + return _response.data diff --git a/src/intercom/internal_articles/raw_client.py b/src/intercom/internal_articles/raw_client.py new file mode 100644 index 0000000..19f4d2b --- /dev/null +++ b/src/intercom/internal_articles/raw_client.py @@ -0,0 +1,798 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..articles.types.internal_article import InternalArticle +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.jsonable_encoder import jsonable_encoder +from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata +from ..core.unchecked_base_model import construct_type +from ..errors.bad_request_error import BadRequestError +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.create_internal_article_request import CreateInternalArticleRequest +from ..types.deleted_internal_article_object import DeletedInternalArticleObject +from ..types.error import Error +from ..types.internal_article_list import InternalArticleList +from .types.internal_article_search_response import InternalArticleSearchResponse + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawInternalArticlesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_internal_articles( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[InternalArticleList]: + """ + You can fetch a list of all internal articles by making a GET request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[InternalArticleList] + successful + """ + _response = self._client_wrapper.httpx_client.request( + "internal_articles", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticleList, + construct_type( + type_=InternalArticleList, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def create_internal_article( + self, + *, + request: typing.Optional[CreateInternalArticleRequest] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[InternalArticle]: + """ + You can create a new internal article by making a POST request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request : typing.Optional[CreateInternalArticleRequest] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[InternalArticle] + internal article created + """ + _response = self._client_wrapper.httpx_client.request( + "internal_articles", + method="POST", + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateInternalArticleRequest, direction="write" + ), + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def retrieve_internal_article( + self, internal_article_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[InternalArticle]: + """ + You can fetch the details of a single internal article by making a GET request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[InternalArticle] + Internal article found + """ + _response = self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(internal_article_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def update_internal_article( + self, + internal_article_id: int, + *, + title: typing.Optional[str] = OMIT, + body: typing.Optional[str] = OMIT, + author_id: typing.Optional[int] = OMIT, + owner_id: typing.Optional[int] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[InternalArticle]: + """ + You can update the details of a single internal article by making a PUT request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the internal article which is given by Intercom. + + title : typing.Optional[str] + The title of the article. + + body : typing.Optional[str] + The content of the article. + + author_id : typing.Optional[int] + The id of the author of the article. + + owner_id : typing.Optional[int] + The id of the author of the article. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[InternalArticle] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(internal_article_id)}", + method="PUT", + json={ + "title": title, + "body": body, + "author_id": author_id, + "owner_id": owner_id, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def delete_internal_article( + self, internal_article_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[DeletedInternalArticleObject]: + """ + You can delete a single internal article by making a DELETE request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the internal article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeletedInternalArticleObject] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(internal_article_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeletedInternalArticleObject, + construct_type( + type_=DeletedInternalArticleObject, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def search_internal_articles( + self, *, folder_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[InternalArticleSearchResponse]: + """ + You can search for internal articles by making a GET request to `https://api.intercom.io/internal_articles/search`. + + Parameters + ---------- + folder_id : typing.Optional[str] + The ID of the folder to search in. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[InternalArticleSearchResponse] + Search successful + """ + _response = self._client_wrapper.httpx_client.request( + "internal_articles/search", + method="GET", + params={ + "folder_id": folder_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticleSearchResponse, + construct_type( + type_=InternalArticleSearchResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawInternalArticlesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_internal_articles( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[InternalArticleList]: + """ + You can fetch a list of all internal articles by making a GET request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[InternalArticleList] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + "internal_articles", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticleList, + construct_type( + type_=InternalArticleList, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def create_internal_article( + self, + *, + request: typing.Optional[CreateInternalArticleRequest] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[InternalArticle]: + """ + You can create a new internal article by making a POST request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request : typing.Optional[CreateInternalArticleRequest] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[InternalArticle] + internal article created + """ + _response = await self._client_wrapper.httpx_client.request( + "internal_articles", + method="POST", + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateInternalArticleRequest, direction="write" + ), + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def retrieve_internal_article( + self, internal_article_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[InternalArticle]: + """ + You can fetch the details of a single internal article by making a GET request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[InternalArticle] + Internal article found + """ + _response = await self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(internal_article_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def update_internal_article( + self, + internal_article_id: int, + *, + title: typing.Optional[str] = OMIT, + body: typing.Optional[str] = OMIT, + author_id: typing.Optional[int] = OMIT, + owner_id: typing.Optional[int] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[InternalArticle]: + """ + You can update the details of a single internal article by making a PUT request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the internal article which is given by Intercom. + + title : typing.Optional[str] + The title of the article. + + body : typing.Optional[str] + The content of the article. + + author_id : typing.Optional[int] + The id of the author of the article. + + owner_id : typing.Optional[int] + The id of the author of the article. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[InternalArticle] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(internal_article_id)}", + method="PUT", + json={ + "title": title, + "body": body, + "author_id": author_id, + "owner_id": owner_id, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def delete_internal_article( + self, internal_article_id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[DeletedInternalArticleObject]: + """ + You can delete a single internal article by making a DELETE request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + internal_article_id : int + The unique identifier for the internal article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeletedInternalArticleObject] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(internal_article_id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeletedInternalArticleObject, + construct_type( + type_=DeletedInternalArticleObject, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def search_internal_articles( + self, *, folder_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[InternalArticleSearchResponse]: + """ + You can search for internal articles by making a GET request to `https://api.intercom.io/internal_articles/search`. + + Parameters + ---------- + folder_id : typing.Optional[str] + The ID of the folder to search in. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[InternalArticleSearchResponse] + Search successful + """ + _response = await self._client_wrapper.httpx_client.request( + "internal_articles/search", + method="GET", + params={ + "folder_id": folder_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticleSearchResponse, + construct_type( + type_=InternalArticleSearchResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/internal_articles/types/__init__.py b/src/intercom/internal_articles/types/__init__.py new file mode 100644 index 0000000..23336f7 --- /dev/null +++ b/src/intercom/internal_articles/types/__init__.py @@ -0,0 +1,9 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .internal_article_list_item import InternalArticleListItem +from .internal_article_search_response import InternalArticleSearchResponse +from .internal_article_search_response_data import InternalArticleSearchResponseData + +__all__ = ["InternalArticleListItem", "InternalArticleSearchResponse", "InternalArticleSearchResponseData"] diff --git a/src/intercom/internal_articles/types/internal_article_list_item.py b/src/intercom/internal_articles/types/internal_article_list_item.py new file mode 100644 index 0000000..1abf2d6 --- /dev/null +++ b/src/intercom/internal_articles/types/internal_article_list_item.py @@ -0,0 +1,67 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class InternalArticleListItem(UncheckedBaseModel): + """ + The data returned about your internal articles when you list them. + """ + + type: typing.Optional[typing.Literal["internal_article"]] = pydantic.Field(default=None) + """ + The type of object - `internal_article`. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier for the article which is given by Intercom. + """ + + title: typing.Optional[str] = pydantic.Field(default=None) + """ + The title of the article. + """ + + body: typing.Optional[str] = pydantic.Field(default=None) + """ + The body of the article in HTML. + """ + + owner_id: typing.Optional[int] = pydantic.Field(default=None) + """ + The id of the owner of the article. + """ + + author_id: typing.Optional[int] = pydantic.Field(default=None) + """ + The id of the author of the article. + """ + + created_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time when the article was created. + """ + + updated_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time when the article was last updated. + """ + + locale: typing.Optional[str] = pydantic.Field(default=None) + """ + The default locale of the article. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/internal_articles/types/internal_article_search_response.py b/src/intercom/internal_articles/types/internal_article_search_response.py new file mode 100644 index 0000000..427225d --- /dev/null +++ b/src/intercom/internal_articles/types/internal_article_search_response.py @@ -0,0 +1,41 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from ...types.cursor_pages import CursorPages +from .internal_article_search_response_data import InternalArticleSearchResponseData + + +class InternalArticleSearchResponse(UncheckedBaseModel): + """ + The results of an Internal Article search + """ + + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) + """ + The type of the object - `list`. + """ + + total_count: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of Internal Articles matching the search query + """ + + data: typing.Optional[InternalArticleSearchResponseData] = pydantic.Field(default=None) + """ + An object containing the results of the search. + """ + + pages: typing.Optional[CursorPages] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/tickets/types/update_ticket_request_assignment.py b/src/intercom/internal_articles/types/internal_article_search_response_data.py similarity index 61% rename from src/intercom/tickets/types/update_ticket_request_assignment.py rename to src/intercom/internal_articles/types/internal_article_search_response_data.py index b088f80..3fa1f4f 100644 --- a/src/intercom/tickets/types/update_ticket_request_assignment.py +++ b/src/intercom/internal_articles/types/internal_article_search_response_data.py @@ -3,19 +3,19 @@ import typing import pydantic +from ...articles.types.internal_article import InternalArticle from ...core.pydantic_utilities import IS_PYDANTIC_V2 from ...core.unchecked_base_model import UncheckedBaseModel -class UpdateTicketRequestAssignment(UncheckedBaseModel): - admin_id: typing.Optional[str] = pydantic.Field(default=None) +class InternalArticleSearchResponseData(UncheckedBaseModel): """ - The ID of the admin performing the action. + An object containing the results of the search. """ - assignee_id: typing.Optional[str] = pydantic.Field(default=None) + internal_articles: typing.Optional[typing.List[InternalArticle]] = pydantic.Field(default=None) """ - The ID of the admin or team to which the ticket is assigned. Set this 0 to unassign it. + An array of Internal Article objects """ if IS_PYDANTIC_V2: diff --git a/src/intercom/jobs/__init__.py b/src/intercom/jobs/__init__.py new file mode 100644 index 0000000..f921dea --- /dev/null +++ b/src/intercom/jobs/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import Jobs, JobsStatus + +__all__ = ["Jobs", "JobsStatus"] diff --git a/src/intercom/jobs/client.py b/src/intercom/jobs/client.py new file mode 100644 index 0000000..e52d103 --- /dev/null +++ b/src/intercom/jobs/client.py @@ -0,0 +1,110 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from .raw_client import AsyncRawJobsClient, RawJobsClient +from .types.jobs import Jobs + + +class JobsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawJobsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawJobsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawJobsClient + """ + return self._raw_client + + def status(self, job_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Jobs: + """ + Retrieve the status of job execution. + + Parameters + ---------- + job_id : str + The unique identifier for the job which is given by Intercom + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Jobs + Job execution status + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.jobs.status( + job_id="job_id", + ) + """ + _response = self._raw_client.status(job_id, request_options=request_options) + return _response.data + + +class AsyncJobsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawJobsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawJobsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawJobsClient + """ + return self._raw_client + + async def status(self, job_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Jobs: + """ + Retrieve the status of job execution. + + Parameters + ---------- + job_id : str + The unique identifier for the job which is given by Intercom + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Jobs + Job execution status + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.jobs.status( + job_id="job_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.status(job_id, request_options=request_options) + return _response.data diff --git a/src/intercom/jobs/raw_client.py b/src/intercom/jobs/raw_client.py new file mode 100644 index 0000000..8e829ae --- /dev/null +++ b/src/intercom/jobs/raw_client.py @@ -0,0 +1,145 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.jsonable_encoder import jsonable_encoder +from ..core.request_options import RequestOptions +from ..core.unchecked_base_model import construct_type +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.error import Error +from .types.jobs import Jobs + + +class RawJobsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def status(self, job_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Jobs]: + """ + Retrieve the status of job execution. + + Parameters + ---------- + job_id : str + The unique identifier for the job which is given by Intercom + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Jobs] + Job execution status + """ + _response = self._client_wrapper.httpx_client.request( + f"jobs/status/{jsonable_encoder(job_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Jobs, + construct_type( + type_=Jobs, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawJobsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def status( + self, job_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[Jobs]: + """ + Retrieve the status of job execution. + + Parameters + ---------- + job_id : str + The unique identifier for the job which is given by Intercom + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Jobs] + Job execution status + """ + _response = await self._client_wrapper.httpx_client.request( + f"jobs/status/{jsonable_encoder(job_id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Jobs, + construct_type( + type_=Jobs, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/jobs/types/__init__.py b/src/intercom/jobs/types/__init__.py new file mode 100644 index 0000000..e980d4e --- /dev/null +++ b/src/intercom/jobs/types/__init__.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .jobs import Jobs +from .jobs_status import JobsStatus + +__all__ = ["Jobs", "JobsStatus"] diff --git a/src/intercom/jobs/types/jobs.py b/src/intercom/jobs/types/jobs.py new file mode 100644 index 0000000..1654a66 --- /dev/null +++ b/src/intercom/jobs/types/jobs.py @@ -0,0 +1,58 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .jobs_status import JobsStatus + + +class Jobs(UncheckedBaseModel): + """ + Jobs are tasks that are processed asynchronously by the Intercom system after being enqueued via the API. This allows for efficient handling of operations that may take time to complete, such as data imports or exports. You can check the status of your jobs to monitor their progress and ensure they are completed successfully. + """ + + type: typing.Optional[typing.Literal["job"]] = pydantic.Field(default=None) + """ + The type of the object + """ + + id: str = pydantic.Field() + """ + The id of the job that's currently being processed or has completed. + """ + + url: typing.Optional[str] = pydantic.Field(default=None) + """ + API endpoint URL to check the job status. + """ + + status: typing.Optional[JobsStatus] = pydantic.Field(default=None) + """ + The status of the job execution. + """ + + resource_type: typing.Optional[str] = pydantic.Field(default=None) + """ + The type of resource created during job execution. + """ + + resource_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the resource created during job execution (e.g. ticket id) + """ + + resource_url: typing.Optional[str] = pydantic.Field(default=None) + """ + The url of the resource created during job exeuction. Use this url to fetch the resource. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/jobs/types/jobs_status.py b/src/intercom/jobs/types/jobs_status.py new file mode 100644 index 0000000..e2b915a --- /dev/null +++ b/src/intercom/jobs/types/jobs_status.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +JobsStatus = typing.Union[typing.Literal["pending", "success", "failed"], typing.Any] diff --git a/src/intercom/messages/client.py b/src/intercom/messages/client.py index c57e93c..4fe8bbc 100644 --- a/src/intercom/messages/client.py +++ b/src/intercom/messages/client.py @@ -28,7 +28,10 @@ def with_raw_response(self) -> RawMessagesClient: return self._raw_client def create( - self, *, request: CreateMessageRequest, request_options: typing.Optional[RequestOptions] = None + self, + *, + request: typing.Optional[CreateMessageRequest] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> Message: """ You can create a message that has been initiated by an admin. The conversation can be either an in-app message or an email. @@ -45,7 +48,7 @@ def create( Parameters ---------- - request : CreateMessageRequest + request : typing.Optional[CreateMessageRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -102,7 +105,10 @@ def with_raw_response(self) -> AsyncRawMessagesClient: return self._raw_client async def create( - self, *, request: CreateMessageRequest, request_options: typing.Optional[RequestOptions] = None + self, + *, + request: typing.Optional[CreateMessageRequest] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> Message: """ You can create a message that has been initiated by an admin. The conversation can be either an in-app message or an email. @@ -119,7 +125,7 @@ async def create( Parameters ---------- - request : CreateMessageRequest + request : typing.Optional[CreateMessageRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. diff --git a/src/intercom/messages/raw_client.py b/src/intercom/messages/raw_client.py index e8e1498..5040570 100644 --- a/src/intercom/messages/raw_client.py +++ b/src/intercom/messages/raw_client.py @@ -26,7 +26,10 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper def create( - self, *, request: CreateMessageRequest, request_options: typing.Optional[RequestOptions] = None + self, + *, + request: typing.Optional[CreateMessageRequest] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Message]: """ You can create a message that has been initiated by an admin. The conversation can be either an in-app message or an email. @@ -43,7 +46,7 @@ def create( Parameters ---------- - request : CreateMessageRequest + request : typing.Optional[CreateMessageRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -130,7 +133,10 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper async def create( - self, *, request: CreateMessageRequest, request_options: typing.Optional[RequestOptions] = None + self, + *, + request: typing.Optional[CreateMessageRequest] = None, + request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Message]: """ You can create a message that has been initiated by an admin. The conversation can be either an in-app message or an email. @@ -147,7 +153,7 @@ async def create( Parameters ---------- - request : CreateMessageRequest + request : typing.Optional[CreateMessageRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. diff --git a/src/intercom/messages/types/message.py b/src/intercom/messages/types/message.py index 9add7f8..289ece7 100644 --- a/src/intercom/messages/types/message.py +++ b/src/intercom/messages/types/message.py @@ -28,7 +28,7 @@ class Message(UncheckedBaseModel): The time the conversation was created. """ - subject: str = pydantic.Field() + subject: typing.Optional[str] = pydantic.Field(default=None) """ The subject of the message. Only present if message_type: email. """ @@ -43,7 +43,7 @@ class Message(UncheckedBaseModel): The type of message that was sent. Can be email, inapp, facebook or twitter. """ - conversation_id: str = pydantic.Field() + conversation_id: typing.Optional[str] = pydantic.Field(default=None) """ The associated conversation_id """ diff --git a/src/intercom/news/feeds/client.py b/src/intercom/news/feeds/client.py index 766b576..83cff99 100644 --- a/src/intercom/news/feeds/client.py +++ b/src/intercom/news/feeds/client.py @@ -4,8 +4,7 @@ from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ...core.request_options import RequestOptions -from ...types.paginated_news_item_response import PaginatedNewsItemResponse -from ...types.paginated_newsfeed_response import PaginatedNewsfeedResponse +from ...types.paginated_response import PaginatedResponse from ..types.newsfeed import Newsfeed from .raw_client import AsyncRawFeedsClient, RawFeedsClient @@ -27,7 +26,7 @@ def with_raw_response(self) -> RawFeedsClient: def list_items( self, newsfeed_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> PaginatedNewsItemResponse: + ) -> PaginatedResponse: """ You can fetch a list of all news items that are live on a given newsfeed @@ -41,7 +40,7 @@ def list_items( Returns ------- - PaginatedNewsItemResponse + PaginatedResponse successful Examples @@ -58,7 +57,7 @@ def list_items( _response = self._raw_client.list_items(newsfeed_id, request_options=request_options) return _response.data - def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> PaginatedNewsfeedResponse: + def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> PaginatedResponse: """ You can fetch a list of all newsfeeds @@ -69,7 +68,7 @@ def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> Pa Returns ------- - PaginatedNewsfeedResponse + PaginatedResponse successful Examples @@ -133,7 +132,7 @@ def with_raw_response(self) -> AsyncRawFeedsClient: async def list_items( self, newsfeed_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> PaginatedNewsItemResponse: + ) -> PaginatedResponse: """ You can fetch a list of all news items that are live on a given newsfeed @@ -147,7 +146,7 @@ async def list_items( Returns ------- - PaginatedNewsItemResponse + PaginatedResponse successful Examples @@ -172,7 +171,7 @@ async def main() -> None: _response = await self._raw_client.list_items(newsfeed_id, request_options=request_options) return _response.data - async def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> PaginatedNewsfeedResponse: + async def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> PaginatedResponse: """ You can fetch a list of all newsfeeds @@ -183,7 +182,7 @@ async def list(self, *, request_options: typing.Optional[RequestOptions] = None) Returns ------- - PaginatedNewsfeedResponse + PaginatedResponse successful Examples diff --git a/src/intercom/news/feeds/raw_client.py b/src/intercom/news/feeds/raw_client.py index 5561a19..6f422e8 100644 --- a/src/intercom/news/feeds/raw_client.py +++ b/src/intercom/news/feeds/raw_client.py @@ -11,8 +11,7 @@ from ...core.unchecked_base_model import construct_type from ...errors.unauthorized_error import UnauthorizedError from ...types.error import Error -from ...types.paginated_news_item_response import PaginatedNewsItemResponse -from ...types.paginated_newsfeed_response import PaginatedNewsfeedResponse +from ...types.paginated_response import PaginatedResponse from ..types.newsfeed import Newsfeed @@ -22,7 +21,7 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def list_items( self, newsfeed_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[PaginatedNewsItemResponse]: + ) -> HttpResponse[PaginatedResponse]: """ You can fetch a list of all news items that are live on a given newsfeed @@ -36,7 +35,7 @@ def list_items( Returns ------- - HttpResponse[PaginatedNewsItemResponse] + HttpResponse[PaginatedResponse] successful """ _response = self._client_wrapper.httpx_client.request( @@ -47,9 +46,9 @@ def list_items( try: if 200 <= _response.status_code < 300: _data = typing.cast( - PaginatedNewsItemResponse, + PaginatedResponse, construct_type( - type_=PaginatedNewsItemResponse, # type: ignore + type_=PaginatedResponse, # type: ignore object_=_response.json(), ), ) @@ -70,9 +69,7 @@ def list_items( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - def list( - self, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[PaginatedNewsfeedResponse]: + def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[PaginatedResponse]: """ You can fetch a list of all newsfeeds @@ -83,7 +80,7 @@ def list( Returns ------- - HttpResponse[PaginatedNewsfeedResponse] + HttpResponse[PaginatedResponse] successful """ _response = self._client_wrapper.httpx_client.request( @@ -94,9 +91,9 @@ def list( try: if 200 <= _response.status_code < 300: _data = typing.cast( - PaginatedNewsfeedResponse, + PaginatedResponse, construct_type( - type_=PaginatedNewsfeedResponse, # type: ignore + type_=PaginatedResponse, # type: ignore object_=_response.json(), ), ) @@ -174,7 +171,7 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def list_items( self, newsfeed_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[PaginatedNewsItemResponse]: + ) -> AsyncHttpResponse[PaginatedResponse]: """ You can fetch a list of all news items that are live on a given newsfeed @@ -188,7 +185,7 @@ async def list_items( Returns ------- - AsyncHttpResponse[PaginatedNewsItemResponse] + AsyncHttpResponse[PaginatedResponse] successful """ _response = await self._client_wrapper.httpx_client.request( @@ -199,9 +196,9 @@ async def list_items( try: if 200 <= _response.status_code < 300: _data = typing.cast( - PaginatedNewsItemResponse, + PaginatedResponse, construct_type( - type_=PaginatedNewsItemResponse, # type: ignore + type_=PaginatedResponse, # type: ignore object_=_response.json(), ), ) @@ -224,7 +221,7 @@ async def list_items( async def list( self, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[PaginatedNewsfeedResponse]: + ) -> AsyncHttpResponse[PaginatedResponse]: """ You can fetch a list of all newsfeeds @@ -235,7 +232,7 @@ async def list( Returns ------- - AsyncHttpResponse[PaginatedNewsfeedResponse] + AsyncHttpResponse[PaginatedResponse] successful """ _response = await self._client_wrapper.httpx_client.request( @@ -246,9 +243,9 @@ async def list( try: if 200 <= _response.status_code < 300: _data = typing.cast( - PaginatedNewsfeedResponse, + PaginatedResponse, construct_type( - type_=PaginatedNewsfeedResponse, # type: ignore + type_=PaginatedResponse, # type: ignore object_=_response.json(), ), ) diff --git a/src/intercom/news/items/client.py b/src/intercom/news/items/client.py index 1252a3b..66b693d 100644 --- a/src/intercom/news/items/client.py +++ b/src/intercom/news/items/client.py @@ -6,7 +6,7 @@ from ...core.request_options import RequestOptions from ...types.deleted_object import DeletedObject from ...types.news_item_request_state import NewsItemRequestState -from ...types.paginated_news_item_response import PaginatedNewsItemResponse +from ...types.paginated_response import PaginatedResponse from ..types.news_item import NewsItem from ..types.newsfeed_assignment import NewsfeedAssignment from .raw_client import AsyncRawItemsClient, RawItemsClient @@ -30,7 +30,7 @@ def with_raw_response(self) -> RawItemsClient: """ return self._raw_client - def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> PaginatedNewsItemResponse: + def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> PaginatedResponse: """ You can fetch a list of all news items @@ -41,7 +41,7 @@ def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> Pa Returns ------- - PaginatedNewsItemResponse + PaginatedResponse successful Examples @@ -117,7 +117,7 @@ def create( client.news.items.create( title="Halloween is here!", body="

New costumes in store for this spooky season

", - sender_id=991267734, + sender_id=991267834, state="live", deliver_silently=True, labels=["Product", "Update", "New"], @@ -143,13 +143,13 @@ def create( ) return _response.data - def find(self, news_item_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> NewsItem: + def find(self, news_item_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> NewsItem: """ You can fetch the details of a single news item. Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -168,7 +168,7 @@ def find(self, news_item_id: str, *, request_options: typing.Optional[RequestOpt token="YOUR_TOKEN", ) client.news.items.find( - news_item_id="123", + news_item_id=1, ) """ _response = self._raw_client.find(news_item_id, request_options=request_options) @@ -176,7 +176,7 @@ def find(self, news_item_id: str, *, request_options: typing.Optional[RequestOpt def update( self, - news_item_id: str, + news_item_id: int, *, title: str, sender_id: int, @@ -191,7 +191,7 @@ def update( """ Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. title : str @@ -234,10 +234,10 @@ def update( token="YOUR_TOKEN", ) client.news.items.update( - news_item_id="123", + news_item_id=1, title="Christmas is here!", body="

New gifts in store for the jolly season

", - sender_id=991267745, + sender_id=991267845, reactions=["😝", "😂"], ) """ @@ -255,13 +255,13 @@ def update( ) return _response.data - def delete(self, news_item_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> DeletedObject: + def delete(self, news_item_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> DeletedObject: """ You can delete a single news item. Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -280,7 +280,7 @@ def delete(self, news_item_id: str, *, request_options: typing.Optional[RequestO token="YOUR_TOKEN", ) client.news.items.delete( - news_item_id="123", + news_item_id=1, ) """ _response = self._raw_client.delete(news_item_id, request_options=request_options) @@ -302,7 +302,7 @@ def with_raw_response(self) -> AsyncRawItemsClient: """ return self._raw_client - async def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> PaginatedNewsItemResponse: + async def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> PaginatedResponse: """ You can fetch a list of all news items @@ -313,7 +313,7 @@ async def list(self, *, request_options: typing.Optional[RequestOptions] = None) Returns ------- - PaginatedNewsItemResponse + PaginatedResponse successful Examples @@ -402,7 +402,7 @@ async def main() -> None: await client.news.items.create( title="Halloween is here!", body="

New costumes in store for this spooky season

", - sender_id=991267734, + sender_id=991267834, state="live", deliver_silently=True, labels=["Product", "Update", "New"], @@ -431,13 +431,13 @@ async def main() -> None: ) return _response.data - async def find(self, news_item_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> NewsItem: + async def find(self, news_item_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> NewsItem: """ You can fetch the details of a single news item. Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -461,7 +461,7 @@ async def find(self, news_item_id: str, *, request_options: typing.Optional[Requ async def main() -> None: await client.news.items.find( - news_item_id="123", + news_item_id=1, ) @@ -472,7 +472,7 @@ async def main() -> None: async def update( self, - news_item_id: str, + news_item_id: int, *, title: str, sender_id: int, @@ -487,7 +487,7 @@ async def update( """ Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. title : str @@ -535,10 +535,10 @@ async def update( async def main() -> None: await client.news.items.update( - news_item_id="123", + news_item_id=1, title="Christmas is here!", body="

New gifts in store for the jolly season

", - sender_id=991267745, + sender_id=991267845, reactions=["😝", "😂"], ) @@ -560,14 +560,14 @@ async def main() -> None: return _response.data async def delete( - self, news_item_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, news_item_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> DeletedObject: """ You can delete a single news item. Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -591,7 +591,7 @@ async def delete( async def main() -> None: await client.news.items.delete( - news_item_id="123", + news_item_id=1, ) diff --git a/src/intercom/news/items/raw_client.py b/src/intercom/news/items/raw_client.py index 229758a..0262aaf 100644 --- a/src/intercom/news/items/raw_client.py +++ b/src/intercom/news/items/raw_client.py @@ -15,7 +15,7 @@ from ...types.deleted_object import DeletedObject from ...types.error import Error from ...types.news_item_request_state import NewsItemRequestState -from ...types.paginated_news_item_response import PaginatedNewsItemResponse +from ...types.paginated_response import PaginatedResponse from ..types.news_item import NewsItem from ..types.newsfeed_assignment import NewsfeedAssignment @@ -27,9 +27,7 @@ class RawItemsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def list( - self, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[PaginatedNewsItemResponse]: + def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[PaginatedResponse]: """ You can fetch a list of all news items @@ -40,7 +38,7 @@ def list( Returns ------- - HttpResponse[PaginatedNewsItemResponse] + HttpResponse[PaginatedResponse] successful """ _response = self._client_wrapper.httpx_client.request( @@ -51,9 +49,9 @@ def list( try: if 200 <= _response.status_code < 300: _data = typing.cast( - PaginatedNewsItemResponse, + PaginatedResponse, construct_type( - type_=PaginatedNewsItemResponse, # type: ignore + type_=PaginatedResponse, # type: ignore object_=_response.json(), ), ) @@ -172,14 +170,14 @@ def create( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def find( - self, news_item_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, news_item_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[NewsItem]: """ You can fetch the details of a single news item. Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -234,7 +232,7 @@ def find( def update( self, - news_item_id: str, + news_item_id: int, *, title: str, sender_id: int, @@ -249,7 +247,7 @@ def update( """ Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. title : str @@ -343,14 +341,14 @@ def update( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def delete( - self, news_item_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, news_item_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[DeletedObject]: """ You can delete a single news item. Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -410,7 +408,7 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def list( self, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[PaginatedNewsItemResponse]: + ) -> AsyncHttpResponse[PaginatedResponse]: """ You can fetch a list of all news items @@ -421,7 +419,7 @@ async def list( Returns ------- - AsyncHttpResponse[PaginatedNewsItemResponse] + AsyncHttpResponse[PaginatedResponse] successful """ _response = await self._client_wrapper.httpx_client.request( @@ -432,9 +430,9 @@ async def list( try: if 200 <= _response.status_code < 300: _data = typing.cast( - PaginatedNewsItemResponse, + PaginatedResponse, construct_type( - type_=PaginatedNewsItemResponse, # type: ignore + type_=PaginatedResponse, # type: ignore object_=_response.json(), ), ) @@ -553,14 +551,14 @@ async def create( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def find( - self, news_item_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, news_item_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[NewsItem]: """ You can fetch the details of a single news item. Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. request_options : typing.Optional[RequestOptions] @@ -615,7 +613,7 @@ async def find( async def update( self, - news_item_id: str, + news_item_id: int, *, title: str, sender_id: int, @@ -630,7 +628,7 @@ async def update( """ Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. title : str @@ -724,14 +722,14 @@ async def update( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def delete( - self, news_item_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, news_item_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[DeletedObject]: """ You can delete a single news item. Parameters ---------- - news_item_id : str + news_item_id : int The unique identifier for the news item which is given by Intercom. request_options : typing.Optional[RequestOptions] diff --git a/src/intercom/news/types/news_item.py b/src/intercom/news/types/news_item.py index 0b6b04e..99519ef 100644 --- a/src/intercom/news/types/news_item.py +++ b/src/intercom/news/types/news_item.py @@ -14,37 +14,32 @@ class NewsItem(UncheckedBaseModel): A News Item is a content type in Intercom enabling you to announce product updates, company news, promotions, events and more with your customers. """ - type: typing.Literal["news-item"] = pydantic.Field(default="news-item") - """ - The type of object. - """ - - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier for the news item which is given by Intercom. """ - workspace_id: str = pydantic.Field() + workspace_id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the workspace which the news item belongs to. """ - title: str = pydantic.Field() + title: typing.Optional[str] = pydantic.Field(default=None) """ The title of the news item. """ - body: str = pydantic.Field() + body: typing.Optional[str] = pydantic.Field(default=None) """ The news item body, which may contain HTML. """ - sender_id: int = pydantic.Field() + sender_id: typing.Optional[int] = pydantic.Field(default=None) """ The id of the sender of the news item. Must be a teammate on the workspace. """ - state: NewsItemState = pydantic.Field() + state: typing.Optional[NewsItemState] = pydantic.Field(default=None) """ News items will not be visible to your users in the assigned newsfeeds until they are set live. """ @@ -74,7 +69,7 @@ class NewsItem(UncheckedBaseModel): When set to true, the news item will appear in the messenger newsfeed without showing a notification badge. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ Timestamp for when the news item was created. """ diff --git a/src/intercom/news/types/newsfeed.py b/src/intercom/news/types/newsfeed.py index fb64616..c5d0630 100644 --- a/src/intercom/news/types/newsfeed.py +++ b/src/intercom/news/types/newsfeed.py @@ -14,22 +14,17 @@ class Newsfeed(UncheckedBaseModel): Newsfeeds currently cannot be edited through the API, please refer to [this article](https://www.intercom.com/help/en/articles/6362267-getting-started-with-news) to set up your newsfeeds in Intercom. """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier for the newsfeed which is given by Intercom. """ - type: typing.Literal["newsfeed"] = pydantic.Field(default="newsfeed") - """ - The type of object. - """ - - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the newsfeed. This name will never be visible to your users. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ Timestamp for when the newsfeed was created. """ diff --git a/src/intercom/news/types/newsfeed_assignment.py b/src/intercom/news/types/newsfeed_assignment.py index 94e1299..087b6b8 100644 --- a/src/intercom/news/types/newsfeed_assignment.py +++ b/src/intercom/news/types/newsfeed_assignment.py @@ -12,12 +12,12 @@ class NewsfeedAssignment(UncheckedBaseModel): Assigns a news item to a newsfeed. """ - newsfeed_id: int = pydantic.Field() + newsfeed_id: typing.Optional[int] = pydantic.Field(default=None) """ The unique identifier for the newsfeed which is given by Intercom. Publish dates cannot be in the future, to schedule news items use the dedicated feature in app (see this article). """ - published_at: int = pydantic.Field() + published_at: typing.Optional[int] = pydantic.Field(default=None) """ Publish date of the news item on the newsfeed, use this field if you want to set a publish date in the past (e.g. when importing existing news items). On write, this field will be ignored if the news item state is "draft". """ diff --git a/src/intercom/notes/client.py b/src/intercom/notes/client.py index e6ad025..de4e3ed 100644 --- a/src/intercom/notes/client.py +++ b/src/intercom/notes/client.py @@ -121,13 +121,13 @@ def create( _response = self._raw_client.create(contact_id, body=body, admin_id=admin_id, request_options=request_options) return _response.data - def find(self, note_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Note: + def find(self, note_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> Note: """ You can fetch the details of a single note. Parameters ---------- - note_id : str + note_id : int The unique identifier of a given note request_options : typing.Optional[RequestOptions] @@ -146,7 +146,7 @@ def find(self, note_id: str, *, request_options: typing.Optional[RequestOptions] token="YOUR_TOKEN", ) client.notes.find( - note_id="1", + note_id=1, ) """ _response = self._raw_client.find(note_id, request_options=request_options) @@ -281,13 +281,13 @@ async def main() -> None: ) return _response.data - async def find(self, note_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Note: + async def find(self, note_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> Note: """ You can fetch the details of a single note. Parameters ---------- - note_id : str + note_id : int The unique identifier of a given note request_options : typing.Optional[RequestOptions] @@ -311,7 +311,7 @@ async def find(self, note_id: str, *, request_options: typing.Optional[RequestOp async def main() -> None: await client.notes.find( - note_id="1", + note_id=1, ) diff --git a/src/intercom/notes/raw_client.py b/src/intercom/notes/raw_client.py index 234f5c6..d6b31d0 100644 --- a/src/intercom/notes/raw_client.py +++ b/src/intercom/notes/raw_client.py @@ -170,13 +170,13 @@ def create( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - def find(self, note_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Note]: + def find(self, note_id: int, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Note]: """ You can fetch the details of a single note. Parameters ---------- - note_id : str + note_id : int The unique identifier of a given note request_options : typing.Optional[RequestOptions] @@ -384,14 +384,14 @@ async def create( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def find( - self, note_id: str, *, request_options: typing.Optional[RequestOptions] = None + self, note_id: int, *, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[Note]: """ You can fetch the details of a single note. Parameters ---------- - note_id : str + note_id : int The unique identifier of a given note request_options : typing.Optional[RequestOptions] diff --git a/src/intercom/notes/types/note.py b/src/intercom/notes/types/note.py index c5cb3c4..3bddbc5 100644 --- a/src/intercom/notes/types/note.py +++ b/src/intercom/notes/types/note.py @@ -14,17 +14,17 @@ class Note(UncheckedBaseModel): Notes allow you to annotate and comment on your contacts. """ - type: typing.Literal["note"] = pydantic.Field(default="note") + type: typing.Optional[str] = pydantic.Field(default=None) """ String representing the object's type. Always has the value `note`. """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the note. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ The time the note was created. """ @@ -34,12 +34,12 @@ class Note(UncheckedBaseModel): Represents the contact that the note was created about. """ - author: Admin = pydantic.Field() + author: typing.Optional[Admin] = pydantic.Field(default=None) """ Optional. Represents the Admin that created the note. """ - body: str = pydantic.Field() + body: typing.Optional[str] = pydantic.Field(default=None) """ The body text of the note. """ diff --git a/src/intercom/notes/types/note_contact.py b/src/intercom/notes/types/note_contact.py index 5258ab7..35a73e5 100644 --- a/src/intercom/notes/types/note_contact.py +++ b/src/intercom/notes/types/note_contact.py @@ -12,7 +12,7 @@ class NoteContact(UncheckedBaseModel): Represents the contact that the note was created about. """ - type: typing.Optional[typing.Literal["contact"]] = pydantic.Field(default=None) + type: typing.Optional[str] = pydantic.Field(default=None) """ String representing the object's type. Always has the value `contact`. """ diff --git a/src/intercom/phone_call_redirects/client.py b/src/intercom/phone_call_redirects/client.py index 5f5157e..b5e4108 100644 --- a/src/intercom/phone_call_redirects/client.py +++ b/src/intercom/phone_call_redirects/client.py @@ -4,7 +4,7 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.request_options import RequestOptions -from ..types.custom_attributes import CustomAttributes +from ..types.create_phone_switch_request import CreatePhoneSwitchRequest from ..types.phone_switch import PhoneSwitch from .raw_client import AsyncRawPhoneCallRedirectsClient, RawPhoneCallRedirectsClient @@ -30,10 +30,9 @@ def with_raw_response(self) -> RawPhoneCallRedirectsClient: def create( self, *, - phone: str, - custom_attributes: typing.Optional[CustomAttributes] = OMIT, + request: typing.Optional[CreatePhoneSwitchRequest] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> PhoneSwitch: + ) -> typing.Optional[PhoneSwitch]: """ You can use the API to deflect phone calls to the Intercom Messenger. Calling this endpoint will send an SMS with a link to the Messenger to the phone number specified. @@ -42,34 +41,31 @@ def create( Parameters ---------- - phone : str - Phone number in E.164 format, that will receive the SMS to continue the conversation in the Messenger. - - custom_attributes : typing.Optional[CustomAttributes] + request : typing.Optional[CreatePhoneSwitchRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - PhoneSwitch + typing.Optional[PhoneSwitch] successful Examples -------- - from intercom import Intercom + from intercom import CreatePhoneSwitchRequest, Intercom client = Intercom( token="YOUR_TOKEN", ) client.phone_call_redirects.create( - phone="+353832345678", - custom_attributes={"issue_type": "Billing", "priority": "High"}, + request=CreatePhoneSwitchRequest( + phone="+353832345678", + custom_attributes={"issue_type": "Billing", "priority": "High"}, + ), ) """ - _response = self._raw_client.create( - phone=phone, custom_attributes=custom_attributes, request_options=request_options - ) + _response = self._raw_client.create(request=request, request_options=request_options) return _response.data @@ -91,10 +87,9 @@ def with_raw_response(self) -> AsyncRawPhoneCallRedirectsClient: async def create( self, *, - phone: str, - custom_attributes: typing.Optional[CustomAttributes] = OMIT, + request: typing.Optional[CreatePhoneSwitchRequest] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> PhoneSwitch: + ) -> typing.Optional[PhoneSwitch]: """ You can use the API to deflect phone calls to the Intercom Messenger. Calling this endpoint will send an SMS with a link to the Messenger to the phone number specified. @@ -103,24 +98,21 @@ async def create( Parameters ---------- - phone : str - Phone number in E.164 format, that will receive the SMS to continue the conversation in the Messenger. - - custom_attributes : typing.Optional[CustomAttributes] + request : typing.Optional[CreatePhoneSwitchRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - PhoneSwitch + typing.Optional[PhoneSwitch] successful Examples -------- import asyncio - from intercom import AsyncIntercom + from intercom import AsyncIntercom, CreatePhoneSwitchRequest client = AsyncIntercom( token="YOUR_TOKEN", @@ -129,14 +121,14 @@ async def create( async def main() -> None: await client.phone_call_redirects.create( - phone="+353832345678", - custom_attributes={"issue_type": "Billing", "priority": "High"}, + request=CreatePhoneSwitchRequest( + phone="+353832345678", + custom_attributes={"issue_type": "Billing", "priority": "High"}, + ), ) asyncio.run(main()) """ - _response = await self._raw_client.create( - phone=phone, custom_attributes=custom_attributes, request_options=request_options - ) + _response = await self._raw_client.create(request=request, request_options=request_options) return _response.data diff --git a/src/intercom/phone_call_redirects/raw_client.py b/src/intercom/phone_call_redirects/raw_client.py index b76fc65..073d869 100644 --- a/src/intercom/phone_call_redirects/raw_client.py +++ b/src/intercom/phone_call_redirects/raw_client.py @@ -7,11 +7,12 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata from ..core.unchecked_base_model import construct_type from ..errors.bad_request_error import BadRequestError from ..errors.unauthorized_error import UnauthorizedError from ..errors.unprocessable_entity_error import UnprocessableEntityError -from ..types.custom_attributes import CustomAttributes +from ..types.create_phone_switch_request import CreatePhoneSwitchRequest from ..types.error import Error from ..types.phone_switch import PhoneSwitch @@ -26,10 +27,9 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): def create( self, *, - phone: str, - custom_attributes: typing.Optional[CustomAttributes] = OMIT, + request: typing.Optional[CreatePhoneSwitchRequest] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[PhoneSwitch]: + ) -> HttpResponse[typing.Optional[PhoneSwitch]]: """ You can use the API to deflect phone calls to the Intercom Messenger. Calling this endpoint will send an SMS with a link to the Messenger to the phone number specified. @@ -38,26 +38,22 @@ def create( Parameters ---------- - phone : str - Phone number in E.164 format, that will receive the SMS to continue the conversation in the Messenger. - - custom_attributes : typing.Optional[CustomAttributes] + request : typing.Optional[CreatePhoneSwitchRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - HttpResponse[PhoneSwitch] + HttpResponse[typing.Optional[PhoneSwitch]] successful """ _response = self._client_wrapper.httpx_client.request( "phone_call_redirects", method="POST", - json={ - "phone": phone, - "custom_attributes": custom_attributes, - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreatePhoneSwitchRequest, direction="write" + ), headers={ "content-type": "application/json", }, @@ -65,11 +61,13 @@ def create( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - PhoneSwitch, + typing.Optional[PhoneSwitch], construct_type( - type_=PhoneSwitch, # type: ignore + type_=typing.Optional[PhoneSwitch], # type: ignore object_=_response.json(), ), ) @@ -120,10 +118,9 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def create( self, *, - phone: str, - custom_attributes: typing.Optional[CustomAttributes] = OMIT, + request: typing.Optional[CreatePhoneSwitchRequest] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[PhoneSwitch]: + ) -> AsyncHttpResponse[typing.Optional[PhoneSwitch]]: """ You can use the API to deflect phone calls to the Intercom Messenger. Calling this endpoint will send an SMS with a link to the Messenger to the phone number specified. @@ -132,26 +129,22 @@ async def create( Parameters ---------- - phone : str - Phone number in E.164 format, that will receive the SMS to continue the conversation in the Messenger. - - custom_attributes : typing.Optional[CustomAttributes] + request : typing.Optional[CreatePhoneSwitchRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncHttpResponse[PhoneSwitch] + AsyncHttpResponse[typing.Optional[PhoneSwitch]] successful """ _response = await self._client_wrapper.httpx_client.request( "phone_call_redirects", method="POST", - json={ - "phone": phone, - "custom_attributes": custom_attributes, - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreatePhoneSwitchRequest, direction="write" + ), headers={ "content-type": "application/json", }, @@ -159,11 +152,13 @@ async def create( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - PhoneSwitch, + typing.Optional[PhoneSwitch], construct_type( - type_=PhoneSwitch, # type: ignore + type_=typing.Optional[PhoneSwitch], # type: ignore object_=_response.json(), ), ) diff --git a/src/intercom/segments/types/segment.py b/src/intercom/segments/types/segment.py index 8dbd043..b385198 100644 --- a/src/intercom/segments/types/segment.py +++ b/src/intercom/segments/types/segment.py @@ -13,22 +13,22 @@ class Segment(UncheckedBaseModel): A segment is a group of your contacts defined by the rules that you set. """ - type: typing.Literal["segment"] = pydantic.Field(default="segment") + type: typing.Optional[typing.Literal["segment"]] = pydantic.Field(default=None) """ The type of object. """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier representing the segment. """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the segment. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ The time the segment was created. """ @@ -38,7 +38,7 @@ class Segment(UncheckedBaseModel): The time the segment was updated. """ - person_type: SegmentPersonType = pydantic.Field() + person_type: typing.Optional[SegmentPersonType] = pydantic.Field(default=None) """ Type of the contact: contact (lead) or user. """ diff --git a/src/intercom/subscription_types/types/subscription_type.py b/src/intercom/subscription_types/types/subscription_type.py index fa4dd1a..8f4c0f2 100644 --- a/src/intercom/subscription_types/types/subscription_type.py +++ b/src/intercom/subscription_types/types/subscription_type.py @@ -16,33 +16,33 @@ class SubscriptionType(UncheckedBaseModel): A subscription type lets customers easily opt out of non-essential communications without missing what's important to them. """ - type: typing.Literal["subscription"] = pydantic.Field(default="subscription") + type: typing.Optional[typing.Literal["subscription"]] = pydantic.Field(default=None) """ The type of the object - subscription """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier representing the subscription type. """ - state: SubscriptionTypeState = pydantic.Field() + state: typing.Optional[SubscriptionTypeState] = pydantic.Field(default=None) """ The state of the subscription type. """ - default_translation: Translation - translations: typing.List[Translation] = pydantic.Field() + default_translation: typing.Optional[Translation] = None + translations: typing.Optional[typing.List[Translation]] = pydantic.Field(default=None) """ An array of translations objects with the localised version of the subscription type in each available locale within your translation settings. """ - consent_type: SubscriptionTypeConsentType = pydantic.Field() + consent_type: typing.Optional[SubscriptionTypeConsentType] = pydantic.Field(default=None) """ Describes the type of consent. """ - content_types: typing.List[SubscriptionTypeContentTypesItem] = pydantic.Field() + content_types: typing.Optional[typing.List[SubscriptionTypeContentTypesItem]] = pydantic.Field(default=None) """ The message types that this subscription supports - can contain `email` or `sms_message`. """ diff --git a/src/intercom/tags/__init__.py b/src/intercom/tags/__init__.py index fc57985..96b3050 100644 --- a/src/intercom/tags/__init__.py +++ b/src/intercom/tags/__init__.py @@ -2,6 +2,6 @@ # isort: skip_file -from .types import Tag, TagsCreateRequestBody +from .types import Tag, TagBasic, TagsCreateRequestBody -__all__ = ["Tag", "TagsCreateRequestBody"] +__all__ = ["Tag", "TagBasic", "TagsCreateRequestBody"] diff --git a/src/intercom/tags/client.py b/src/intercom/tags/client.py index 0a0579c..fdb545d 100644 --- a/src/intercom/tags/client.py +++ b/src/intercom/tags/client.py @@ -167,7 +167,7 @@ def untag_conversation( conversation_id tag_id : str - id + tag_id admin_id : str The unique identifier for the admin which is given by Intercom. @@ -593,7 +593,7 @@ async def untag_conversation( conversation_id tag_id : str - id + tag_id admin_id : str The unique identifier for the admin which is given by Intercom. diff --git a/src/intercom/tags/raw_client.py b/src/intercom/tags/raw_client.py index e54869d..b5c3565 100644 --- a/src/intercom/tags/raw_client.py +++ b/src/intercom/tags/raw_client.py @@ -258,7 +258,7 @@ def untag_conversation( conversation_id tag_id : str - id + tag_id admin_id : str The unique identifier for the admin which is given by Intercom. @@ -963,7 +963,7 @@ async def untag_conversation( conversation_id tag_id : str - id + tag_id admin_id : str The unique identifier for the admin which is given by Intercom. diff --git a/src/intercom/tags/types/__init__.py b/src/intercom/tags/types/__init__.py index 19ffcaa..95c8e55 100644 --- a/src/intercom/tags/types/__init__.py +++ b/src/intercom/tags/types/__init__.py @@ -3,6 +3,7 @@ # isort: skip_file from .tag import Tag +from .tag_basic import TagBasic from .tags_create_request_body import TagsCreateRequestBody -__all__ = ["Tag", "TagsCreateRequestBody"] +__all__ = ["Tag", "TagBasic", "TagsCreateRequestBody"] diff --git a/src/intercom/tags/types/tag_basic.py b/src/intercom/tags/types/tag_basic.py new file mode 100644 index 0000000..0eaac93 --- /dev/null +++ b/src/intercom/tags/types/tag_basic.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class TagBasic(UncheckedBaseModel): + """ + A tag allows you to label your contacts, companies, and conversations and list them using that tag. + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + value is "tag" + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the tag + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the tag + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/teams/types/team.py b/src/intercom/teams/types/team.py index d27fe24..6589e91 100644 --- a/src/intercom/teams/types/team.py +++ b/src/intercom/teams/types/team.py @@ -13,22 +13,22 @@ class Team(UncheckedBaseModel): Teams are groups of admins in Intercom. """ - type: typing.Literal["team"] = pydantic.Field(default="team") + type: typing.Optional[str] = pydantic.Field(default=None) """ Value is always "team" """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the team """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the team """ - admin_ids: typing.List[int] = pydantic.Field() + admin_ids: typing.Optional[typing.List[int]] = pydantic.Field(default=None) """ The list of admin IDs that are a part of the team. """ diff --git a/src/intercom/ticket_states/__init__.py b/src/intercom/ticket_states/__init__.py new file mode 100644 index 0000000..5cde020 --- /dev/null +++ b/src/intercom/ticket_states/__init__.py @@ -0,0 +1,4 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + diff --git a/src/intercom/ticket_states/client.py b/src/intercom/ticket_states/client.py new file mode 100644 index 0000000..f61c4c5 --- /dev/null +++ b/src/intercom/ticket_states/client.py @@ -0,0 +1,100 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.request_options import RequestOptions +from ..types.ticket_state_list import TicketStateList +from .raw_client import AsyncRawTicketStatesClient, RawTicketStatesClient + + +class TicketStatesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawTicketStatesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawTicketStatesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawTicketStatesClient + """ + return self._raw_client + + def list_ticket_states(self, *, request_options: typing.Optional[RequestOptions] = None) -> TicketStateList: + """ + You can get a list of all ticket states for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TicketStateList + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.ticket_states.list_ticket_states() + """ + _response = self._raw_client.list_ticket_states(request_options=request_options) + return _response.data + + +class AsyncTicketStatesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawTicketStatesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawTicketStatesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawTicketStatesClient + """ + return self._raw_client + + async def list_ticket_states(self, *, request_options: typing.Optional[RequestOptions] = None) -> TicketStateList: + """ + You can get a list of all ticket states for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + TicketStateList + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.ticket_states.list_ticket_states() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_ticket_states(request_options=request_options) + return _response.data diff --git a/src/intercom/ticket_states/raw_client.py b/src/intercom/ticket_states/raw_client.py new file mode 100644 index 0000000..b42d577 --- /dev/null +++ b/src/intercom/ticket_states/raw_client.py @@ -0,0 +1,117 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ..core.api_error import ApiError +from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ..core.http_response import AsyncHttpResponse, HttpResponse +from ..core.request_options import RequestOptions +from ..core.unchecked_base_model import construct_type +from ..errors.unauthorized_error import UnauthorizedError +from ..types.error import Error +from ..types.ticket_state_list import TicketStateList + + +class RawTicketStatesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_ticket_states( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[TicketStateList]: + """ + You can get a list of all ticket states for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[TicketStateList] + successful + """ + _response = self._client_wrapper.httpx_client.request( + "ticket_states", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TicketStateList, + construct_type( + type_=TicketStateList, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawTicketStatesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_ticket_states( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[TicketStateList]: + """ + You can get a list of all ticket states for a workspace. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[TicketStateList] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + "ticket_states", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + TicketStateList, + construct_type( + type_=TicketStateList, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/ticket_types/__init__.py b/src/intercom/ticket_types/__init__.py index 9eee489..1e2a69c 100644 --- a/src/intercom/ticket_types/__init__.py +++ b/src/intercom/ticket_types/__init__.py @@ -2,13 +2,8 @@ # isort: skip_file -from .types import CreateTicketTypeRequestCategory, UpdateTicketTypeRequestBodyCategory +from .types import UpdateTicketTypeRequestCategory from . import attributes from .attributes import CreateTicketTypeAttributeRequestDataType -__all__ = [ - "CreateTicketTypeAttributeRequestDataType", - "CreateTicketTypeRequestCategory", - "UpdateTicketTypeRequestBodyCategory", - "attributes", -] +__all__ = ["CreateTicketTypeAttributeRequestDataType", "UpdateTicketTypeRequestCategory", "attributes"] diff --git a/src/intercom/ticket_types/attributes/client.py b/src/intercom/ticket_types/attributes/client.py index 4cb02c5..443b17a 100644 --- a/src/intercom/ticket_types/attributes/client.py +++ b/src/intercom/ticket_types/attributes/client.py @@ -42,7 +42,7 @@ def create( list_items: typing.Optional[str] = OMIT, allow_multiple_values: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> TicketTypeAttribute: + ) -> typing.Optional[TicketTypeAttribute]: """ You can create a new attribute for a ticket type. @@ -86,7 +86,7 @@ def create( Returns ------- - TicketTypeAttribute + typing.Optional[TicketTypeAttribute] Ticket Type Attribute created Examples @@ -136,7 +136,7 @@ def update( allow_multiple_values: typing.Optional[bool] = OMIT, archived: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> TicketTypeAttribute: + ) -> typing.Optional[TicketTypeAttribute]: """ You can update an existing attribute for a ticket type. @@ -183,7 +183,7 @@ def update( Returns ------- - TicketTypeAttribute + typing.Optional[TicketTypeAttribute] Ticket Type Attribute updated Examples @@ -247,7 +247,7 @@ async def create( list_items: typing.Optional[str] = OMIT, allow_multiple_values: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> TicketTypeAttribute: + ) -> typing.Optional[TicketTypeAttribute]: """ You can create a new attribute for a ticket type. @@ -291,7 +291,7 @@ async def create( Returns ------- - TicketTypeAttribute + typing.Optional[TicketTypeAttribute] Ticket Type Attribute created Examples @@ -349,7 +349,7 @@ async def update( allow_multiple_values: typing.Optional[bool] = OMIT, archived: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> TicketTypeAttribute: + ) -> typing.Optional[TicketTypeAttribute]: """ You can update an existing attribute for a ticket type. @@ -396,7 +396,7 @@ async def update( Returns ------- - TicketTypeAttribute + typing.Optional[TicketTypeAttribute] Ticket Type Attribute updated Examples diff --git a/src/intercom/ticket_types/attributes/raw_client.py b/src/intercom/ticket_types/attributes/raw_client.py index 0de72e8..4e47e00 100644 --- a/src/intercom/ticket_types/attributes/raw_client.py +++ b/src/intercom/ticket_types/attributes/raw_client.py @@ -37,7 +37,7 @@ def create( list_items: typing.Optional[str] = OMIT, allow_multiple_values: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[TicketTypeAttribute]: + ) -> HttpResponse[typing.Optional[TicketTypeAttribute]]: """ You can create a new attribute for a ticket type. @@ -81,7 +81,7 @@ def create( Returns ------- - HttpResponse[TicketTypeAttribute] + HttpResponse[typing.Optional[TicketTypeAttribute]] Ticket Type Attribute created """ _response = self._client_wrapper.httpx_client.request( @@ -106,11 +106,13 @@ def create( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - TicketTypeAttribute, + typing.Optional[TicketTypeAttribute], construct_type( - type_=TicketTypeAttribute, # type: ignore + type_=typing.Optional[TicketTypeAttribute], # type: ignore object_=_response.json(), ), ) @@ -147,7 +149,7 @@ def update( allow_multiple_values: typing.Optional[bool] = OMIT, archived: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[TicketTypeAttribute]: + ) -> HttpResponse[typing.Optional[TicketTypeAttribute]]: """ You can update an existing attribute for a ticket type. @@ -194,7 +196,7 @@ def update( Returns ------- - HttpResponse[TicketTypeAttribute] + HttpResponse[typing.Optional[TicketTypeAttribute]] Ticket Type Attribute updated """ _response = self._client_wrapper.httpx_client.request( @@ -219,11 +221,13 @@ def update( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - TicketTypeAttribute, + typing.Optional[TicketTypeAttribute], construct_type( - type_=TicketTypeAttribute, # type: ignore + type_=typing.Optional[TicketTypeAttribute], # type: ignore object_=_response.json(), ), ) @@ -264,7 +268,7 @@ async def create( list_items: typing.Optional[str] = OMIT, allow_multiple_values: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[TicketTypeAttribute]: + ) -> AsyncHttpResponse[typing.Optional[TicketTypeAttribute]]: """ You can create a new attribute for a ticket type. @@ -308,7 +312,7 @@ async def create( Returns ------- - AsyncHttpResponse[TicketTypeAttribute] + AsyncHttpResponse[typing.Optional[TicketTypeAttribute]] Ticket Type Attribute created """ _response = await self._client_wrapper.httpx_client.request( @@ -333,11 +337,13 @@ async def create( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - TicketTypeAttribute, + typing.Optional[TicketTypeAttribute], construct_type( - type_=TicketTypeAttribute, # type: ignore + type_=typing.Optional[TicketTypeAttribute], # type: ignore object_=_response.json(), ), ) @@ -374,7 +380,7 @@ async def update( allow_multiple_values: typing.Optional[bool] = OMIT, archived: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[TicketTypeAttribute]: + ) -> AsyncHttpResponse[typing.Optional[TicketTypeAttribute]]: """ You can update an existing attribute for a ticket type. @@ -421,7 +427,7 @@ async def update( Returns ------- - AsyncHttpResponse[TicketTypeAttribute] + AsyncHttpResponse[typing.Optional[TicketTypeAttribute]] Ticket Type Attribute updated """ _response = await self._client_wrapper.httpx_client.request( @@ -446,11 +452,13 @@ async def update( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - TicketTypeAttribute, + typing.Optional[TicketTypeAttribute], construct_type( - type_=TicketTypeAttribute, # type: ignore + type_=typing.Optional[TicketTypeAttribute], # type: ignore object_=_response.json(), ), ) diff --git a/src/intercom/ticket_types/client.py b/src/intercom/ticket_types/client.py index c01dd27..0ed4c8e 100644 --- a/src/intercom/ticket_types/client.py +++ b/src/intercom/ticket_types/client.py @@ -5,11 +5,11 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.request_options import RequestOptions from ..tickets.types.ticket_type import TicketType +from ..types.create_ticket_type_request import CreateTicketTypeRequest from ..types.ticket_type_list import TicketTypeList from .attributes.client import AsyncAttributesClient, AttributesClient from .raw_client import AsyncRawTicketTypesClient, RawTicketTypesClient -from .types.create_ticket_type_request_category import CreateTicketTypeRequestCategory -from .types.update_ticket_type_request_body_category import UpdateTicketTypeRequestBodyCategory +from .types.update_ticket_type_request_category import UpdateTicketTypeRequestCategory # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -60,13 +60,9 @@ def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> Ti def create( self, *, - name: str, - description: typing.Optional[str] = OMIT, - category: typing.Optional[CreateTicketTypeRequestCategory] = OMIT, - icon: typing.Optional[str] = OMIT, - is_internal: typing.Optional[bool] = OMIT, + request: typing.Optional[CreateTicketTypeRequest] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> TicketType: + ) -> typing.Optional[TicketType]: """ You can create a new ticket type. > 📘 Creating ticket types. @@ -76,54 +72,38 @@ def create( Parameters ---------- - name : str - The name of the ticket type. - - description : typing.Optional[str] - The description of the ticket type. - - category : typing.Optional[CreateTicketTypeRequestCategory] - Category of the Ticket Type. - - icon : typing.Optional[str] - The icon of the ticket type. - - is_internal : typing.Optional[bool] - Whether the tickets associated with this ticket type are intended for internal use only or will be shared with customers. This is currently a limited attribute. + request : typing.Optional[CreateTicketTypeRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - TicketType + typing.Optional[TicketType] Ticket type created Examples -------- - from intercom import Intercom + from intercom import CreateTicketTypeRequest, Intercom client = Intercom( token="YOUR_TOKEN", ) client.ticket_types.create( - name="Customer Issue", - description="Customer Report Template", - category="Customer", - icon="🎟️", + request=CreateTicketTypeRequest( + name="Customer Issue", + description="Customer Report Template", + category="Customer", + icon="🎟️", + ), ) """ - _response = self._raw_client.create( - name=name, - description=description, - category=category, - icon=icon, - is_internal=is_internal, - request_options=request_options, - ) + _response = self._raw_client.create(request=request, request_options=request_options) return _response.data - def get(self, ticket_type_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> TicketType: + def get( + self, ticket_type_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.Optional[TicketType]: """ You can fetch the details of a single ticket type. @@ -137,7 +117,7 @@ def get(self, ticket_type_id: str, *, request_options: typing.Optional[RequestOp Returns ------- - TicketType + typing.Optional[TicketType] Ticket type found Examples @@ -160,12 +140,12 @@ def update( *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, - category: typing.Optional[UpdateTicketTypeRequestBodyCategory] = OMIT, + category: typing.Optional[UpdateTicketTypeRequestCategory] = OMIT, icon: typing.Optional[str] = OMIT, archived: typing.Optional[bool] = OMIT, is_internal: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> TicketType: + ) -> typing.Optional[TicketType]: """ You can update a ticket type. @@ -185,7 +165,7 @@ def update( description : typing.Optional[str] The description of the ticket type. - category : typing.Optional[UpdateTicketTypeRequestBodyCategory] + category : typing.Optional[UpdateTicketTypeRequestCategory] Category of the Ticket Type. icon : typing.Optional[str] @@ -202,7 +182,7 @@ def update( Returns ------- - TicketType + typing.Optional[TicketType] Ticket type updated Examples @@ -283,13 +263,9 @@ async def main() -> None: async def create( self, *, - name: str, - description: typing.Optional[str] = OMIT, - category: typing.Optional[CreateTicketTypeRequestCategory] = OMIT, - icon: typing.Optional[str] = OMIT, - is_internal: typing.Optional[bool] = OMIT, + request: typing.Optional[CreateTicketTypeRequest] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> TicketType: + ) -> typing.Optional[TicketType]: """ You can create a new ticket type. > 📘 Creating ticket types. @@ -299,34 +275,21 @@ async def create( Parameters ---------- - name : str - The name of the ticket type. - - description : typing.Optional[str] - The description of the ticket type. - - category : typing.Optional[CreateTicketTypeRequestCategory] - Category of the Ticket Type. - - icon : typing.Optional[str] - The icon of the ticket type. - - is_internal : typing.Optional[bool] - Whether the tickets associated with this ticket type are intended for internal use only or will be shared with customers. This is currently a limited attribute. + request : typing.Optional[CreateTicketTypeRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - TicketType + typing.Optional[TicketType] Ticket type created Examples -------- import asyncio - from intercom import AsyncIntercom + from intercom import AsyncIntercom, CreateTicketTypeRequest client = AsyncIntercom( token="YOUR_TOKEN", @@ -335,26 +298,23 @@ async def create( async def main() -> None: await client.ticket_types.create( - name="Customer Issue", - description="Customer Report Template", - category="Customer", - icon="🎟️", + request=CreateTicketTypeRequest( + name="Customer Issue", + description="Customer Report Template", + category="Customer", + icon="🎟️", + ), ) asyncio.run(main()) """ - _response = await self._raw_client.create( - name=name, - description=description, - category=category, - icon=icon, - is_internal=is_internal, - request_options=request_options, - ) + _response = await self._raw_client.create(request=request, request_options=request_options) return _response.data - async def get(self, ticket_type_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> TicketType: + async def get( + self, ticket_type_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.Optional[TicketType]: """ You can fetch the details of a single ticket type. @@ -368,7 +328,7 @@ async def get(self, ticket_type_id: str, *, request_options: typing.Optional[Req Returns ------- - TicketType + typing.Optional[TicketType] Ticket type found Examples @@ -399,12 +359,12 @@ async def update( *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, - category: typing.Optional[UpdateTicketTypeRequestBodyCategory] = OMIT, + category: typing.Optional[UpdateTicketTypeRequestCategory] = OMIT, icon: typing.Optional[str] = OMIT, archived: typing.Optional[bool] = OMIT, is_internal: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> TicketType: + ) -> typing.Optional[TicketType]: """ You can update a ticket type. @@ -424,7 +384,7 @@ async def update( description : typing.Optional[str] The description of the ticket type. - category : typing.Optional[UpdateTicketTypeRequestBodyCategory] + category : typing.Optional[UpdateTicketTypeRequestCategory] Category of the Ticket Type. icon : typing.Optional[str] @@ -441,7 +401,7 @@ async def update( Returns ------- - TicketType + typing.Optional[TicketType] Ticket type updated Examples diff --git a/src/intercom/ticket_types/raw_client.py b/src/intercom/ticket_types/raw_client.py index b031dad..7e70ed6 100644 --- a/src/intercom/ticket_types/raw_client.py +++ b/src/intercom/ticket_types/raw_client.py @@ -8,13 +8,14 @@ from ..core.http_response import AsyncHttpResponse, HttpResponse from ..core.jsonable_encoder import jsonable_encoder from ..core.request_options import RequestOptions +from ..core.serialization import convert_and_respect_annotation_metadata from ..core.unchecked_base_model import construct_type from ..errors.unauthorized_error import UnauthorizedError from ..tickets.types.ticket_type import TicketType +from ..types.create_ticket_type_request import CreateTicketTypeRequest from ..types.error import Error from ..types.ticket_type_list import TicketTypeList -from .types.create_ticket_type_request_category import CreateTicketTypeRequestCategory -from .types.update_ticket_type_request_body_category import UpdateTicketTypeRequestBodyCategory +from .types.update_ticket_type_request_category import UpdateTicketTypeRequestCategory # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -72,13 +73,9 @@ def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> Ht def create( self, *, - name: str, - description: typing.Optional[str] = OMIT, - category: typing.Optional[CreateTicketTypeRequestCategory] = OMIT, - icon: typing.Optional[str] = OMIT, - is_internal: typing.Optional[bool] = OMIT, + request: typing.Optional[CreateTicketTypeRequest] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[TicketType]: + ) -> HttpResponse[typing.Optional[TicketType]]: """ You can create a new ticket type. > 📘 Creating ticket types. @@ -88,39 +85,22 @@ def create( Parameters ---------- - name : str - The name of the ticket type. - - description : typing.Optional[str] - The description of the ticket type. - - category : typing.Optional[CreateTicketTypeRequestCategory] - Category of the Ticket Type. - - icon : typing.Optional[str] - The icon of the ticket type. - - is_internal : typing.Optional[bool] - Whether the tickets associated with this ticket type are intended for internal use only or will be shared with customers. This is currently a limited attribute. + request : typing.Optional[CreateTicketTypeRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - HttpResponse[TicketType] + HttpResponse[typing.Optional[TicketType]] Ticket type created """ _response = self._client_wrapper.httpx_client.request( "ticket_types", method="POST", - json={ - "name": name, - "description": description, - "category": category, - "icon": icon, - "is_internal": is_internal, - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateTicketTypeRequest, direction="write" + ), headers={ "content-type": "application/json", }, @@ -128,11 +108,13 @@ def create( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - TicketType, + typing.Optional[TicketType], construct_type( - type_=TicketType, # type: ignore + type_=typing.Optional[TicketType], # type: ignore object_=_response.json(), ), ) @@ -155,7 +137,7 @@ def create( def get( self, ticket_type_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[TicketType]: + ) -> HttpResponse[typing.Optional[TicketType]]: """ You can fetch the details of a single ticket type. @@ -169,7 +151,7 @@ def get( Returns ------- - HttpResponse[TicketType] + HttpResponse[typing.Optional[TicketType]] Ticket type found """ _response = self._client_wrapper.httpx_client.request( @@ -178,11 +160,13 @@ def get( request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - TicketType, + typing.Optional[TicketType], construct_type( - type_=TicketType, # type: ignore + type_=typing.Optional[TicketType], # type: ignore object_=_response.json(), ), ) @@ -209,12 +193,12 @@ def update( *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, - category: typing.Optional[UpdateTicketTypeRequestBodyCategory] = OMIT, + category: typing.Optional[UpdateTicketTypeRequestCategory] = OMIT, icon: typing.Optional[str] = OMIT, archived: typing.Optional[bool] = OMIT, is_internal: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[TicketType]: + ) -> HttpResponse[typing.Optional[TicketType]]: """ You can update a ticket type. @@ -234,7 +218,7 @@ def update( description : typing.Optional[str] The description of the ticket type. - category : typing.Optional[UpdateTicketTypeRequestBodyCategory] + category : typing.Optional[UpdateTicketTypeRequestCategory] Category of the Ticket Type. icon : typing.Optional[str] @@ -251,7 +235,7 @@ def update( Returns ------- - HttpResponse[TicketType] + HttpResponse[typing.Optional[TicketType]] Ticket type updated """ _response = self._client_wrapper.httpx_client.request( @@ -272,11 +256,13 @@ def update( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - TicketType, + typing.Optional[TicketType], construct_type( - type_=TicketType, # type: ignore + type_=typing.Optional[TicketType], # type: ignore object_=_response.json(), ), ) @@ -352,13 +338,9 @@ async def list( async def create( self, *, - name: str, - description: typing.Optional[str] = OMIT, - category: typing.Optional[CreateTicketTypeRequestCategory] = OMIT, - icon: typing.Optional[str] = OMIT, - is_internal: typing.Optional[bool] = OMIT, + request: typing.Optional[CreateTicketTypeRequest] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[TicketType]: + ) -> AsyncHttpResponse[typing.Optional[TicketType]]: """ You can create a new ticket type. > 📘 Creating ticket types. @@ -368,39 +350,22 @@ async def create( Parameters ---------- - name : str - The name of the ticket type. - - description : typing.Optional[str] - The description of the ticket type. - - category : typing.Optional[CreateTicketTypeRequestCategory] - Category of the Ticket Type. - - icon : typing.Optional[str] - The icon of the ticket type. - - is_internal : typing.Optional[bool] - Whether the tickets associated with this ticket type are intended for internal use only or will be shared with customers. This is currently a limited attribute. + request : typing.Optional[CreateTicketTypeRequest] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncHttpResponse[TicketType] + AsyncHttpResponse[typing.Optional[TicketType]] Ticket type created """ _response = await self._client_wrapper.httpx_client.request( "ticket_types", method="POST", - json={ - "name": name, - "description": description, - "category": category, - "icon": icon, - "is_internal": is_internal, - }, + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateTicketTypeRequest, direction="write" + ), headers={ "content-type": "application/json", }, @@ -408,11 +373,13 @@ async def create( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - TicketType, + typing.Optional[TicketType], construct_type( - type_=TicketType, # type: ignore + type_=typing.Optional[TicketType], # type: ignore object_=_response.json(), ), ) @@ -435,7 +402,7 @@ async def create( async def get( self, ticket_type_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[TicketType]: + ) -> AsyncHttpResponse[typing.Optional[TicketType]]: """ You can fetch the details of a single ticket type. @@ -449,7 +416,7 @@ async def get( Returns ------- - AsyncHttpResponse[TicketType] + AsyncHttpResponse[typing.Optional[TicketType]] Ticket type found """ _response = await self._client_wrapper.httpx_client.request( @@ -458,11 +425,13 @@ async def get( request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - TicketType, + typing.Optional[TicketType], construct_type( - type_=TicketType, # type: ignore + type_=typing.Optional[TicketType], # type: ignore object_=_response.json(), ), ) @@ -489,12 +458,12 @@ async def update( *, name: typing.Optional[str] = OMIT, description: typing.Optional[str] = OMIT, - category: typing.Optional[UpdateTicketTypeRequestBodyCategory] = OMIT, + category: typing.Optional[UpdateTicketTypeRequestCategory] = OMIT, icon: typing.Optional[str] = OMIT, archived: typing.Optional[bool] = OMIT, is_internal: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[TicketType]: + ) -> AsyncHttpResponse[typing.Optional[TicketType]]: """ You can update a ticket type. @@ -514,7 +483,7 @@ async def update( description : typing.Optional[str] The description of the ticket type. - category : typing.Optional[UpdateTicketTypeRequestBodyCategory] + category : typing.Optional[UpdateTicketTypeRequestCategory] Category of the Ticket Type. icon : typing.Optional[str] @@ -531,7 +500,7 @@ async def update( Returns ------- - AsyncHttpResponse[TicketType] + AsyncHttpResponse[typing.Optional[TicketType]] Ticket type updated """ _response = await self._client_wrapper.httpx_client.request( @@ -552,11 +521,13 @@ async def update( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - TicketType, + typing.Optional[TicketType], construct_type( - type_=TicketType, # type: ignore + type_=typing.Optional[TicketType], # type: ignore object_=_response.json(), ), ) diff --git a/src/intercom/ticket_types/types/__init__.py b/src/intercom/ticket_types/types/__init__.py index 9f90de2..de326a3 100644 --- a/src/intercom/ticket_types/types/__init__.py +++ b/src/intercom/ticket_types/types/__init__.py @@ -2,7 +2,6 @@ # isort: skip_file -from .create_ticket_type_request_category import CreateTicketTypeRequestCategory -from .update_ticket_type_request_body_category import UpdateTicketTypeRequestBodyCategory +from .update_ticket_type_request_category import UpdateTicketTypeRequestCategory -__all__ = ["CreateTicketTypeRequestCategory", "UpdateTicketTypeRequestBodyCategory"] +__all__ = ["UpdateTicketTypeRequestCategory"] diff --git a/src/intercom/ticket_types/types/update_ticket_type_request_body_category.py b/src/intercom/ticket_types/types/update_ticket_type_request_body_category.py deleted file mode 100644 index 2dc9d82..0000000 --- a/src/intercom/ticket_types/types/update_ticket_type_request_body_category.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -UpdateTicketTypeRequestBodyCategory = typing.Union[typing.Literal["Customer", "Back-office", "Tracker"], typing.Any] diff --git a/src/intercom/unstable/types/update_ticket_type_request_category.py b/src/intercom/ticket_types/types/update_ticket_type_request_category.py similarity index 100% rename from src/intercom/unstable/types/update_ticket_type_request_category.py rename to src/intercom/ticket_types/types/update_ticket_type_request_category.py diff --git a/src/intercom/tickets/__init__.py b/src/intercom/tickets/__init__.py index 2b84247..0b43a42 100644 --- a/src/intercom/tickets/__init__.py +++ b/src/intercom/tickets/__init__.py @@ -3,31 +3,49 @@ # isort: skip_file from .types import ( + DeleteTicketResponse, Ticket, TicketCategory, TicketContacts, TicketPart, TicketPartPreviousTicketState, TicketPartTicketState, - TicketTicketState, + TicketPartUpdatedAttributeData, + TicketPartUpdatedAttributeDataAttribute, + TicketPartUpdatedAttributeDataValue, + TicketPartUpdatedAttributeDataValueId, + TicketPartUpdatedAttributeDataValueLabel, + TicketState, + TicketStateCategory, + TicketStateDetailed, + TicketStateDetailedCategory, + TicketStateDetailedTicketTypes, TicketType, TicketTypeCategory, + TicketTypeTicketStates, TicketsReplyRequestBody, - UpdateTicketRequestAssignment, - UpdateTicketRequestState, ) __all__ = [ + "DeleteTicketResponse", "Ticket", "TicketCategory", "TicketContacts", "TicketPart", "TicketPartPreviousTicketState", "TicketPartTicketState", - "TicketTicketState", + "TicketPartUpdatedAttributeData", + "TicketPartUpdatedAttributeDataAttribute", + "TicketPartUpdatedAttributeDataValue", + "TicketPartUpdatedAttributeDataValueId", + "TicketPartUpdatedAttributeDataValueLabel", + "TicketState", + "TicketStateCategory", + "TicketStateDetailed", + "TicketStateDetailedCategory", + "TicketStateDetailedTicketTypes", "TicketType", "TicketTypeCategory", + "TicketTypeTicketStates", "TicketsReplyRequestBody", - "UpdateTicketRequestAssignment", - "UpdateTicketRequestState", ] diff --git a/src/intercom/tickets/client.py b/src/intercom/tickets/client.py index 03cb766..30ce992 100644 --- a/src/intercom/tickets/client.py +++ b/src/intercom/tickets/client.py @@ -5,16 +5,16 @@ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.pagination import AsyncPager, SyncPager from ..core.request_options import RequestOptions +from ..jobs.types.jobs import Jobs +from ..types.create_ticket_request_assignment import CreateTicketRequestAssignment from ..types.create_ticket_request_contacts_item import CreateTicketRequestContactsItem from ..types.search_request_query import SearchRequestQuery from ..types.starting_after_paging import StartingAfterPaging from ..types.ticket_reply import TicketReply -from ..types.ticket_request_custom_attributes import TicketRequestCustomAttributes from .raw_client import AsyncRawTicketsClient, RawTicketsClient +from .types.delete_ticket_response import DeleteTicketResponse from .types.ticket import Ticket from .types.tickets_reply_request_body import TicketsReplyRequestBody -from .types.update_ticket_request_assignment import UpdateTicketRequestAssignment -from .types.update_ticket_request_state import UpdateTicketRequestState # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -57,7 +57,7 @@ def reply( Returns ------- TicketReply - Admin quick_reply reply + Admin Reply to send Quick Reply Options Examples -------- @@ -70,7 +70,7 @@ def reply( ticket_id="123", request=ContactReplyTicketIntercomUserIdRequest( body="Thanks again :)", - intercom_user_id="667d619d8a68186f43bafe82", + intercom_user_id="6762f2971bb69f9f2193bc49", ), ) """ @@ -82,11 +82,13 @@ def create( *, ticket_type_id: str, contacts: typing.Sequence[CreateTicketRequestContactsItem], + skip_notifications: typing.Optional[bool] = OMIT, + conversation_to_link_id: typing.Optional[str] = OMIT, company_id: typing.Optional[str] = OMIT, created_at: typing.Optional[int] = OMIT, - ticket_attributes: typing.Optional[TicketRequestCustomAttributes] = OMIT, + assignment: typing.Optional[CreateTicketRequestAssignment] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> Ticket: + ) -> typing.Optional[Ticket]: """ You can create a new ticket. @@ -98,20 +100,30 @@ def create( contacts : typing.Sequence[CreateTicketRequestContactsItem] The list of contacts (users or leads) affected by this ticket. Currently only one is allowed + skip_notifications : typing.Optional[bool] + Option to disable notifications when a Ticket is created. + + conversation_to_link_id : typing.Optional[str] + The ID of the conversation you want to link to the ticket. Here are the valid ways of linking two tickets: + - conversation | back-office ticket + - customer tickets | non-shared back-office ticket + - conversation | tracker ticket + - customer ticket | tracker ticket + company_id : typing.Optional[str] - The ID of the company that the ticket is associated with. The ID that you set upon company creation. + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom created_at : typing.Optional[int] The time the ticket was created. If not provided, the current time will be used. - ticket_attributes : typing.Optional[TicketRequestCustomAttributes] + assignment : typing.Optional[CreateTicketRequestAssignment] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Ticket + typing.Optional[Ticket] Successful response Examples @@ -125,26 +137,103 @@ def create( ticket_type_id="1234", contacts=[ CreateTicketRequestContactsItemId( - id="667d61b78a68186f43bafe8d", + id="6762f2d81bb69f9f2193bc54", ) ], - ticket_attributes={ - "_default_title_": "example", - "_default_description_": "there is a problem", - }, ) """ _response = self._raw_client.create( ticket_type_id=ticket_type_id, contacts=contacts, + skip_notifications=skip_notifications, + conversation_to_link_id=conversation_to_link_id, company_id=company_id, created_at=created_at, - ticket_attributes=ticket_attributes, + assignment=assignment, + request_options=request_options, + ) + return _response.data + + def enqueue_create_ticket( + self, + *, + ticket_type_id: str, + contacts: typing.Sequence[CreateTicketRequestContactsItem], + skip_notifications: typing.Optional[bool] = OMIT, + conversation_to_link_id: typing.Optional[str] = OMIT, + company_id: typing.Optional[str] = OMIT, + created_at: typing.Optional[int] = OMIT, + assignment: typing.Optional[CreateTicketRequestAssignment] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Jobs: + """ + Enqueues ticket creation for asynchronous processing, returning if the job was enqueued successfully to be processed. We attempt to perform a best-effort validation on inputs before tasks are enqueued. If the given parameters are incorrect, we won't enqueue the job. + + Parameters + ---------- + ticket_type_id : str + The ID of the type of ticket you want to create + + contacts : typing.Sequence[CreateTicketRequestContactsItem] + The list of contacts (users or leads) affected by this ticket. Currently only one is allowed + + skip_notifications : typing.Optional[bool] + Option to disable notifications when a Ticket is created. + + conversation_to_link_id : typing.Optional[str] + The ID of the conversation you want to link to the ticket. Here are the valid ways of linking two tickets: + - conversation | back-office ticket + - customer tickets | non-shared back-office ticket + - conversation | tracker ticket + - customer ticket | tracker ticket + + company_id : typing.Optional[str] + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom + + created_at : typing.Optional[int] + The time the ticket was created. If not provided, the current time will be used. + + assignment : typing.Optional[CreateTicketRequestAssignment] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Jobs + Successful response + + Examples + -------- + from intercom import CreateTicketRequestContactsItemId, Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.tickets.enqueue_create_ticket( + ticket_type_id="1234", + contacts=[ + CreateTicketRequestContactsItemId( + id="6762f2d81bb69f9f2193bc54", + ) + ], + ) + """ + _response = self._raw_client.enqueue_create_ticket( + ticket_type_id=ticket_type_id, + contacts=contacts, + skip_notifications=skip_notifications, + conversation_to_link_id=conversation_to_link_id, + company_id=company_id, + created_at=created_at, + assignment=assignment, request_options=request_options, ) return _response.data - def get(self, ticket_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Ticket: + def get( + self, ticket_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.Optional[Ticket]: """ You can fetch the details of a single ticket. @@ -158,7 +247,7 @@ def get(self, ticket_id: str, *, request_options: typing.Optional[RequestOptions Returns ------- - Ticket + typing.Optional[Ticket] Ticket found Examples @@ -180,13 +269,15 @@ def update( ticket_id: str, *, ticket_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, - state: typing.Optional[UpdateTicketRequestState] = OMIT, + ticket_state_id: typing.Optional[str] = OMIT, + company_id: typing.Optional[str] = OMIT, open: typing.Optional[bool] = OMIT, is_shared: typing.Optional[bool] = OMIT, snoozed_until: typing.Optional[int] = OMIT, - assignment: typing.Optional[UpdateTicketRequestAssignment] = OMIT, + admin_id: typing.Optional[int] = OMIT, + assignee_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> Ticket: + ) -> typing.Optional[Ticket]: """ You can update a ticket. @@ -198,8 +289,11 @@ def update( ticket_attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] The attributes set on the ticket. - state : typing.Optional[UpdateTicketRequestState] - The state of the ticket. + ticket_state_id : typing.Optional[str] + The ID of the ticket state associated with the ticket type. + + company_id : typing.Optional[str] + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company. open : typing.Optional[bool] Specify if a ticket is open. Set to false to close a ticket. Closing a ticket will also unsnooze it. @@ -210,20 +304,23 @@ def update( snoozed_until : typing.Optional[int] The time you want the ticket to reopen. - assignment : typing.Optional[UpdateTicketRequestAssignment] + admin_id : typing.Optional[int] + The ID of the admin performing ticket update. Needed for workflows execution and attributing actions to specific admins. + + assignee_id : typing.Optional[str] + The ID of the admin or team to which the ticket is assigned. Set this 0 to unassign it. request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Ticket + typing.Optional[Ticket] Successful response Examples -------- from intercom import Intercom - from intercom.tickets import UpdateTicketRequestAssignment client = Intercom( token="YOUR_TOKEN", @@ -234,34 +331,67 @@ def update( "_default_title_": "example", "_default_description_": "there is a problem", }, - state="in_progress", + ticket_state_id="123", open=True, snoozed_until=1673609604, - assignment=UpdateTicketRequestAssignment( - admin_id="991267883", - assignee_id="991267885", - ), + admin_id=991268011, + assignee_id="123", ) """ _response = self._raw_client.update( ticket_id, ticket_attributes=ticket_attributes, - state=state, + ticket_state_id=ticket_state_id, + company_id=company_id, open=open, is_shared=is_shared, snoozed_until=snoozed_until, - assignment=assignment, + admin_id=admin_id, + assignee_id=assignee_id, request_options=request_options, ) return _response.data + def delete_ticket( + self, ticket_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> DeleteTicketResponse: + """ + You can delete a ticket using the Intercom provided ID. + + Parameters + ---------- + ticket_id : str + The unique identifier for the ticket which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeleteTicketResponse + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.tickets.delete_ticket( + ticket_id="ticket_id", + ) + """ + _response = self._raw_client.delete_ticket(ticket_id, request_options=request_options) + return _response.data + def search( self, *, query: SearchRequestQuery, pagination: typing.Optional[StartingAfterPaging] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> SyncPager[Ticket]: + ) -> SyncPager[typing.Optional[Ticket]]: """ You can search for multiple tickets by the value of their attributes in order to fetch exactly which ones you want. @@ -285,6 +415,7 @@ def search( ### Accepted Fields Most keys listed as part of the Ticket model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foobar"`). + The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. | Field | Type | | :---------------------------------------- | :--------------------------------------------------------------------------------------- | @@ -304,6 +435,13 @@ def search( | snoozed_until | Date (UNIX timestamp) | | ticket_attribute.{id} | String or Boolean or Date (UNIX timestamp) or Float or Integer | + {% admonition type="info" name="Searching by Category" %} + When searching for tickets by the **`category`** field, specific terms must be used instead of the category names: + * For **Customer** category tickets, use the term `request`. + * For **Back-office** category tickets, use the term `task`. + * For **Tracker** category tickets, use the term `tracker`. + {% /admonition %} + ### Accepted Operators {% admonition type="info" name="Searching based on `created_at`" %} @@ -336,7 +474,7 @@ def search( Returns ------- - SyncPager[Ticket] + SyncPager[typing.Optional[Ticket]] successful Examples @@ -412,7 +550,7 @@ async def reply( Returns ------- TicketReply - Admin quick_reply reply + Admin Reply to send Quick Reply Options Examples -------- @@ -430,7 +568,7 @@ async def main() -> None: ticket_id="123", request=ContactReplyTicketIntercomUserIdRequest( body="Thanks again :)", - intercom_user_id="667d619d8a68186f43bafe82", + intercom_user_id="6762f2971bb69f9f2193bc49", ), ) @@ -445,11 +583,13 @@ async def create( *, ticket_type_id: str, contacts: typing.Sequence[CreateTicketRequestContactsItem], + skip_notifications: typing.Optional[bool] = OMIT, + conversation_to_link_id: typing.Optional[str] = OMIT, company_id: typing.Optional[str] = OMIT, created_at: typing.Optional[int] = OMIT, - ticket_attributes: typing.Optional[TicketRequestCustomAttributes] = OMIT, + assignment: typing.Optional[CreateTicketRequestAssignment] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> Ticket: + ) -> typing.Optional[Ticket]: """ You can create a new ticket. @@ -461,20 +601,30 @@ async def create( contacts : typing.Sequence[CreateTicketRequestContactsItem] The list of contacts (users or leads) affected by this ticket. Currently only one is allowed + skip_notifications : typing.Optional[bool] + Option to disable notifications when a Ticket is created. + + conversation_to_link_id : typing.Optional[str] + The ID of the conversation you want to link to the ticket. Here are the valid ways of linking two tickets: + - conversation | back-office ticket + - customer tickets | non-shared back-office ticket + - conversation | tracker ticket + - customer ticket | tracker ticket + company_id : typing.Optional[str] - The ID of the company that the ticket is associated with. The ID that you set upon company creation. + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom created_at : typing.Optional[int] The time the ticket was created. If not provided, the current time will be used. - ticket_attributes : typing.Optional[TicketRequestCustomAttributes] + assignment : typing.Optional[CreateTicketRequestAssignment] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Ticket + typing.Optional[Ticket] Successful response Examples @@ -493,13 +643,9 @@ async def main() -> None: ticket_type_id="1234", contacts=[ CreateTicketRequestContactsItemId( - id="667d61b78a68186f43bafe8d", + id="6762f2d81bb69f9f2193bc54", ) ], - ticket_attributes={ - "_default_title_": "example", - "_default_description_": "there is a problem", - }, ) @@ -508,14 +654,103 @@ async def main() -> None: _response = await self._raw_client.create( ticket_type_id=ticket_type_id, contacts=contacts, + skip_notifications=skip_notifications, + conversation_to_link_id=conversation_to_link_id, company_id=company_id, created_at=created_at, - ticket_attributes=ticket_attributes, + assignment=assignment, request_options=request_options, ) return _response.data - async def get(self, ticket_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Ticket: + async def enqueue_create_ticket( + self, + *, + ticket_type_id: str, + contacts: typing.Sequence[CreateTicketRequestContactsItem], + skip_notifications: typing.Optional[bool] = OMIT, + conversation_to_link_id: typing.Optional[str] = OMIT, + company_id: typing.Optional[str] = OMIT, + created_at: typing.Optional[int] = OMIT, + assignment: typing.Optional[CreateTicketRequestAssignment] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> Jobs: + """ + Enqueues ticket creation for asynchronous processing, returning if the job was enqueued successfully to be processed. We attempt to perform a best-effort validation on inputs before tasks are enqueued. If the given parameters are incorrect, we won't enqueue the job. + + Parameters + ---------- + ticket_type_id : str + The ID of the type of ticket you want to create + + contacts : typing.Sequence[CreateTicketRequestContactsItem] + The list of contacts (users or leads) affected by this ticket. Currently only one is allowed + + skip_notifications : typing.Optional[bool] + Option to disable notifications when a Ticket is created. + + conversation_to_link_id : typing.Optional[str] + The ID of the conversation you want to link to the ticket. Here are the valid ways of linking two tickets: + - conversation | back-office ticket + - customer tickets | non-shared back-office ticket + - conversation | tracker ticket + - customer ticket | tracker ticket + + company_id : typing.Optional[str] + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom + + created_at : typing.Optional[int] + The time the ticket was created. If not provided, the current time will be used. + + assignment : typing.Optional[CreateTicketRequestAssignment] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Jobs + Successful response + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom, CreateTicketRequestContactsItemId + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.tickets.enqueue_create_ticket( + ticket_type_id="1234", + contacts=[ + CreateTicketRequestContactsItemId( + id="6762f2d81bb69f9f2193bc54", + ) + ], + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.enqueue_create_ticket( + ticket_type_id=ticket_type_id, + contacts=contacts, + skip_notifications=skip_notifications, + conversation_to_link_id=conversation_to_link_id, + company_id=company_id, + created_at=created_at, + assignment=assignment, + request_options=request_options, + ) + return _response.data + + async def get( + self, ticket_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.Optional[Ticket]: """ You can fetch the details of a single ticket. @@ -529,7 +764,7 @@ async def get(self, ticket_id: str, *, request_options: typing.Optional[RequestO Returns ------- - Ticket + typing.Optional[Ticket] Ticket found Examples @@ -559,13 +794,15 @@ async def update( ticket_id: str, *, ticket_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, - state: typing.Optional[UpdateTicketRequestState] = OMIT, + ticket_state_id: typing.Optional[str] = OMIT, + company_id: typing.Optional[str] = OMIT, open: typing.Optional[bool] = OMIT, is_shared: typing.Optional[bool] = OMIT, snoozed_until: typing.Optional[int] = OMIT, - assignment: typing.Optional[UpdateTicketRequestAssignment] = OMIT, + admin_id: typing.Optional[int] = OMIT, + assignee_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> Ticket: + ) -> typing.Optional[Ticket]: """ You can update a ticket. @@ -577,8 +814,11 @@ async def update( ticket_attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] The attributes set on the ticket. - state : typing.Optional[UpdateTicketRequestState] - The state of the ticket. + ticket_state_id : typing.Optional[str] + The ID of the ticket state associated with the ticket type. + + company_id : typing.Optional[str] + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company. open : typing.Optional[bool] Specify if a ticket is open. Set to false to close a ticket. Closing a ticket will also unsnooze it. @@ -589,14 +829,18 @@ async def update( snoozed_until : typing.Optional[int] The time you want the ticket to reopen. - assignment : typing.Optional[UpdateTicketRequestAssignment] + admin_id : typing.Optional[int] + The ID of the admin performing ticket update. Needed for workflows execution and attributing actions to specific admins. + + assignee_id : typing.Optional[str] + The ID of the admin or team to which the ticket is assigned. Set this 0 to unassign it. request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - Ticket + typing.Optional[Ticket] Successful response Examples @@ -604,7 +848,6 @@ async def update( import asyncio from intercom import AsyncIntercom - from intercom.tickets import UpdateTicketRequestAssignment client = AsyncIntercom( token="YOUR_TOKEN", @@ -618,13 +861,11 @@ async def main() -> None: "_default_title_": "example", "_default_description_": "there is a problem", }, - state="in_progress", + ticket_state_id="123", open=True, snoozed_until=1673609604, - assignment=UpdateTicketRequestAssignment( - admin_id="991267883", - assignee_id="991267885", - ), + admin_id=991268011, + assignee_id="123", ) @@ -633,22 +874,65 @@ async def main() -> None: _response = await self._raw_client.update( ticket_id, ticket_attributes=ticket_attributes, - state=state, + ticket_state_id=ticket_state_id, + company_id=company_id, open=open, is_shared=is_shared, snoozed_until=snoozed_until, - assignment=assignment, + admin_id=admin_id, + assignee_id=assignee_id, request_options=request_options, ) return _response.data + async def delete_ticket( + self, ticket_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> DeleteTicketResponse: + """ + You can delete a ticket using the Intercom provided ID. + + Parameters + ---------- + ticket_id : str + The unique identifier for the ticket which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeleteTicketResponse + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.tickets.delete_ticket( + ticket_id="ticket_id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_ticket(ticket_id, request_options=request_options) + return _response.data + async def search( self, *, query: SearchRequestQuery, pagination: typing.Optional[StartingAfterPaging] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncPager[Ticket]: + ) -> AsyncPager[typing.Optional[Ticket]]: """ You can search for multiple tickets by the value of their attributes in order to fetch exactly which ones you want. @@ -672,6 +956,7 @@ async def search( ### Accepted Fields Most keys listed as part of the Ticket model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foobar"`). + The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. | Field | Type | | :---------------------------------------- | :--------------------------------------------------------------------------------------- | @@ -691,6 +976,13 @@ async def search( | snoozed_until | Date (UNIX timestamp) | | ticket_attribute.{id} | String or Boolean or Date (UNIX timestamp) or Float or Integer | + {% admonition type="info" name="Searching by Category" %} + When searching for tickets by the **`category`** field, specific terms must be used instead of the category names: + * For **Customer** category tickets, use the term `request`. + * For **Back-office** category tickets, use the term `task`. + * For **Tracker** category tickets, use the term `tracker`. + {% /admonition %} + ### Accepted Operators {% admonition type="info" name="Searching based on `created_at`" %} @@ -723,7 +1015,7 @@ async def search( Returns ------- - AsyncPager[Ticket] + AsyncPager[typing.Optional[Ticket]] successful Examples diff --git a/src/intercom/tickets/raw_client.py b/src/intercom/tickets/raw_client.py index 1a604dc..d5e4264 100644 --- a/src/intercom/tickets/raw_client.py +++ b/src/intercom/tickets/raw_client.py @@ -14,17 +14,17 @@ from ..errors.bad_request_error import BadRequestError from ..errors.not_found_error import NotFoundError from ..errors.unauthorized_error import UnauthorizedError +from ..jobs.types.jobs import Jobs +from ..types.create_ticket_request_assignment import CreateTicketRequestAssignment from ..types.create_ticket_request_contacts_item import CreateTicketRequestContactsItem from ..types.error import Error from ..types.search_request_query import SearchRequestQuery from ..types.starting_after_paging import StartingAfterPaging from ..types.ticket_list import TicketList from ..types.ticket_reply import TicketReply -from ..types.ticket_request_custom_attributes import TicketRequestCustomAttributes +from .types.delete_ticket_response import DeleteTicketResponse from .types.ticket import Ticket from .types.tickets_reply_request_body import TicketsReplyRequestBody -from .types.update_ticket_request_assignment import UpdateTicketRequestAssignment -from .types.update_ticket_request_state import UpdateTicketRequestState # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -56,7 +56,7 @@ def reply( Returns ------- HttpResponse[TicketReply] - Admin quick_reply reply + Admin Reply to send Quick Reply Options """ _response = self._client_wrapper.httpx_client.request( f"tickets/{jsonable_encoder(ticket_id)}/reply", @@ -123,11 +123,13 @@ def create( *, ticket_type_id: str, contacts: typing.Sequence[CreateTicketRequestContactsItem], + skip_notifications: typing.Optional[bool] = OMIT, + conversation_to_link_id: typing.Optional[str] = OMIT, company_id: typing.Optional[str] = OMIT, created_at: typing.Optional[int] = OMIT, - ticket_attributes: typing.Optional[TicketRequestCustomAttributes] = OMIT, + assignment: typing.Optional[CreateTicketRequestAssignment] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[Ticket]: + ) -> HttpResponse[typing.Optional[Ticket]]: """ You can create a new ticket. @@ -139,33 +141,47 @@ def create( contacts : typing.Sequence[CreateTicketRequestContactsItem] The list of contacts (users or leads) affected by this ticket. Currently only one is allowed + skip_notifications : typing.Optional[bool] + Option to disable notifications when a Ticket is created. + + conversation_to_link_id : typing.Optional[str] + The ID of the conversation you want to link to the ticket. Here are the valid ways of linking two tickets: + - conversation | back-office ticket + - customer tickets | non-shared back-office ticket + - conversation | tracker ticket + - customer ticket | tracker ticket + company_id : typing.Optional[str] - The ID of the company that the ticket is associated with. The ID that you set upon company creation. + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom created_at : typing.Optional[int] The time the ticket was created. If not provided, the current time will be used. - ticket_attributes : typing.Optional[TicketRequestCustomAttributes] + assignment : typing.Optional[CreateTicketRequestAssignment] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - HttpResponse[Ticket] + HttpResponse[typing.Optional[Ticket]] Successful response """ _response = self._client_wrapper.httpx_client.request( "tickets", method="POST", json={ + "skip_notifications": skip_notifications, "ticket_type_id": ticket_type_id, "contacts": convert_and_respect_annotation_metadata( object_=contacts, annotation=typing.Sequence[CreateTicketRequestContactsItem], direction="write" ), + "conversation_to_link_id": conversation_to_link_id, "company_id": company_id, "created_at": created_at, - "ticket_attributes": ticket_attributes, + "assignment": convert_and_respect_annotation_metadata( + object_=assignment, annotation=CreateTicketRequestAssignment, direction="write" + ), }, headers={ "content-type": "application/json", @@ -174,11 +190,13 @@ def create( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Ticket, + typing.Optional[Ticket], construct_type( - type_=Ticket, # type: ignore + type_=typing.Optional[Ticket], # type: ignore object_=_response.json(), ), ) @@ -199,7 +217,117 @@ def create( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - def get(self, ticket_id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Ticket]: + def enqueue_create_ticket( + self, + *, + ticket_type_id: str, + contacts: typing.Sequence[CreateTicketRequestContactsItem], + skip_notifications: typing.Optional[bool] = OMIT, + conversation_to_link_id: typing.Optional[str] = OMIT, + company_id: typing.Optional[str] = OMIT, + created_at: typing.Optional[int] = OMIT, + assignment: typing.Optional[CreateTicketRequestAssignment] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[Jobs]: + """ + Enqueues ticket creation for asynchronous processing, returning if the job was enqueued successfully to be processed. We attempt to perform a best-effort validation on inputs before tasks are enqueued. If the given parameters are incorrect, we won't enqueue the job. + + Parameters + ---------- + ticket_type_id : str + The ID of the type of ticket you want to create + + contacts : typing.Sequence[CreateTicketRequestContactsItem] + The list of contacts (users or leads) affected by this ticket. Currently only one is allowed + + skip_notifications : typing.Optional[bool] + Option to disable notifications when a Ticket is created. + + conversation_to_link_id : typing.Optional[str] + The ID of the conversation you want to link to the ticket. Here are the valid ways of linking two tickets: + - conversation | back-office ticket + - customer tickets | non-shared back-office ticket + - conversation | tracker ticket + - customer ticket | tracker ticket + + company_id : typing.Optional[str] + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom + + created_at : typing.Optional[int] + The time the ticket was created. If not provided, the current time will be used. + + assignment : typing.Optional[CreateTicketRequestAssignment] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Jobs] + Successful response + """ + _response = self._client_wrapper.httpx_client.request( + "tickets/enqueue", + method="POST", + json={ + "skip_notifications": skip_notifications, + "ticket_type_id": ticket_type_id, + "contacts": convert_and_respect_annotation_metadata( + object_=contacts, annotation=typing.Sequence[CreateTicketRequestContactsItem], direction="write" + ), + "conversation_to_link_id": conversation_to_link_id, + "company_id": company_id, + "created_at": created_at, + "assignment": convert_and_respect_annotation_metadata( + object_=assignment, annotation=CreateTicketRequestAssignment, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Jobs, + construct_type( + type_=Jobs, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get( + self, ticket_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[typing.Optional[Ticket]]: """ You can fetch the details of a single ticket. @@ -213,7 +341,7 @@ def get(self, ticket_id: str, *, request_options: typing.Optional[RequestOptions Returns ------- - HttpResponse[Ticket] + HttpResponse[typing.Optional[Ticket]] Ticket found """ _response = self._client_wrapper.httpx_client.request( @@ -222,11 +350,13 @@ def get(self, ticket_id: str, *, request_options: typing.Optional[RequestOptions request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Ticket, + typing.Optional[Ticket], construct_type( - type_=Ticket, # type: ignore + type_=typing.Optional[Ticket], # type: ignore object_=_response.json(), ), ) @@ -252,13 +382,15 @@ def update( ticket_id: str, *, ticket_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, - state: typing.Optional[UpdateTicketRequestState] = OMIT, + ticket_state_id: typing.Optional[str] = OMIT, + company_id: typing.Optional[str] = OMIT, open: typing.Optional[bool] = OMIT, is_shared: typing.Optional[bool] = OMIT, snoozed_until: typing.Optional[int] = OMIT, - assignment: typing.Optional[UpdateTicketRequestAssignment] = OMIT, + admin_id: typing.Optional[int] = OMIT, + assignee_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[Ticket]: + ) -> HttpResponse[typing.Optional[Ticket]]: """ You can update a ticket. @@ -270,8 +402,11 @@ def update( ticket_attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] The attributes set on the ticket. - state : typing.Optional[UpdateTicketRequestState] - The state of the ticket. + ticket_state_id : typing.Optional[str] + The ID of the ticket state associated with the ticket type. + + company_id : typing.Optional[str] + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company. open : typing.Optional[bool] Specify if a ticket is open. Set to false to close a ticket. Closing a ticket will also unsnooze it. @@ -282,14 +417,18 @@ def update( snoozed_until : typing.Optional[int] The time you want the ticket to reopen. - assignment : typing.Optional[UpdateTicketRequestAssignment] + admin_id : typing.Optional[int] + The ID of the admin performing ticket update. Needed for workflows execution and attributing actions to specific admins. + + assignee_id : typing.Optional[str] + The ID of the admin or team to which the ticket is assigned. Set this 0 to unassign it. request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - HttpResponse[Ticket] + HttpResponse[typing.Optional[Ticket]] Successful response """ _response = self._client_wrapper.httpx_client.request( @@ -297,13 +436,13 @@ def update( method="PUT", json={ "ticket_attributes": ticket_attributes, - "state": state, + "ticket_state_id": ticket_state_id, + "company_id": company_id, "open": open, "is_shared": is_shared, "snoozed_until": snoozed_until, - "assignment": convert_and_respect_annotation_metadata( - object_=assignment, annotation=UpdateTicketRequestAssignment, direction="write" - ), + "admin_id": admin_id, + "assignee_id": assignee_id, }, headers={ "content-type": "application/json", @@ -311,12 +450,86 @@ def update( request_options=request_options, omit=OMIT, ) + try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[Ticket], + construct_type( + type_=typing.Optional[Ticket], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def delete_ticket( + self, ticket_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[DeleteTicketResponse]: + """ + You can delete a ticket using the Intercom provided ID. + + Parameters + ---------- + ticket_id : str + The unique identifier for the ticket which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeleteTicketResponse] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"tickets/{jsonable_encoder(ticket_id)}", + method="DELETE", + request_options=request_options, + ) try: if 200 <= _response.status_code < 300: _data = typing.cast( - Ticket, + DeleteTicketResponse, construct_type( - type_=Ticket, # type: ignore + type_=DeleteTicketResponse, # type: ignore object_=_response.json(), ), ) @@ -354,7 +567,7 @@ def search( query: SearchRequestQuery, pagination: typing.Optional[StartingAfterPaging] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> SyncPager[Ticket]: + ) -> SyncPager[typing.Optional[Ticket]]: """ You can search for multiple tickets by the value of their attributes in order to fetch exactly which ones you want. @@ -378,6 +591,7 @@ def search( ### Accepted Fields Most keys listed as part of the Ticket model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foobar"`). + The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. | Field | Type | | :---------------------------------------- | :--------------------------------------------------------------------------------------- | @@ -397,6 +611,13 @@ def search( | snoozed_until | Date (UNIX timestamp) | | ticket_attribute.{id} | String or Boolean or Date (UNIX timestamp) or Float or Integer | + {% admonition type="info" name="Searching by Category" %} + When searching for tickets by the **`category`** field, specific terms must be used instead of the category names: + * For **Customer** category tickets, use the term `request`. + * For **Back-office** category tickets, use the term `task`. + * For **Tracker** category tickets, use the term `tracker`. + {% /admonition %} + ### Accepted Operators {% admonition type="info" name="Searching based on `created_at`" %} @@ -429,7 +650,7 @@ def search( Returns ------- - SyncPager[Ticket] + SyncPager[typing.Optional[Ticket]] successful """ _response = self._client_wrapper.httpx_client.request( @@ -504,7 +725,7 @@ async def reply( Returns ------- AsyncHttpResponse[TicketReply] - Admin quick_reply reply + Admin Reply to send Quick Reply Options """ _response = await self._client_wrapper.httpx_client.request( f"tickets/{jsonable_encoder(ticket_id)}/reply", @@ -571,11 +792,13 @@ async def create( *, ticket_type_id: str, contacts: typing.Sequence[CreateTicketRequestContactsItem], + skip_notifications: typing.Optional[bool] = OMIT, + conversation_to_link_id: typing.Optional[str] = OMIT, company_id: typing.Optional[str] = OMIT, created_at: typing.Optional[int] = OMIT, - ticket_attributes: typing.Optional[TicketRequestCustomAttributes] = OMIT, + assignment: typing.Optional[CreateTicketRequestAssignment] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[Ticket]: + ) -> AsyncHttpResponse[typing.Optional[Ticket]]: """ You can create a new ticket. @@ -587,33 +810,146 @@ async def create( contacts : typing.Sequence[CreateTicketRequestContactsItem] The list of contacts (users or leads) affected by this ticket. Currently only one is allowed + skip_notifications : typing.Optional[bool] + Option to disable notifications when a Ticket is created. + + conversation_to_link_id : typing.Optional[str] + The ID of the conversation you want to link to the ticket. Here are the valid ways of linking two tickets: + - conversation | back-office ticket + - customer tickets | non-shared back-office ticket + - conversation | tracker ticket + - customer ticket | tracker ticket + company_id : typing.Optional[str] - The ID of the company that the ticket is associated with. The ID that you set upon company creation. + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom created_at : typing.Optional[int] The time the ticket was created. If not provided, the current time will be used. - ticket_attributes : typing.Optional[TicketRequestCustomAttributes] + assignment : typing.Optional[CreateTicketRequestAssignment] request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncHttpResponse[Ticket] + AsyncHttpResponse[typing.Optional[Ticket]] Successful response """ _response = await self._client_wrapper.httpx_client.request( "tickets", method="POST", json={ + "skip_notifications": skip_notifications, "ticket_type_id": ticket_type_id, "contacts": convert_and_respect_annotation_metadata( object_=contacts, annotation=typing.Sequence[CreateTicketRequestContactsItem], direction="write" ), + "conversation_to_link_id": conversation_to_link_id, "company_id": company_id, "created_at": created_at, - "ticket_attributes": ticket_attributes, + "assignment": convert_and_respect_annotation_metadata( + object_=assignment, annotation=CreateTicketRequestAssignment, direction="write" + ), + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[Ticket], + construct_type( + type_=typing.Optional[Ticket], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def enqueue_create_ticket( + self, + *, + ticket_type_id: str, + contacts: typing.Sequence[CreateTicketRequestContactsItem], + skip_notifications: typing.Optional[bool] = OMIT, + conversation_to_link_id: typing.Optional[str] = OMIT, + company_id: typing.Optional[str] = OMIT, + created_at: typing.Optional[int] = OMIT, + assignment: typing.Optional[CreateTicketRequestAssignment] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[Jobs]: + """ + Enqueues ticket creation for asynchronous processing, returning if the job was enqueued successfully to be processed. We attempt to perform a best-effort validation on inputs before tasks are enqueued. If the given parameters are incorrect, we won't enqueue the job. + + Parameters + ---------- + ticket_type_id : str + The ID of the type of ticket you want to create + + contacts : typing.Sequence[CreateTicketRequestContactsItem] + The list of contacts (users or leads) affected by this ticket. Currently only one is allowed + + skip_notifications : typing.Optional[bool] + Option to disable notifications when a Ticket is created. + + conversation_to_link_id : typing.Optional[str] + The ID of the conversation you want to link to the ticket. Here are the valid ways of linking two tickets: + - conversation | back-office ticket + - customer tickets | non-shared back-office ticket + - conversation | tracker ticket + - customer ticket | tracker ticket + + company_id : typing.Optional[str] + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom + + created_at : typing.Optional[int] + The time the ticket was created. If not provided, the current time will be used. + + assignment : typing.Optional[CreateTicketRequestAssignment] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Jobs] + Successful response + """ + _response = await self._client_wrapper.httpx_client.request( + "tickets/enqueue", + method="POST", + json={ + "skip_notifications": skip_notifications, + "ticket_type_id": ticket_type_id, + "contacts": convert_and_respect_annotation_metadata( + object_=contacts, annotation=typing.Sequence[CreateTicketRequestContactsItem], direction="write" + ), + "conversation_to_link_id": conversation_to_link_id, + "company_id": company_id, + "created_at": created_at, + "assignment": convert_and_respect_annotation_metadata( + object_=assignment, annotation=CreateTicketRequestAssignment, direction="write" + ), }, headers={ "content-type": "application/json", @@ -624,13 +960,24 @@ async def create( try: if 200 <= _response.status_code < 300: _data = typing.cast( - Ticket, + Jobs, construct_type( - type_=Ticket, # type: ignore + type_=Jobs, # type: ignore object_=_response.json(), ), ) return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) if _response.status_code == 401: raise UnauthorizedError( headers=dict(_response.headers), @@ -649,7 +996,7 @@ async def create( async def get( self, ticket_id: str, *, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[Ticket]: + ) -> AsyncHttpResponse[typing.Optional[Ticket]]: """ You can fetch the details of a single ticket. @@ -663,7 +1010,7 @@ async def get( Returns ------- - AsyncHttpResponse[Ticket] + AsyncHttpResponse[typing.Optional[Ticket]] Ticket found """ _response = await self._client_wrapper.httpx_client.request( @@ -672,11 +1019,13 @@ async def get( request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Ticket, + typing.Optional[Ticket], construct_type( - type_=Ticket, # type: ignore + type_=typing.Optional[Ticket], # type: ignore object_=_response.json(), ), ) @@ -702,13 +1051,15 @@ async def update( ticket_id: str, *, ticket_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT, - state: typing.Optional[UpdateTicketRequestState] = OMIT, + ticket_state_id: typing.Optional[str] = OMIT, + company_id: typing.Optional[str] = OMIT, open: typing.Optional[bool] = OMIT, is_shared: typing.Optional[bool] = OMIT, snoozed_until: typing.Optional[int] = OMIT, - assignment: typing.Optional[UpdateTicketRequestAssignment] = OMIT, + admin_id: typing.Optional[int] = OMIT, + assignee_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[Ticket]: + ) -> AsyncHttpResponse[typing.Optional[Ticket]]: """ You can update a ticket. @@ -720,8 +1071,11 @@ async def update( ticket_attributes : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] The attributes set on the ticket. - state : typing.Optional[UpdateTicketRequestState] - The state of the ticket. + ticket_state_id : typing.Optional[str] + The ID of the ticket state associated with the ticket type. + + company_id : typing.Optional[str] + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom. Set to nil to remove company. open : typing.Optional[bool] Specify if a ticket is open. Set to false to close a ticket. Closing a ticket will also unsnooze it. @@ -732,14 +1086,18 @@ async def update( snoozed_until : typing.Optional[int] The time you want the ticket to reopen. - assignment : typing.Optional[UpdateTicketRequestAssignment] + admin_id : typing.Optional[int] + The ID of the admin performing ticket update. Needed for workflows execution and attributing actions to specific admins. + + assignee_id : typing.Optional[str] + The ID of the admin or team to which the ticket is assigned. Set this 0 to unassign it. request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncHttpResponse[Ticket] + AsyncHttpResponse[typing.Optional[Ticket]] Successful response """ _response = await self._client_wrapper.httpx_client.request( @@ -747,13 +1105,13 @@ async def update( method="PUT", json={ "ticket_attributes": ticket_attributes, - "state": state, + "ticket_state_id": ticket_state_id, + "company_id": company_id, "open": open, "is_shared": is_shared, "snoozed_until": snoozed_until, - "assignment": convert_and_respect_annotation_metadata( - object_=assignment, annotation=UpdateTicketRequestAssignment, direction="write" - ), + "admin_id": admin_id, + "assignee_id": assignee_id, }, headers={ "content-type": "application/json", @@ -761,12 +1119,86 @@ async def update( request_options=request_options, omit=OMIT, ) + try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[Ticket], + construct_type( + type_=typing.Optional[Ticket], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def delete_ticket( + self, ticket_id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[DeleteTicketResponse]: + """ + You can delete a ticket using the Intercom provided ID. + + Parameters + ---------- + ticket_id : str + The unique identifier for the ticket which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeleteTicketResponse] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"tickets/{jsonable_encoder(ticket_id)}", + method="DELETE", + request_options=request_options, + ) try: if 200 <= _response.status_code < 300: _data = typing.cast( - Ticket, + DeleteTicketResponse, construct_type( - type_=Ticket, # type: ignore + type_=DeleteTicketResponse, # type: ignore object_=_response.json(), ), ) @@ -804,7 +1236,7 @@ async def search( query: SearchRequestQuery, pagination: typing.Optional[StartingAfterPaging] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncPager[Ticket]: + ) -> AsyncPager[typing.Optional[Ticket]]: """ You can search for multiple tickets by the value of their attributes in order to fetch exactly which ones you want. @@ -828,6 +1260,7 @@ async def search( ### Accepted Fields Most keys listed as part of the Ticket model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as `created_at` accepts a date, the `value` cannot be a string such as `"foobar"`). + The `source.body` field is unique as the search will not be performed against the entire value, but instead against every element of the value separately. For example, when searching for a conversation with a `"I need support"` body - the query should contain a `=` operator with the value `"support"` for such conversation to be returned. A query with a `=` operator and a `"need support"` value will not yield a result. | Field | Type | | :---------------------------------------- | :--------------------------------------------------------------------------------------- | @@ -847,6 +1280,13 @@ async def search( | snoozed_until | Date (UNIX timestamp) | | ticket_attribute.{id} | String or Boolean or Date (UNIX timestamp) or Float or Integer | + {% admonition type="info" name="Searching by Category" %} + When searching for tickets by the **`category`** field, specific terms must be used instead of the category names: + * For **Customer** category tickets, use the term `request`. + * For **Back-office** category tickets, use the term `task`. + * For **Tracker** category tickets, use the term `tracker`. + {% /admonition %} + ### Accepted Operators {% admonition type="info" name="Searching based on `created_at`" %} @@ -879,7 +1319,7 @@ async def search( Returns ------- - AsyncPager[Ticket] + AsyncPager[typing.Optional[Ticket]] successful """ _response = await self._client_wrapper.httpx_client.request( diff --git a/src/intercom/tickets/types/__init__.py b/src/intercom/tickets/types/__init__.py index c28b527..8e89c14 100644 --- a/src/intercom/tickets/types/__init__.py +++ b/src/intercom/tickets/types/__init__.py @@ -2,30 +2,48 @@ # isort: skip_file +from .delete_ticket_response import DeleteTicketResponse from .ticket import Ticket from .ticket_category import TicketCategory from .ticket_contacts import TicketContacts from .ticket_part import TicketPart from .ticket_part_previous_ticket_state import TicketPartPreviousTicketState from .ticket_part_ticket_state import TicketPartTicketState -from .ticket_ticket_state import TicketTicketState +from .ticket_part_updated_attribute_data import TicketPartUpdatedAttributeData +from .ticket_part_updated_attribute_data_attribute import TicketPartUpdatedAttributeDataAttribute +from .ticket_part_updated_attribute_data_value import TicketPartUpdatedAttributeDataValue +from .ticket_part_updated_attribute_data_value_id import TicketPartUpdatedAttributeDataValueId +from .ticket_part_updated_attribute_data_value_label import TicketPartUpdatedAttributeDataValueLabel +from .ticket_state import TicketState +from .ticket_state_category import TicketStateCategory +from .ticket_state_detailed import TicketStateDetailed +from .ticket_state_detailed_category import TicketStateDetailedCategory +from .ticket_state_detailed_ticket_types import TicketStateDetailedTicketTypes from .ticket_type import TicketType from .ticket_type_category import TicketTypeCategory +from .ticket_type_ticket_states import TicketTypeTicketStates from .tickets_reply_request_body import TicketsReplyRequestBody -from .update_ticket_request_assignment import UpdateTicketRequestAssignment -from .update_ticket_request_state import UpdateTicketRequestState __all__ = [ + "DeleteTicketResponse", "Ticket", "TicketCategory", "TicketContacts", "TicketPart", "TicketPartPreviousTicketState", "TicketPartTicketState", - "TicketTicketState", + "TicketPartUpdatedAttributeData", + "TicketPartUpdatedAttributeDataAttribute", + "TicketPartUpdatedAttributeDataValue", + "TicketPartUpdatedAttributeDataValueId", + "TicketPartUpdatedAttributeDataValueLabel", + "TicketState", + "TicketStateCategory", + "TicketStateDetailed", + "TicketStateDetailedCategory", + "TicketStateDetailedTicketTypes", "TicketType", "TicketTypeCategory", + "TicketTypeTicketStates", "TicketsReplyRequestBody", - "UpdateTicketRequestAssignment", - "UpdateTicketRequestState", ] diff --git a/src/intercom/tickets/types/delete_ticket_response.py b/src/intercom/tickets/types/delete_ticket_response.py new file mode 100644 index 0000000..4b748b1 --- /dev/null +++ b/src/intercom/tickets/types/delete_ticket_response.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class DeleteTicketResponse(UncheckedBaseModel): + """ + Response when a ticket is deleted. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier for the ticket. + """ + + object: typing.Optional[typing.Literal["ticket"]] = pydantic.Field(default=None) + """ + always ticket + """ + + deleted: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the ticket is deleted or not. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/tickets/types/ticket.py b/src/intercom/tickets/types/ticket.py index a7e72bb..eca715f 100644 --- a/src/intercom/tickets/types/ticket.py +++ b/src/intercom/tickets/types/ticket.py @@ -10,7 +10,7 @@ from ...types.ticket_parts import TicketParts from .ticket_category import TicketCategory from .ticket_contacts import TicketContacts -from .ticket_ticket_state import TicketTicketState +from .ticket_state import TicketState from .ticket_type import TicketType @@ -19,34 +19,30 @@ class Ticket(UncheckedBaseModel): Tickets are how you track requests from your users. """ - type: typing.Literal["ticket"] = pydantic.Field(default="ticket") + type: typing.Optional[typing.Literal["ticket"]] = pydantic.Field(default=None) """ Always ticket """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier for the ticket which is given by Intercom. """ - ticket_id: str = pydantic.Field() + ticket_id: typing.Optional[str] = pydantic.Field(default=None) """ The ID of the Ticket used in the Intercom Inbox and Messenger. Do not use ticket_id for API queries. """ - category: TicketCategory = pydantic.Field() + category: typing.Optional[TicketCategory] = pydantic.Field(default=None) """ Category of the Ticket. """ - ticket_attributes: TicketCustomAttributes - ticket_state: TicketTicketState = pydantic.Field() - """ - The state the ticket is currently in - """ - - ticket_type: TicketType - contacts: TicketContacts + ticket_attributes: typing.Optional[TicketCustomAttributes] = None + ticket_state: typing.Optional[TicketState] = None + ticket_type: typing.Optional[TicketType] = None + contacts: typing.Optional[TicketContacts] = None admin_assignee_id: typing.Optional[str] = pydantic.Field(default=None) """ The id representing the admin assigned to the ticket. @@ -84,16 +80,6 @@ class Ticket(UncheckedBaseModel): Whether or not the ticket is shared with the customer. """ - ticket_state_internal_label: typing.Optional[str] = pydantic.Field(default=None) - """ - The state the ticket is currently in, in a human readable form - visible in Intercom - """ - - ticket_state_external_label: typing.Optional[str] = pydantic.Field(default=None) - """ - The state the ticket is currently in, in a human readable form - visible to customers, in the messenger, email and tickets portal. - """ - if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/tickets/types/ticket_contacts.py b/src/intercom/tickets/types/ticket_contacts.py index 7a11c16..af0454d 100644 --- a/src/intercom/tickets/types/ticket_contacts.py +++ b/src/intercom/tickets/types/ticket_contacts.py @@ -13,12 +13,12 @@ class TicketContacts(UncheckedBaseModel): The list of contacts affected by a ticket. """ - type: typing.Literal["contact.list"] = pydantic.Field(default="contact.list") + type: typing.Optional[typing.Literal["contact.list"]] = pydantic.Field(default=None) """ always contact.list """ - contacts: typing.List[ContactReference] = pydantic.Field() + contacts: typing.Optional[typing.List[ContactReference]] = pydantic.Field(default=None) """ The list of contacts affected by this ticket. """ diff --git a/src/intercom/tickets/types/ticket_part.py b/src/intercom/tickets/types/ticket_part.py index 415a3a4..c6056e2 100644 --- a/src/intercom/tickets/types/ticket_part.py +++ b/src/intercom/tickets/types/ticket_part.py @@ -10,6 +10,7 @@ from ...types.ticket_part_author import TicketPartAuthor from .ticket_part_previous_ticket_state import TicketPartPreviousTicketState from .ticket_part_ticket_state import TicketPartTicketState +from .ticket_part_updated_attribute_data import TicketPartUpdatedAttributeData class TicketPart(UncheckedBaseModel): @@ -17,17 +18,17 @@ class TicketPart(UncheckedBaseModel): A Ticket Part represents a message in the ticket. """ - type: typing.Literal["ticket_part"] = pydantic.Field(default="ticket_part") + type: typing.Optional[str] = pydantic.Field(default=None) """ Always ticket_part """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id representing the ticket part. """ - part_type: str = pydantic.Field() + part_type: typing.Optional[str] = pydantic.Field(default=None) """ The type of ticket part. """ @@ -42,12 +43,12 @@ class TicketPart(UncheckedBaseModel): The previous state of the ticket. """ - ticket_state: TicketPartTicketState = pydantic.Field() + ticket_state: typing.Optional[TicketPartTicketState] = pydantic.Field(default=None) """ The state of the ticket. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ The time the ticket part was created. """ @@ -78,6 +79,16 @@ class TicketPart(UncheckedBaseModel): Whether or not the ticket part has been redacted. """ + app_package_code: typing.Optional[str] = pydantic.Field(default=None) + """ + The app package code if this part was created via API. Note this field won't show if the part was not created via API. + """ + + updated_attribute_data: typing.Optional[TicketPartUpdatedAttributeData] = pydantic.Field(default=None) + """ + The updated attribute data of the ticket part. Only present for attribute update parts. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/tickets/types/ticket_part_updated_attribute_data.py b/src/intercom/tickets/types/ticket_part_updated_attribute_data.py new file mode 100644 index 0000000..42980c0 --- /dev/null +++ b/src/intercom/tickets/types/ticket_part_updated_attribute_data.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .ticket_part_updated_attribute_data_attribute import TicketPartUpdatedAttributeDataAttribute +from .ticket_part_updated_attribute_data_value import TicketPartUpdatedAttributeDataValue + + +class TicketPartUpdatedAttributeData(UncheckedBaseModel): + """ + The updated attribute data of the ticket part. Only present for attribute update parts. + """ + + attribute: TicketPartUpdatedAttributeDataAttribute = pydantic.Field() + """ + Information about the attribute that was updated. + """ + + value: TicketPartUpdatedAttributeDataValue = pydantic.Field() + """ + The new value of the attribute. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/tickets/types/ticket_part_updated_attribute_data_attribute.py b/src/intercom/tickets/types/ticket_part_updated_attribute_data_attribute.py new file mode 100644 index 0000000..b7bd91e --- /dev/null +++ b/src/intercom/tickets/types/ticket_part_updated_attribute_data_attribute.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class TicketPartUpdatedAttributeDataAttribute(UncheckedBaseModel): + """ + Information about the attribute that was updated. + """ + + type: typing.Literal["attribute"] = pydantic.Field(default="attribute") + """ + The type of the object. Always 'attribute'. + """ + + id: str = pydantic.Field() + """ + The unique identifier of the attribute. + """ + + label: str = pydantic.Field() + """ + The human-readable name of the attribute. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/tickets/types/ticket_part_updated_attribute_data_value.py b/src/intercom/tickets/types/ticket_part_updated_attribute_data_value.py new file mode 100644 index 0000000..9ea5c01 --- /dev/null +++ b/src/intercom/tickets/types/ticket_part_updated_attribute_data_value.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .ticket_part_updated_attribute_data_value_id import TicketPartUpdatedAttributeDataValueId +from .ticket_part_updated_attribute_data_value_label import TicketPartUpdatedAttributeDataValueLabel + + +class TicketPartUpdatedAttributeDataValue(UncheckedBaseModel): + """ + The new value of the attribute. + """ + + type: typing.Literal["value"] = pydantic.Field(default="value") + """ + The type of the object. Always 'value'. + """ + + id: TicketPartUpdatedAttributeDataValueId + label: TicketPartUpdatedAttributeDataValueLabel + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/tickets/types/ticket_part_updated_attribute_data_value_id.py b/src/intercom/tickets/types/ticket_part_updated_attribute_data_value_id.py new file mode 100644 index 0000000..01d2f9d --- /dev/null +++ b/src/intercom/tickets/types/ticket_part_updated_attribute_data_value_id.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TicketPartUpdatedAttributeDataValueId = typing.Union[typing.Optional[str], typing.List[int]] diff --git a/src/intercom/tickets/types/ticket_part_updated_attribute_data_value_label.py b/src/intercom/tickets/types/ticket_part_updated_attribute_data_value_label.py new file mode 100644 index 0000000..4026e8a --- /dev/null +++ b/src/intercom/tickets/types/ticket_part_updated_attribute_data_value_label.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TicketPartUpdatedAttributeDataValueLabel = typing.Union[str, typing.List[str]] diff --git a/src/intercom/tickets/types/ticket_state.py b/src/intercom/tickets/types/ticket_state.py new file mode 100644 index 0000000..6beb7dd --- /dev/null +++ b/src/intercom/tickets/types/ticket_state.py @@ -0,0 +1,48 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .ticket_state_category import TicketStateCategory + + +class TicketState(UncheckedBaseModel): + """ + A ticket state, used to define the state of a ticket. + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + String representing the object's type. Always has the value `ticket_state`. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the ticket state + """ + + category: typing.Optional[TicketStateCategory] = pydantic.Field(default=None) + """ + The category of the ticket state + """ + + internal_label: typing.Optional[str] = pydantic.Field(default=None) + """ + The state the ticket is currently in, in a human readable form - visible in Intercom + """ + + external_label: typing.Optional[str] = pydantic.Field(default=None) + """ + The state the ticket is currently in, in a human readable form - visible to customers, in the messenger, email and tickets portal. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/tickets/types/ticket_ticket_state.py b/src/intercom/tickets/types/ticket_state_category.py similarity index 83% rename from src/intercom/tickets/types/ticket_ticket_state.py rename to src/intercom/tickets/types/ticket_state_category.py index 0c384dd..d53c56a 100644 --- a/src/intercom/tickets/types/ticket_ticket_state.py +++ b/src/intercom/tickets/types/ticket_state_category.py @@ -2,6 +2,6 @@ import typing -TicketTicketState = typing.Union[ +TicketStateCategory = typing.Union[ typing.Literal["submitted", "in_progress", "waiting_on_customer", "resolved"], typing.Any ] diff --git a/src/intercom/tickets/types/ticket_state_detailed.py b/src/intercom/tickets/types/ticket_state_detailed.py new file mode 100644 index 0000000..973767f --- /dev/null +++ b/src/intercom/tickets/types/ticket_state_detailed.py @@ -0,0 +1,59 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .ticket_state_detailed_category import TicketStateDetailedCategory +from .ticket_state_detailed_ticket_types import TicketStateDetailedTicketTypes + + +class TicketStateDetailed(UncheckedBaseModel): + """ + A ticket state, used to define the state of a ticket. + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + String representing the object's type. Always has the value `ticket_state`. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the ticket state + """ + + category: typing.Optional[TicketStateDetailedCategory] = pydantic.Field(default=None) + """ + The category of the ticket state + """ + + internal_label: typing.Optional[str] = pydantic.Field(default=None) + """ + The state the ticket is currently in, in a human readable form - visible in Intercom + """ + + external_label: typing.Optional[str] = pydantic.Field(default=None) + """ + The state the ticket is currently in, in a human readable form - visible to customers, in the messenger, email and tickets portal. + """ + + archived: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the ticket state is archived + """ + + ticket_types: typing.Optional[TicketStateDetailedTicketTypes] = pydantic.Field(default=None) + """ + A list of ticket types associated with a given ticket state. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/tickets/types/ticket_state_detailed_category.py b/src/intercom/tickets/types/ticket_state_detailed_category.py new file mode 100644 index 0000000..d8426ec --- /dev/null +++ b/src/intercom/tickets/types/ticket_state_detailed_category.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +TicketStateDetailedCategory = typing.Union[ + typing.Literal["submitted", "in_progress", "waiting_on_customer", "resolved"], typing.Any +] diff --git a/src/intercom/tickets/types/ticket_state_detailed_ticket_types.py b/src/intercom/tickets/types/ticket_state_detailed_ticket_types.py new file mode 100644 index 0000000..4a5f143 --- /dev/null +++ b/src/intercom/tickets/types/ticket_state_detailed_ticket_types.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .ticket_type import TicketType + + +class TicketStateDetailedTicketTypes(UncheckedBaseModel): + """ + A list of ticket types associated with a given ticket state. + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + String representing the object's type. Always has the value `list`. + """ + + data: typing.Optional[typing.List[typing.Optional[TicketType]]] = pydantic.Field(default=None) + """ + A list of ticket type attributes associated with a given ticket type. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/tickets/types/ticket_type.py b/src/intercom/tickets/types/ticket_type.py index 6f92762..fef0d5a 100644 --- a/src/intercom/tickets/types/ticket_type.py +++ b/src/intercom/tickets/types/ticket_type.py @@ -7,6 +7,7 @@ from ...core.unchecked_base_model import UncheckedBaseModel from ...types.ticket_type_attribute_list import TicketTypeAttributeList from .ticket_type_category import TicketTypeCategory +from .ticket_type_ticket_states import TicketTypeTicketStates class TicketType(UncheckedBaseModel): @@ -14,48 +15,53 @@ class TicketType(UncheckedBaseModel): A ticket type, used to define the data fields to be captured in a ticket. """ - type: typing.Literal["ticket_type"] = pydantic.Field(default="ticket_type") + type: typing.Optional[str] = pydantic.Field(default=None) """ String representing the object's type. Always has the value `ticket_type`. """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id representing the ticket type. """ - category: TicketTypeCategory = pydantic.Field() + category: typing.Optional[TicketTypeCategory] = pydantic.Field(default=None) """ Category of the Ticket Type. """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the ticket type """ - description: str = pydantic.Field() + description: typing.Optional[str] = pydantic.Field(default=None) """ The description of the ticket type """ - icon: str = pydantic.Field() + icon: typing.Optional[str] = pydantic.Field(default=None) """ The icon of the ticket type """ - workspace_id: str = pydantic.Field() + workspace_id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the workspace that the ticket type belongs to. """ - ticket_type_attributes: TicketTypeAttributeList - archived: bool = pydantic.Field() + ticket_type_attributes: typing.Optional[TicketTypeAttributeList] = None + ticket_states: typing.Optional[TicketTypeTicketStates] = pydantic.Field(default=None) + """ + A list of ticket states associated with a given ticket type. + """ + + archived: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the ticket type is archived or not. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ The date and time the ticket type was created. """ diff --git a/src/intercom/tickets/types/ticket_type_ticket_states.py b/src/intercom/tickets/types/ticket_type_ticket_states.py new file mode 100644 index 0000000..73d3d3c --- /dev/null +++ b/src/intercom/tickets/types/ticket_type_ticket_states.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .ticket_state import TicketState + + +class TicketTypeTicketStates(UncheckedBaseModel): + """ + A list of ticket states associated with a given ticket type. + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + String representing the object's type. Always has the value `list`. + """ + + data: typing.Optional[typing.List[typing.Optional[TicketState]]] = pydantic.Field(default=None) + """ + A list of ticket states associated with a given ticket type. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/tickets/types/update_ticket_request_state.py b/src/intercom/tickets/types/update_ticket_request_state.py deleted file mode 100644 index effb50f..0000000 --- a/src/intercom/tickets/types/update_ticket_request_state.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -UpdateTicketRequestState = typing.Union[typing.Literal["in_progress", "waiting_on_customer", "resolved"], typing.Any] diff --git a/src/intercom/types/__init__.py b/src/intercom/types/__init__.py index 6cdd39b..a31c0a6 100644 --- a/src/intercom/types/__init__.py +++ b/src/intercom/types/__init__.py @@ -2,7 +2,6 @@ # isort: skip_file -from .action_component import ActionComponent, ActionComponent_Sheet, ActionComponent_Submit, ActionComponent_Url from .activity_log import ActivityLog from .activity_log_activity_type import ActivityLogActivityType from .activity_log_list import ActivityLogList @@ -26,48 +25,26 @@ from .article_translated_content import ArticleTranslatedContent from .assign_conversation_request import AssignConversationRequest from .assign_conversation_request_type import AssignConversationRequestType -from .button_component import ButtonComponent -from .button_component_style import ButtonComponentStyle -from .canvas_object import CanvasObject -from .checkbox_component import CheckboxComponent -from .checkbox_component_save_state import CheckboxComponentSaveState -from .checkbox_option import CheckboxOption +from .away_status_reason import AwayStatusReason +from .call_list import CallList from .close_conversation_request import CloseConversationRequest from .collection_list import CollectionList from .company_attached_contacts import CompanyAttachedContacts from .company_attached_segments import CompanyAttachedSegments +from .company_data import CompanyData from .company_list import CompanyList from .company_scroll import CompanyScroll -from .component import ( - Component, - Component_Button, - Component_Checkbox, - Component_DataTable, - Component_Divider, - Component_Dropdown, - Component_Image, - Component_Input, - Component_List, - Component_SingleSelect, - Component_Spacer, - Component_Text, - Component_Textarea, -) -from .configure_request import ConfigureRequest -from .configure_request_component_id import ConfigureRequestComponentId -from .configure_request_zero import ConfigureRequestZero -from .configure_response import ConfigureResponse -from .configure_response_canvas import ConfigureResponseCanvas from .contact_archived import ContactArchived from .contact_attached_companies import ContactAttachedCompanies +from .contact_blocked import ContactBlocked from .contact_companies import ContactCompanies -from .contact_company import ContactCompany from .contact_deleted import ContactDeleted from .contact_list import ContactList from .contact_location import ContactLocation from .contact_notes import ContactNotes from .contact_reference import ContactReference from .contact_reply_base_request import ContactReplyBaseRequest +from .contact_reply_base_request_reply_options_item import ContactReplyBaseRequestReplyOptionsItem from .contact_reply_conversation_request import ContactReplyConversationRequest from .contact_reply_email_request import ContactReplyEmailRequest from .contact_reply_intercom_user_id_request import ContactReplyIntercomUserIdRequest @@ -81,31 +58,50 @@ from .contact_subscription_types import ContactSubscriptionTypes from .contact_tags import ContactTags from .contact_unarchived import ContactUnarchived -from .content_object import ContentObject from .content_sources_list import ContentSourcesList -from .context import Context -from .context_location import ContextLocation from .conversation_attachment_files import ConversationAttachmentFiles +from .conversation_attribute_updated_by_admin import ConversationAttributeUpdatedByAdmin +from .conversation_attribute_updated_by_admin_attribute import ConversationAttributeUpdatedByAdminAttribute +from .conversation_attribute_updated_by_admin_value import ConversationAttributeUpdatedByAdminValue +from .conversation_attribute_updated_by_workflow import ConversationAttributeUpdatedByWorkflow +from .conversation_attribute_updated_by_workflow_attribute import ConversationAttributeUpdatedByWorkflowAttribute +from .conversation_attribute_updated_by_workflow_value import ConversationAttributeUpdatedByWorkflowValue +from .conversation_attribute_updated_by_workflow_workflow import ConversationAttributeUpdatedByWorkflowWorkflow from .conversation_contacts import ConversationContacts +from .conversation_deleted import ConversationDeleted from .conversation_first_contact_reply import ConversationFirstContactReply +from .conversation_list import ConversationList from .conversation_part import ConversationPart from .conversation_part_author import ConversationPartAuthor +from .conversation_part_metadata import ConversationPartMetadata +from .conversation_part_metadata_quick_reply_options_item import ConversationPartMetadataQuickReplyOptionsItem +from .conversation_part_state import ConversationPartState from .conversation_parts import ConversationParts from .conversation_rating import ConversationRating +from .conversation_response_time import ConversationResponseTime from .conversation_source import ConversationSource from .conversation_source_type import ConversationSourceType from .conversation_statistics import ConversationStatistics from .conversation_teammates import ConversationTeammates +from .create_article_request import CreateArticleRequest +from .create_article_request_parent_type import CreateArticleRequestParentType +from .create_article_request_state import CreateArticleRequestState from .create_contact_request import CreateContactRequest from .create_contact_request_two import CreateContactRequestTwo from .create_contact_request_with_email import CreateContactRequestWithEmail from .create_contact_request_with_external_id import CreateContactRequestWithExternalId from .create_contact_request_with_role import CreateContactRequestWithRole +from .create_data_attribute_request import CreateDataAttributeRequest +from .create_data_attribute_request_one import CreateDataAttributeRequestOne +from .create_data_attribute_request_one_data_type import CreateDataAttributeRequestOneDataType +from .create_data_attribute_request_options import CreateDataAttributeRequestOptions +from .create_data_attribute_request_options_options_item import CreateDataAttributeRequestOptionsOptionsItem from .create_data_event_request import CreateDataEventRequest from .create_data_event_request_two import CreateDataEventRequestTwo from .create_data_event_request_with_email import CreateDataEventRequestWithEmail from .create_data_event_request_with_id import CreateDataEventRequestWithId from .create_data_event_request_with_user_id import CreateDataEventRequestWithUserId +from .create_internal_article_request import CreateInternalArticleRequest from .create_message_request import CreateMessageRequest, CreateMessageRequest_Email, CreateMessageRequest_Inapp from .create_message_request_from import CreateMessageRequestFrom from .create_message_request_three import CreateMessageRequestThree @@ -113,16 +109,33 @@ from .create_message_request_type import CreateMessageRequestType from .create_message_request_with_email import CreateMessageRequestWithEmail from .create_message_request_with_inapp import CreateMessageRequestWithInapp +from .create_or_update_company_request import CreateOrUpdateCompanyRequest from .create_or_update_tag_request import CreateOrUpdateTagRequest +from .create_phone_switch_request import CreatePhoneSwitchRequest from .create_ticket_reply_with_comment_request import CreateTicketReplyWithCommentRequest -from .create_ticket_request import CreateTicketRequest +from .create_ticket_request_assignment import CreateTicketRequestAssignment +from .create_ticket_request_body import CreateTicketRequestBody from .create_ticket_request_contacts_item import CreateTicketRequestContactsItem from .create_ticket_request_contacts_item_email import CreateTicketRequestContactsItemEmail from .create_ticket_request_contacts_item_external_id import CreateTicketRequestContactsItemExternalId from .create_ticket_request_contacts_item_id import CreateTicketRequestContactsItemId -from .current_canvas import CurrentCanvas +from .create_ticket_type_request import CreateTicketTypeRequest +from .create_ticket_type_request_category import CreateTicketTypeRequestCategory from .cursor_pages import CursorPages +from .custom_action_finished import CustomActionFinished +from .custom_action_finished_action import CustomActionFinishedAction +from .custom_action_finished_action_result import CustomActionFinishedActionResult +from .custom_action_started import CustomActionStarted +from .custom_action_started_action import CustomActionStartedAction from .custom_attributes import CustomAttributes +from .custom_attributes_value import CustomAttributesValue +from .custom_channel_attribute import CustomChannelAttribute +from .custom_channel_base_event import CustomChannelBaseEvent +from .custom_channel_contact import CustomChannelContact +from .custom_channel_contact_type import CustomChannelContactType +from .custom_channel_notification_response import CustomChannelNotificationResponse +from .custom_object_instance_deleted import CustomObjectInstanceDeleted +from .custom_object_instance_list import CustomObjectInstanceList from .customer_request import CustomerRequest from .customer_request_email import CustomerRequestEmail from .customer_request_intercom_user_id import CustomerRequestIntercomUserId @@ -133,53 +146,51 @@ from .data_event_summary import DataEventSummary from .data_event_summary_item import DataEventSummaryItem from .data_export_csv import DataExportCsv -from .data_table_component import DataTableComponent -from .data_table_item import DataTableItem +from .datetime import Datetime from .deleted_article_object import DeletedArticleObject from .deleted_collection_object import DeletedCollectionObject from .deleted_company_object import DeletedCompanyObject +from .deleted_internal_article_object import DeletedInternalArticleObject from .deleted_object import DeletedObject -from .divider_component import DividerComponent -from .dropdown_component import DropdownComponent -from .dropdown_component_save_state import DropdownComponentSaveState -from .dropdown_option import DropdownOption +from .email_address_header import EmailAddressHeader +from .email_message_metadata import EmailMessageMetadata from .error import Error from .error_errors_item import ErrorErrorsItem -from .event import Event +from .event_details import EventDetails from .file_attribute import FileAttribute from .group_content import GroupContent from .group_translated_content import GroupTranslatedContent -from .image_component import ImageComponent -from .image_component_align import ImageComponentAlign -from .initialize_request import InitializeRequest -from .initialize_response import InitializeResponse -from .input_component import InputComponent -from .input_component_save_state import InputComponentSaveState +from .internal_article_list import InternalArticleList from .linked_object import LinkedObject from .linked_object_list import LinkedObjectList from .linked_object_type import LinkedObjectType -from .list_component import ListComponent -from .list_component_items_item import ListComponentItemsItem -from .list_item import ListItem -from .list_item_with_image import ListItemWithImage -from .list_item_without_image import ListItemWithoutImage -from .live_canvas_request import LiveCanvasRequest -from .live_canvas_response import LiveCanvasResponse from .metadata import Metadata from .multiple_filter_search_request import MultipleFilterSearchRequest from .multiple_filter_search_request_operator import MultipleFilterSearchRequestOperator -from .multiple_or_single_filter_search_request import MultipleOrSingleFilterSearchRequest +from .multiple_filter_search_request_value import MultipleFilterSearchRequestValue from .news_item_request import NewsItemRequest from .news_item_request_state import NewsItemRequestState +from .not_found_error_body import NotFoundErrorBody +from .not_found_error_body_errors_item import NotFoundErrorBodyErrorsItem from .note_list import NoteList from .offset_pages import OffsetPages from .open_conversation_request import OpenConversationRequest +from .operator_workflow_event import OperatorWorkflowEvent +from .operator_workflow_event_event import OperatorWorkflowEventEvent +from .operator_workflow_event_workflow import OperatorWorkflowEventWorkflow from .pages_link import PagesLink -from .paginated_conversation_response import PaginatedConversationResponse -from .paginated_news_item_response import PaginatedNewsItemResponse -from .paginated_newsfeed_response import PaginatedNewsfeedResponse +from .paginated_response import PaginatedResponse +from .paginated_response_data_item import ( + PaginatedResponseDataItem, + PaginatedResponseDataItem_NewsItem, + PaginatedResponseDataItem_Newsfeed, +) +from .paginated_response_type import PaginatedResponseType from .part_attachment import PartAttachment from .phone_switch import PhoneSwitch +from .quick_reply_option import QuickReplyOption +from .recipient import Recipient +from .recipient_type import RecipientType from .redact_conversation_request import ( RedactConversationRequest, RedactConversationRequest_ConversationPart, @@ -189,27 +200,18 @@ from .redact_conversation_request_source import RedactConversationRequestSource from .reference import Reference from .reply_conversation_request import ReplyConversationRequest -from .results_response import ResultsResponse from .search_request import SearchRequest from .search_request_query import SearchRequestQuery from .segment_list import SegmentList -from .sheet_action_component import SheetActionComponent from .single_filter_search_request import SingleFilterSearchRequest from .single_filter_search_request_operator import SingleFilterSearchRequestOperator from .single_filter_search_request_value import SingleFilterSearchRequestValue -from .single_select_component import SingleSelectComponent -from .single_select_component_save_state import SingleSelectComponentSaveState -from .single_select_option import SingleSelectOption +from .single_filter_search_request_value_item import SingleFilterSearchRequestValueItem from .sla_applied import SlaApplied from .sla_applied_sla_status import SlaAppliedSlaStatus from .snooze_conversation_request import SnoozeConversationRequest from .social_profile import SocialProfile -from .spacer_component import SpacerComponent -from .spacer_component_size import SpacerComponentSize from .starting_after_paging import StartingAfterPaging -from .submit_action_component import SubmitActionComponent -from .submit_request import SubmitRequest -from .submit_response import SubmitResponse from .subscription_type_list import SubscriptionTypeList from .tag_company_request import TagCompanyRequest from .tag_company_request_companies_item import TagCompanyRequestCompaniesItem @@ -219,10 +221,6 @@ from .tags import Tags from .team_list import TeamList from .team_priority_level import TeamPriorityLevel -from .text_area_component import TextAreaComponent -from .text_component import TextComponent -from .text_component_align import TextComponentAlign -from .text_component_style import TextComponentStyle from .ticket_custom_attributes import TicketCustomAttributes from .ticket_list import TicketList from .ticket_part_author import TicketPartAuthor @@ -231,6 +229,7 @@ from .ticket_reply import TicketReply from .ticket_reply_part_type import TicketReplyPartType from .ticket_request_custom_attributes import TicketRequestCustomAttributes +from .ticket_state_list import TicketStateList from .ticket_type_attribute import TicketTypeAttribute from .ticket_type_attribute_data_type import TicketTypeAttributeDataType from .ticket_type_attribute_list import TicketTypeAttributeList @@ -238,11 +237,15 @@ from .translation import Translation from .untag_company_request import UntagCompanyRequest from .untag_company_request_companies_item import UntagCompanyRequestCompaniesItem +from .update_article_request_body import UpdateArticleRequestBody +from .update_article_request_body_parent_type import UpdateArticleRequestBodyParentType +from .update_data_attribute_request_body import UpdateDataAttributeRequestBody +from .update_data_attribute_request_options import UpdateDataAttributeRequestOptions +from .update_data_attribute_request_options_options_item import UpdateDataAttributeRequestOptionsOptionsItem from .update_visitor_request import UpdateVisitorRequest from .update_visitor_request_one import UpdateVisitorRequestOne from .update_visitor_request_with_id import UpdateVisitorRequestWithId from .update_visitor_request_with_user_id import UpdateVisitorRequestWithUserId -from .url_action_component import UrlActionComponent from .visitor import Visitor from .visitor_avatar import VisitorAvatar from .visitor_companies import VisitorCompanies @@ -252,12 +255,13 @@ from .visitor_social_profiles import VisitorSocialProfiles from .visitor_tags import VisitorTags from .visitor_tags_tags_item import VisitorTagsTagsItem +from .whatsapp_message_status_list import WhatsappMessageStatusList +from .whatsapp_message_status_list_events_item import WhatsappMessageStatusListEventsItem +from .whatsapp_message_status_list_events_item_status import WhatsappMessageStatusListEventsItemStatus +from .whatsapp_message_status_list_pages import WhatsappMessageStatusListPages +from .whatsapp_message_status_list_pages_next import WhatsappMessageStatusListPagesNext __all__ = [ - "ActionComponent", - "ActionComponent_Sheet", - "ActionComponent_Submit", - "ActionComponent_Url", "ActivityLog", "ActivityLogActivityType", "ActivityLogList", @@ -281,46 +285,26 @@ "ArticleTranslatedContent", "AssignConversationRequest", "AssignConversationRequestType", - "ButtonComponent", - "ButtonComponentStyle", - "CanvasObject", - "CheckboxComponent", - "CheckboxComponentSaveState", - "CheckboxOption", + "AwayStatusReason", + "CallList", "CloseConversationRequest", "CollectionList", "CompanyAttachedContacts", "CompanyAttachedSegments", + "CompanyData", "CompanyList", "CompanyScroll", - "Component", - "Component_Button", - "Component_Checkbox", - "Component_DataTable", - "Component_Divider", - "Component_Dropdown", - "Component_Image", - "Component_Input", - "Component_List", - "Component_SingleSelect", - "Component_Spacer", - "Component_Text", - "Component_Textarea", - "ConfigureRequest", - "ConfigureRequestComponentId", - "ConfigureRequestZero", - "ConfigureResponse", - "ConfigureResponseCanvas", "ContactArchived", "ContactAttachedCompanies", + "ContactBlocked", "ContactCompanies", - "ContactCompany", "ContactDeleted", "ContactList", "ContactLocation", "ContactNotes", "ContactReference", "ContactReplyBaseRequest", + "ContactReplyBaseRequestReplyOptionsItem", "ContactReplyConversationRequest", "ContactReplyEmailRequest", "ContactReplyIntercomUserIdRequest", @@ -334,31 +318,50 @@ "ContactSubscriptionTypes", "ContactTags", "ContactUnarchived", - "ContentObject", "ContentSourcesList", - "Context", - "ContextLocation", "ConversationAttachmentFiles", + "ConversationAttributeUpdatedByAdmin", + "ConversationAttributeUpdatedByAdminAttribute", + "ConversationAttributeUpdatedByAdminValue", + "ConversationAttributeUpdatedByWorkflow", + "ConversationAttributeUpdatedByWorkflowAttribute", + "ConversationAttributeUpdatedByWorkflowValue", + "ConversationAttributeUpdatedByWorkflowWorkflow", "ConversationContacts", + "ConversationDeleted", "ConversationFirstContactReply", + "ConversationList", "ConversationPart", "ConversationPartAuthor", + "ConversationPartMetadata", + "ConversationPartMetadataQuickReplyOptionsItem", + "ConversationPartState", "ConversationParts", "ConversationRating", + "ConversationResponseTime", "ConversationSource", "ConversationSourceType", "ConversationStatistics", "ConversationTeammates", + "CreateArticleRequest", + "CreateArticleRequestParentType", + "CreateArticleRequestState", "CreateContactRequest", "CreateContactRequestTwo", "CreateContactRequestWithEmail", "CreateContactRequestWithExternalId", "CreateContactRequestWithRole", + "CreateDataAttributeRequest", + "CreateDataAttributeRequestOne", + "CreateDataAttributeRequestOneDataType", + "CreateDataAttributeRequestOptions", + "CreateDataAttributeRequestOptionsOptionsItem", "CreateDataEventRequest", "CreateDataEventRequestTwo", "CreateDataEventRequestWithEmail", "CreateDataEventRequestWithId", "CreateDataEventRequestWithUserId", + "CreateInternalArticleRequest", "CreateMessageRequest", "CreateMessageRequestFrom", "CreateMessageRequestThree", @@ -368,16 +371,33 @@ "CreateMessageRequestWithInapp", "CreateMessageRequest_Email", "CreateMessageRequest_Inapp", + "CreateOrUpdateCompanyRequest", "CreateOrUpdateTagRequest", + "CreatePhoneSwitchRequest", "CreateTicketReplyWithCommentRequest", - "CreateTicketRequest", + "CreateTicketRequestAssignment", + "CreateTicketRequestBody", "CreateTicketRequestContactsItem", "CreateTicketRequestContactsItemEmail", "CreateTicketRequestContactsItemExternalId", "CreateTicketRequestContactsItemId", - "CurrentCanvas", + "CreateTicketTypeRequest", + "CreateTicketTypeRequestCategory", "CursorPages", + "CustomActionFinished", + "CustomActionFinishedAction", + "CustomActionFinishedActionResult", + "CustomActionStarted", + "CustomActionStartedAction", "CustomAttributes", + "CustomAttributesValue", + "CustomChannelAttribute", + "CustomChannelBaseEvent", + "CustomChannelContact", + "CustomChannelContactType", + "CustomChannelNotificationResponse", + "CustomObjectInstanceDeleted", + "CustomObjectInstanceList", "CustomerRequest", "CustomerRequestEmail", "CustomerRequestIntercomUserId", @@ -388,53 +408,49 @@ "DataEventSummary", "DataEventSummaryItem", "DataExportCsv", - "DataTableComponent", - "DataTableItem", + "Datetime", "DeletedArticleObject", "DeletedCollectionObject", "DeletedCompanyObject", + "DeletedInternalArticleObject", "DeletedObject", - "DividerComponent", - "DropdownComponent", - "DropdownComponentSaveState", - "DropdownOption", + "EmailAddressHeader", + "EmailMessageMetadata", "Error", "ErrorErrorsItem", - "Event", + "EventDetails", "FileAttribute", "GroupContent", "GroupTranslatedContent", - "ImageComponent", - "ImageComponentAlign", - "InitializeRequest", - "InitializeResponse", - "InputComponent", - "InputComponentSaveState", + "InternalArticleList", "LinkedObject", "LinkedObjectList", "LinkedObjectType", - "ListComponent", - "ListComponentItemsItem", - "ListItem", - "ListItemWithImage", - "ListItemWithoutImage", - "LiveCanvasRequest", - "LiveCanvasResponse", "Metadata", "MultipleFilterSearchRequest", "MultipleFilterSearchRequestOperator", - "MultipleOrSingleFilterSearchRequest", + "MultipleFilterSearchRequestValue", "NewsItemRequest", "NewsItemRequestState", + "NotFoundErrorBody", + "NotFoundErrorBodyErrorsItem", "NoteList", "OffsetPages", "OpenConversationRequest", + "OperatorWorkflowEvent", + "OperatorWorkflowEventEvent", + "OperatorWorkflowEventWorkflow", "PagesLink", - "PaginatedConversationResponse", - "PaginatedNewsItemResponse", - "PaginatedNewsfeedResponse", + "PaginatedResponse", + "PaginatedResponseDataItem", + "PaginatedResponseDataItem_NewsItem", + "PaginatedResponseDataItem_Newsfeed", + "PaginatedResponseType", "PartAttachment", "PhoneSwitch", + "QuickReplyOption", + "Recipient", + "RecipientType", "RedactConversationRequest", "RedactConversationRequestConversationPart", "RedactConversationRequestSource", @@ -442,27 +458,18 @@ "RedactConversationRequest_Source", "Reference", "ReplyConversationRequest", - "ResultsResponse", "SearchRequest", "SearchRequestQuery", "SegmentList", - "SheetActionComponent", "SingleFilterSearchRequest", "SingleFilterSearchRequestOperator", "SingleFilterSearchRequestValue", - "SingleSelectComponent", - "SingleSelectComponentSaveState", - "SingleSelectOption", + "SingleFilterSearchRequestValueItem", "SlaApplied", "SlaAppliedSlaStatus", "SnoozeConversationRequest", "SocialProfile", - "SpacerComponent", - "SpacerComponentSize", "StartingAfterPaging", - "SubmitActionComponent", - "SubmitRequest", - "SubmitResponse", "SubscriptionTypeList", "TagCompanyRequest", "TagCompanyRequestCompaniesItem", @@ -472,10 +479,6 @@ "Tags", "TeamList", "TeamPriorityLevel", - "TextAreaComponent", - "TextComponent", - "TextComponentAlign", - "TextComponentStyle", "TicketCustomAttributes", "TicketList", "TicketPartAuthor", @@ -484,6 +487,7 @@ "TicketReply", "TicketReplyPartType", "TicketRequestCustomAttributes", + "TicketStateList", "TicketTypeAttribute", "TicketTypeAttributeDataType", "TicketTypeAttributeList", @@ -491,11 +495,15 @@ "Translation", "UntagCompanyRequest", "UntagCompanyRequestCompaniesItem", + "UpdateArticleRequestBody", + "UpdateArticleRequestBodyParentType", + "UpdateDataAttributeRequestBody", + "UpdateDataAttributeRequestOptions", + "UpdateDataAttributeRequestOptionsOptionsItem", "UpdateVisitorRequest", "UpdateVisitorRequestOne", "UpdateVisitorRequestWithId", "UpdateVisitorRequestWithUserId", - "UrlActionComponent", "Visitor", "VisitorAvatar", "VisitorCompanies", @@ -505,4 +513,9 @@ "VisitorSocialProfiles", "VisitorTags", "VisitorTagsTagsItem", + "WhatsappMessageStatusList", + "WhatsappMessageStatusListEventsItem", + "WhatsappMessageStatusListEventsItemStatus", + "WhatsappMessageStatusListPages", + "WhatsappMessageStatusListPagesNext", ] diff --git a/src/intercom/types/action_component.py b/src/intercom/types/action_component.py deleted file mode 100644 index ccab028..0000000 --- a/src/intercom/types/action_component.py +++ /dev/null @@ -1,56 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from __future__ import annotations - -import typing - -import pydantic -import typing_extensions -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel, UnionMetadata - - -class ActionComponent_Sheet(UncheckedBaseModel): - type: typing.Literal["sheet"] = "sheet" - url: str - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class ActionComponent_Url(UncheckedBaseModel): - type: typing.Literal["url"] = "url" - url: str - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class ActionComponent_Submit(UncheckedBaseModel): - type: typing.Literal["submit"] = "submit" - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -ActionComponent = typing_extensions.Annotated[ - typing.Union[ActionComponent_Sheet, ActionComponent_Url, ActionComponent_Submit], UnionMetadata(discriminant="type") -] diff --git a/src/intercom/types/activity_log.py b/src/intercom/types/activity_log.py index 7aad54b..b775941 100644 --- a/src/intercom/types/activity_log.py +++ b/src/intercom/types/activity_log.py @@ -15,12 +15,12 @@ class ActivityLog(UncheckedBaseModel): Activities performed by Admins. """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id representing the activity. """ - performed_by: ActivityLogPerformedBy = pydantic.Field() + performed_by: typing.Optional[ActivityLogPerformedBy] = pydantic.Field(default=None) """ Details about the Admin involved in the activity. """ @@ -31,7 +31,7 @@ class ActivityLog(UncheckedBaseModel): The time the activity was created. """ - activity_type: ActivityLogActivityType + activity_type: typing.Optional[ActivityLogActivityType] = None activity_description: typing.Optional[str] = pydantic.Field(default=None) """ A sentence or two describing the activity. diff --git a/src/intercom/types/activity_log_activity_type.py b/src/intercom/types/activity_log_activity_type.py index 48d6405..d0fc757 100644 --- a/src/intercom/types/activity_log_activity_type.py +++ b/src/intercom/types/activity_log_activity_type.py @@ -4,7 +4,8 @@ ActivityLogActivityType = typing.Union[ typing.Literal[ - "admin_assignment_limit_change", + "admin_conversation_assignment_limit_change", + "admin_ticket_assignment_limit_change", "admin_away_mode_change", "admin_deletion", "admin_deprovisioned", diff --git a/src/intercom/types/activity_log_list.py b/src/intercom/types/activity_log_list.py index 105a7c0..3d0bf0a 100644 --- a/src/intercom/types/activity_log_list.py +++ b/src/intercom/types/activity_log_list.py @@ -14,13 +14,13 @@ class ActivityLogList(UncheckedBaseModel): A paginated list of activity logs. """ - type: typing.Literal["activity_log.list"] = pydantic.Field(default="activity_log.list") + type: typing.Optional[str] = pydantic.Field(default=None) """ String representing the object's type. Always has the value `activity_log.list`. """ pages: typing.Optional[CursorPages] = None - activity_logs: typing.List[ActivityLog] = pydantic.Field() + activity_logs: typing.Optional[typing.List[typing.Optional[ActivityLog]]] = pydantic.Field(default=None) """ An array of activity logs """ diff --git a/src/intercom/types/activity_log_metadata.py b/src/intercom/types/activity_log_metadata.py index 8c0d436..09d848f 100644 --- a/src/intercom/types/activity_log_metadata.py +++ b/src/intercom/types/activity_log_metadata.py @@ -57,6 +57,16 @@ class ActivityLogMetadata(UncheckedBaseModel): The name of the Admin who initiated the activity. """ + conversation_assignment_limit: typing.Optional[int] = pydantic.Field(default=None) + """ + The conversation assignment limit value for an admin. + """ + + ticket_assignment_limit: typing.Optional[int] = pydantic.Field(default=None) + """ + The ticket assignment limit value for an admin. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/types/activity_log_performed_by.py b/src/intercom/types/activity_log_performed_by.py index af8bcf8..21311c5 100644 --- a/src/intercom/types/activity_log_performed_by.py +++ b/src/intercom/types/activity_log_performed_by.py @@ -12,7 +12,7 @@ class ActivityLogPerformedBy(UncheckedBaseModel): Details about the Admin involved in the activity. """ - type: typing.Optional[typing.Literal["admin"]] = pydantic.Field(default=None) + type: typing.Optional[str] = pydantic.Field(default=None) """ String representing the object's type. Always has the value `admin`. """ diff --git a/src/intercom/types/addressable_list.py b/src/intercom/types/addressable_list.py index 4ed668e..7c9b76e 100644 --- a/src/intercom/types/addressable_list.py +++ b/src/intercom/types/addressable_list.py @@ -12,17 +12,17 @@ class AddressableList(UncheckedBaseModel): A list used to access other resources from a parent model. """ - type: str = pydantic.Field() + type: typing.Optional[str] = pydantic.Field(default=None) """ The addressable object type """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the addressable object """ - url: str = pydantic.Field() + url: typing.Optional[str] = pydantic.Field(default=None) """ Url to get more company resources for this contact """ diff --git a/src/intercom/types/admin_list.py b/src/intercom/types/admin_list.py index 7ccd717..39feaca 100644 --- a/src/intercom/types/admin_list.py +++ b/src/intercom/types/admin_list.py @@ -13,12 +13,12 @@ class AdminList(UncheckedBaseModel): A list of admins associated with a given workspace. """ - type: typing.Literal["admin.list"] = pydantic.Field(default="admin.list") + type: typing.Optional[str] = pydantic.Field(default=None) """ String representing the object's type. Always has the value `admin.list`. """ - admins: typing.List[Admin] = pydantic.Field() + admins: typing.Optional[typing.List[typing.Optional[Admin]]] = pydantic.Field(default=None) """ A list of admins associated with a given workspace. """ diff --git a/src/intercom/types/admin_reply_conversation_request.py b/src/intercom/types/admin_reply_conversation_request.py index 35451ff..253ccb3 100644 --- a/src/intercom/types/admin_reply_conversation_request.py +++ b/src/intercom/types/admin_reply_conversation_request.py @@ -7,6 +7,7 @@ from ..core.unchecked_base_model import UncheckedBaseModel from .admin_reply_conversation_request_message_type import AdminReplyConversationRequestMessageType from .conversation_attachment_files import ConversationAttachmentFiles +from .quick_reply_option import QuickReplyOption class AdminReplyConversationRequest(UncheckedBaseModel): @@ -31,6 +32,11 @@ class AdminReplyConversationRequest(UncheckedBaseModel): The time the reply was created. If not provided, the current time will be used. """ + reply_options: typing.Optional[typing.List[QuickReplyOption]] = pydantic.Field(default=None) + """ + The quick reply options to display to the end user. Must be present for quick_reply message types. + """ + attachment_urls: typing.Optional[typing.List[str]] = pydantic.Field(default=None) """ A list of image URLs that will be added as attachments. You can include up to 10 URLs. diff --git a/src/intercom/types/admin_reply_conversation_request_message_type.py b/src/intercom/types/admin_reply_conversation_request_message_type.py index de8dd8c..23e821b 100644 --- a/src/intercom/types/admin_reply_conversation_request_message_type.py +++ b/src/intercom/types/admin_reply_conversation_request_message_type.py @@ -2,4 +2,4 @@ import typing -AdminReplyConversationRequestMessageType = typing.Union[typing.Literal["comment", "note"], typing.Any] +AdminReplyConversationRequestMessageType = typing.Union[typing.Literal["comment", "note", "quick_reply"], typing.Any] diff --git a/src/intercom/types/admin_with_app.py b/src/intercom/types/admin_with_app.py index a82a150..9d8cfa5 100644 --- a/src/intercom/types/admin_with_app.py +++ b/src/intercom/types/admin_with_app.py @@ -14,47 +14,47 @@ class AdminWithApp(UncheckedBaseModel): Admins are the teammate accounts that have access to a workspace """ - type: typing.Literal["admin"] = pydantic.Field(default="admin") + type: typing.Optional[str] = pydantic.Field(default=None) """ String representing the object's type. Always has the value `admin`. """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id representing the admin. """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the admin. """ - email: str = pydantic.Field() + email: typing.Optional[str] = pydantic.Field(default=None) """ The email of the admin. """ - job_title: str = pydantic.Field() + job_title: typing.Optional[str] = pydantic.Field(default=None) """ The job title of the admin. """ - away_mode_enabled: bool = pydantic.Field() + away_mode_enabled: typing.Optional[bool] = pydantic.Field(default=None) """ Identifies if this admin is currently set in away mode. """ - away_mode_reassign: bool = pydantic.Field() + away_mode_reassign: typing.Optional[bool] = pydantic.Field(default=None) """ Identifies if this admin is set to automatically reassign new conversations to the apps default inbox. """ - has_inbox_seat: bool = pydantic.Field() + has_inbox_seat: typing.Optional[bool] = pydantic.Field(default=None) """ Identifies if this admin has a paid inbox seat to restrict/allow features that require them. """ - team_ids: typing.List[int] = pydantic.Field() + team_ids: typing.Optional[typing.List[int]] = pydantic.Field(default=None) """ This is a list of ids of the teams that this admin is part of. """ diff --git a/src/intercom/types/admin_with_app_avatar.py b/src/intercom/types/admin_with_app_avatar.py index 48aac24..3495059 100644 --- a/src/intercom/types/admin_with_app_avatar.py +++ b/src/intercom/types/admin_with_app_avatar.py @@ -12,7 +12,7 @@ class AdminWithAppAvatar(UncheckedBaseModel): This object represents the avatar associated with the admin. """ - type: typing.Optional[typing.Literal["avatar"]] = pydantic.Field(default=None) + type: typing.Optional[str] = pydantic.Field(default=None) """ This is a string that identifies the type of the object. It will always have the value `avatar`. """ diff --git a/src/intercom/types/app.py b/src/intercom/types/app.py index 36711e9..fed90a5 100644 --- a/src/intercom/types/app.py +++ b/src/intercom/types/app.py @@ -12,37 +12,37 @@ class App(UncheckedBaseModel): App is a workspace on Intercom """ - type: str = pydantic.Field() + type: typing.Optional[str] = pydantic.Field(default=None) """ """ - id_code: str = pydantic.Field() + id_code: typing.Optional[str] = pydantic.Field(default=None) """ The id of the app. """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the app. """ - region: str = pydantic.Field() + region: typing.Optional[str] = pydantic.Field(default=None) """ The Intercom region the app is located in. """ - timezone: str = pydantic.Field() + timezone: typing.Optional[str] = pydantic.Field(default=None) """ The timezone of the region where the app is located. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ When the app was created. """ - identity_verification: bool = pydantic.Field() + identity_verification: typing.Optional[bool] = pydantic.Field(default=None) """ Whether or not the app uses identity verification. """ diff --git a/src/intercom/types/article_content.py b/src/intercom/types/article_content.py index 071f3ef..f9b7bbc 100644 --- a/src/intercom/types/article_content.py +++ b/src/intercom/types/article_content.py @@ -13,32 +13,32 @@ class ArticleContent(UncheckedBaseModel): The Content of an Article. """ - type: typing.Literal["article_content"] = pydantic.Field(default="article_content") + type: typing.Optional[str] = pydantic.Field(default=None) """ The type of object - `article_content` . """ - title: str = pydantic.Field() + title: typing.Optional[str] = pydantic.Field(default=None) """ The title of the article. """ - description: str = pydantic.Field() + description: typing.Optional[str] = pydantic.Field(default=None) """ The description of the article. """ - body: str = pydantic.Field() + body: typing.Optional[str] = pydantic.Field(default=None) """ The body of the article. """ - author_id: int = pydantic.Field() + author_id: typing.Optional[int] = pydantic.Field(default=None) """ The ID of the author of the article. """ - state: ArticleContentState = pydantic.Field() + state: typing.Optional[ArticleContentState] = pydantic.Field(default=None) """ Whether the article is `published` or is a `draft` . """ diff --git a/src/intercom/types/article_list.py b/src/intercom/types/article_list.py index 00943b9..67efb42 100644 --- a/src/intercom/types/article_list.py +++ b/src/intercom/types/article_list.py @@ -13,18 +13,18 @@ class ArticleList(UncheckedBaseModel): This will return a list of articles for the App. """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of the object - `list`. """ pages: typing.Optional[typing.Optional[typing.Any]] = None - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ A count of the total number of articles. """ - data: typing.List[ArticleListItem] = pydantic.Field() + data: typing.Optional[typing.List[ArticleListItem]] = pydantic.Field(default=None) """ An array of Article objects """ diff --git a/src/intercom/types/article_translated_content.py b/src/intercom/types/article_translated_content.py index acf5968..76493d4 100644 --- a/src/intercom/types/article_translated_content.py +++ b/src/intercom/types/article_translated_content.py @@ -15,7 +15,7 @@ class ArticleTranslatedContent(UncheckedBaseModel): The Translated Content of an Article. The keys are the locale codes and the values are the translated content of the article. """ - type: typing.Optional[typing.Literal["article_translated_content"]] = pydantic.Field(default=None) + type: typing.Optional[str] = pydantic.Field(default=None) """ The type of object - article_translated_content. """ diff --git a/src/intercom/types/away_status_reason.py b/src/intercom/types/away_status_reason.py new file mode 100644 index 0000000..e17b875 --- /dev/null +++ b/src/intercom/types/away_status_reason.py @@ -0,0 +1,54 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class AwayStatusReason(UncheckedBaseModel): + type: typing.Optional[str] = None + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier for the away status reason + """ + + label: typing.Optional[str] = pydantic.Field(default=None) + """ + The display text for the away status reason + """ + + emoji: typing.Optional[str] = pydantic.Field(default=None) + """ + The emoji associated with the status reason + """ + + order: typing.Optional[int] = pydantic.Field(default=None) + """ + The display order of the status reason + """ + + deleted: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the status reason has been soft deleted + """ + + created_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The Unix timestamp when the status reason was created + """ + + updated_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The Unix timestamp when the status reason was last updated + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/button_component.py b/src/intercom/types/button_component.py deleted file mode 100644 index e5ca43e..0000000 --- a/src/intercom/types/button_component.py +++ /dev/null @@ -1,52 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .action_component import ActionComponent -from .button_component_style import ButtonComponentStyle - - -class ButtonComponent(UncheckedBaseModel): - """ - A button component is used to take an action by clicking a button. This can either: - - [Trigger a submit request to be sent](https://developers.intercom.com/docs/references/canvas-kit/actioncomponents/submit-action) Inbox Messenger - - [Open a link in a new page](https://developers.intercom.com/docs/references/canvas-kit/actioncomponents/url-action) Inbox Messenger - - [Open a sheet](https://developers.intercom.com/docs/references/canvas-kit/actioncomponents/sheets-action) Messenger - """ - - id: str = pydantic.Field() - """ - A unique identifier for the component. - """ - - label: str = pydantic.Field() - """ - The text that will be rendered inside the button. - """ - - action: ActionComponent = pydantic.Field() - """ - This can be a Submit Action, URL Action, or Sheets Action. - """ - - style: typing.Optional[ButtonComponentStyle] = pydantic.Field(default=None) - """ - Styles the button. Default is 'primary'. - """ - - disabled: typing.Optional[bool] = pydantic.Field(default=None) - """ - Styles the button and prevents the action. Default is false. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/button_component_style.py b/src/intercom/types/button_component_style.py deleted file mode 100644 index ea9ad49..0000000 --- a/src/intercom/types/button_component_style.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -ButtonComponentStyle = typing.Union[typing.Literal["primary", "secondary", "link"], typing.Any] diff --git a/src/intercom/types/paginated_news_item_response.py b/src/intercom/types/call_list.py similarity index 59% rename from src/intercom/types/paginated_news_item_response.py rename to src/intercom/types/call_list.py index 1cf9dcd..e1cf109 100644 --- a/src/intercom/types/paginated_news_item_response.py +++ b/src/intercom/types/call_list.py @@ -3,33 +3,34 @@ import typing import pydantic +from ..calls.types.call import Call from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel -from ..news.types.news_item import NewsItem from .cursor_pages import CursorPages -class PaginatedNewsItemResponse(UncheckedBaseModel): +class CallList(UncheckedBaseModel): """ - Paginated News Item Response + A paginated list of calls. """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[str] = pydantic.Field(default=None) """ - The type of object + String representing the object's type. Always has the value `list`. """ - pages: typing.Optional[CursorPages] = None - total_count: int = pydantic.Field() + data: typing.Optional[typing.List[Call]] = pydantic.Field(default=None) """ - A count of the total number of News Items. + A list of calls. """ - data: typing.List[NewsItem] = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ - An array of News Items + Total number of items available. """ + pages: typing.Optional[CursorPages] = None + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/types/canvas_object.py b/src/intercom/types/canvas_object.py deleted file mode 100644 index b3f3b74..0000000 --- a/src/intercom/types/canvas_object.py +++ /dev/null @@ -1,43 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .content_object import ContentObject - - -class CanvasObject(UncheckedBaseModel): - """ - You have to respond to the majority of requests with a canvas object. This will tell us what UI to show for your app. - - A canvas can either be static (meaning we send you the next request only when an action takes place) or live (meaning we send you the next request when someone views the app). - - - A static canvas needs a ContentObject which will contain the components to show. - - A live canvas needs a `content_url` which we we will make the Live Canvas requests to when the app is viewed. This is only possible for apps viewed or used in the Messenger. - """ - - content: ContentObject = pydantic.Field() - """ - The content object that will be shown as the UI of the app. Max Size is 64KB. - """ - - content_url: typing.Optional[str] = pydantic.Field(default=None) - """ - The URL which we make Live Canvas requests to. You must respond to these with a content object. Max size is 64KB. - """ - - stored_data: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None) - """ - Optional Stored Data that you want to be returned in the next sent request. Max Size is 64KB. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/checkbox_component.py b/src/intercom/types/checkbox_component.py deleted file mode 100644 index 1c98f18..0000000 --- a/src/intercom/types/checkbox_component.py +++ /dev/null @@ -1,58 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .checkbox_component_save_state import CheckboxComponentSaveState -from .checkbox_option import CheckboxOption - - -class CheckboxComponent(UncheckedBaseModel): - """ - A checkbox component is used to capture multiple choices from as many options as you want to provide. You can submit the options by: - - - Using a ButtonComponent (which will submit all interactive components in the canvas) - - When a submit action takes place, the results are given in a hash with the `id` from the checkbox component used as the key and an array containing the `id` of each chosen option as the value. - """ - - id: str = pydantic.Field() - """ - A unique identifier for the component. - """ - - option: typing.List[CheckboxOption] = pydantic.Field() - """ - The list of options. Minimum of 1. - """ - - label: str = pydantic.Field() - """ - The text shown above the options. - """ - - value: typing.Optional[typing.List[str]] = pydantic.Field(default=None) - """ - The option's that are selected by default. - """ - - save_state: typing.Optional[CheckboxComponentSaveState] = pydantic.Field(default=None) - """ - Styles the input. Default is `unsaved`. Prevent action with `saved`. - """ - - disabled: typing.Optional[bool] = pydantic.Field(default=None) - """ - Styles all options and prevents the action. Default is false. Will be overridden if save_state is saved. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/checkbox_component_save_state.py b/src/intercom/types/checkbox_component_save_state.py deleted file mode 100644 index 33ed701..0000000 --- a/src/intercom/types/checkbox_component_save_state.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -CheckboxComponentSaveState = typing.Union[typing.Literal["unsaved", "saved", "failed"], typing.Any] diff --git a/src/intercom/types/collection_list.py b/src/intercom/types/collection_list.py index 7dafac2..2711d18 100644 --- a/src/intercom/types/collection_list.py +++ b/src/intercom/types/collection_list.py @@ -14,18 +14,18 @@ class CollectionList(UncheckedBaseModel): This will return a list of Collections for the App. """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of the object - `list`. """ pages: typing.Optional[OffsetPages] = None - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ A count of the total number of collections. """ - data: typing.List[Collection] = pydantic.Field() + data: typing.Optional[typing.List[Collection]] = pydantic.Field(default=None) """ An array of collection objects """ diff --git a/src/intercom/types/company_attached_contacts.py b/src/intercom/types/company_attached_contacts.py index 8240704..6b23ee2 100644 --- a/src/intercom/types/company_attached_contacts.py +++ b/src/intercom/types/company_attached_contacts.py @@ -14,17 +14,17 @@ class CompanyAttachedContacts(UncheckedBaseModel): A list of Contact Objects """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of object - `list` """ - data: typing.List[Contact] = pydantic.Field() + data: typing.Optional[typing.List[Contact]] = pydantic.Field(default=None) """ An array containing Contact Objects """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ The total number of contacts """ diff --git a/src/intercom/types/company_attached_segments.py b/src/intercom/types/company_attached_segments.py index c0a3439..032bebe 100644 --- a/src/intercom/types/company_attached_segments.py +++ b/src/intercom/types/company_attached_segments.py @@ -13,12 +13,12 @@ class CompanyAttachedSegments(UncheckedBaseModel): A list of Segment Objects """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of object - `list` """ - data: typing.List[Segment] = pydantic.Field() + data: typing.Optional[typing.List[Segment]] = pydantic.Field(default=None) """ An array containing Segment Objects """ diff --git a/src/intercom/types/spacer_component.py b/src/intercom/types/company_data.py similarity index 58% rename from src/intercom/types/spacer_component.py rename to src/intercom/types/company_data.py index 0374242..34ead61 100644 --- a/src/intercom/types/spacer_component.py +++ b/src/intercom/types/company_data.py @@ -5,22 +5,26 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel -from .spacer_component_size import SpacerComponentSize -class SpacerComponent(UncheckedBaseModel): +class CompanyData(UncheckedBaseModel): """ - A spacer component is used to create empty space between components. + An object containing data about the companies that a contact is associated with. """ id: typing.Optional[str] = pydantic.Field(default=None) """ - A unique identifier for the component. + The unique identifier for the company which is given by Intercom. """ - size: typing.Optional[SpacerComponentSize] = pydantic.Field(default=None) + type: typing.Optional[typing.Literal["company"]] = pydantic.Field(default=None) """ - The amount of space between components. Default is `s`. + The type of the object. Always company. + """ + + url: typing.Optional[str] = pydantic.Field(default=None) + """ + The relative URL of the company. """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/company_list.py b/src/intercom/types/company_list.py index 7a67bad..078fa69 100644 --- a/src/intercom/types/company_list.py +++ b/src/intercom/types/company_list.py @@ -15,12 +15,12 @@ class CompanyList(UncheckedBaseModel): """ pages: typing.Optional[OffsetPages] = None - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ The total number of companies. """ - data: typing.List[Company] = pydantic.Field() + data: typing.Optional[typing.List[Company]] = pydantic.Field(default=None) """ An array containing Company Objects. """ diff --git a/src/intercom/types/company_scroll.py b/src/intercom/types/company_scroll.py index 72fd10e..a164b4d 100644 --- a/src/intercom/types/company_scroll.py +++ b/src/intercom/types/company_scroll.py @@ -14,12 +14,12 @@ class CompanyScroll(UncheckedBaseModel): Companies allow you to represent organizations using your product. Each company will have its own description and be associated with contacts. You can fetch, create, update and list companies. """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of object - `list` """ - data: typing.List[Company] + data: typing.Optional[typing.List[Company]] = None pages: typing.Optional[CursorPages] = None total_count: typing.Optional[int] = pydantic.Field(default=None) """ diff --git a/src/intercom/types/component.py b/src/intercom/types/component.py deleted file mode 100644 index 4c9f1ad..0000000 --- a/src/intercom/types/component.py +++ /dev/null @@ -1,258 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from __future__ import annotations - -import typing - -import pydantic -import typing_extensions -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel, UnionMetadata -from .action_component import ActionComponent -from .button_component_style import ButtonComponentStyle -from .checkbox_component_save_state import CheckboxComponentSaveState -from .checkbox_option import CheckboxOption -from .data_table_item import DataTableItem -from .dropdown_component_save_state import DropdownComponentSaveState -from .dropdown_option import DropdownOption -from .image_component_align import ImageComponentAlign -from .input_component_save_state import InputComponentSaveState -from .list_component_items_item import ListComponentItemsItem -from .single_select_component_save_state import SingleSelectComponentSaveState -from .single_select_option import SingleSelectOption -from .spacer_component_size import SpacerComponentSize -from .text_component_align import TextComponentAlign -from .text_component_style import TextComponentStyle -from .url_action_component import UrlActionComponent - - -class Component_Button(UncheckedBaseModel): - type: typing.Literal["button"] = "button" - id: str - label: str - action: ActionComponent - style: typing.Optional[ButtonComponentStyle] = None - disabled: typing.Optional[bool] = None - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class Component_Checkbox(UncheckedBaseModel): - type: typing.Literal["checkbox"] = "checkbox" - id: str - option: typing.List[CheckboxOption] - label: str - value: typing.Optional[typing.List[str]] = None - save_state: typing.Optional[CheckboxComponentSaveState] = None - disabled: typing.Optional[bool] = None - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class Component_Dropdown(UncheckedBaseModel): - type: typing.Literal["dropdown"] = "dropdown" - id: str - options: typing.List[DropdownOption] - label: typing.Optional[str] = None - value: typing.Optional[str] = None - save_state: typing.Optional[DropdownComponentSaveState] = None - disabled: typing.Optional[bool] = None - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class Component_Input(UncheckedBaseModel): - type: typing.Literal["input"] = "input" - id: str - label: typing.Optional[str] = None - placeholder: typing.Optional[str] = None - value: typing.Optional[str] = None - action: typing.Optional[ActionComponent] = None - save_state: typing.Optional[InputComponentSaveState] = None - disabled: typing.Optional[bool] = None - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class Component_List(UncheckedBaseModel): - type: typing.Literal["list"] = "list" - items: typing.List[ListComponentItemsItem] - disabled: typing.Optional[bool] = None - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class Component_SingleSelect(UncheckedBaseModel): - type: typing.Literal["single-select"] = "single-select" - id: str - options: typing.List[SingleSelectOption] - label: typing.Optional[str] = None - value: typing.Optional[str] = None - save_state: typing.Optional[SingleSelectComponentSaveState] = None - disabled: typing.Optional[bool] = None - action: typing.Optional[ActionComponent] = None - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class Component_Textarea(UncheckedBaseModel): - type: typing.Literal["textarea"] = "textarea" - id: str - label: typing.Optional[str] = None - placeholder: typing.Optional[str] = None - value: typing.Optional[str] = None - error: typing.Optional[bool] = None - disabled: typing.Optional[bool] = None - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class Component_DataTable(UncheckedBaseModel): - type: typing.Literal["data-table"] = "data-table" - items: typing.List[DataTableItem] - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class Component_Divider(UncheckedBaseModel): - type: typing.Literal["divider"] = "divider" - id: typing.Optional[str] = None - bottom_margin: typing.Optional[typing.Literal["none"]] = None - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class Component_Image(UncheckedBaseModel): - type: typing.Literal["image"] = "image" - id: typing.Optional[str] = None - url: str - align: typing.Optional[ImageComponentAlign] = None - width: int - height: int - rounded: typing.Optional[bool] = None - bottom_margin: typing.Optional[typing.Literal["none"]] = None - action: typing.Optional[UrlActionComponent] = None - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class Component_Spacer(UncheckedBaseModel): - type: typing.Literal["spacer"] = "spacer" - id: typing.Optional[str] = None - size: typing.Optional[SpacerComponentSize] = None - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -class Component_Text(UncheckedBaseModel): - type: typing.Literal["text"] = "text" - id: typing.Optional[str] = None - text: str - align: typing.Optional[TextComponentAlign] = None - style: typing.Optional[TextComponentStyle] = None - bottom_margin: typing.Optional[typing.Literal["none"]] = None - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow - - -Component = typing_extensions.Annotated[ - typing.Union[ - Component_Button, - Component_Checkbox, - Component_Dropdown, - Component_Input, - Component_List, - Component_SingleSelect, - Component_Textarea, - Component_DataTable, - Component_Divider, - Component_Image, - Component_Spacer, - Component_Text, - ], - UnionMetadata(discriminant="type"), -] diff --git a/src/intercom/types/configure_request.py b/src/intercom/types/configure_request.py deleted file mode 100644 index ff26b90..0000000 --- a/src/intercom/types/configure_request.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -from .configure_request_component_id import ConfigureRequestComponentId -from .configure_request_zero import ConfigureRequestZero - -ConfigureRequest = typing.Union[ConfigureRequestZero, ConfigureRequestComponentId] diff --git a/src/intercom/types/configure_request_component_id.py b/src/intercom/types/configure_request_component_id.py deleted file mode 100644 index ccd2a11..0000000 --- a/src/intercom/types/configure_request_component_id.py +++ /dev/null @@ -1,56 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..admins.types.admin import Admin -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .canvas_object import CanvasObject -from .context import Context - - -class ConfigureRequestComponentId(UncheckedBaseModel): - workspace_id: str = pydantic.Field() - """ - The workspace ID of the teammate. Attribute is app_id for V1.2 and below. - """ - - workspace_region: str = pydantic.Field() - """ - The Intercom hosted region that this app is located in. - """ - - component_id: str = pydantic.Field() - """ - The id of the component clicked by the teammate to trigger the request. - """ - - admin: Admin = pydantic.Field() - """ - The Intercom teammate configuring the app. - """ - - context: Context = pydantic.Field() - """ - The context of where the app is added, where the user last visited, and information on the Messenger settings. - """ - - current_canvas: CanvasObject = pydantic.Field() - """ - The current canvas the teammate can see. - """ - - input_values: typing.Dict[str, typing.Optional[typing.Any]] = pydantic.Field() - """ - A list of key/value pairs of data, inputted by the teammate on the current canvas. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/configure_response.py b/src/intercom/types/configure_response.py deleted file mode 100644 index 1f812a1..0000000 --- a/src/intercom/types/configure_response.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -from .configure_response_canvas import ConfigureResponseCanvas -from .results_response import ResultsResponse - -ConfigureResponse = typing.Union[ResultsResponse, ConfigureResponseCanvas] diff --git a/src/intercom/types/contact_archived.py b/src/intercom/types/contact_archived.py index 8430ed0..edbc3cc 100644 --- a/src/intercom/types/contact_archived.py +++ b/src/intercom/types/contact_archived.py @@ -4,30 +4,15 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel +from .contact_reference import ContactReference -class ContactArchived(UncheckedBaseModel): +class ContactArchived(ContactReference): """ archived contact object """ - type: typing.Literal["contact"] = pydantic.Field(default="contact") - """ - always contact - """ - - id: str = pydantic.Field() - """ - The unique identifier for the contact which is given by Intercom. - """ - - external_id: typing.Optional[str] = pydantic.Field(default=None) - """ - The unique identifier for the contact which is provided by the Client. - """ - - archived: bool = pydantic.Field() + archived: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the contact is archived or not. """ diff --git a/src/intercom/types/contact_attached_companies.py b/src/intercom/types/contact_attached_companies.py index 94c093f..01b7030 100644 --- a/src/intercom/types/contact_attached_companies.py +++ b/src/intercom/types/contact_attached_companies.py @@ -14,17 +14,17 @@ class ContactAttachedCompanies(UncheckedBaseModel): A list of Company Objects """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of object """ - companies: typing.List[Company] = pydantic.Field() + companies: typing.Optional[typing.List[Company]] = pydantic.Field(default=None) """ An array containing Company Objects """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ The total number of companies associated to this contact """ diff --git a/src/intercom/types/list_item_with_image.py b/src/intercom/types/contact_blocked.py similarity index 57% rename from src/intercom/types/list_item_with_image.py rename to src/intercom/types/contact_blocked.py index e69d8a9..caeb5ac 100644 --- a/src/intercom/types/list_item_with_image.py +++ b/src/intercom/types/contact_blocked.py @@ -4,23 +4,17 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from .list_item import ListItem +from .contact_reference import ContactReference -class ListItemWithImage(ListItem): - image: str = pydantic.Field() +class ContactBlocked(ContactReference): """ - An image that will be displayed to the left of the item. + blocked contact object """ - image_width: int = pydantic.Field() + blocked: typing.Optional[bool] = pydantic.Field(default=None) """ - The exact width of the image in pixels. - """ - - image_height: int = pydantic.Field() - """ - The exact height of the image in pixels. + Always true. """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/contact_companies.py b/src/intercom/types/contact_companies.py index 79ddfcb..8975f79 100644 --- a/src/intercom/types/contact_companies.py +++ b/src/intercom/types/contact_companies.py @@ -5,35 +5,30 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel -from .contact_company import ContactCompany +from .company_data import CompanyData class ContactCompanies(UncheckedBaseModel): """ - An object containing companies meta data about the companies that a contact has. Up to 10 will be displayed here. Use the url to get more. + An object with metadata about companies attached to a contact . Up to 10 will be displayed here. Use the url to get more. """ - type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) + data: typing.Optional[typing.List[CompanyData]] = pydantic.Field(default=None) """ - The type of object + An array of company data objects attached to the contact. """ - data: typing.Optional[typing.List[ContactCompany]] = pydantic.Field(default=None) - """ - An array containing Company Objects - """ - - url: str = pydantic.Field() + url: typing.Optional[str] = pydantic.Field(default=None) """ Url to get more company resources for this contact """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ - Int representing the total number of companyies attached to this contact + Integer representing the total number of companies attached to this contact """ - has_more: bool = pydantic.Field() + has_more: typing.Optional[bool] = pydantic.Field(default=None) """ Whether there's more Addressable Objects to be viewed. If true, use the url to view all """ diff --git a/src/intercom/types/contact_deleted.py b/src/intercom/types/contact_deleted.py index f6e6c80..3b4ba10 100644 --- a/src/intercom/types/contact_deleted.py +++ b/src/intercom/types/contact_deleted.py @@ -4,30 +4,15 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel +from .contact_reference import ContactReference -class ContactDeleted(UncheckedBaseModel): +class ContactDeleted(ContactReference): """ deleted contact object """ - type: typing.Literal["contact"] = pydantic.Field(default="contact") - """ - always contact - """ - - id: str = pydantic.Field() - """ - The unique identifier for the contact which is given by Intercom. - """ - - external_id: typing.Optional[str] = pydantic.Field(default=None) - """ - The unique identifier for the contact which is provided by the Client. - """ - - deleted: bool = pydantic.Field() + deleted: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the contact is deleted or not. """ diff --git a/src/intercom/types/contact_list.py b/src/intercom/types/contact_list.py index 867f09f..9d1914d 100644 --- a/src/intercom/types/contact_list.py +++ b/src/intercom/types/contact_list.py @@ -14,17 +14,17 @@ class ContactList(UncheckedBaseModel): Contacts are your users in Intercom. """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ Always list """ - data: typing.List[Contact] = pydantic.Field() + data: typing.Optional[typing.List[Contact]] = pydantic.Field(default=None) """ The list of contact objects """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ A count of the total number of objects. """ diff --git a/src/intercom/types/contact_location.py b/src/intercom/types/contact_location.py index 0866784..f24ea02 100644 --- a/src/intercom/types/contact_location.py +++ b/src/intercom/types/contact_location.py @@ -12,7 +12,7 @@ class ContactLocation(UncheckedBaseModel): An object containing location meta data about a Intercom contact. """ - type: typing.Literal["location"] = pydantic.Field(default="location") + type: typing.Optional[str] = pydantic.Field(default=None) """ Always location """ diff --git a/src/intercom/types/contact_notes.py b/src/intercom/types/contact_notes.py index 9cf498f..e81bc8c 100644 --- a/src/intercom/types/contact_notes.py +++ b/src/intercom/types/contact_notes.py @@ -13,22 +13,22 @@ class ContactNotes(UncheckedBaseModel): An object containing notes meta data about the notes that a contact has. Up to 10 will be displayed here. Use the url to get more. """ - data: typing.List[AddressableList] = pydantic.Field() + data: typing.Optional[typing.List[AddressableList]] = pydantic.Field(default=None) """ This object represents the notes attached to a contact. """ - url: str = pydantic.Field() + url: typing.Optional[str] = pydantic.Field(default=None) """ Url to get more company resources for this contact """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ Int representing the total number of companyies attached to this contact """ - has_more: bool = pydantic.Field() + has_more: typing.Optional[bool] = pydantic.Field(default=None) """ Whether there's more Addressable Objects to be viewed. If true, use the url to view all """ diff --git a/src/intercom/types/contact_reference.py b/src/intercom/types/contact_reference.py index e5502fe..5e07f67 100644 --- a/src/intercom/types/contact_reference.py +++ b/src/intercom/types/contact_reference.py @@ -12,12 +12,12 @@ class ContactReference(UncheckedBaseModel): reference to contact object """ - type: typing.Literal["contact"] = pydantic.Field(default="contact") + type: typing.Optional[typing.Literal["contact"]] = pydantic.Field(default=None) """ always contact """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier for the contact which is given by Intercom. """ diff --git a/src/intercom/types/contact_reply_base_request.py b/src/intercom/types/contact_reply_base_request.py index 49d6df9..41d6be3 100644 --- a/src/intercom/types/contact_reply_base_request.py +++ b/src/intercom/types/contact_reply_base_request.py @@ -5,6 +5,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel +from .contact_reply_base_request_reply_options_item import ContactReplyBaseRequestReplyOptionsItem class ContactReplyBaseRequest(UncheckedBaseModel): @@ -25,6 +26,11 @@ class ContactReplyBaseRequest(UncheckedBaseModel): A list of image URLs that will be added as attachments. You can include up to 10 URLs. """ + reply_options: typing.Optional[typing.List[ContactReplyBaseRequestReplyOptionsItem]] = pydantic.Field(default=None) + """ + The quick reply selection the contact wishes to respond with. These map to buttons displayed in the Messenger UI if sent by a bot, or the reply options sent by an Admin via the API. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/types/event.py b/src/intercom/types/contact_reply_base_request_reply_options_item.py similarity index 59% rename from src/intercom/types/event.py rename to src/intercom/types/contact_reply_base_request_reply_options_item.py index 96d58e4..99bc835 100644 --- a/src/intercom/types/event.py +++ b/src/intercom/types/contact_reply_base_request_reply_options_item.py @@ -3,18 +3,21 @@ import typing import pydantic +import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.serialization import FieldMetadata from ..core.unchecked_base_model import UncheckedBaseModel -class Event(UncheckedBaseModel): +class ContactReplyBaseRequestReplyOptionsItem(UncheckedBaseModel): + text: str = pydantic.Field() """ - The event object enables Intercom to know more about the actions that took place in your app. Currently, you can only tell us when an app's flow has been completed. + The text of the chosen reply option. """ - type: typing.Literal["completed"] = pydantic.Field(default="completed") + uuid_: typing_extensions.Annotated[str, FieldMetadata(alias="uuid")] = pydantic.Field() """ - What action took place. The only value currently accepted is `completed`. + The unique identifier for the quick reply option selected. """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/contact_segments.py b/src/intercom/types/contact_segments.py index 48d5a1b..9431191 100644 --- a/src/intercom/types/contact_segments.py +++ b/src/intercom/types/contact_segments.py @@ -13,12 +13,12 @@ class ContactSegments(UncheckedBaseModel): A list of segments objects attached to a specific contact. """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of the object """ - data: typing.List[Segment] = pydantic.Field() + data: typing.Optional[typing.List[Segment]] = pydantic.Field(default=None) """ Segment objects associated with the contact. """ diff --git a/src/intercom/types/contact_social_profiles.py b/src/intercom/types/contact_social_profiles.py index 946c8c1..c00fb2a 100644 --- a/src/intercom/types/contact_social_profiles.py +++ b/src/intercom/types/contact_social_profiles.py @@ -13,7 +13,7 @@ class ContactSocialProfiles(UncheckedBaseModel): An object containing social profiles that a contact has. """ - data: typing.List[SocialProfile] = pydantic.Field() + data: typing.Optional[typing.List[SocialProfile]] = pydantic.Field(default=None) """ A list of social profiles objects associated with the contact. """ diff --git a/src/intercom/types/contact_subscription_types.py b/src/intercom/types/contact_subscription_types.py index ae348c9..a075e34 100644 --- a/src/intercom/types/contact_subscription_types.py +++ b/src/intercom/types/contact_subscription_types.py @@ -13,22 +13,22 @@ class ContactSubscriptionTypes(UncheckedBaseModel): An object containing Subscription Types meta data about the SubscriptionTypes that a contact has. """ - data: typing.List[AddressableList] = pydantic.Field() + data: typing.Optional[typing.List[AddressableList]] = pydantic.Field(default=None) """ This object represents the subscriptions attached to a contact. """ - url: str = pydantic.Field() + url: typing.Optional[str] = pydantic.Field(default=None) """ Url to get more subscription type resources for this contact """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ Int representing the total number of subscription types attached to this contact """ - has_more: bool = pydantic.Field() + has_more: typing.Optional[bool] = pydantic.Field(default=None) """ Whether there's more Addressable Objects to be viewed. If true, use the url to view all """ diff --git a/src/intercom/types/contact_tags.py b/src/intercom/types/contact_tags.py index 5a94714..5f90ba3 100644 --- a/src/intercom/types/contact_tags.py +++ b/src/intercom/types/contact_tags.py @@ -13,22 +13,22 @@ class ContactTags(UncheckedBaseModel): An object containing tags meta data about the tags that a contact has. Up to 10 will be displayed here. Use the url to get more. """ - data: typing.List[AddressableList] = pydantic.Field() + data: typing.Optional[typing.List[AddressableList]] = pydantic.Field(default=None) """ This object represents the tags attached to a contact. """ - url: str = pydantic.Field() + url: typing.Optional[str] = pydantic.Field(default=None) """ url to get more tag resources for this contact """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ Int representing the total number of tags attached to this contact """ - has_more: bool = pydantic.Field() + has_more: typing.Optional[bool] = pydantic.Field(default=None) """ Whether there's more Addressable Objects to be viewed. If true, use the url to view all """ diff --git a/src/intercom/types/contact_unarchived.py b/src/intercom/types/contact_unarchived.py index 38fac21..b194e9f 100644 --- a/src/intercom/types/contact_unarchived.py +++ b/src/intercom/types/contact_unarchived.py @@ -4,30 +4,15 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel +from .contact_reference import ContactReference -class ContactUnarchived(UncheckedBaseModel): +class ContactUnarchived(ContactReference): """ unarchived contact object """ - type: typing.Literal["contact"] = pydantic.Field(default="contact") - """ - always contact - """ - - id: str = pydantic.Field() - """ - The unique identifier for the contact which is given by Intercom. - """ - - external_id: typing.Optional[str] = pydantic.Field(default=None) - """ - The unique identifier for the contact which is provided by the Client. - """ - - archived: bool = pydantic.Field() + archived: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the contact is archived or not. """ diff --git a/src/intercom/types/content_object.py b/src/intercom/types/content_object.py deleted file mode 100644 index 857f544..0000000 --- a/src/intercom/types/content_object.py +++ /dev/null @@ -1,30 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .component import Component - - -class ContentObject(UncheckedBaseModel): - """ - The content object is where you specify the UI of your app. You provide us with a set of `components` in a components array that we then render. - - The content object should usually be returned within the [canvas object](https://developers.intercom.com/docs/references/canvas-kit/responseobjects/canvas). If you're responding to a Live Canvas request however, then you should only respond with the content object. - """ - - components: typing.List[Component] = pydantic.Field() - """ - The list of components to be rendered. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/content_sources_list.py b/src/intercom/types/content_sources_list.py index 14cdd1c..62f2eb1 100644 --- a/src/intercom/types/content_sources_list.py +++ b/src/intercom/types/content_sources_list.py @@ -9,13 +9,13 @@ class ContentSourcesList(UncheckedBaseModel): - type: typing.Literal["content_source.list"] = "content_source.list" - total_count: int = pydantic.Field() + type: typing.Optional[typing.Literal["content_source.list"]] = None + total_count: typing.Optional[int] = pydantic.Field(default=None) """ The total number of content sources used by AI Agent in the conversation. """ - content_sources: typing.List[ContentSource] = pydantic.Field() + content_sources: typing.Optional[typing.List[ContentSource]] = pydantic.Field(default=None) """ The content sources used by AI Agent in the conversation. """ diff --git a/src/intercom/types/context.py b/src/intercom/types/context.py deleted file mode 100644 index 25e0f59..0000000 --- a/src/intercom/types/context.py +++ /dev/null @@ -1,55 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .context_location import ContextLocation - - -class Context(UncheckedBaseModel): - """ - The context object provides additional details on where the app has been added (or is currently being used), what page the app is being used on, and information on the Messenger settings. This is in order for you give a fully customised experience based on the customers use case. - - If the `location` is `conversation` then you will also be given a `conversation_id`. If you need to use details about the conversation, then you have to use the `conversation_id` to [make a call to our Conversations API and retrieve the conversation object](https://developers.intercom.com/intercom-api-reference/reference#get-a-single-conversation). - """ - - conversation_id: typing.Optional[int] = pydantic.Field(default=None) - """ - The id of the conversation where the app is added or being used. - """ - - location: typing.Optional[ContextLocation] = pydantic.Field(default=None) - """ - Where the app is added or the action took place. Can be either 'conversation', 'home', 'message', or 'operator'. - """ - - locale: typing.Optional[str] = pydantic.Field(default=None) - """ - The default end-user language of the Messenger. Use to localise Messenger App content. - """ - - messenger_action_colour: typing.Optional[str] = pydantic.Field(default=None) - """ - The messengers action colour. Use in Sheets and Icons to make a Messenger App experience feel part of the host Messenger. - """ - - messenger_background_colour: typing.Optional[str] = pydantic.Field(default=None) - """ - The messengers background colour. Use in Sheets and Icons to make a Messenger App experience feel part of the host Messenger. - """ - - referrer: typing.Optional[str] = pydantic.Field(default=None) - """ - The current page URL where the app is being used. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/context_location.py b/src/intercom/types/context_location.py deleted file mode 100644 index f416a3b..0000000 --- a/src/intercom/types/context_location.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -ContextLocation = typing.Union[typing.Literal["conversation", "home", "message", "operator"], typing.Any] diff --git a/src/intercom/types/conversation_attachment_files.py b/src/intercom/types/conversation_attachment_files.py index 97f5197..92970bc 100644 --- a/src/intercom/types/conversation_attachment_files.py +++ b/src/intercom/types/conversation_attachment_files.py @@ -12,17 +12,17 @@ class ConversationAttachmentFiles(UncheckedBaseModel): Properties of the attachment files in a conversation part """ - content_type: str = pydantic.Field() + content_type: typing.Optional[str] = pydantic.Field(default=None) """ The content type of the file """ - data: str = pydantic.Field() + data: typing.Optional[str] = pydantic.Field(default=None) """ The base64 encoded file data. """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the file. """ diff --git a/src/intercom/types/conversation_attribute_updated_by_admin.py b/src/intercom/types/conversation_attribute_updated_by_admin.py new file mode 100644 index 0000000..13873aa --- /dev/null +++ b/src/intercom/types/conversation_attribute_updated_by_admin.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .conversation_attribute_updated_by_admin_attribute import ConversationAttributeUpdatedByAdminAttribute +from .conversation_attribute_updated_by_admin_value import ConversationAttributeUpdatedByAdminValue + + +class ConversationAttributeUpdatedByAdmin(UncheckedBaseModel): + """ + Contains details about Custom Data Attributes (CDAs) that were modified by an admin (operator) for conversation part type conversation_attribute_updated_by_admin. + """ + + attribute: typing.Optional[ConversationAttributeUpdatedByAdminAttribute] = None + value: typing.Optional[ConversationAttributeUpdatedByAdminValue] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/url_action_component.py b/src/intercom/types/conversation_attribute_updated_by_admin_attribute.py similarity index 73% rename from src/intercom/types/url_action_component.py rename to src/intercom/types/conversation_attribute_updated_by_admin_attribute.py index 7c961fe..c0d761f 100644 --- a/src/intercom/types/url_action_component.py +++ b/src/intercom/types/conversation_attribute_updated_by_admin_attribute.py @@ -7,14 +7,10 @@ from ..core.unchecked_base_model import UncheckedBaseModel -class UrlActionComponent(UncheckedBaseModel): +class ConversationAttributeUpdatedByAdminAttribute(UncheckedBaseModel): + name: typing.Optional[str] = pydantic.Field(default=None) """ - A URL action opens a given link in a new browser tab. - """ - - url: str = pydantic.Field() - """ - The link you want to open. + Name of the CDA updated """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/submit_action_component.py b/src/intercom/types/conversation_attribute_updated_by_admin_value.py similarity index 63% rename from src/intercom/types/submit_action_component.py rename to src/intercom/types/conversation_attribute_updated_by_admin_value.py index ea5788f..ee5cd5f 100644 --- a/src/intercom/types/submit_action_component.py +++ b/src/intercom/types/conversation_attribute_updated_by_admin_value.py @@ -7,9 +7,10 @@ from ..core.unchecked_base_model import UncheckedBaseModel -class SubmitActionComponent(UncheckedBaseModel): +class ConversationAttributeUpdatedByAdminValue(UncheckedBaseModel): + name: typing.Optional[str] = pydantic.Field(default=None) """ - A submit action triggers a [Submit Request](https://developers.intercom.com/docs/canvas-kit#submit-request) to be sent. This request will include all values which have been entered into all the interactive components on the current canvas. + Value of the CDA updated """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/conversation_attribute_updated_by_workflow.py b/src/intercom/types/conversation_attribute_updated_by_workflow.py new file mode 100644 index 0000000..c33ff98 --- /dev/null +++ b/src/intercom/types/conversation_attribute_updated_by_workflow.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .conversation_attribute_updated_by_workflow_attribute import ConversationAttributeUpdatedByWorkflowAttribute +from .conversation_attribute_updated_by_workflow_value import ConversationAttributeUpdatedByWorkflowValue +from .conversation_attribute_updated_by_workflow_workflow import ConversationAttributeUpdatedByWorkflowWorkflow + + +class ConversationAttributeUpdatedByWorkflow(UncheckedBaseModel): + """ + Contains details about the workflow that was triggered and any Custom Data Attributes (CDAs) that were modified during the workflow execution for conversation part type conversation_attribute_updated_by_workflow. + """ + + workflow: typing.Optional[ConversationAttributeUpdatedByWorkflowWorkflow] = None + attribute: typing.Optional[ConversationAttributeUpdatedByWorkflowAttribute] = None + value: typing.Optional[ConversationAttributeUpdatedByWorkflowValue] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/configure_response_canvas.py b/src/intercom/types/conversation_attribute_updated_by_workflow_attribute.py similarity index 63% rename from src/intercom/types/configure_response_canvas.py rename to src/intercom/types/conversation_attribute_updated_by_workflow_attribute.py index ee41462..86730a0 100644 --- a/src/intercom/types/configure_response_canvas.py +++ b/src/intercom/types/conversation_attribute_updated_by_workflow_attribute.py @@ -5,13 +5,12 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel -from .canvas_object import CanvasObject -class ConfigureResponseCanvas(UncheckedBaseModel): - canvas: CanvasObject = pydantic.Field() +class ConversationAttributeUpdatedByWorkflowAttribute(UncheckedBaseModel): + name: typing.Optional[str] = pydantic.Field(default=None) """ - The canvas object that defines the new UI to be shown. This will replace the previous canvas that was visible until the teammate interacted with your app. + Name of the CDA updated """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/conversation_attribute_updated_by_workflow_value.py b/src/intercom/types/conversation_attribute_updated_by_workflow_value.py new file mode 100644 index 0000000..461e4ec --- /dev/null +++ b/src/intercom/types/conversation_attribute_updated_by_workflow_value.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class ConversationAttributeUpdatedByWorkflowValue(UncheckedBaseModel): + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Value of the CDA updated + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/conversation_attribute_updated_by_workflow_workflow.py b/src/intercom/types/conversation_attribute_updated_by_workflow_workflow.py new file mode 100644 index 0000000..445eb7f --- /dev/null +++ b/src/intercom/types/conversation_attribute_updated_by_workflow_workflow.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class ConversationAttributeUpdatedByWorkflowWorkflow(UncheckedBaseModel): + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name of the workflow + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/conversation_contacts.py b/src/intercom/types/conversation_contacts.py index 450c24a..a216f92 100644 --- a/src/intercom/types/conversation_contacts.py +++ b/src/intercom/types/conversation_contacts.py @@ -13,8 +13,12 @@ class ConversationContacts(UncheckedBaseModel): The list of contacts (users or leads) involved in this conversation. This will only contain one customer unless more were added via the group conversation feature. """ - type: typing.Literal["contact.list"] = "contact.list" - contacts: typing.List[ContactReference] = pydantic.Field() + type: typing.Optional[typing.Literal["contact.list"]] = pydantic.Field(default=None) + """ + + """ + + contacts: typing.Optional[typing.List[ContactReference]] = pydantic.Field(default=None) """ The list of contacts (users or leads) involved in this conversation. This will only contain one customer unless more were added via the group conversation feature. """ diff --git a/src/intercom/types/divider_component.py b/src/intercom/types/conversation_deleted.py similarity index 62% rename from src/intercom/types/divider_component.py rename to src/intercom/types/conversation_deleted.py index ef729f1..07b8a1c 100644 --- a/src/intercom/types/divider_component.py +++ b/src/intercom/types/conversation_deleted.py @@ -7,19 +7,24 @@ from ..core.unchecked_base_model import UncheckedBaseModel -class DividerComponent(UncheckedBaseModel): +class ConversationDeleted(UncheckedBaseModel): """ - A divider component is used to separate components with a line. + deleted conversation object """ id: typing.Optional[str] = pydantic.Field(default=None) """ - A unique identifier for the component. + The unique identifier for the conversation. """ - bottom_margin: typing.Optional[typing.Literal["none"]] = pydantic.Field(default=None) + object: typing.Optional[typing.Literal["conversation"]] = pydantic.Field(default=None) """ - Disables a component's margin-bottom of 10px. + always conversation + """ + + deleted: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the conversation is deleted or not. """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/conversation_first_contact_reply.py b/src/intercom/types/conversation_first_contact_reply.py index 7963edd..f158081 100644 --- a/src/intercom/types/conversation_first_contact_reply.py +++ b/src/intercom/types/conversation_first_contact_reply.py @@ -12,12 +12,12 @@ class ConversationFirstContactReply(UncheckedBaseModel): An object containing information on the first users message. For a contact initiated message this will represent the users original message. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ """ - type: str = pydantic.Field() + type: typing.Optional[str] = pydantic.Field(default=None) """ """ diff --git a/src/intercom/types/paginated_conversation_response.py b/src/intercom/types/conversation_list.py similarity index 77% rename from src/intercom/types/paginated_conversation_response.py rename to src/intercom/types/conversation_list.py index d07c35d..5fad7df 100644 --- a/src/intercom/types/paginated_conversation_response.py +++ b/src/intercom/types/conversation_list.py @@ -9,22 +9,22 @@ from .cursor_pages import CursorPages -class PaginatedConversationResponse(UncheckedBaseModel): +class ConversationList(UncheckedBaseModel): """ Conversations are how you can communicate with users in Intercom. They are created when a contact replies to an outbound message, or when one admin directly sends a message to a single contact. """ - type: typing.Literal["conversation.list"] = pydantic.Field(default="conversation.list") + type: typing.Optional[typing.Literal["conversation.list"]] = pydantic.Field(default=None) """ Always conversation.list """ - conversations: typing.List[Conversation] = pydantic.Field() + conversations: typing.Optional[typing.List[Conversation]] = pydantic.Field(default=None) """ The list of conversation objects """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ A count of the total number of objects. """ diff --git a/src/intercom/types/conversation_part.py b/src/intercom/types/conversation_part.py index 152337e..2766f48 100644 --- a/src/intercom/types/conversation_part.py +++ b/src/intercom/types/conversation_part.py @@ -5,7 +5,12 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel +from ..tags.types.tag_basic import TagBasic from .conversation_part_author import ConversationPartAuthor +from .conversation_part_metadata import ConversationPartMetadata +from .conversation_part_state import ConversationPartState +from .email_message_metadata import EmailMessageMetadata +from .event_details import EventDetails from .part_attachment import PartAttachment from .reference import Reference @@ -15,17 +20,17 @@ class ConversationPart(UncheckedBaseModel): A Conversation Part represents a message in the conversation. """ - type: typing.Literal["conversation_part"] = pydantic.Field(default="conversation_part") + type: typing.Optional[str] = pydantic.Field(default=None) """ Always conversation_part """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id representing the conversation part. """ - part_type: str = pydantic.Field() + part_type: typing.Optional[str] = pydantic.Field(default=None) """ The type of conversation part. """ @@ -35,7 +40,7 @@ class ConversationPart(UncheckedBaseModel): The message body, which may contain HTML. For Twitter, this will show a generic message regarding why the body is obscured. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ The time the conversation part was created. """ @@ -45,7 +50,7 @@ class ConversationPart(UncheckedBaseModel): The last time the conversation part was updated. """ - notified_at: int = pydantic.Field() + notified_at: typing.Optional[int] = pydantic.Field(default=None) """ The time the user was notified with the conversation part. """ @@ -55,7 +60,7 @@ class ConversationPart(UncheckedBaseModel): The id of the admin that was assigned the conversation by this conversation_part (null if there has been no change in assignment.) """ - author: ConversationPartAuthor + author: typing.Optional[ConversationPartAuthor] = None attachments: typing.Optional[typing.List[PartAttachment]] = pydantic.Field(default=None) """ A list of attachments for the part. @@ -66,11 +71,29 @@ class ConversationPart(UncheckedBaseModel): The external id of the conversation part """ - redacted: bool = pydantic.Field() + redacted: typing.Optional[bool] = pydantic.Field(default=None) """ Whether or not the conversation part has been redacted. """ + email_message_metadata: typing.Optional[EmailMessageMetadata] = None + metadata: typing.Optional[ConversationPartMetadata] = None + state: typing.Optional[ConversationPartState] = pydantic.Field(default=None) + """ + Indicates the current state of conversation when the conversation part was created. + """ + + tags: typing.Optional[typing.List[TagBasic]] = pydantic.Field(default=None) + """ + A list of tags objects associated with the conversation part. + """ + + event_details: typing.Optional[EventDetails] = None + app_package_code: typing.Optional[str] = pydantic.Field(default=None) + """ + The app package code if this part was created via API. null if the part was not created via API. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/types/conversation_part_author.py b/src/intercom/types/conversation_part_author.py index bcfeafb..3af9b14 100644 --- a/src/intercom/types/conversation_part_author.py +++ b/src/intercom/types/conversation_part_author.py @@ -12,26 +12,36 @@ class ConversationPartAuthor(UncheckedBaseModel): The object who initiated the conversation, which can be a Contact, Admin or Team. Bots and campaigns send messages on behalf of Admins or Teams. For Twitter, this will be blank. """ - type: str = pydantic.Field() + type: typing.Optional[str] = pydantic.Field(default=None) """ The type of the author """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the author """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the author """ - email: str = pydantic.Field() + email: typing.Optional[str] = pydantic.Field(default=None) """ The email of the author """ + from_ai_agent: typing.Optional[bool] = pydantic.Field(default=None) + """ + If this conversation part was sent by the AI Agent + """ + + is_ai_answer: typing.Optional[bool] = pydantic.Field(default=None) + """ + If this conversation part body was generated by the AI Agent + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/types/conversation_part_metadata.py b/src/intercom/types/conversation_part_metadata.py new file mode 100644 index 0000000..2b31b86 --- /dev/null +++ b/src/intercom/types/conversation_part_metadata.py @@ -0,0 +1,35 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .conversation_part_metadata_quick_reply_options_item import ConversationPartMetadataQuickReplyOptionsItem + + +class ConversationPartMetadata(UncheckedBaseModel): + """ + Metadata for a conversation part + """ + + quick_reply_options: typing.Optional[typing.List[ConversationPartMetadataQuickReplyOptionsItem]] = pydantic.Field( + default=None + ) + """ + The quick reply options sent by the Admin or bot, presented in this conversation part. + """ + + quick_reply_uuid: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier for the quick reply option that was clicked by the end user. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/conversation_part_metadata_quick_reply_options_item.py b/src/intercom/types/conversation_part_metadata_quick_reply_options_item.py new file mode 100644 index 0000000..ccfe697 --- /dev/null +++ b/src/intercom/types/conversation_part_metadata_quick_reply_options_item.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from .quick_reply_option import QuickReplyOption + + +class ConversationPartMetadataQuickReplyOptionsItem(QuickReplyOption): + translations: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None) + """ + The translations for the quick reply option. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/conversation_part_state.py b/src/intercom/types/conversation_part_state.py new file mode 100644 index 0000000..96342fb --- /dev/null +++ b/src/intercom/types/conversation_part_state.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +ConversationPartState = typing.Union[typing.Literal["open", "closed", "snoozed"], typing.Any] diff --git a/src/intercom/types/conversation_parts.py b/src/intercom/types/conversation_parts.py index f3e3374..e7f31bd 100644 --- a/src/intercom/types/conversation_parts.py +++ b/src/intercom/types/conversation_parts.py @@ -13,17 +13,17 @@ class ConversationParts(UncheckedBaseModel): A list of Conversation Part objects for each part message in the conversation. This is only returned when Retrieving a Conversation, and ignored when Listing all Conversations. There is a limit of 500 parts. """ - type: typing.Literal["conversation_part.list"] = pydantic.Field(default="conversation_part.list") + type: typing.Optional[typing.Literal["conversation_part.list"]] = pydantic.Field(default=None) """ """ - conversation_parts: typing.List[ConversationPart] = pydantic.Field() + conversation_parts: typing.Optional[typing.List[ConversationPart]] = pydantic.Field(default=None) """ A list of Conversation Part objects for each part message in the conversation. This is only returned when Retrieving a Conversation, and ignored when Listing all Conversations. There is a limit of 500 parts. """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ """ diff --git a/src/intercom/types/conversation_rating.py b/src/intercom/types/conversation_rating.py index fd76822..8f3a608 100644 --- a/src/intercom/types/conversation_rating.py +++ b/src/intercom/types/conversation_rating.py @@ -14,23 +14,28 @@ class ConversationRating(UncheckedBaseModel): The Conversation Rating object which contains information on the rating and/or remark added by a Contact and the Admin assigned to the conversation. """ - rating: int = pydantic.Field() + rating: typing.Optional[int] = pydantic.Field(default=None) """ The rating, between 1 and 5, for the conversation. """ - remark: str = pydantic.Field() + remark: typing.Optional[str] = pydantic.Field(default=None) """ An optional field to add a remark to correspond to the number rating """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ The time the rating was requested in the conversation being rated. """ - contact: ContactReference - teammate: Reference + updated_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time the rating was last updated. + """ + + contact: typing.Optional[ContactReference] = None + teammate: typing.Optional[Reference] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/intercom/types/dropdown_option.py b/src/intercom/types/conversation_response_time.py similarity index 53% rename from src/intercom/types/dropdown_option.py rename to src/intercom/types/conversation_response_time.py index 324abfa..e0e3389 100644 --- a/src/intercom/types/dropdown_option.py +++ b/src/intercom/types/conversation_response_time.py @@ -7,29 +7,24 @@ from ..core.unchecked_base_model import UncheckedBaseModel -class DropdownOption(UncheckedBaseModel): +class ConversationResponseTime(UncheckedBaseModel): """ - A dropdown option component that can be selected. + Details of first response time of assigned team in seconds. """ - type: typing.Literal["option"] = pydantic.Field(default="option") + team_id: typing.Optional[int] = pydantic.Field(default=None) """ - The type of component you are rendering. + Id of the assigned team. """ - id: str = pydantic.Field() + team_name: typing.Optional[str] = pydantic.Field(default=None) """ - A unique identifier for the option. + Name of the assigned Team, null if team does not exist, Unassigned if no team is assigned. """ - text: str = pydantic.Field() + response_time: typing.Optional[int] = pydantic.Field(default=None) """ - The text shown within this option. - """ - - disabled: typing.Optional[bool] = pydantic.Field(default=None) - """ - Styles the option and prevents the action. Default is false. + First response time of assigned team in seconds. """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/conversation_source.py b/src/intercom/types/conversation_source.py index b016f53..31a365d 100644 --- a/src/intercom/types/conversation_source.py +++ b/src/intercom/types/conversation_source.py @@ -12,25 +12,25 @@ class ConversationSource(UncheckedBaseModel): """ - The Conversation Part that originated this conversation, which can be Contact, Admin, Campaign, Automated or Operator initiated. + The type of the conversation part that started this conversation. Can be Contact, Admin, Campaign, Automated or Operator initiated. """ - type: ConversationSourceType = pydantic.Field() + type: typing.Optional[ConversationSourceType] = pydantic.Field(default=None) """ This includes conversation, email, facebook, instagram, phone_call, phone_switch, push, sms, twitter and whatsapp. """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id representing the message. """ - delivered_as: str = pydantic.Field() + delivered_as: typing.Optional[str] = pydantic.Field(default=None) """ The conversation's initiation type. Possible values are customer_initiated, campaigns_initiated (legacy campaigns), operator_initiated (Custom bot), automated (Series and other outbounds with dynamic audience message) and admin_initiated (fixed audience message, ticket initiated by an admin, group email). """ - subject: str = pydantic.Field() + subject: typing.Optional[str] = pydantic.Field(default=None) """ Optional. The message subject. For Twitter, this will show a generic message regarding why the subject is obscured. """ @@ -40,7 +40,7 @@ class ConversationSource(UncheckedBaseModel): The message body, which may contain HTML. For Twitter, this will show a generic message regarding why the body is obscured. """ - author: ConversationPartAuthor + author: typing.Optional[ConversationPartAuthor] = None attachments: typing.Optional[typing.List[PartAttachment]] = pydantic.Field(default=None) """ A list of attachments for the part. @@ -51,7 +51,7 @@ class ConversationSource(UncheckedBaseModel): The URL where the conversation was started. For Twitter, Email, and Bots, this will be blank. """ - redacted: bool = pydantic.Field() + redacted: typing.Optional[bool] = pydantic.Field(default=None) """ Whether or not the source message has been redacted. Only applicable for contact initiated messages. """ diff --git a/src/intercom/types/conversation_statistics.py b/src/intercom/types/conversation_statistics.py index 4e65607..d44cbf6 100644 --- a/src/intercom/types/conversation_statistics.py +++ b/src/intercom/types/conversation_statistics.py @@ -5,6 +5,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel +from .conversation_response_time import ConversationResponseTime class ConversationStatistics(UncheckedBaseModel): @@ -12,7 +13,7 @@ class ConversationStatistics(UncheckedBaseModel): A Statistics object containing all information required for reporting, with timestamps and calculated metrics. """ - type: typing.Literal["conversation_statistics"] = pydantic.Field(default="conversation_statistics") + type: typing.Optional[str] = pydantic.Field(default=None) """ """ @@ -107,6 +108,25 @@ class ConversationStatistics(UncheckedBaseModel): Total number of conversation parts. """ + assigned_team_first_response_time_by_team: typing.Optional[typing.List[ConversationResponseTime]] = pydantic.Field( + default=None + ) + """ + An array of conversation response time objects + """ + + assigned_team_first_response_time_in_office_hours: typing.Optional[typing.List[ConversationResponseTime]] = ( + pydantic.Field(default=None) + ) + """ + An array of conversation response time objects within office hours + """ + + handling_time: typing.Optional[int] = pydantic.Field(default=None) + """ + Time from conversation assignment to conversation close in seconds. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/types/create_article_request.py b/src/intercom/types/create_article_request.py new file mode 100644 index 0000000..83428ff --- /dev/null +++ b/src/intercom/types/create_article_request.py @@ -0,0 +1,62 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .article_translated_content import ArticleTranslatedContent +from .create_article_request_parent_type import CreateArticleRequestParentType +from .create_article_request_state import CreateArticleRequestState + + +class CreateArticleRequest(UncheckedBaseModel): + """ + You can create an Article + """ + + title: str = pydantic.Field() + """ + The title of the article.For multilingual articles, this will be the title of the default language's content. + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + The description of the article. For multilingual articles, this will be the description of the default language's content. + """ + + body: typing.Optional[str] = pydantic.Field(default=None) + """ + The content of the article. For multilingual articles, this will be the body of the default language's content. + """ + + author_id: int = pydantic.Field() + """ + The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. + """ + + state: typing.Optional[CreateArticleRequestState] = pydantic.Field(default=None) + """ + Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. + """ + + parent_id: typing.Optional[int] = pydantic.Field(default=None) + """ + The id of the article's parent collection or section. An article without this field stands alone. + """ + + parent_type: typing.Optional[CreateArticleRequestParentType] = pydantic.Field(default=None) + """ + The type of parent, which can either be a `collection` or `section`. + """ + + translated_content: typing.Optional[ArticleTranslatedContent] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/articles/types/create_article_request_parent_type.py b/src/intercom/types/create_article_request_parent_type.py similarity index 100% rename from src/intercom/articles/types/create_article_request_parent_type.py rename to src/intercom/types/create_article_request_parent_type.py diff --git a/src/intercom/articles/types/create_article_request_state.py b/src/intercom/types/create_article_request_state.py similarity index 100% rename from src/intercom/articles/types/create_article_request_state.py rename to src/intercom/types/create_article_request_state.py diff --git a/src/intercom/types/create_data_attribute_request.py b/src/intercom/types/create_data_attribute_request.py new file mode 100644 index 0000000..cd76eee --- /dev/null +++ b/src/intercom/types/create_data_attribute_request.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .create_data_attribute_request_one import CreateDataAttributeRequestOne +from .create_data_attribute_request_options import CreateDataAttributeRequestOptions + +CreateDataAttributeRequest = typing.Union[CreateDataAttributeRequestOptions, CreateDataAttributeRequestOne] diff --git a/src/intercom/types/create_data_attribute_request_one.py b/src/intercom/types/create_data_attribute_request_one.py new file mode 100644 index 0000000..1693ecd --- /dev/null +++ b/src/intercom/types/create_data_attribute_request_one.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .create_data_attribute_request_one_data_type import CreateDataAttributeRequestOneDataType + + +class CreateDataAttributeRequestOne(UncheckedBaseModel): + data_type: typing.Optional[CreateDataAttributeRequestOneDataType] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/data_attributes/types/create_data_attribute_request_data_type.py b/src/intercom/types/create_data_attribute_request_one_data_type.py similarity index 76% rename from src/intercom/data_attributes/types/create_data_attribute_request_data_type.py rename to src/intercom/types/create_data_attribute_request_one_data_type.py index c2471b7..0689e73 100644 --- a/src/intercom/data_attributes/types/create_data_attribute_request_data_type.py +++ b/src/intercom/types/create_data_attribute_request_one_data_type.py @@ -2,6 +2,6 @@ import typing -CreateDataAttributeRequestDataType = typing.Union[ +CreateDataAttributeRequestOneDataType = typing.Union[ typing.Literal["string", "integer", "float", "boolean", "datetime", "date"], typing.Any ] diff --git a/src/intercom/types/data_table_component.py b/src/intercom/types/create_data_attribute_request_options.py similarity index 52% rename from src/intercom/types/data_table_component.py rename to src/intercom/types/create_data_attribute_request_options.py index 0ebe884..4cfcb97 100644 --- a/src/intercom/types/data_table_component.py +++ b/src/intercom/types/create_data_attribute_request_options.py @@ -5,17 +5,14 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel -from .data_table_item import DataTableItem +from .create_data_attribute_request_options_options_item import CreateDataAttributeRequestOptionsOptionsItem -class DataTableComponent(UncheckedBaseModel): +class CreateDataAttributeRequestOptions(UncheckedBaseModel): + data_type: typing.Optional[typing.Literal["options"]] = None + options: typing.List[CreateDataAttributeRequestOptionsOptionsItem] = pydantic.Field() """ - A data-table component is used for rendering a table of key-value pairs. For Messenger, text will wrap around on multiple lines. For Inbox and Frame (ie. Configure) views, we will truncate and use tooltips on hover if the text overflows. - """ - - items: typing.List[DataTableItem] = pydantic.Field() - """ - The items that will be rendered in the data-table. + Array of objects representing the options of the list, with `value` as the key and the option as the value. At least two options are required. """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/create_data_attribute_request_options_options_item.py b/src/intercom/types/create_data_attribute_request_options_options_item.py new file mode 100644 index 0000000..e879b4f --- /dev/null +++ b/src/intercom/types/create_data_attribute_request_options_options_item.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class CreateDataAttributeRequestOptionsOptionsItem(UncheckedBaseModel): + value: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/create_internal_article_request.py b/src/intercom/types/create_internal_article_request.py new file mode 100644 index 0000000..8a26987 --- /dev/null +++ b/src/intercom/types/create_internal_article_request.py @@ -0,0 +1,42 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class CreateInternalArticleRequest(UncheckedBaseModel): + """ + You can create an Internal Article + """ + + title: str = pydantic.Field() + """ + The title of the article. + """ + + body: typing.Optional[str] = pydantic.Field(default=None) + """ + The content of the article. + """ + + author_id: int = pydantic.Field() + """ + The id of the author of the article. + """ + + owner_id: int = pydantic.Field() + """ + The id of the owner of the article. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/create_or_update_company_request.py b/src/intercom/types/create_or_update_company_request.py new file mode 100644 index 0000000..88f9557 --- /dev/null +++ b/src/intercom/types/create_or_update_company_request.py @@ -0,0 +1,67 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class CreateOrUpdateCompanyRequest(UncheckedBaseModel): + """ + You can create or update a Company + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the Company + """ + + company_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The company id you have defined for the company. Can't be updated + """ + + plan: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the plan you have associated with the company. + """ + + size: typing.Optional[int] = pydantic.Field(default=None) + """ + The number of employees in this company. + """ + + website: typing.Optional[str] = pydantic.Field(default=None) + """ + The URL for this company's website. Please note that the value specified here is not validated. Accepts any string. + """ + + industry: typing.Optional[str] = pydantic.Field(default=None) + """ + The industry that this company operates in. + """ + + custom_attributes: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None) + """ + A hash of key/value pairs containing any other data about the company you want Intercom to store. + """ + + remote_created_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time the company was created by you. + """ + + monthly_spend: typing.Optional[int] = pydantic.Field(default=None) + """ + How much revenue the company generates for your business. Note that this will truncate floats. i.e. it only allow for whole integers, 155.98 will be truncated to 155. Note that this has an upper limit of 2**31-1 or 2147483647.. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/sheet_action_component.py b/src/intercom/types/create_phone_switch_request.py similarity index 61% rename from src/intercom/types/sheet_action_component.py rename to src/intercom/types/create_phone_switch_request.py index 656bd49..988e85d 100644 --- a/src/intercom/types/sheet_action_component.py +++ b/src/intercom/types/create_phone_switch_request.py @@ -5,20 +5,21 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel +from .custom_attributes import CustomAttributes -class SheetActionComponent(UncheckedBaseModel): +class CreatePhoneSwitchRequest(UncheckedBaseModel): """ - A sheet action opens the link you give within the Messenger as an embedded iframe. - - [More on how Sheets work is in our Canvas Kit documentation.](https://developers.intercom.com/docs/canvas-kit#sheets-optional) + You can create an phone switch """ - url: str = pydantic.Field() + phone: str = pydantic.Field() """ - The link which hosts your sheet. + Phone number in E.164 format, that will receive the SMS to continue the conversation in the Messenger. """ + custom_attributes: typing.Optional[CustomAttributes] = None + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/types/create_ticket_request_assignment.py b/src/intercom/types/create_ticket_request_assignment.py new file mode 100644 index 0000000..8c70618 --- /dev/null +++ b/src/intercom/types/create_ticket_request_assignment.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class CreateTicketRequestAssignment(UncheckedBaseModel): + admin_assignee_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The ID of the admin to which the ticket is assigned. If not provided, the ticket will be unassigned. + """ + + team_assignee_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The ID of the team to which the ticket is assigned. If not provided, the ticket will be unassigned. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/create_ticket_request.py b/src/intercom/types/create_ticket_request_body.py similarity index 66% rename from src/intercom/types/create_ticket_request.py rename to src/intercom/types/create_ticket_request_body.py index abee343..7680a22 100644 --- a/src/intercom/types/create_ticket_request.py +++ b/src/intercom/types/create_ticket_request_body.py @@ -5,11 +5,11 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel +from .create_ticket_request_assignment import CreateTicketRequestAssignment from .create_ticket_request_contacts_item import CreateTicketRequestContactsItem -from .ticket_request_custom_attributes import TicketRequestCustomAttributes -class CreateTicketRequest(UncheckedBaseModel): +class CreateTicketRequestBody(UncheckedBaseModel): """ You can create a Ticket """ @@ -24,9 +24,18 @@ class CreateTicketRequest(UncheckedBaseModel): The list of contacts (users or leads) affected by this ticket. Currently only one is allowed """ + conversation_to_link_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The ID of the conversation you want to link to the ticket. Here are the valid ways of linking two tickets: + - conversation | back-office ticket + - customer tickets | non-shared back-office ticket + - conversation | tracker ticket + - customer ticket | tracker ticket + """ + company_id: typing.Optional[str] = pydantic.Field(default=None) """ - The ID of the company that the ticket is associated with. The ID that you set upon company creation. + The ID of the company that the ticket is associated with. The unique identifier for the company which is given by Intercom """ created_at: typing.Optional[int] = pydantic.Field(default=None) @@ -34,7 +43,7 @@ class CreateTicketRequest(UncheckedBaseModel): The time the ticket was created. If not provided, the current time will be used. """ - ticket_attributes: typing.Optional[TicketRequestCustomAttributes] = None + assignment: typing.Optional[CreateTicketRequestAssignment] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/intercom/types/create_ticket_type_request.py b/src/intercom/types/create_ticket_type_request.py new file mode 100644 index 0000000..5ce9d1e --- /dev/null +++ b/src/intercom/types/create_ticket_type_request.py @@ -0,0 +1,49 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .create_ticket_type_request_category import CreateTicketTypeRequestCategory + + +class CreateTicketTypeRequest(UncheckedBaseModel): + """ + The request payload for creating a ticket type. + You can copy the `icon` property for your ticket type from [Twemoji Cheatsheet](https://twemoji-cheatsheet.vercel.app/) + """ + + name: str = pydantic.Field() + """ + The name of the ticket type. + """ + + description: typing.Optional[str] = pydantic.Field(default=None) + """ + The description of the ticket type. + """ + + category: typing.Optional[CreateTicketTypeRequestCategory] = pydantic.Field(default=None) + """ + Category of the Ticket Type. + """ + + icon: typing.Optional[str] = pydantic.Field(default=None) + """ + The icon of the ticket type. + """ + + is_internal: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the tickets associated with this ticket type are intended for internal use only or will be shared with customers. This is currently a limited attribute. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/ticket_types/types/create_ticket_type_request_category.py b/src/intercom/types/create_ticket_type_request_category.py similarity index 100% rename from src/intercom/ticket_types/types/create_ticket_type_request_category.py rename to src/intercom/types/create_ticket_type_request_category.py diff --git a/src/intercom/types/cursor_pages.py b/src/intercom/types/cursor_pages.py index 1c27e2e..9877488 100644 --- a/src/intercom/types/cursor_pages.py +++ b/src/intercom/types/cursor_pages.py @@ -14,7 +14,7 @@ class CursorPages(UncheckedBaseModel): A "cursor" or pointer is used to keep track of the current position in the result set, allowing the API to return the data in small chunks or "pages" as needed. """ - type: typing.Literal["pages"] = pydantic.Field(default="pages") + type: typing.Optional[typing.Literal["pages"]] = pydantic.Field(default=None) """ the type of object `pages`. """ diff --git a/src/intercom/types/custom_action_finished.py b/src/intercom/types/custom_action_finished.py new file mode 100644 index 0000000..4054d04 --- /dev/null +++ b/src/intercom/types/custom_action_finished.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .custom_action_finished_action import CustomActionFinishedAction + + +class CustomActionFinished(UncheckedBaseModel): + """ + Contains details about final status of the completed action for conversation part type custom_action_finished. + """ + + action: typing.Optional[CustomActionFinishedAction] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/current_canvas.py b/src/intercom/types/custom_action_finished_action.py similarity index 61% rename from src/intercom/types/current_canvas.py rename to src/intercom/types/custom_action_finished_action.py index 9adeb2e..7c05f07 100644 --- a/src/intercom/types/current_canvas.py +++ b/src/intercom/types/custom_action_finished_action.py @@ -5,17 +5,18 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel -from .canvas_object import CanvasObject +from .custom_action_finished_action_result import CustomActionFinishedActionResult -class CurrentCanvas(UncheckedBaseModel): +class CustomActionFinishedAction(UncheckedBaseModel): + name: typing.Optional[str] = pydantic.Field(default=None) """ - The current canvas that was most recently showing before the request was sent. This object mirrors the same format as the Canvas Object. + Name of the action """ - current_canvas: CanvasObject = pydantic.Field() + result: typing.Optional[CustomActionFinishedActionResult] = pydantic.Field(default=None) """ - The canvas object representing the current canvas state. + Status of the action """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/custom_action_finished_action_result.py b/src/intercom/types/custom_action_finished_action_result.py new file mode 100644 index 0000000..0f1e35a --- /dev/null +++ b/src/intercom/types/custom_action_finished_action_result.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CustomActionFinishedActionResult = typing.Union[typing.Literal["success", "failed"], typing.Any] diff --git a/src/intercom/types/custom_action_started.py b/src/intercom/types/custom_action_started.py new file mode 100644 index 0000000..de8480e --- /dev/null +++ b/src/intercom/types/custom_action_started.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .custom_action_started_action import CustomActionStartedAction + + +class CustomActionStarted(UncheckedBaseModel): + """ + Contains details about name of the action that was initiated for conversation part type custom_action_started. + """ + + action: typing.Optional[CustomActionStartedAction] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/custom_action_started_action.py b/src/intercom/types/custom_action_started_action.py new file mode 100644 index 0000000..1bc8192 --- /dev/null +++ b/src/intercom/types/custom_action_started_action.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class CustomActionStartedAction(UncheckedBaseModel): + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name of the action + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/custom_attributes.py b/src/intercom/types/custom_attributes.py index 751b394..52b1b17 100644 --- a/src/intercom/types/custom_attributes.py +++ b/src/intercom/types/custom_attributes.py @@ -2,4 +2,6 @@ import typing -CustomAttributes = typing.Dict[str, typing.Optional[typing.Any]] +from .custom_attributes_value import CustomAttributesValue + +CustomAttributes = typing.Dict[str, CustomAttributesValue] diff --git a/src/intercom/types/custom_attributes_value.py b/src/intercom/types/custom_attributes_value.py new file mode 100644 index 0000000..93669f7 --- /dev/null +++ b/src/intercom/types/custom_attributes_value.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .custom_object_instance_list import CustomObjectInstanceList +from .datetime import Datetime + +CustomAttributesValue = typing.Union[str, int, Datetime, CustomObjectInstanceList] diff --git a/src/intercom/types/initialize_response.py b/src/intercom/types/custom_channel_attribute.py similarity index 63% rename from src/intercom/types/initialize_response.py rename to src/intercom/types/custom_channel_attribute.py index b7f9adf..88d3994 100644 --- a/src/intercom/types/initialize_response.py +++ b/src/intercom/types/custom_channel_attribute.py @@ -5,17 +5,17 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel -from .canvas_object import CanvasObject -class InitializeResponse(UncheckedBaseModel): +class CustomChannelAttribute(UncheckedBaseModel): + id: str = pydantic.Field() """ - The response object returned when initializing an app, specifying the UI for the first screen using components. + Identifier for the attribute being collected. """ - canvas: CanvasObject = pydantic.Field() + value: str = pydantic.Field() """ - The canvas object that defines the UI to be shown for the app. + Value provided by the user for the attribute. """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/live_canvas_response.py b/src/intercom/types/custom_channel_base_event.py similarity index 62% rename from src/intercom/types/live_canvas_response.py rename to src/intercom/types/custom_channel_base_event.py index 4f8d833..3670a05 100644 --- a/src/intercom/types/live_canvas_response.py +++ b/src/intercom/types/custom_channel_base_event.py @@ -5,19 +5,22 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel -from .content_object import ContentObject +from .custom_channel_contact import CustomChannelContact -class LiveCanvasResponse(UncheckedBaseModel): +class CustomChannelBaseEvent(UncheckedBaseModel): + event_id: str = pydantic.Field() """ - The response object returned when responding to a Live Canvas request. This contains the components you want to show. + Unique identifier for the event. """ - content: ContentObject = pydantic.Field() + external_conversation_id: str = pydantic.Field() """ - The content object that defines the components to be shown. + Identifier for the conversation in your application. """ + contact: CustomChannelContact + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/types/custom_channel_contact.py b/src/intercom/types/custom_channel_contact.py new file mode 100644 index 0000000..cb1d76b --- /dev/null +++ b/src/intercom/types/custom_channel_contact.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .custom_channel_contact_type import CustomChannelContactType + + +class CustomChannelContact(UncheckedBaseModel): + type: CustomChannelContactType = pydantic.Field() + """ + Type of contact, must be "user" or "lead". + """ + + external_id: str = pydantic.Field() + """ + External identifier for the contact. Intercom will take care of the mapping of your external_id with our internal ones so you don't have to worry about it. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name of the contact. Required for user type. + """ + + email: typing.Optional[str] = pydantic.Field(default=None) + """ + Email address of the contact. Required for user type. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/custom_channel_contact_type.py b/src/intercom/types/custom_channel_contact_type.py new file mode 100644 index 0000000..de33161 --- /dev/null +++ b/src/intercom/types/custom_channel_contact_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CustomChannelContactType = typing.Union[typing.Literal["user", "lead"], typing.Any] diff --git a/src/intercom/types/single_select_option.py b/src/intercom/types/custom_channel_notification_response.py similarity index 52% rename from src/intercom/types/single_select_option.py rename to src/intercom/types/custom_channel_notification_response.py index fe2ef03..394f61c 100644 --- a/src/intercom/types/single_select_option.py +++ b/src/intercom/types/custom_channel_notification_response.py @@ -7,29 +7,25 @@ from ..core.unchecked_base_model import UncheckedBaseModel -class SingleSelectOption(UncheckedBaseModel): +class CustomChannelNotificationResponse(UncheckedBaseModel): + external_conversation_id: str = pydantic.Field() """ - A single select option component that can be selected. + The external conversation ID provided in the notification request """ - type: typing.Literal["option"] = pydantic.Field(default="option") + conversation_id: str = pydantic.Field() """ - The type of component you are rendering. + The Intercom conversation ID mapped to the external conversation ID """ - id: str = pydantic.Field() + external_contact_id: str = pydantic.Field() """ - A unique identifier for the option. + The external contact ID provided in the notification request """ - text: str = pydantic.Field() + contact_id: str = pydantic.Field() """ - The text shown within this option. - """ - - disabled: typing.Optional[bool] = pydantic.Field(default=None) - """ - Styles the option and prevents the action. Default is false. + The Intercom contact ID mapped to the external contact ID """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/custom_object_instance_deleted.py b/src/intercom/types/custom_object_instance_deleted.py new file mode 100644 index 0000000..5d401bf --- /dev/null +++ b/src/intercom/types/custom_object_instance_deleted.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class CustomObjectInstanceDeleted(UncheckedBaseModel): + """ + deleted custom object instance object + """ + + object: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier of the Custom Object type that defines the structure of the Custom Object instance. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The Intercom defined id representing the Custom Object instance. + """ + + deleted: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the Custom Object instance is deleted or not. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/custom_object_instance_list.py b/src/intercom/types/custom_object_instance_list.py new file mode 100644 index 0000000..9cc9735 --- /dev/null +++ b/src/intercom/types/custom_object_instance_list.py @@ -0,0 +1,29 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from ..custom_object_instances.types.custom_object_instance import CustomObjectInstance + + +class CustomObjectInstanceList(UncheckedBaseModel): + """ + The list of associated custom object instances for a given reference attribute on the parent object. + """ + + type: typing.Optional[str] = None + instances: typing.Optional[typing.List[typing.Optional[CustomObjectInstance]]] = pydantic.Field(default=None) + """ + The list of associated custom object instances for a given reference attribute on the parent object. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/data_attribute_list.py b/src/intercom/types/data_attribute_list.py index 5690567..2a7b137 100644 --- a/src/intercom/types/data_attribute_list.py +++ b/src/intercom/types/data_attribute_list.py @@ -13,12 +13,12 @@ class DataAttributeList(UncheckedBaseModel): A list of all data attributes belonging to a workspace for contacts, companies or conversations. """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of the object """ - data: typing.List[DataAttribute] = pydantic.Field() + data: typing.Optional[typing.List[DataAttribute]] = pydantic.Field(default=None) """ A list of data attributes """ diff --git a/src/intercom/types/data_event_list.py b/src/intercom/types/data_event_list.py index 1ebe4a5..f69a464 100644 --- a/src/intercom/types/data_event_list.py +++ b/src/intercom/types/data_event_list.py @@ -14,12 +14,12 @@ class DataEventList(UncheckedBaseModel): This will return a list of data events for the App. """ - type: typing.Literal["event.list"] = pydantic.Field(default="event.list") + type: typing.Optional[typing.Literal["event.list"]] = pydantic.Field(default=None) """ The type of the object """ - events: typing.List[DataEvent] = pydantic.Field() + events: typing.Optional[typing.List[DataEvent]] = pydantic.Field(default=None) """ A list of data events """ diff --git a/src/intercom/types/data_event_summary.py b/src/intercom/types/data_event_summary.py index e39975d..4dab92b 100644 --- a/src/intercom/types/data_event_summary.py +++ b/src/intercom/types/data_event_summary.py @@ -33,7 +33,7 @@ class DataEventSummary(UncheckedBaseModel): The user ID of the user """ - events: typing.List[DataEventSummaryItem] = pydantic.Field() + events: typing.List[typing.Optional[DataEventSummaryItem]] = pydantic.Field() """ A summary of data events """ diff --git a/src/intercom/types/data_event_summary_item.py b/src/intercom/types/data_event_summary_item.py index f540a43..aa3842f 100644 --- a/src/intercom/types/data_event_summary_item.py +++ b/src/intercom/types/data_event_summary_item.py @@ -12,22 +12,22 @@ class DataEventSummaryItem(UncheckedBaseModel): This will return a summary of a data event for the App. """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the event """ - first: str = pydantic.Field() + first: typing.Optional[str] = pydantic.Field(default=None) """ The first time the event was sent """ - last: str = pydantic.Field() + last: typing.Optional[str] = pydantic.Field(default=None) """ The last time the event was sent """ - count: int = pydantic.Field() + count: typing.Optional[int] = pydantic.Field(default=None) """ The number of times the event was sent """ diff --git a/src/intercom/types/data_export_csv.py b/src/intercom/types/data_export_csv.py index 2f83871..40518e8 100644 --- a/src/intercom/types/data_export_csv.py +++ b/src/intercom/types/data_export_csv.py @@ -12,7 +12,7 @@ class DataExportCsv(UncheckedBaseModel): A CSV output file """ - user_id: str = pydantic.Field() + user_id: typing.Optional[str] = pydantic.Field(default=None) """ The user_id of the user who was sent the message. """ @@ -22,37 +22,37 @@ class DataExportCsv(UncheckedBaseModel): The external_user_id of the user who was sent the message """ - company_id: str = pydantic.Field() + company_id: typing.Optional[str] = pydantic.Field(default=None) """ The company ID of the user in relation to the message that was sent. Will return -1 if no company is present. """ - email: str = pydantic.Field() + email: typing.Optional[str] = pydantic.Field(default=None) """ The users email who was sent the message. """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The full name of the user receiving the message """ - ruleset_id: str = pydantic.Field() + ruleset_id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the message. """ - content_id: str = pydantic.Field() + content_id: typing.Optional[str] = pydantic.Field(default=None) """ The specific content that was received. In an A/B test each version has its own Content ID. """ - content_type: str = pydantic.Field() + content_type: typing.Optional[str] = pydantic.Field(default=None) """ Email, Chat, Post etc. """ - content_title: str = pydantic.Field() + content_title: typing.Optional[str] = pydantic.Field(default=None) """ The title of the content you see in your Intercom workspace. """ diff --git a/src/intercom/types/datetime.py b/src/intercom/types/datetime.py new file mode 100644 index 0000000..97bfdac --- /dev/null +++ b/src/intercom/types/datetime.py @@ -0,0 +1,6 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +Datetime = typing.Union[dt.datetime, int] diff --git a/src/intercom/types/deleted_article_object.py b/src/intercom/types/deleted_article_object.py index 13bf420..40038e7 100644 --- a/src/intercom/types/deleted_article_object.py +++ b/src/intercom/types/deleted_article_object.py @@ -12,17 +12,17 @@ class DeletedArticleObject(UncheckedBaseModel): Response returned when an object is deleted """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier for the article which you provided in the URL. """ - object: typing.Literal["article"] = pydantic.Field(default="article") + object: typing.Optional[typing.Literal["article"]] = pydantic.Field(default=None) """ The type of object which was deleted. - article """ - deleted: bool = pydantic.Field() + deleted: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the article was deleted successfully or not. """ diff --git a/src/intercom/types/deleted_collection_object.py b/src/intercom/types/deleted_collection_object.py index 509a2fc..1628b9f 100644 --- a/src/intercom/types/deleted_collection_object.py +++ b/src/intercom/types/deleted_collection_object.py @@ -12,17 +12,17 @@ class DeletedCollectionObject(UncheckedBaseModel): Response returned when an object is deleted """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier for the collection which you provided in the URL. """ - object: typing.Literal["collection"] = pydantic.Field(default="collection") + object: typing.Optional[typing.Literal["collection"]] = pydantic.Field(default=None) """ The type of object which was deleted. - `collection` """ - deleted: bool = pydantic.Field() + deleted: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the collection was deleted successfully or not. """ diff --git a/src/intercom/types/deleted_company_object.py b/src/intercom/types/deleted_company_object.py index e173078..16ad8ef 100644 --- a/src/intercom/types/deleted_company_object.py +++ b/src/intercom/types/deleted_company_object.py @@ -12,17 +12,17 @@ class DeletedCompanyObject(UncheckedBaseModel): Response returned when an object is deleted """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier for the company which is given by Intercom. """ - object: typing.Literal["company"] = pydantic.Field(default="company") + object: typing.Optional[typing.Literal["company"]] = pydantic.Field(default=None) """ The type of object which was deleted. - `company` """ - deleted: bool = pydantic.Field() + deleted: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the company was deleted successfully or not. """ diff --git a/src/intercom/types/deleted_internal_article_object.py b/src/intercom/types/deleted_internal_article_object.py new file mode 100644 index 0000000..848b27e --- /dev/null +++ b/src/intercom/types/deleted_internal_article_object.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class DeletedInternalArticleObject(UncheckedBaseModel): + """ + Response returned when an object is deleted + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier for the internal article which you provided in the URL. + """ + + object: typing.Optional[typing.Literal["internal_article"]] = pydantic.Field(default=None) + """ + The type of object which was deleted. - internal_article + """ + + deleted: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the internal article was deleted successfully or not. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/deleted_object.py b/src/intercom/types/deleted_object.py index c3ed7d6..dbf1f77 100644 --- a/src/intercom/types/deleted_object.py +++ b/src/intercom/types/deleted_object.py @@ -12,17 +12,17 @@ class DeletedObject(UncheckedBaseModel): Response returned when an object is deleted """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier for the news item which you provided in the URL. """ - object: typing.Literal["news-item"] = pydantic.Field(default="news-item") + object: typing.Optional[typing.Literal["news-item"]] = pydantic.Field(default=None) """ The type of object which was deleted - news-item. """ - deleted: bool = pydantic.Field() + deleted: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the news item was deleted successfully or not. """ diff --git a/src/intercom/types/dropdown_component.py b/src/intercom/types/dropdown_component.py deleted file mode 100644 index dd170e7..0000000 --- a/src/intercom/types/dropdown_component.py +++ /dev/null @@ -1,56 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .dropdown_component_save_state import DropdownComponentSaveState -from .dropdown_option import DropdownOption - - -class DropdownComponent(UncheckedBaseModel): - """ - A dropdown component is used to capture a choice from the options that you provide. - - When submitted, the dropdown choices are returned in a hash with the id from the dropdown component used as the key and the id from the chosen option as the value. - """ - - id: str = pydantic.Field() - """ - A unique identifier for the component. - """ - - options: typing.List[DropdownOption] = pydantic.Field() - """ - The list of options. Can provide 2 to 10. - """ - - label: typing.Optional[str] = pydantic.Field(default=None) - """ - The text shown above the dropdown. - """ - - value: typing.Optional[str] = pydantic.Field(default=None) - """ - The option that is selected by default. - """ - - save_state: typing.Optional[DropdownComponentSaveState] = pydantic.Field(default=None) - """ - Styles all options and prevents the action. Default is `unsaved`. Will be overridden if `save_state` is `saved`. - """ - - disabled: typing.Optional[bool] = pydantic.Field(default=None) - """ - Styles all options and prevents the action. Default is false. Will be overridden if save_state is saved. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/dropdown_component_save_state.py b/src/intercom/types/dropdown_component_save_state.py deleted file mode 100644 index acd8e89..0000000 --- a/src/intercom/types/dropdown_component_save_state.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -DropdownComponentSaveState = typing.Union[typing.Literal["unsaved", "saved", "failed"], typing.Any] diff --git a/src/intercom/types/email_address_header.py b/src/intercom/types/email_address_header.py new file mode 100644 index 0000000..9e990ad --- /dev/null +++ b/src/intercom/types/email_address_header.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class EmailAddressHeader(UncheckedBaseModel): + """ + Contains data for an email address header for a conversation part that was sent as an email. + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + The type of email address header + """ + + email_address: typing.Optional[str] = pydantic.Field(default=None) + """ + The email address + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name associated with the email address + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/data_table_item.py b/src/intercom/types/email_message_metadata.py similarity index 57% rename from src/intercom/types/data_table_item.py rename to src/intercom/types/email_message_metadata.py index eb416f2..eb80c07 100644 --- a/src/intercom/types/data_table_item.py +++ b/src/intercom/types/email_message_metadata.py @@ -5,26 +5,22 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel +from .email_address_header import EmailAddressHeader -class DataTableItem(UncheckedBaseModel): +class EmailMessageMetadata(UncheckedBaseModel): """ - A field-value pair component for use in a data table. + Contains metadata if the message was sent as an email """ - type: typing.Literal["field-value"] = pydantic.Field(default="field-value") + subject: typing.Optional[str] = pydantic.Field(default=None) """ - The type of component you are rendering. + The subject of the email """ - field: str = pydantic.Field() + email_address_headers: typing.Optional[typing.List[EmailAddressHeader]] = pydantic.Field(default=None) """ - The text of the key in your key-value pair. - """ - - value: str = pydantic.Field() - """ - The text of the value in your key-value pair. + A list of an email address headers. """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/event_details.py b/src/intercom/types/event_details.py new file mode 100644 index 0000000..2bef222 --- /dev/null +++ b/src/intercom/types/event_details.py @@ -0,0 +1,17 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .conversation_attribute_updated_by_admin import ConversationAttributeUpdatedByAdmin +from .conversation_attribute_updated_by_workflow import ConversationAttributeUpdatedByWorkflow +from .custom_action_finished import CustomActionFinished +from .custom_action_started import CustomActionStarted +from .operator_workflow_event import OperatorWorkflowEvent + +EventDetails = typing.Union[ + ConversationAttributeUpdatedByWorkflow, + ConversationAttributeUpdatedByAdmin, + CustomActionStarted, + CustomActionFinished, + OperatorWorkflowEvent, +] diff --git a/src/intercom/types/file_attribute.py b/src/intercom/types/file_attribute.py index 8ba2af0..e63f4cc 100644 --- a/src/intercom/types/file_attribute.py +++ b/src/intercom/types/file_attribute.py @@ -12,33 +12,33 @@ class FileAttribute(UncheckedBaseModel): The value describing a file upload set for a custom attribute """ - type: str - name: str = pydantic.Field() + type: typing.Optional[str] = None + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the file """ - url: str = pydantic.Field() + url: typing.Optional[str] = pydantic.Field(default=None) """ The url of the file. This is a temporary URL and will expire after 30 minutes. """ - content_type: str = pydantic.Field() + content_type: typing.Optional[str] = pydantic.Field(default=None) """ The type of file """ - filesize: int = pydantic.Field() + filesize: typing.Optional[int] = pydantic.Field(default=None) """ The size of the file in bytes """ - width: int = pydantic.Field() + width: typing.Optional[int] = pydantic.Field(default=None) """ The width of the file in pixels, if applicable """ - height: int = pydantic.Field() + height: typing.Optional[int] = pydantic.Field(default=None) """ The height of the file in pixels, if applicable """ diff --git a/src/intercom/types/group_content.py b/src/intercom/types/group_content.py index d06dca4..36d3266 100644 --- a/src/intercom/types/group_content.py +++ b/src/intercom/types/group_content.py @@ -12,17 +12,17 @@ class GroupContent(UncheckedBaseModel): The Content of a Group. """ - type: typing.Literal["group_content"] = pydantic.Field(default="group_content") + type: typing.Optional[str] = pydantic.Field(default=None) """ The type of object - `group_content` . """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the collection or section. """ - description: str = pydantic.Field() + description: typing.Optional[str] = pydantic.Field(default=None) """ The description of the collection. Only available for collections. """ diff --git a/src/intercom/types/group_translated_content.py b/src/intercom/types/group_translated_content.py index 7bc6b60..2a73782 100644 --- a/src/intercom/types/group_translated_content.py +++ b/src/intercom/types/group_translated_content.py @@ -15,7 +15,7 @@ class GroupTranslatedContent(UncheckedBaseModel): The Translated Content of an Group. The keys are the locale codes and the values are the translated content of the Group. """ - type: typing.Literal["group_translated_content"] = pydantic.Field(default="group_translated_content") + type: typing.Optional[str] = pydantic.Field(default=None) """ The type of object - group_translated_content. """ diff --git a/src/intercom/types/image_component.py b/src/intercom/types/image_component.py deleted file mode 100644 index 74b796c..0000000 --- a/src/intercom/types/image_component.py +++ /dev/null @@ -1,67 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .image_component_align import ImageComponentAlign -from .url_action_component import UrlActionComponent - - -class ImageComponent(UncheckedBaseModel): - """ - An image component is used to display an image. - - HTTPS Images: - If your request URLs (or website URLs) are over HTTPS, you will need to ensure that images are loaded over HTTPS likewise. Otherwise, they will not work. - """ - - id: typing.Optional[str] = pydantic.Field(default=None) - """ - A unique identifier for the component. - """ - - url: str = pydantic.Field() - """ - The URL where the image is located. - """ - - align: typing.Optional[ImageComponentAlign] = pydantic.Field(default=None) - """ - Aligns the image inside the component. Default is `left`. - """ - - width: int = pydantic.Field() - """ - The exact width of the image in pixels. - """ - - height: int = pydantic.Field() - """ - The exact height of the image in pixels. - """ - - rounded: typing.Optional[bool] = pydantic.Field(default=None) - """ - Rounds the corners of the image. Default is `false`. - """ - - bottom_margin: typing.Optional[typing.Literal["none"]] = pydantic.Field(default=None) - """ - Disables a component's margin-bottom of 10px. - """ - - action: typing.Optional[UrlActionComponent] = pydantic.Field(default=None) - """ - This can be a URL Action only. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/image_component_align.py b/src/intercom/types/image_component_align.py deleted file mode 100644 index 2464853..0000000 --- a/src/intercom/types/image_component_align.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -ImageComponentAlign = typing.Union[typing.Literal["left", "center", "right", "full_width"], typing.Any] diff --git a/src/intercom/types/initialize_request.py b/src/intercom/types/initialize_request.py deleted file mode 100644 index ac06b2d..0000000 --- a/src/intercom/types/initialize_request.py +++ /dev/null @@ -1,61 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..admins.types.admin import Admin -from ..contacts.types.contact import Contact -from ..conversations.types.conversation import Conversation -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .context import Context - - -class InitializeRequest(UncheckedBaseModel): - """ - The request payload will have all the data needed for you to understand who is using your app, where they are using it, and how you should respond. There are different request payloads for Messenger capabilities and Inbox capabilities. - """ - - workspace_id: str = pydantic.Field() - """ - The workspace ID of the teammate. Attribute is `app_id` for V1.2 and below. - """ - - workspace_region: str = pydantic.Field() - """ - The Intercom hosted region that this app is located in. - """ - - admin: Admin = pydantic.Field() - """ - The Intercom teammate viewing the conversation. - """ - - card_creation_options: typing.Dict[str, typing.Optional[typing.Any]] = pydantic.Field() - """ - Key-value pairs which were given as results in response to the Configure request. - """ - - context: Context = pydantic.Field() - """ - The context of where the app is added, where the user last visited, and information on the Messenger settings. - """ - - conversation: Conversation = pydantic.Field() - """ - The conversation your app is being shown for. - """ - - contact: Contact = pydantic.Field() - """ - The contact which is currently being viewed by the teammate in the conversation details panel. We send an individual initialize request for each customer when it's a group conversation. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/input_component.py b/src/intercom/types/input_component.py deleted file mode 100644 index d9e3eed..0000000 --- a/src/intercom/types/input_component.py +++ /dev/null @@ -1,62 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .action_component import ActionComponent -from .input_component_save_state import InputComponentSaveState - - -class InputComponent(UncheckedBaseModel): - """ - An input component is used to capture text input from the end user. You can submit the value of the input by: - - - Adding an `action` to the input component (which will render an inline button) - - Using a ButtonComponent (which will submit all interactive components in the canvas) - """ - - id: str = pydantic.Field() - """ - A unique identifier for the component. - """ - - label: typing.Optional[str] = pydantic.Field(default=None) - """ - The text shown above the input. - """ - - placeholder: typing.Optional[str] = pydantic.Field(default=None) - """ - An example value shown inside the component when it's empty. - """ - - value: typing.Optional[str] = pydantic.Field(default=None) - """ - An entered value which is already inside the component. - """ - - action: typing.Optional[ActionComponent] = pydantic.Field(default=None) - """ - This can be a Submit Action, URL Action, or Sheets Action. - """ - - save_state: typing.Optional[InputComponentSaveState] = pydantic.Field(default=None) - """ - Styles the input. Default is `unsaved`. Prevent action with `saved`. - """ - - disabled: typing.Optional[bool] = pydantic.Field(default=None) - """ - Styles the input and prevents the action. Default is false. Will be overridden if save_state is saved. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/input_component_save_state.py b/src/intercom/types/input_component_save_state.py deleted file mode 100644 index eee1e9a..0000000 --- a/src/intercom/types/input_component_save_state.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -InputComponentSaveState = typing.Union[typing.Literal["unsaved", "saved", "failed"], typing.Any] diff --git a/src/intercom/types/internal_article_list.py b/src/intercom/types/internal_article_list.py new file mode 100644 index 0000000..760b1ea --- /dev/null +++ b/src/intercom/types/internal_article_list.py @@ -0,0 +1,40 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from ..internal_articles.types.internal_article_list_item import InternalArticleListItem +from .cursor_pages import CursorPages + + +class InternalArticleList(UncheckedBaseModel): + """ + This will return a list of internal articles for the App. + """ + + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) + """ + The type of the object - `list`. + """ + + pages: typing.Optional[CursorPages] = None + total_count: typing.Optional[int] = pydantic.Field(default=None) + """ + A count of the total number of internal articles. + """ + + data: typing.Optional[typing.List[InternalArticleListItem]] = pydantic.Field(default=None) + """ + An array of Internal Article objects + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/linked_object.py b/src/intercom/types/linked_object.py index bc8f836..f8d6f3b 100644 --- a/src/intercom/types/linked_object.py +++ b/src/intercom/types/linked_object.py @@ -13,12 +13,12 @@ class LinkedObject(UncheckedBaseModel): A linked conversation or ticket. """ - type: LinkedObjectType = pydantic.Field() + type: typing.Optional[LinkedObjectType] = pydantic.Field(default=None) """ ticket or conversation """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The ID of the linked object """ diff --git a/src/intercom/types/linked_object_list.py b/src/intercom/types/linked_object_list.py index 660b7ec..d3221de 100644 --- a/src/intercom/types/linked_object_list.py +++ b/src/intercom/types/linked_object_list.py @@ -13,22 +13,22 @@ class LinkedObjectList(UncheckedBaseModel): An object containing metadata about linked conversations and linked tickets. Up to 1000 can be returned. """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ Always list. """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ The total number of linked objects. """ - has_more: bool = pydantic.Field() + has_more: typing.Optional[bool] = pydantic.Field(default=None) """ Whether or not there are more linked objects than returned. """ - data: typing.List[LinkedObject] = pydantic.Field() + data: typing.Optional[typing.List[LinkedObject]] = pydantic.Field(default=None) """ An array containing the linked conversations and linked tickets. """ diff --git a/src/intercom/types/list_component.py b/src/intercom/types/list_component.py deleted file mode 100644 index 69f3393..0000000 --- a/src/intercom/types/list_component.py +++ /dev/null @@ -1,37 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .list_component_items_item import ListComponentItemsItem - - -class ListComponent(UncheckedBaseModel): - """ - A list component renders a list of items which you provide in an array. You can make each list item take an action by adding the relevant action object to the item: - - - [Trigger a submit request to be sent](https://developers.intercom.com/docs/references/canvas-kit/actioncomponents/submit-action) Inbox Messenger - - [Open a link in a new page](https://developers.intercom.com/docs/references/canvas-kit/actioncomponents/url-action) Inbox Messenger - - [Open a sheet](https://developers.intercom.com/docs/references/canvas-kit/actioncomponents/sheets-action) Messenger - """ - - items: typing.List[ListComponentItemsItem] = pydantic.Field() - """ - The items that will be rendered in the list. - """ - - disabled: typing.Optional[bool] = pydantic.Field(default=None) - """ - Styles all list items and prevents the action. Default is `false`. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/list_component_items_item.py b/src/intercom/types/list_component_items_item.py deleted file mode 100644 index 8549e33..0000000 --- a/src/intercom/types/list_component_items_item.py +++ /dev/null @@ -1,8 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -from .list_item_with_image import ListItemWithImage -from .list_item_without_image import ListItemWithoutImage - -ListComponentItemsItem = typing.Union[ListItemWithImage, ListItemWithoutImage] diff --git a/src/intercom/types/list_item.py b/src/intercom/types/list_item.py deleted file mode 100644 index f2263d3..0000000 --- a/src/intercom/types/list_item.py +++ /dev/null @@ -1,63 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .action_component import ActionComponent - - -class ListItem(UncheckedBaseModel): - """ - A list item component that can be rendered in a list. - """ - - type: typing.Literal["item"] = pydantic.Field(default="item") - """ - The type of component you are rendering. - """ - - id: str = pydantic.Field() - """ - A unique identifier for the item. - """ - - title: str = pydantic.Field() - """ - The text shown as the title for the item. - """ - - subtitle: typing.Optional[str] = pydantic.Field(default=None) - """ - The text shown underneath the item's title. - """ - - tertiary_text: typing.Optional[str] = pydantic.Field(default=None) - """ - The text shown next to the subtitle, separates by a bullet. - """ - - rounded_image: typing.Optional[bool] = pydantic.Field(default=None) - """ - Rounds the corners of the image. Default is `false`. - """ - - disabled: typing.Optional[bool] = pydantic.Field(default=None) - """ - Styles all list items and prevents the action. Default is `false`. - """ - - action: typing.Optional[ActionComponent] = pydantic.Field(default=None) - """ - This can be a Submit Action, URL Action, or Sheets Action. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/list_item_without_image.py b/src/intercom/types/list_item_without_image.py deleted file mode 100644 index ee43156..0000000 --- a/src/intercom/types/list_item_without_image.py +++ /dev/null @@ -1,33 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from .list_item import ListItem - - -class ListItemWithoutImage(ListItem): - image: typing.Optional[str] = pydantic.Field(default=None) - """ - An image that will be displayed to the left of the item. - """ - - image_width: typing.Optional[int] = pydantic.Field(default=None) - """ - The exact width of the image in pixels. - """ - - image_height: typing.Optional[int] = pydantic.Field(default=None) - """ - The exact height of the image in pixels. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/live_canvas_request.py b/src/intercom/types/live_canvas_request.py deleted file mode 100644 index 998c617..0000000 --- a/src/intercom/types/live_canvas_request.py +++ /dev/null @@ -1,52 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..contacts.types.contact import Contact -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .canvas_object import CanvasObject -from .context import Context - - -class LiveCanvasRequest(UncheckedBaseModel): - """ - Canvases are static by default and require a new request to come through in order to update them. Live canvases however will make requests every time the card is viewed without any interaction needed, meaning the canvas can be kept up-to-date with no action from the user. - - This works for every Messenger request that you can respond with a canvas object to. Instead of returning the content object within the canvas object, you should provide a `content_url` attribute instead with the value being the URL you want us to send a POST request to when someone views the app. - """ - - workspace_id: str = pydantic.Field() - """ - The workspace ID of the teammate. Attribute is `app_id` for V1.2 and below. - """ - - workspace_region: str = pydantic.Field() - """ - The Intercom hosted region that this app is located in. - """ - - canvas: CanvasObject = pydantic.Field() - """ - The current_canvas the teammate can see. - """ - - context: Context = pydantic.Field() - """ - The context of where the app is added, where the user last visited, and information on the Messenger settings. - """ - - contact: Contact = pydantic.Field() - """ - The contact who viewed the card. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/multiple_filter_search_request.py b/src/intercom/types/multiple_filter_search_request.py index 9ed97b0..e0bc1c3 100644 --- a/src/intercom/types/multiple_filter_search_request.py +++ b/src/intercom/types/multiple_filter_search_request.py @@ -20,7 +20,7 @@ class MultipleFilterSearchRequest(UncheckedBaseModel): An operator to allow boolean inspection between multiple fields. """ - value: typing.Optional[typing.List["MultipleOrSingleFilterSearchRequest"]] = None + value: typing.Optional["MultipleFilterSearchRequestValue"] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -32,6 +32,6 @@ class Config: extra = pydantic.Extra.allow -from .multiple_or_single_filter_search_request import MultipleOrSingleFilterSearchRequest # noqa: E402, F401, I001 +from .multiple_filter_search_request_value import MultipleFilterSearchRequestValue # noqa: E402, F401, I001 update_forward_refs(MultipleFilterSearchRequest) diff --git a/src/intercom/types/multiple_or_single_filter_search_request.py b/src/intercom/types/multiple_filter_search_request_value.py similarity index 67% rename from src/intercom/types/multiple_or_single_filter_search_request.py rename to src/intercom/types/multiple_filter_search_request_value.py index 1d6d20f..16a7c59 100644 --- a/src/intercom/types/multiple_or_single_filter_search_request.py +++ b/src/intercom/types/multiple_filter_search_request_value.py @@ -8,4 +8,6 @@ if typing.TYPE_CHECKING: from .multiple_filter_search_request import MultipleFilterSearchRequest -MultipleOrSingleFilterSearchRequest = typing.Union["MultipleFilterSearchRequest", SingleFilterSearchRequest] +MultipleFilterSearchRequestValue = typing.Union[ + typing.List["MultipleFilterSearchRequest"], typing.List[SingleFilterSearchRequest] +] diff --git a/src/intercom/types/not_found_error_body.py b/src/intercom/types/not_found_error_body.py new file mode 100644 index 0000000..b19fe72 --- /dev/null +++ b/src/intercom/types/not_found_error_body.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .not_found_error_body_errors_item import NotFoundErrorBodyErrorsItem + + +class NotFoundErrorBody(UncheckedBaseModel): + type: str = pydantic.Field() + """ + The type is error.list + """ + + request_id: typing.Optional[str] = pydantic.Field(default=None) + """ + + """ + + errors: typing.List[NotFoundErrorBodyErrorsItem] = pydantic.Field() + """ + An array of one or more error objects + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/not_found_error_body_errors_item.py b/src/intercom/types/not_found_error_body_errors_item.py new file mode 100644 index 0000000..ca80ecf --- /dev/null +++ b/src/intercom/types/not_found_error_body_errors_item.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class NotFoundErrorBodyErrorsItem(UncheckedBaseModel): + code: str = pydantic.Field() + """ + ticket_not_found + """ + + message: typing.Optional[str] = pydantic.Field(default=None) + """ + Ticket not found + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/note_list.py b/src/intercom/types/note_list.py index b095fe0..7ba90ce 100644 --- a/src/intercom/types/note_list.py +++ b/src/intercom/types/note_list.py @@ -13,17 +13,17 @@ class NoteList(UncheckedBaseModel): A paginated list of notes associated with a contact. """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[str] = pydantic.Field(default=None) """ String representing the object's type. Always has the value `list`. """ - data: typing.List[Note] = pydantic.Field() + data: typing.Optional[typing.List[Note]] = pydantic.Field(default=None) """ An array of notes. """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ A count of the total number of notes. """ diff --git a/src/intercom/types/operator_workflow_event.py b/src/intercom/types/operator_workflow_event.py new file mode 100644 index 0000000..d9ec497 --- /dev/null +++ b/src/intercom/types/operator_workflow_event.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .operator_workflow_event_event import OperatorWorkflowEventEvent +from .operator_workflow_event_workflow import OperatorWorkflowEventWorkflow + + +class OperatorWorkflowEvent(UncheckedBaseModel): + """ + Contains details about name of the workflow for conversation part type operator_workflow_event. + """ + + workflow: typing.Optional[OperatorWorkflowEventWorkflow] = None + event: typing.Optional[OperatorWorkflowEventEvent] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/operator_workflow_event_event.py b/src/intercom/types/operator_workflow_event_event.py new file mode 100644 index 0000000..10bf3ef --- /dev/null +++ b/src/intercom/types/operator_workflow_event_event.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class OperatorWorkflowEventEvent(UncheckedBaseModel): + type: typing.Optional[str] = pydantic.Field(default=None) + """ + Type of the workflow event initiated + """ + + result: typing.Optional[str] = pydantic.Field(default=None) + """ + Result of the workflow event + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/operator_workflow_event_workflow.py b/src/intercom/types/operator_workflow_event_workflow.py new file mode 100644 index 0000000..0952658 --- /dev/null +++ b/src/intercom/types/operator_workflow_event_workflow.py @@ -0,0 +1,23 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class OperatorWorkflowEventWorkflow(UncheckedBaseModel): + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the workflow + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/pages_link.py b/src/intercom/types/pages_link.py index f041d00..ccd818f 100644 --- a/src/intercom/types/pages_link.py +++ b/src/intercom/types/pages_link.py @@ -14,15 +14,15 @@ class PagesLink(UncheckedBaseModel): Their responses are likely to contain a pages object that hosts pagination links which a client can use to paginate through the data without having to construct a query. The link relations for the pages field are as follows. """ - type: typing.Literal["pages"] = "pages" - page: int + type: typing.Optional[typing.Literal["pages"]] = None + page: typing.Optional[int] = None next: typing.Optional[str] = pydantic.Field(default=None) """ A link to the next page of results. A response that does not contain a next link does not have further data to fetch. """ - per_page: int - total_pages: int + per_page: typing.Optional[int] = None + total_pages: typing.Optional[int] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/intercom/types/paginated_newsfeed_response.py b/src/intercom/types/paginated_response.py similarity index 57% rename from src/intercom/types/paginated_newsfeed_response.py rename to src/intercom/types/paginated_response.py index 4da53c3..787bff8 100644 --- a/src/intercom/types/paginated_newsfeed_response.py +++ b/src/intercom/types/paginated_response.py @@ -5,29 +5,30 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel -from ..news.types.newsfeed import Newsfeed from .cursor_pages import CursorPages +from .paginated_response_data_item import PaginatedResponseDataItem +from .paginated_response_type import PaginatedResponseType -class PaginatedNewsfeedResponse(UncheckedBaseModel): +class PaginatedResponse(UncheckedBaseModel): """ - Paginated Newsfeed Response + Paginated Response """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[PaginatedResponseType] = pydantic.Field(default=None) """ The type of object """ pages: typing.Optional[CursorPages] = None - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ - A count of the total number of Newsfeeds. + A count of the total number of objects. """ - data: typing.List[Newsfeed] = pydantic.Field() + data: typing.Optional[typing.List[PaginatedResponseDataItem]] = pydantic.Field(default=None) """ - An array of Newsfeeds + An array of Objects """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/paginated_response_data_item.py b/src/intercom/types/paginated_response_data_item.py new file mode 100644 index 0000000..0052b2f --- /dev/null +++ b/src/intercom/types/paginated_response_data_item.py @@ -0,0 +1,61 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations + +import typing + +import pydantic +import typing_extensions +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel, UnionMetadata +from ..news.types.news_item_state import NewsItemState +from ..news.types.newsfeed_assignment import NewsfeedAssignment + + +class PaginatedResponseDataItem_NewsItem(UncheckedBaseModel): + type: typing.Literal["news-item"] = "news-item" + id: typing.Optional[str] = None + workspace_id: typing.Optional[str] = None + title: typing.Optional[str] = None + body: typing.Optional[str] = None + sender_id: typing.Optional[int] = None + state: typing.Optional[NewsItemState] = None + newsfeed_assignments: typing.Optional[typing.List[NewsfeedAssignment]] = None + labels: typing.Optional[typing.List[typing.Optional[str]]] = None + cover_image_url: typing.Optional[str] = None + reactions: typing.Optional[typing.List[typing.Optional[str]]] = None + deliver_silently: typing.Optional[bool] = None + created_at: typing.Optional[int] = None + updated_at: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +class PaginatedResponseDataItem_Newsfeed(UncheckedBaseModel): + type: typing.Literal["newsfeed"] = "newsfeed" + id: typing.Optional[str] = None + name: typing.Optional[str] = None + created_at: typing.Optional[int] = None + updated_at: typing.Optional[int] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +PaginatedResponseDataItem = typing_extensions.Annotated[ + typing.Union[PaginatedResponseDataItem_NewsItem, PaginatedResponseDataItem_Newsfeed], + UnionMetadata(discriminant="type"), +] diff --git a/src/intercom/types/paginated_response_type.py b/src/intercom/types/paginated_response_type.py new file mode 100644 index 0000000..04cce50 --- /dev/null +++ b/src/intercom/types/paginated_response_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +PaginatedResponseType = typing.Union[typing.Literal["list", "conversation.list"], typing.Any] diff --git a/src/intercom/types/part_attachment.py b/src/intercom/types/part_attachment.py index 0c4495f..7917095 100644 --- a/src/intercom/types/part_attachment.py +++ b/src/intercom/types/part_attachment.py @@ -12,37 +12,37 @@ class PartAttachment(UncheckedBaseModel): The file attached to a part """ - type: str = pydantic.Field() + type: typing.Optional[str] = pydantic.Field(default=None) """ The type of attachment """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the attachment """ - url: str = pydantic.Field() + url: typing.Optional[str] = pydantic.Field(default=None) """ The URL of the attachment """ - content_type: str = pydantic.Field() + content_type: typing.Optional[str] = pydantic.Field(default=None) """ The content type of the attachment """ - filesize: int = pydantic.Field() + filesize: typing.Optional[int] = pydantic.Field(default=None) """ The size of the attachment """ - width: int = pydantic.Field() + width: typing.Optional[int] = pydantic.Field(default=None) """ The width of the attachment """ - height: int = pydantic.Field() + height: typing.Optional[int] = pydantic.Field(default=None) """ The height of the attachment """ diff --git a/src/intercom/types/phone_switch.py b/src/intercom/types/phone_switch.py index a8cfb40..7f20b7a 100644 --- a/src/intercom/types/phone_switch.py +++ b/src/intercom/types/phone_switch.py @@ -12,12 +12,12 @@ class PhoneSwitch(UncheckedBaseModel): Phone Switch Response """ - type: typing.Literal["phone_call_redirect"] = pydantic.Field(default="phone_call_redirect") + type: typing.Optional[typing.Literal["phone_call_redirect"]] = pydantic.Field(default=None) """ """ - phone: str = pydantic.Field() + phone: typing.Optional[str] = pydantic.Field(default=None) """ Phone number in E.164 format, that has received the SMS to continue the conversation in the Messenger. """ diff --git a/src/intercom/types/checkbox_option.py b/src/intercom/types/quick_reply_option.py similarity index 52% rename from src/intercom/types/checkbox_option.py rename to src/intercom/types/quick_reply_option.py index edc6c9b..15a918d 100644 --- a/src/intercom/types/checkbox_option.py +++ b/src/intercom/types/quick_reply_option.py @@ -3,33 +3,21 @@ import typing import pydantic +import typing_extensions from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.serialization import FieldMetadata from ..core.unchecked_base_model import UncheckedBaseModel -class CheckboxOption(UncheckedBaseModel): - """ - A checkbox option component that can be selected. - """ - - type: typing.Literal["option"] = pydantic.Field(default="option") - """ - The type of component you are rendering. - """ - - id: str = pydantic.Field() - """ - A unique identifier for the option. - """ - +class QuickReplyOption(UncheckedBaseModel): text: str = pydantic.Field() """ - The text shown next to the checkbox. + The text to display in this quick reply option. """ - disabled: typing.Optional[bool] = pydantic.Field(default=None) + uuid_: typing_extensions.Annotated[str, FieldMetadata(alias="uuid")] = pydantic.Field() """ - Styles the option and prevents the action. Default is false. + A unique identifier for this quick reply option. This value will be available within the metadata of the comment conversation part that is created when a user clicks on this reply option. """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/contact_company.py b/src/intercom/types/recipient.py similarity index 64% rename from src/intercom/types/contact_company.py rename to src/intercom/types/recipient.py index bd60d28..e68adf0 100644 --- a/src/intercom/types/contact_company.py +++ b/src/intercom/types/recipient.py @@ -5,26 +5,22 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel +from .recipient_type import RecipientType -class ContactCompany(UncheckedBaseModel): +class Recipient(UncheckedBaseModel): """ - A reference to a company associated with a contact + A recipient of a message """ - id: str = pydantic.Field() + type: RecipientType = pydantic.Field() """ - The unique identifier for the company + The role associated to the contact - `user` or `lead`. """ - type: typing.Literal["company"] = pydantic.Field(default="company") - """ - The type of the object - """ - - url: str = pydantic.Field() + id: str = pydantic.Field() """ - URL to get the full company resource + The identifier for the contact which is given by Intercom. """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/recipient_type.py b/src/intercom/types/recipient_type.py new file mode 100644 index 0000000..f423fd0 --- /dev/null +++ b/src/intercom/types/recipient_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +RecipientType = typing.Union[typing.Literal["user", "lead"], typing.Any] diff --git a/src/intercom/types/reference.py b/src/intercom/types/reference.py index 2905e15..0c8ad77 100644 --- a/src/intercom/types/reference.py +++ b/src/intercom/types/reference.py @@ -12,7 +12,7 @@ class Reference(UncheckedBaseModel): reference to another object """ - type: str = pydantic.Field() + type: typing.Optional[str] = pydantic.Field(default=None) """ """ diff --git a/src/intercom/types/results_response.py b/src/intercom/types/results_response.py deleted file mode 100644 index f6631fc..0000000 --- a/src/intercom/types/results_response.py +++ /dev/null @@ -1,27 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel - - -class ResultsResponse(UncheckedBaseModel): - """ - The results object should be sent when you want to end configuration of the app and trigger the [Initialize request](https://developers.intercom.com/docs/canvas-kit/#initialize) to be sent. You provide the key-value pairs of data you want access to and we will send these in the Initialize request within a [card_creation_options object](https://developers.intercom.com/docs/references/canvas-kit/requestobjects/card-creation-options/#card-creation-options). - """ - - results: typing.Dict[str, typing.Optional[typing.Any]] = pydantic.Field() - """ - Key-value pairs of data you want access to in the Initialize request - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/segment_list.py b/src/intercom/types/segment_list.py index 4f1c48a..1c88624 100644 --- a/src/intercom/types/segment_list.py +++ b/src/intercom/types/segment_list.py @@ -13,12 +13,12 @@ class SegmentList(UncheckedBaseModel): This will return a list of Segment Objects. The result may also have a pages object if the response is paginated. """ - type: typing.Literal["segment.list"] = pydantic.Field(default="segment.list") + type: typing.Optional[typing.Literal["segment.list"]] = pydantic.Field(default=None) """ The type of the object """ - segments: typing.List[Segment] = pydantic.Field() + segments: typing.Optional[typing.List[Segment]] = pydantic.Field(default=None) """ A list of Segment objects """ diff --git a/src/intercom/types/single_filter_search_request_value.py b/src/intercom/types/single_filter_search_request_value.py index 8bfa5aa..fcabc57 100644 --- a/src/intercom/types/single_filter_search_request_value.py +++ b/src/intercom/types/single_filter_search_request_value.py @@ -2,4 +2,6 @@ import typing -SingleFilterSearchRequestValue = typing.Union[str, int, typing.List[str], typing.List[int]] +from .single_filter_search_request_value_item import SingleFilterSearchRequestValueItem + +SingleFilterSearchRequestValue = typing.Union[str, int, typing.List[SingleFilterSearchRequestValueItem]] diff --git a/src/intercom/types/single_filter_search_request_value_item.py b/src/intercom/types/single_filter_search_request_value_item.py new file mode 100644 index 0000000..b921bab --- /dev/null +++ b/src/intercom/types/single_filter_search_request_value_item.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +SingleFilterSearchRequestValueItem = typing.Union[str, int] diff --git a/src/intercom/types/single_select_component.py b/src/intercom/types/single_select_component.py deleted file mode 100644 index ad33ef0..0000000 --- a/src/intercom/types/single_select_component.py +++ /dev/null @@ -1,65 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .action_component import ActionComponent -from .single_select_component_save_state import SingleSelectComponentSaveState -from .single_select_option import SingleSelectOption - - -class SingleSelectComponent(UncheckedBaseModel): - """ - A single-select component is used to capture a choice from up to 10 options that you provide. You can submit the value of the select option by: - - - Adding an `action` to the single-select component - - Using a ButtonComponent (which will submit all interactive components in the canvas) - - When a submit action takes place, the results are given in a hash with the `id` from the single-select component used as the key and the `id` from the chosen option as the value. - """ - - id: str = pydantic.Field() - """ - A unique identifier for the component. - """ - - options: typing.List[SingleSelectOption] = pydantic.Field() - """ - The list of options. Can provide 2 to 10. - """ - - label: typing.Optional[str] = pydantic.Field(default=None) - """ - The text shown above the options. - """ - - value: typing.Optional[str] = pydantic.Field(default=None) - """ - The option that is selected by default. - """ - - save_state: typing.Optional[SingleSelectComponentSaveState] = pydantic.Field(default=None) - """ - Styles the input. Default is `unsaved`. Prevent action with `saved`. - """ - - disabled: typing.Optional[bool] = pydantic.Field(default=None) - """ - Styles all options and prevents the action. Default is false. Will be overridden if save_state is saved. - """ - - action: typing.Optional[ActionComponent] = pydantic.Field(default=None) - """ - This can be a Submit Action, URL Action, or Sheets Action. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/single_select_component_save_state.py b/src/intercom/types/single_select_component_save_state.py deleted file mode 100644 index dc85ce8..0000000 --- a/src/intercom/types/single_select_component_save_state.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -SingleSelectComponentSaveState = typing.Union[typing.Literal["unsaved", "saved", "failed"], typing.Any] diff --git a/src/intercom/types/sla_applied.py b/src/intercom/types/sla_applied.py index 187d1e7..b4b9073 100644 --- a/src/intercom/types/sla_applied.py +++ b/src/intercom/types/sla_applied.py @@ -14,17 +14,17 @@ class SlaApplied(UncheckedBaseModel): Important: if there are any canceled sla_events for the conversation - meaning an SLA has been manually removed from a conversation, the sla_status will always be returned as null. """ - type: str = pydantic.Field() + type: typing.Optional[str] = pydantic.Field(default=None) """ object type """ - sla_name: str = pydantic.Field() + sla_name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the SLA as given by the teammate when it was created. """ - sla_status: SlaAppliedSlaStatus = pydantic.Field() + sla_status: typing.Optional[SlaAppliedSlaStatus] = pydantic.Field(default=None) """ SLA statuses: - `hit`: If there’s at least one hit event in the underlying sla_events table, and no “missed” or “canceled” events for the conversation. diff --git a/src/intercom/types/social_profile.py b/src/intercom/types/social_profile.py index 3838408..f1b91d2 100644 --- a/src/intercom/types/social_profile.py +++ b/src/intercom/types/social_profile.py @@ -12,17 +12,17 @@ class SocialProfile(UncheckedBaseModel): A Social Profile allows you to label your contacts, companies, and conversations and list them using that Social Profile. """ - type: typing.Literal["social_profile"] = pydantic.Field(default="social_profile") + type: typing.Optional[typing.Literal["social_profile"]] = pydantic.Field(default=None) """ value is "social_profile" """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the Social media profile """ - url: str = pydantic.Field() + url: typing.Optional[str] = pydantic.Field(default=None) """ The name of the Social media profile """ diff --git a/src/intercom/types/spacer_component_size.py b/src/intercom/types/spacer_component_size.py deleted file mode 100644 index 3d4f5d3..0000000 --- a/src/intercom/types/spacer_component_size.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -SpacerComponentSize = typing.Union[typing.Literal["xs", "s", "m", "l", "xl"], typing.Any] diff --git a/src/intercom/types/starting_after_paging.py b/src/intercom/types/starting_after_paging.py index 7e5e9cc..e2c1a29 100644 --- a/src/intercom/types/starting_after_paging.py +++ b/src/intercom/types/starting_after_paging.py @@ -8,7 +8,7 @@ class StartingAfterPaging(UncheckedBaseModel): - per_page: int = pydantic.Field() + per_page: typing.Optional[int] = pydantic.Field(default=None) """ The number of results to fetch per page. """ diff --git a/src/intercom/types/submit_request.py b/src/intercom/types/submit_request.py deleted file mode 100644 index 2022592..0000000 --- a/src/intercom/types/submit_request.py +++ /dev/null @@ -1,77 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..admins.types.admin import Admin -from ..contacts.types.contact import Contact -from ..conversations.types.conversation import Conversation -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .context import Context -from .current_canvas import CurrentCanvas - - -class SubmitRequest(UncheckedBaseModel): - """ - The Submit request is triggered when a component with a submit action is interacted with in Messenger Inbox. - """ - - workspace_id: str = pydantic.Field() - """ - The workspace ID of the teammate. Attribute is `app_id` for V1.2 and below. - """ - - workspace_region: str = pydantic.Field() - """ - The Intercom hosted region that this app is located in. - """ - - admin: Admin = pydantic.Field() - """ - The Intercom teammate viewing the conversation. - """ - - component_id: str = pydantic.Field() - """ - The id of the component clicked by the teammate to trigger the request. - """ - - context: Context = pydantic.Field() - """ - The context of where the app is added, where the user last visited, and information on the Messenger settings. - """ - - conversation: Conversation = pydantic.Field() - """ - The conversation where your app is being shown. - """ - - current_canvas: CurrentCanvas = pydantic.Field() - """ - The current canvas the teammate can see. - """ - - contact: Contact = pydantic.Field() - """ - The contact which is currently being viewed by the teammate in the conversation details panel. - """ - - input_values: typing.Dict[str, typing.Optional[typing.Any]] = pydantic.Field() - """ - A list of key/value pairs of data, inputted by the teammate on the current canvas. - """ - - user: Contact = pydantic.Field() - """ - The user who took the action. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/submit_response.py b/src/intercom/types/submit_response.py deleted file mode 100644 index 3e04cf1..0000000 --- a/src/intercom/types/submit_response.py +++ /dev/null @@ -1,47 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .canvas_object import CanvasObject -from .event import Event - - -class SubmitResponse(UncheckedBaseModel): - """ - The response object returned when submitting an app interaction. This will replace the previous canvas that was visible until the app was interacted with. - - You can optionally provide an event object with the attribute `type` given as `completed` to tell us if the app has completed its purpose. For example, an email collector app would be complete when the end-user submits their email address. - - Apps in conversation details can also optionally insert an app into the conversation reply: - - 1. You respond with a card_creation_options object (https://developers.intercom.com/canvas-kit-reference/reference/card-creation-options) - 2. We send a request to the initialize URL for Messenger capabilities (https://developers.intercom.com/docs/build-an-integration/getting-started/build-an-app-for-your-messenger/request-flows) with the card_creation_options object present - 3. You respond with a canvas object with the components you want to insert into the conversation reply - """ - - canvas: CanvasObject = pydantic.Field() - """ - The canvas object that defines the new UI to be shown. - """ - - card_creation_options: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None) - """ - Optional. Key-value pairs that will be sent in the initialize request to insert an app into the conversation reply. - """ - - event: typing.Optional[Event] = pydantic.Field(default=None) - """ - Optional. Indicates if the app has completed its purpose. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/subscription_type_list.py b/src/intercom/types/subscription_type_list.py index c6e39c2..b0d2596 100644 --- a/src/intercom/types/subscription_type_list.py +++ b/src/intercom/types/subscription_type_list.py @@ -13,12 +13,12 @@ class SubscriptionTypeList(UncheckedBaseModel): A list of subscription type objects. """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of the object """ - data: typing.List[SubscriptionType] = pydantic.Field() + data: typing.Optional[typing.List[SubscriptionType]] = pydantic.Field(default=None) """ A list of subscription type objects associated with the workspace . """ diff --git a/src/intercom/types/tag_list.py b/src/intercom/types/tag_list.py index 3ad1c5d..5a1776c 100644 --- a/src/intercom/types/tag_list.py +++ b/src/intercom/types/tag_list.py @@ -13,12 +13,12 @@ class TagList(UncheckedBaseModel): A list of tags objects in the workspace. """ - type: typing.Literal["list"] = pydantic.Field(default="list") + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) """ The type of the object """ - data: typing.List[Tag] = pydantic.Field() + data: typing.Optional[typing.List[Tag]] = pydantic.Field(default=None) """ A list of tags objects associated with the workspace . """ diff --git a/src/intercom/types/tags.py b/src/intercom/types/tags.py index 341ec73..3989c55 100644 --- a/src/intercom/types/tags.py +++ b/src/intercom/types/tags.py @@ -13,12 +13,12 @@ class Tags(UncheckedBaseModel): A list of tags objects associated with a conversation """ - type: typing.Literal["tag.list"] = pydantic.Field(default="tag.list") + type: typing.Optional[typing.Literal["tag.list"]] = pydantic.Field(default=None) """ The type of the object """ - tags: typing.List[Tag] = pydantic.Field() + tags: typing.Optional[typing.List[Tag]] = pydantic.Field(default=None) """ A list of tags objects associated with the conversation. """ diff --git a/src/intercom/types/team_list.py b/src/intercom/types/team_list.py index e4e69ed..52bb029 100644 --- a/src/intercom/types/team_list.py +++ b/src/intercom/types/team_list.py @@ -13,12 +13,12 @@ class TeamList(UncheckedBaseModel): This will return a list of team objects for the App. """ - type: typing.Literal["team.list"] = pydantic.Field(default="team.list") + type: typing.Optional[typing.Literal["team.list"]] = pydantic.Field(default=None) """ The type of the object """ - teams: typing.List[Team] = pydantic.Field() + teams: typing.Optional[typing.List[Team]] = pydantic.Field(default=None) """ A list of team objects """ diff --git a/src/intercom/types/text_area_component.py b/src/intercom/types/text_area_component.py deleted file mode 100644 index 9f7263e..0000000 --- a/src/intercom/types/text_area_component.py +++ /dev/null @@ -1,54 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel - - -class TextAreaComponent(UncheckedBaseModel): - """ - A text area component is used to capture a large amount of text as input with a multi-line text box. You can submit the value of the text area by: - - - Using a ButtonComponent (which will submit all interactive components in the canvas) - """ - - id: str = pydantic.Field() - """ - A unique identifier for the component. - """ - - label: typing.Optional[str] = pydantic.Field(default=None) - """ - The text shown above the text area. - """ - - placeholder: typing.Optional[str] = pydantic.Field(default=None) - """ - An example value shown inside the component when it's empty. - """ - - value: typing.Optional[str] = pydantic.Field(default=None) - """ - An entered value which is already inside the component. - """ - - error: typing.Optional[bool] = pydantic.Field(default=None) - """ - Styles the input as failed. Default is false. - """ - - disabled: typing.Optional[bool] = pydantic.Field(default=None) - """ - Styles the input and prevents the action. Default is false. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/text_component.py b/src/intercom/types/text_component.py deleted file mode 100644 index a08dda6..0000000 --- a/src/intercom/types/text_component.py +++ /dev/null @@ -1,49 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -import pydantic -from ..core.pydantic_utilities import IS_PYDANTIC_V2 -from ..core.unchecked_base_model import UncheckedBaseModel -from .text_component_align import TextComponentAlign -from .text_component_style import TextComponentStyle - - -class TextComponent(UncheckedBaseModel): - """ - A text component is used for rendering blocks of text. Links and bold font can be rendered through Markdown. There are different styles provided which edit the color, weight, and font size. These cannot be edited through Markdown. - """ - - id: typing.Optional[str] = pydantic.Field(default=None) - """ - A unique identifier for the component. - """ - - text: str = pydantic.Field() - """ - The text that will be rendered. - """ - - align: typing.Optional[TextComponentAlign] = pydantic.Field(default=None) - """ - Aligns the text. Default is `left`. - """ - - style: typing.Optional[TextComponentStyle] = pydantic.Field(default=None) - """ - Styles the text. Default is `paragraph`. - """ - - bottom_margin: typing.Optional[typing.Literal["none"]] = pydantic.Field(default=None) - """ - Disables a component's margin-bottom of 10px. - """ - - if IS_PYDANTIC_V2: - model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 - else: - - class Config: - frozen = True - smart_union = True - extra = pydantic.Extra.allow diff --git a/src/intercom/types/text_component_align.py b/src/intercom/types/text_component_align.py deleted file mode 100644 index 0ba0243..0000000 --- a/src/intercom/types/text_component_align.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -TextComponentAlign = typing.Union[typing.Literal["left", "center", "right"], typing.Any] diff --git a/src/intercom/types/text_component_style.py b/src/intercom/types/text_component_style.py deleted file mode 100644 index a2d0aa9..0000000 --- a/src/intercom/types/text_component_style.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -TextComponentStyle = typing.Union[typing.Literal["header", "paragraph", "muted", "error"], typing.Any] diff --git a/src/intercom/types/ticket_list.py b/src/intercom/types/ticket_list.py index bb24c3e..5e6669e 100644 --- a/src/intercom/types/ticket_list.py +++ b/src/intercom/types/ticket_list.py @@ -14,17 +14,17 @@ class TicketList(UncheckedBaseModel): Tickets are how you track requests from your users. """ - type: typing.Literal["ticket.list"] = pydantic.Field(default="ticket.list") + type: typing.Optional[typing.Literal["ticket.list"]] = pydantic.Field(default=None) """ Always ticket.list """ - tickets: typing.List[Ticket] = pydantic.Field() + tickets: typing.Optional[typing.List[typing.Optional[Ticket]]] = pydantic.Field(default=None) """ The list of ticket objects """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ A count of the total number of objects. """ diff --git a/src/intercom/types/ticket_part_author.py b/src/intercom/types/ticket_part_author.py index 0412078..c0538d1 100644 --- a/src/intercom/types/ticket_part_author.py +++ b/src/intercom/types/ticket_part_author.py @@ -13,12 +13,12 @@ class TicketPartAuthor(UncheckedBaseModel): The author that wrote or triggered the part. Can be a bot, admin, team or user. """ - type: TicketPartAuthorType = pydantic.Field() + type: typing.Optional[TicketPartAuthorType] = pydantic.Field(default=None) """ The type of the author """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the author """ @@ -28,7 +28,7 @@ class TicketPartAuthor(UncheckedBaseModel): The name of the author """ - email: str = pydantic.Field() + email: typing.Optional[str] = pydantic.Field(default=None) """ The email of the author """ diff --git a/src/intercom/types/ticket_parts.py b/src/intercom/types/ticket_parts.py index 8957065..230a1bf 100644 --- a/src/intercom/types/ticket_parts.py +++ b/src/intercom/types/ticket_parts.py @@ -13,17 +13,17 @@ class TicketParts(UncheckedBaseModel): A list of Ticket Part objects for each note and event in the ticket. There is a limit of 500 parts. """ - type: typing.Literal["ticket_part.list"] = pydantic.Field(default="ticket_part.list") + type: typing.Optional[typing.Literal["ticket_part.list"]] = pydantic.Field(default=None) """ """ - ticket_parts: typing.List[TicketPart] = pydantic.Field() + ticket_parts: typing.Optional[typing.List[TicketPart]] = pydantic.Field(default=None) """ A list of Ticket Part objects for each ticket. There is a limit of 500 parts. """ - total_count: int = pydantic.Field() + total_count: typing.Optional[int] = pydantic.Field(default=None) """ """ diff --git a/src/intercom/types/ticket_reply.py b/src/intercom/types/ticket_reply.py index d55ee84..ec2ab74 100644 --- a/src/intercom/types/ticket_reply.py +++ b/src/intercom/types/ticket_reply.py @@ -15,17 +15,17 @@ class TicketReply(UncheckedBaseModel): A Ticket Part representing a note, comment, or quick_reply on a ticket """ - type: typing.Literal["ticket_part"] = pydantic.Field(default="ticket_part") + type: typing.Optional[typing.Literal["ticket_part"]] = pydantic.Field(default=None) """ Always ticket_part """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id representing the part. """ - part_type: TicketReplyPartType = pydantic.Field() + part_type: typing.Optional[TicketReplyPartType] = pydantic.Field(default=None) """ Type of the part """ @@ -35,7 +35,7 @@ class TicketReply(UncheckedBaseModel): The message body, which may contain HTML. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ The time the note was created. """ diff --git a/src/intercom/types/ticket_state_list.py b/src/intercom/types/ticket_state_list.py new file mode 100644 index 0000000..b70ef5a --- /dev/null +++ b/src/intercom/types/ticket_state_list.py @@ -0,0 +1,33 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from ..tickets.types.ticket_state_detailed import TicketStateDetailed + + +class TicketStateList(UncheckedBaseModel): + """ + A list of ticket states associated with a given ticket type. + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + String representing the object's type. Always has the value `list`. + """ + + data: typing.Optional[typing.List[typing.Optional[TicketStateDetailed]]] = pydantic.Field(default=None) + """ + A list of ticket states associated with a given ticket type. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/ticket_type_attribute.py b/src/intercom/types/ticket_type_attribute.py index 60141c0..e22b670 100644 --- a/src/intercom/types/ticket_type_attribute.py +++ b/src/intercom/types/ticket_type_attribute.py @@ -13,82 +13,82 @@ class TicketTypeAttribute(UncheckedBaseModel): Ticket type attribute, used to define each data field to be captured in a ticket. """ - type: typing.Literal["ticket_type_attribute"] = pydantic.Field(default="ticket_type_attribute") + type: typing.Optional[str] = pydantic.Field(default=None) """ String representing the object's type. Always has the value `ticket_type_attribute`. """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The id representing the ticket type attribute. """ - workspace_id: str = pydantic.Field() + workspace_id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the workspace that the ticket type attribute belongs to. """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The name of the ticket type attribute """ - description: str = pydantic.Field() + description: typing.Optional[str] = pydantic.Field(default=None) """ The description of the ticket type attribute """ - data_type: TicketTypeAttributeDataType = pydantic.Field() + data_type: typing.Optional[TicketTypeAttributeDataType] = pydantic.Field(default=None) """ The type of the data attribute (allowed values: "string list integer decimal boolean datetime files") """ - input_options: typing.Dict[str, typing.Optional[typing.Any]] = pydantic.Field() + input_options: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = pydantic.Field(default=None) """ Input options for the attribute """ - order: int = pydantic.Field() + order: typing.Optional[int] = pydantic.Field(default=None) """ The order of the attribute against other attributes """ - required_to_create: bool = pydantic.Field() + required_to_create: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the attribute is required or not for teammates. """ - required_to_create_for_contacts: bool = pydantic.Field() + required_to_create_for_contacts: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the attribute is required or not for contacts. """ - visible_on_create: bool = pydantic.Field() + visible_on_create: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the attribute is visible or not to teammates. """ - visible_to_contacts: bool = pydantic.Field() + visible_to_contacts: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the attribute is visible or not to contacts. """ - default: bool = pydantic.Field() + default: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the attribute is built in or not. """ - ticket_type_id: int = pydantic.Field() + ticket_type_id: typing.Optional[int] = pydantic.Field(default=None) """ The id of the ticket type that the attribute belongs to. """ - archived: bool = pydantic.Field() + archived: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the ticket type attribute is archived or not. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ The date and time the ticket type attribute was created. """ diff --git a/src/intercom/types/ticket_type_attribute_list.py b/src/intercom/types/ticket_type_attribute_list.py index c707631..b74b43b 100644 --- a/src/intercom/types/ticket_type_attribute_list.py +++ b/src/intercom/types/ticket_type_attribute_list.py @@ -13,12 +13,14 @@ class TicketTypeAttributeList(UncheckedBaseModel): A list of attributes associated with a given ticket type. """ - type: typing.Literal["ticket_type_attributes.list"] = pydantic.Field(default="ticket_type_attributes.list") + type: typing.Optional[str] = pydantic.Field(default=None) """ String representing the object's type. Always has the value `ticket_type_attributes.list`. """ - ticket_type_attributes: typing.List[TicketTypeAttribute] = pydantic.Field() + ticket_type_attributes: typing.Optional[typing.List[typing.Optional[TicketTypeAttribute]]] = pydantic.Field( + default=None + ) """ A list of ticket type attributes associated with a given ticket type. """ diff --git a/src/intercom/types/ticket_type_list.py b/src/intercom/types/ticket_type_list.py index 098c902..6971149 100644 --- a/src/intercom/types/ticket_type_list.py +++ b/src/intercom/types/ticket_type_list.py @@ -13,12 +13,12 @@ class TicketTypeList(UncheckedBaseModel): A list of ticket types associated with a given workspace. """ - type: typing.Literal["ticket_type_attributes.list"] = pydantic.Field(default="ticket_type_attributes.list") + type: typing.Optional[str] = pydantic.Field(default=None) """ - String representing the object's type. Always has the value `ticket_type.list`. + String representing the object's type. Always has the value `list`. """ - ticket_types: typing.List[TicketType] = pydantic.Field() + data: typing.Optional[typing.List[typing.Optional[TicketType]]] = pydantic.Field(default=None) """ A list of ticket_types associated with a given workspace. """ diff --git a/src/intercom/types/translation.py b/src/intercom/types/translation.py index a2b14e9..9b10833 100644 --- a/src/intercom/types/translation.py +++ b/src/intercom/types/translation.py @@ -12,17 +12,17 @@ class Translation(UncheckedBaseModel): A translation object contains the localised details of a subscription type. """ - name: str = pydantic.Field() + name: typing.Optional[str] = pydantic.Field(default=None) """ The localised name of the subscription type. """ - description: str = pydantic.Field() + description: typing.Optional[str] = pydantic.Field(default=None) """ The localised description of the subscription type. """ - locale: str = pydantic.Field() + locale: typing.Optional[str] = pydantic.Field(default=None) """ The two character identifier for the language of the translation object. """ diff --git a/src/intercom/types/untag_company_request_companies_item.py b/src/intercom/types/untag_company_request_companies_item.py index f7ec650..b87a55f 100644 --- a/src/intercom/types/untag_company_request_companies_item.py +++ b/src/intercom/types/untag_company_request_companies_item.py @@ -8,17 +8,17 @@ class UntagCompanyRequestCompaniesItem(UncheckedBaseModel): - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The Intercom defined id representing the company. """ - company_id: str = pydantic.Field() + company_id: typing.Optional[str] = pydantic.Field(default=None) """ The company id you have defined for the company. """ - untag: typing.Literal[True] = pydantic.Field(default=True) + untag: typing.Optional[bool] = pydantic.Field(default=None) """ Always set to true """ diff --git a/src/intercom/types/update_article_request_body.py b/src/intercom/types/update_article_request_body.py new file mode 100644 index 0000000..58fb436 --- /dev/null +++ b/src/intercom/types/update_article_request_body.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .update_article_request_body_parent_type import UpdateArticleRequestBodyParentType + + +class UpdateArticleRequestBody(UncheckedBaseModel): + parent_type: typing.Optional[UpdateArticleRequestBodyParentType] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/articles/types/update_article_request_body_parent_type.py b/src/intercom/types/update_article_request_body_parent_type.py similarity index 100% rename from src/intercom/articles/types/update_article_request_body_parent_type.py rename to src/intercom/types/update_article_request_body_parent_type.py diff --git a/src/intercom/types/update_data_attribute_request_body.py b/src/intercom/types/update_data_attribute_request_body.py new file mode 100644 index 0000000..c2e56ce --- /dev/null +++ b/src/intercom/types/update_data_attribute_request_body.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .update_data_attribute_request_options import UpdateDataAttributeRequestOptions + +UpdateDataAttributeRequestBody = typing.Union[UpdateDataAttributeRequestOptions, typing.Optional[typing.Any]] diff --git a/src/intercom/types/update_data_attribute_request_options.py b/src/intercom/types/update_data_attribute_request_options.py new file mode 100644 index 0000000..1fd40c3 --- /dev/null +++ b/src/intercom/types/update_data_attribute_request_options.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .update_data_attribute_request_options_options_item import UpdateDataAttributeRequestOptionsOptionsItem + + +class UpdateDataAttributeRequestOptions(UncheckedBaseModel): + options: typing.List[UpdateDataAttributeRequestOptionsOptionsItem] = pydantic.Field() + """ + Array of objects representing the options of the list, with `value` as the key and the option as the value. At least two options are required. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/update_data_attribute_request_options_options_item.py b/src/intercom/types/update_data_attribute_request_options_options_item.py new file mode 100644 index 0000000..42bce4e --- /dev/null +++ b/src/intercom/types/update_data_attribute_request_options_options_item.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class UpdateDataAttributeRequestOptionsOptionsItem(UncheckedBaseModel): + value: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/visitor.py b/src/intercom/types/visitor.py index d5b780b..f8493f4 100644 --- a/src/intercom/types/visitor.py +++ b/src/intercom/types/visitor.py @@ -18,27 +18,27 @@ class Visitor(UncheckedBaseModel): Visitors are useful for representing anonymous people that have not yet been identified. They usually represent website visitors. Visitors are not visible in Intercom platform. The Visitors resource provides methods to fetch, update, convert and delete. """ - type: typing.Literal["visitor"] = pydantic.Field(default="visitor") + type: typing.Optional[typing.Literal["visitor"]] = pydantic.Field(default=None) """ Value is 'visitor' """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The Intercom defined id representing the Visitor. """ - user_id: str = pydantic.Field() + user_id: typing.Optional[str] = pydantic.Field(default=None) """ Automatically generated identifier for the Visitor. """ - anonymous: bool = pydantic.Field() + anonymous: typing.Optional[bool] = pydantic.Field(default=None) """ Identifies if this visitor is anonymous. """ - email: str = pydantic.Field() + email: typing.Optional[str] = pydantic.Field(default=None) """ The email of the visitor. """ @@ -59,7 +59,7 @@ class Visitor(UncheckedBaseModel): """ avatar: typing.Optional[VisitorAvatar] = None - app_id: str = pydantic.Field() + app_id: typing.Optional[str] = pydantic.Field(default=None) """ The id of the app the visitor is associated with. """ @@ -71,7 +71,7 @@ class Visitor(UncheckedBaseModel): The time the Lead last recorded making a request. """ - created_at: int = pydantic.Field() + created_at: typing.Optional[int] = pydantic.Field(default=None) """ The time the Visitor was added to Intercom. """ @@ -81,7 +81,7 @@ class Visitor(UncheckedBaseModel): The time the Visitor was added to Intercom. """ - signed_up_at: int = pydantic.Field() + signed_up_at: typing.Optional[int] = pydantic.Field(default=None) """ The time the Visitor signed up for your product. """ diff --git a/src/intercom/types/visitor_deleted_object.py b/src/intercom/types/visitor_deleted_object.py index f2cc5b2..1246b34 100644 --- a/src/intercom/types/visitor_deleted_object.py +++ b/src/intercom/types/visitor_deleted_object.py @@ -12,17 +12,17 @@ class VisitorDeletedObject(UncheckedBaseModel): Response returned when an object is deleted """ - id: str = pydantic.Field() + id: typing.Optional[str] = pydantic.Field(default=None) """ The unique identifier for the visitor which is given by Intercom. """ - type: typing.Literal["visitor"] = pydantic.Field(default="visitor") + type: typing.Optional[typing.Literal["visitor"]] = pydantic.Field(default=None) """ The type of object which was deleted """ - user_id: str = pydantic.Field() + user_id: typing.Optional[str] = pydantic.Field(default=None) """ Automatically generated identifier for the Visitor. """ diff --git a/src/intercom/types/whatsapp_message_status_list.py b/src/intercom/types/whatsapp_message_status_list.py new file mode 100644 index 0000000..fcadc4b --- /dev/null +++ b/src/intercom/types/whatsapp_message_status_list.py @@ -0,0 +1,34 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .whatsapp_message_status_list_events_item import WhatsappMessageStatusListEventsItem +from .whatsapp_message_status_list_pages import WhatsappMessageStatusListPages + + +class WhatsappMessageStatusList(UncheckedBaseModel): + type: typing.Literal["list"] = "list" + ruleset_id: str = pydantic.Field() + """ + The provided ruleset ID + """ + + pages: WhatsappMessageStatusListPages + total_count: int = pydantic.Field() + """ + Total number of events + """ + + events: typing.List[WhatsappMessageStatusListEventsItem] + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/whatsapp_message_status_list_events_item.py b/src/intercom/types/whatsapp_message_status_list_events_item.py new file mode 100644 index 0000000..19ec9f8 --- /dev/null +++ b/src/intercom/types/whatsapp_message_status_list_events_item.py @@ -0,0 +1,59 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel +from .whatsapp_message_status_list_events_item_status import WhatsappMessageStatusListEventsItemStatus + + +class WhatsappMessageStatusListEventsItem(UncheckedBaseModel): + id: str = pydantic.Field() + """ + Event ID + """ + + conversation_id: str = pydantic.Field() + """ + ID of the conversation + """ + + status: WhatsappMessageStatusListEventsItemStatus = pydantic.Field() + """ + Current status of the message + """ + + type: typing.Literal["broadcast_outbound"] = pydantic.Field(default="broadcast_outbound") + """ + Event type + """ + + created_at: int = pydantic.Field() + """ + Creation timestamp + """ + + updated_at: int = pydantic.Field() + """ + Last update timestamp + """ + + whatsapp_message_id: str = pydantic.Field() + """ + WhatsApp's message identifier + """ + + template_name: typing.Optional[str] = pydantic.Field(default=None) + """ + Name of the WhatsApp template used + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/types/whatsapp_message_status_list_events_item_status.py b/src/intercom/types/whatsapp_message_status_list_events_item_status.py new file mode 100644 index 0000000..3db079a --- /dev/null +++ b/src/intercom/types/whatsapp_message_status_list_events_item_status.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +WhatsappMessageStatusListEventsItemStatus = typing.Union[ + typing.Literal["sent", "delivered", "read", "failed"], typing.Any +] diff --git a/src/intercom/types/configure_request_zero.py b/src/intercom/types/whatsapp_message_status_list_pages.py similarity index 53% rename from src/intercom/types/configure_request_zero.py rename to src/intercom/types/whatsapp_message_status_list_pages.py index 46bef93..5af4f33 100644 --- a/src/intercom/types/configure_request_zero.py +++ b/src/intercom/types/whatsapp_message_status_list_pages.py @@ -3,26 +3,26 @@ import typing import pydantic -from ..admins.types.admin import Admin from ..core.pydantic_utilities import IS_PYDANTIC_V2 from ..core.unchecked_base_model import UncheckedBaseModel -from .context import Context +from .whatsapp_message_status_list_pages_next import WhatsappMessageStatusListPagesNext -class ConfigureRequestZero(UncheckedBaseModel): - workspace_id: str = pydantic.Field() +class WhatsappMessageStatusListPages(UncheckedBaseModel): + type: typing.Literal["pages"] = "pages" + per_page: int = pydantic.Field() """ - The workspace ID of the teammate. Attribute is app_id for V1.2 and below. + Number of results per page """ - admin: Admin = pydantic.Field() + total_pages: int = pydantic.Field() """ - The Intercom teammate configuring the app. + Total number of pages """ - context: Context = pydantic.Field() + next: typing.Optional[WhatsappMessageStatusListPagesNext] = pydantic.Field(default=None) """ - The context of where the app is added, where the user last visited, and information on the Messenger settings. + Information for fetching next page (null if no more pages) """ if IS_PYDANTIC_V2: diff --git a/src/intercom/types/whatsapp_message_status_list_pages_next.py b/src/intercom/types/whatsapp_message_status_list_pages_next.py new file mode 100644 index 0000000..c9974e5 --- /dev/null +++ b/src/intercom/types/whatsapp_message_status_list_pages_next.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2 +from ..core.unchecked_base_model import UncheckedBaseModel + + +class WhatsappMessageStatusListPagesNext(UncheckedBaseModel): + """ + Information for fetching next page (null if no more pages) + """ + + starting_after: typing.Optional[str] = pydantic.Field(default=None) + """ + Cursor for the next page + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/__init__.py b/src/intercom/unstable/__init__.py index d7f4dd4..f392994 100644 --- a/src/intercom/unstable/__init__.py +++ b/src/intercom/unstable/__init__.py @@ -27,6 +27,7 @@ AssignConversationRequest, AssignConversationRequestType, AwayStatusReason, + CallList, CloseConversationRequest, CollectionList, CompanyAttachedContacts, @@ -83,7 +84,17 @@ ConversationSourceType, ConversationStatistics, ConversationTeammates, + CreateArticleRequest, + CreateArticleRequestState, + CreateDataAttributeRequest, + CreateDataAttributeRequestOne, + CreateDataAttributeRequestOneDataType, + CreateDataAttributeRequestOptions, + CreateDataAttributeRequestOptionsOptionsItem, + CreateInternalArticleRequest, + CreateOrUpdateCompanyRequest, CreateOrUpdateTagRequest, + CreatePhoneSwitchRequest, CreateTicketReplyWithCommentRequest, CreateTicketRequestAssignment, CreateTicketRequestBody, @@ -91,6 +102,8 @@ CreateTicketRequestContactsItemEmail, CreateTicketRequestContactsItemExternalId, CreateTicketRequestContactsItemId, + CreateTicketTypeRequest, + CreateTicketTypeRequestCategory, CursorPages, CustomActionFinished, CustomActionFinishedAction, @@ -120,6 +133,7 @@ DeletedArticleObject, DeletedCollectionObject, DeletedCompanyObject, + DeletedInternalArticleObject, DeletedObject, EmailAddressHeader, EmailMessageMetadata, @@ -131,6 +145,7 @@ GroupTranslatedContent, IntercomVersion, IntercomVersionUnstable, + InternalArticleList, LinkedObject, LinkedObjectList, LinkedObjectType, @@ -202,10 +217,9 @@ Translation, UntagCompanyRequest, UntagCompanyRequestCompaniesItem, - UpdateArticleRequestBody, - UpdateArticleRequestState, - UpdateTicketTypeRequestBody, - UpdateTicketTypeRequestCategory, + UpdateDataAttributeRequestBody, + UpdateDataAttributeRequestOptions, + UpdateDataAttributeRequestOptionsOptionsItem, Visitor, VisitorAvatar, VisitorCompanies, @@ -237,6 +251,8 @@ ai_content_source, articles, away_status_reasons, + brands, + calls, companies, contacts, conversations, @@ -245,9 +261,12 @@ data_attributes, data_events, data_export, + emails, export, help_center, + internal_articles, jobs, + macros, messages, news, notes, @@ -287,7 +306,10 @@ ArticleSearchHighlightsHighlightedTitleItemType, ArticleSearchResponse, ArticleSearchResponseData, + InternalArticle, ) +from .brands import Brand, BrandList +from .calls import Call, ListCallsWithTranscriptsResponse, ListCallsWithTranscriptsResponseDataItem from .companies import Company, CompanyPlan, CompanySegments, CompanyTags from .contacts import ( Contact, @@ -315,14 +337,7 @@ ManageConversationRequestBody_Snoozed, ) from .custom_object_instances import CustomObjectInstance -from .data_attributes import ( - CreateDataAttributeRequestDataType, - CreateDataAttributeRequestModel, - DataAttribute, - DataAttributeDataType, - DataAttributeModel, - LisDataAttributesRequestModel, -) +from .data_attributes import DataAttribute, DataAttributeDataType, DataAttributeModel, LisDataAttributesRequestModel from .data_events import ( CreateDataEventSummariesRequestEventSummaries, DataEvent, @@ -332,6 +347,7 @@ LisDataEventsRequestFilterUserId, ) from .data_export import DataExport, DataExportStatus +from .emails import EmailList, EmailSetting from .export import ( GetExportReportingDataGetDatasetsResponse, GetExportReportingDataGetDatasetsResponseDataItem, @@ -339,7 +355,9 @@ PostExportReportingDataEnqueueResponse, ) from .help_center import Collection, HelpCenter, HelpCenterList +from .internal_articles import InternalArticleListItem, InternalArticleSearchResponse, InternalArticleSearchResponseData from .jobs import Jobs, JobsStatus +from .macros import Macro, MacroAvailableOnItem, MacroList, MacroListPages, MacroListPagesNext, MacroVisibleTo from .messages import Message, MessageMessageType from .news import NewsItem, NewsItemState, Newsfeed, NewsfeedAssignment from .notes import Note, NoteContact @@ -420,6 +438,10 @@ "AttachContactToConversationRequestCustomerUserId", "AwayStatusReason", "BadRequestError", + "Brand", + "BrandList", + "Call", + "CallList", "CloseConversationRequest", "Collection", "CollectionList", @@ -492,14 +514,22 @@ "ConversationState", "ConversationStatistics", "ConversationTeammates", + "CreateArticleRequest", + "CreateArticleRequestState", "CreateContactResponse", "CreateContentImportSourceRequestStatus", "CreateConversationRequestFrom", "CreateConversationRequestFromType", - "CreateDataAttributeRequestDataType", - "CreateDataAttributeRequestModel", + "CreateDataAttributeRequest", + "CreateDataAttributeRequestOne", + "CreateDataAttributeRequestOneDataType", + "CreateDataAttributeRequestOptions", + "CreateDataAttributeRequestOptionsOptionsItem", "CreateDataEventSummariesRequestEventSummaries", + "CreateInternalArticleRequest", + "CreateOrUpdateCompanyRequest", "CreateOrUpdateTagRequest", + "CreatePhoneSwitchRequest", "CreateTagRequestBody", "CreateTicketReplyWithCommentRequest", "CreateTicketRequestAssignment", @@ -509,6 +539,8 @@ "CreateTicketRequestContactsItemExternalId", "CreateTicketRequestContactsItemId", "CreateTicketTypeAttributeRequestDataType", + "CreateTicketTypeRequest", + "CreateTicketTypeRequestCategory", "CursorPages", "CustomActionFinished", "CustomActionFinishedAction", @@ -546,9 +578,12 @@ "DeletedArticleObject", "DeletedCollectionObject", "DeletedCompanyObject", + "DeletedInternalArticleObject", "DeletedObject", "EmailAddressHeader", + "EmailList", "EmailMessageMetadata", + "EmailSetting", "Error", "ErrorErrorsItem", "EventDetails", @@ -565,6 +600,11 @@ "HelpCenterList", "IntercomVersion", "IntercomVersionUnstable", + "InternalArticle", + "InternalArticleList", + "InternalArticleListItem", + "InternalArticleSearchResponse", + "InternalArticleSearchResponseData", "InternalServerError", "Jobs", "JobsStatus", @@ -576,6 +616,14 @@ "LisDataEventsRequestFilterEmail", "LisDataEventsRequestFilterIntercomUserId", "LisDataEventsRequestFilterUserId", + "ListCallsWithTranscriptsResponse", + "ListCallsWithTranscriptsResponseDataItem", + "Macro", + "MacroAvailableOnItem", + "MacroList", + "MacroListPages", + "MacroListPagesNext", + "MacroVisibleTo", "ManageConversationRequestBody", "ManageConversationRequestBody_Assignment", "ManageConversationRequestBody_Close", @@ -694,13 +742,12 @@ "UnprocessableEntityError", "UntagCompanyRequest", "UntagCompanyRequestCompaniesItem", - "UpdateArticleRequestBody", - "UpdateArticleRequestState", "UpdateContactResponse", "UpdateContentImportSourceRequestStatus", "UpdateContentImportSourceRequestSyncBehavior", - "UpdateTicketTypeRequestBody", - "UpdateTicketTypeRequestCategory", + "UpdateDataAttributeRequestBody", + "UpdateDataAttributeRequestOptions", + "UpdateDataAttributeRequestOptionsOptionsItem", "Visitor", "VisitorAvatar", "VisitorCompanies", @@ -721,6 +768,8 @@ "ai_content_source", "articles", "away_status_reasons", + "brands", + "calls", "companies", "contacts", "conversations", @@ -729,9 +778,12 @@ "data_attributes", "data_events", "data_export", + "emails", "export", "help_center", + "internal_articles", "jobs", + "macros", "messages", "news", "notes", diff --git a/src/intercom/unstable/ai_agent/types/ai_agent.py b/src/intercom/unstable/ai_agent/types/ai_agent.py index 3c61c27..38e16fd 100644 --- a/src/intercom/unstable/ai_agent/types/ai_agent.py +++ b/src/intercom/unstable/ai_agent/types/ai_agent.py @@ -44,6 +44,16 @@ class AiAgent(UncheckedBaseModel): The customer satisfaction rating remark given to AI Agent. """ + created_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time when the AI agent rating was created. + """ + + updated_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time when the AI agent rating was last updated. + """ + content_sources: typing.Optional[ContentSourcesList] = None if IS_PYDANTIC_V2: diff --git a/src/intercom/unstable/articles/__init__.py b/src/intercom/unstable/articles/__init__.py index f8adce5..4874009 100644 --- a/src/intercom/unstable/articles/__init__.py +++ b/src/intercom/unstable/articles/__init__.py @@ -13,6 +13,7 @@ ArticleSearchHighlightsHighlightedTitleItemType, ArticleSearchResponse, ArticleSearchResponseData, + InternalArticle, ) __all__ = [ @@ -26,4 +27,5 @@ "ArticleSearchHighlightsHighlightedTitleItemType", "ArticleSearchResponse", "ArticleSearchResponseData", + "InternalArticle", ] diff --git a/src/intercom/unstable/articles/types/__init__.py b/src/intercom/unstable/articles/types/__init__.py index 80005c4..3cd8409 100644 --- a/src/intercom/unstable/articles/types/__init__.py +++ b/src/intercom/unstable/articles/types/__init__.py @@ -14,6 +14,7 @@ from .article_search_highlights_highlighted_title_item_type import ArticleSearchHighlightsHighlightedTitleItemType from .article_search_response import ArticleSearchResponse from .article_search_response_data import ArticleSearchResponseData +from .internal_article import InternalArticle __all__ = [ "Article", @@ -26,4 +27,5 @@ "ArticleSearchHighlightsHighlightedTitleItemType", "ArticleSearchResponse", "ArticleSearchResponseData", + "InternalArticle", ] diff --git a/src/intercom/unstable/articles/types/internal_article.py b/src/intercom/unstable/articles/types/internal_article.py new file mode 100644 index 0000000..3b83a54 --- /dev/null +++ b/src/intercom/unstable/articles/types/internal_article.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +from ...internal_articles.types.internal_article_list_item import InternalArticleListItem + +InternalArticle = InternalArticleListItem diff --git a/src/intercom/unstable/brands/__init__.py b/src/intercom/unstable/brands/__init__.py new file mode 100644 index 0000000..c3c2bc5 --- /dev/null +++ b/src/intercom/unstable/brands/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import Brand, BrandList + +__all__ = ["Brand", "BrandList"] diff --git a/src/intercom/unstable/brands/client.py b/src/intercom/unstable/brands/client.py new file mode 100644 index 0000000..d9879b4 --- /dev/null +++ b/src/intercom/unstable/brands/client.py @@ -0,0 +1,173 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.request_options import RequestOptions +from .raw_client import AsyncRawBrandsClient, RawBrandsClient +from .types.brand import Brand +from .types.brand_list import BrandList + + +class BrandsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawBrandsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawBrandsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawBrandsClient + """ + return self._raw_client + + def list_brands(self, *, request_options: typing.Optional[RequestOptions] = None) -> BrandList: + """ + Retrieves all brands for the workspace, including the default brand. + The default brand id always matches the workspace + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BrandList + Successful response + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.brands.list_brands() + """ + _response = self._raw_client.list_brands(request_options=request_options) + return _response.data + + def retrieve_brand(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Brand: + """ + Fetches a specific brand by its unique identifier + + Parameters + ---------- + id : str + The unique identifier of the brand + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Brand + Successful response + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.brands.retrieve_brand( + id="id", + ) + """ + _response = self._raw_client.retrieve_brand(id, request_options=request_options) + return _response.data + + +class AsyncBrandsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawBrandsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawBrandsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawBrandsClient + """ + return self._raw_client + + async def list_brands(self, *, request_options: typing.Optional[RequestOptions] = None) -> BrandList: + """ + Retrieves all brands for the workspace, including the default brand. + The default brand id always matches the workspace + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + BrandList + Successful response + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.brands.list_brands() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_brands(request_options=request_options) + return _response.data + + async def retrieve_brand(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Brand: + """ + Fetches a specific brand by its unique identifier + + Parameters + ---------- + id : str + The unique identifier of the brand + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Brand + Successful response + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.brands.retrieve_brand( + id="id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.retrieve_brand(id, request_options=request_options) + return _response.data diff --git a/src/intercom/unstable/brands/raw_client.py b/src/intercom/unstable/brands/raw_client.py new file mode 100644 index 0000000..78016d9 --- /dev/null +++ b/src/intercom/unstable/brands/raw_client.py @@ -0,0 +1,242 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.jsonable_encoder import jsonable_encoder +from ...core.request_options import RequestOptions +from ...core.unchecked_base_model import construct_type +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.error import Error +from .types.brand import Brand +from .types.brand_list import BrandList + + +class RawBrandsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_brands(self, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[BrandList]: + """ + Retrieves all brands for the workspace, including the default brand. + The default brand id always matches the workspace + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[BrandList] + Successful response + """ + _response = self._client_wrapper.httpx_client.request( + "brands", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BrandList, + construct_type( + type_=BrandList, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def retrieve_brand( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[Brand]: + """ + Fetches a specific brand by its unique identifier + + Parameters + ---------- + id : str + The unique identifier of the brand + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Brand] + Successful response + """ + _response = self._client_wrapper.httpx_client.request( + f"brands/{jsonable_encoder(id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Brand, + construct_type( + type_=Brand, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawBrandsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_brands( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[BrandList]: + """ + Retrieves all brands for the workspace, including the default brand. + The default brand id always matches the workspace + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[BrandList] + Successful response + """ + _response = await self._client_wrapper.httpx_client.request( + "brands", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + BrandList, + construct_type( + type_=BrandList, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def retrieve_brand( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[Brand]: + """ + Fetches a specific brand by its unique identifier + + Parameters + ---------- + id : str + The unique identifier of the brand + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Brand] + Successful response + """ + _response = await self._client_wrapper.httpx_client.request( + f"brands/{jsonable_encoder(id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Brand, + construct_type( + type_=Brand, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/unstable/brands/types/__init__.py b/src/intercom/unstable/brands/types/__init__.py new file mode 100644 index 0000000..6d334db --- /dev/null +++ b/src/intercom/unstable/brands/types/__init__.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .brand import Brand +from .brand_list import BrandList + +__all__ = ["Brand", "BrandList"] diff --git a/src/intercom/unstable/brands/types/brand.py b/src/intercom/unstable/brands/types/brand.py new file mode 100644 index 0000000..8888094 --- /dev/null +++ b/src/intercom/unstable/brands/types/brand.py @@ -0,0 +1,62 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel + + +class Brand(UncheckedBaseModel): + """ + Represents a branding configuration for the workspace + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + The type of object + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + Unique brand identifier. For default brand, matches the workspace ID + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + Display name of the brand + """ + + is_default: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether this is the workspace's default brand + """ + + created_at: typing.Optional[int] = pydantic.Field(default=None) + """ + Unix timestamp of brand creation + """ + + updated_at: typing.Optional[int] = pydantic.Field(default=None) + """ + Unix timestamp of last modification + """ + + help_center_id: typing.Optional[str] = pydantic.Field(default=None) + """ + Associated help center identifier + """ + + default_address_settings_id: typing.Optional[str] = pydantic.Field(default=None) + """ + Default email settings ID for this brand + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/brands/types/brand_list.py b/src/intercom/unstable/brands/types/brand_list.py new file mode 100644 index 0000000..b77a7ce --- /dev/null +++ b/src/intercom/unstable/brands/types/brand_list.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel +from .brand import Brand + + +class BrandList(UncheckedBaseModel): + """ + A list of brands + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + The type of object + """ + + data: typing.Optional[typing.List[Brand]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/calls/__init__.py b/src/intercom/unstable/calls/__init__.py new file mode 100644 index 0000000..bf542ca --- /dev/null +++ b/src/intercom/unstable/calls/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import Call, ListCallsWithTranscriptsResponse, ListCallsWithTranscriptsResponseDataItem + +__all__ = ["Call", "ListCallsWithTranscriptsResponse", "ListCallsWithTranscriptsResponseDataItem"] diff --git a/src/intercom/unstable/calls/client.py b/src/intercom/unstable/calls/client.py new file mode 100644 index 0000000..7432f22 --- /dev/null +++ b/src/intercom/unstable/calls/client.py @@ -0,0 +1,417 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.request_options import RequestOptions +from ..types.call_list import CallList +from .raw_client import AsyncRawCallsClient, RawCallsClient +from .types.call import Call +from .types.list_calls_with_transcripts_response import ListCallsWithTranscriptsResponse + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class CallsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawCallsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawCallsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawCallsClient + """ + return self._raw_client + + def list_calls( + self, + *, + page: typing.Optional[int] = None, + per_page: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CallList: + """ + Retrieve a paginated list of calls. + + Parameters + ---------- + page : typing.Optional[int] + The page of results to fetch. Defaults to first page + + per_page : typing.Optional[int] + How many results to display per page. Defaults to 25. Max 25. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CallList + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.calls.list_calls() + """ + _response = self._raw_client.list_calls(page=page, per_page=per_page, request_options=request_options) + return _response.data + + def show_call(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Call: + """ + Retrieve a single call by id. + + Parameters + ---------- + id : str + The id of the call to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Call + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.calls.show_call( + id="id", + ) + """ + _response = self._raw_client.show_call(id, request_options=request_options) + return _response.data + + def show_call_recording(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: + """ + Redirects to a signed URL for the call's recording if it exists. + + Parameters + ---------- + id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.calls.show_call_recording( + id="id", + ) + """ + _response = self._raw_client.show_call_recording(id, request_options=request_options) + return _response.data + + def show_call_transcript(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> str: + """ + Returns the transcript for the specified call as a downloadable text file. + + Parameters + ---------- + id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + str + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.calls.show_call_transcript( + id="id", + ) + """ + _response = self._raw_client.show_call_transcript(id, request_options=request_options) + return _response.data + + def list_calls_with_transcripts( + self, *, conversation_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None + ) -> ListCallsWithTranscriptsResponse: + """ + Retrieve calls by a list of conversation ids and include transcripts when available. + A maximum of 20 `conversation_ids` can be provided. If none are provided or more than 20 are provided, a 400 error is returned. + + Parameters + ---------- + conversation_ids : typing.Sequence[str] + A list of conversation ids to fetch calls for. Maximum 20. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ListCallsWithTranscriptsResponse + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.calls.list_calls_with_transcripts( + conversation_ids=["64619700005694", "64619700005695"], + ) + """ + _response = self._raw_client.list_calls_with_transcripts( + conversation_ids=conversation_ids, request_options=request_options + ) + return _response.data + + +class AsyncCallsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawCallsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawCallsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawCallsClient + """ + return self._raw_client + + async def list_calls( + self, + *, + page: typing.Optional[int] = None, + per_page: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> CallList: + """ + Retrieve a paginated list of calls. + + Parameters + ---------- + page : typing.Optional[int] + The page of results to fetch. Defaults to first page + + per_page : typing.Optional[int] + How many results to display per page. Defaults to 25. Max 25. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + CallList + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.calls.list_calls() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_calls(page=page, per_page=per_page, request_options=request_options) + return _response.data + + async def show_call(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> Call: + """ + Retrieve a single call by id. + + Parameters + ---------- + id : str + The id of the call to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + Call + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.calls.show_call( + id="id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.show_call(id, request_options=request_options) + return _response.data + + async def show_call_recording(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> None: + """ + Redirects to a signed URL for the call's recording if it exists. + + Parameters + ---------- + id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + None + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.calls.show_call_recording( + id="id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.show_call_recording(id, request_options=request_options) + return _response.data + + async def show_call_transcript(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> str: + """ + Returns the transcript for the specified call as a downloadable text file. + + Parameters + ---------- + id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + str + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.calls.show_call_transcript( + id="id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.show_call_transcript(id, request_options=request_options) + return _response.data + + async def list_calls_with_transcripts( + self, *, conversation_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None + ) -> ListCallsWithTranscriptsResponse: + """ + Retrieve calls by a list of conversation ids and include transcripts when available. + A maximum of 20 `conversation_ids` can be provided. If none are provided or more than 20 are provided, a 400 error is returned. + + Parameters + ---------- + conversation_ids : typing.Sequence[str] + A list of conversation ids to fetch calls for. Maximum 20. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + ListCallsWithTranscriptsResponse + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.calls.list_calls_with_transcripts( + conversation_ids=["64619700005694", "64619700005695"], + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_calls_with_transcripts( + conversation_ids=conversation_ids, request_options=request_options + ) + return _response.data diff --git a/src/intercom/unstable/calls/raw_client.py b/src/intercom/unstable/calls/raw_client.py new file mode 100644 index 0000000..bff6748 --- /dev/null +++ b/src/intercom/unstable/calls/raw_client.py @@ -0,0 +1,603 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.jsonable_encoder import jsonable_encoder +from ...core.request_options import RequestOptions +from ...core.unchecked_base_model import construct_type +from ..errors.bad_request_error import BadRequestError +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.call_list import CallList +from ..types.error import Error +from .types.call import Call +from .types.list_calls_with_transcripts_response import ListCallsWithTranscriptsResponse + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawCallsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_calls( + self, + *, + page: typing.Optional[int] = None, + per_page: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[CallList]: + """ + Retrieve a paginated list of calls. + + Parameters + ---------- + page : typing.Optional[int] + The page of results to fetch. Defaults to first page + + per_page : typing.Optional[int] + How many results to display per page. Defaults to 25. Max 25. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[CallList] + successful + """ + _response = self._client_wrapper.httpx_client.request( + "calls", + method="GET", + params={ + "page": page, + "per_page": per_page, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CallList, + construct_type( + type_=CallList, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def show_call(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Call]: + """ + Retrieve a single call by id. + + Parameters + ---------- + id : str + The id of the call to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[Call] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Call, + construct_type( + type_=Call, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def show_call_recording( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[None]: + """ + Redirects to a signed URL for the call's recording if it exists. + + Parameters + ---------- + id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[None] + """ + _response = self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(id)}/recording", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=None) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def show_call_transcript( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[str]: + """ + Returns the transcript for the specified call as a downloadable text file. + + Parameters + ---------- + id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[str] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(id)}/transcript", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return HttpResponse(response=_response, data=_response.text) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def list_calls_with_transcripts( + self, *, conversation_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[ListCallsWithTranscriptsResponse]: + """ + Retrieve calls by a list of conversation ids and include transcripts when available. + A maximum of 20 `conversation_ids` can be provided. If none are provided or more than 20 are provided, a 400 error is returned. + + Parameters + ---------- + conversation_ids : typing.Sequence[str] + A list of conversation ids to fetch calls for. Maximum 20. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[ListCallsWithTranscriptsResponse] + successful + """ + _response = self._client_wrapper.httpx_client.request( + "calls/search", + method="POST", + json={ + "conversation_ids": conversation_ids, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ListCallsWithTranscriptsResponse, + construct_type( + type_=ListCallsWithTranscriptsResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawCallsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_calls( + self, + *, + page: typing.Optional[int] = None, + per_page: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[CallList]: + """ + Retrieve a paginated list of calls. + + Parameters + ---------- + page : typing.Optional[int] + The page of results to fetch. Defaults to first page + + per_page : typing.Optional[int] + How many results to display per page. Defaults to 25. Max 25. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[CallList] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + "calls", + method="GET", + params={ + "page": page, + "per_page": per_page, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + CallList, + construct_type( + type_=CallList, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def show_call( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[Call]: + """ + Retrieve a single call by id. + + Parameters + ---------- + id : str + The id of the call to retrieve + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[Call] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + Call, + construct_type( + type_=Call, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def show_call_recording( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[None]: + """ + Redirects to a signed URL for the call's recording if it exists. + + Parameters + ---------- + id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[None] + """ + _response = await self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(id)}/recording", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=None) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def show_call_transcript( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[str]: + """ + Returns the transcript for the specified call as a downloadable text file. + + Parameters + ---------- + id : str + The id of the call + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[str] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"calls/{jsonable_encoder(id)}/transcript", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + return AsyncHttpResponse(response=_response, data=_response.text) # type: ignore + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def list_calls_with_transcripts( + self, *, conversation_ids: typing.Sequence[str], request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[ListCallsWithTranscriptsResponse]: + """ + Retrieve calls by a list of conversation ids and include transcripts when available. + A maximum of 20 `conversation_ids` can be provided. If none are provided or more than 20 are provided, a 400 error is returned. + + Parameters + ---------- + conversation_ids : typing.Sequence[str] + A list of conversation ids to fetch calls for. Maximum 20. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[ListCallsWithTranscriptsResponse] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + "calls/search", + method="POST", + json={ + "conversation_ids": conversation_ids, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + ListCallsWithTranscriptsResponse, + construct_type( + type_=ListCallsWithTranscriptsResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/unstable/calls/types/__init__.py b/src/intercom/unstable/calls/types/__init__.py new file mode 100644 index 0000000..f0f25e4 --- /dev/null +++ b/src/intercom/unstable/calls/types/__init__.py @@ -0,0 +1,9 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .call import Call +from .list_calls_with_transcripts_response import ListCallsWithTranscriptsResponse +from .list_calls_with_transcripts_response_data_item import ListCallsWithTranscriptsResponseDataItem + +__all__ = ["Call", "ListCallsWithTranscriptsResponse", "ListCallsWithTranscriptsResponseDataItem"] diff --git a/src/intercom/unstable/calls/types/call.py b/src/intercom/unstable/calls/types/call.py new file mode 100644 index 0000000..30cc9df --- /dev/null +++ b/src/intercom/unstable/calls/types/call.py @@ -0,0 +1,93 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel +from ...types.datetime import Datetime + + +class Call(UncheckedBaseModel): + """ + Represents a phone call in Intercom + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + String representing the object's type. Always has the value `call`. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the call. + """ + + conversation_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the conversation associated with the call, if any. + """ + + admin_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the admin associated with the call, if any. + """ + + contact_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The id of the contact associated with the call, if any. + """ + + state: typing.Optional[str] = pydantic.Field(default=None) + """ + The current state of the call. + """ + + initiated_at: typing.Optional[Datetime] = None + answered_at: typing.Optional[Datetime] = None + ended_at: typing.Optional[Datetime] = None + created_at: typing.Optional[Datetime] = None + updated_at: typing.Optional[Datetime] = None + recording_url: typing.Optional[str] = pydantic.Field(default=None) + """ + API URL to download or redirect to the call recording if available. + """ + + call_type: typing.Optional[str] = pydantic.Field(default=None) + """ + The type of call. + """ + + direction: typing.Optional[str] = pydantic.Field(default=None) + """ + The direction of the call. + """ + + ended_reason: typing.Optional[str] = pydantic.Field(default=None) + """ + The reason for the call end, if applicable. + """ + + phone: typing.Optional[str] = pydantic.Field(default=None) + """ + The phone number involved in the call, in E.164 format. + """ + + fin_recording_url: typing.Optional[str] = pydantic.Field(default=None) + """ + API URL to the AI Agent (Fin) call recording if available. + """ + + fin_transcription_url: typing.Optional[str] = pydantic.Field(default=None) + """ + API URL to the AI Agent (Fin) call transcript if available. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/calls/types/list_calls_with_transcripts_response.py b/src/intercom/unstable/calls/types/list_calls_with_transcripts_response.py new file mode 100644 index 0000000..840f91b --- /dev/null +++ b/src/intercom/unstable/calls/types/list_calls_with_transcripts_response.py @@ -0,0 +1,22 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel +from .list_calls_with_transcripts_response_data_item import ListCallsWithTranscriptsResponseDataItem + + +class ListCallsWithTranscriptsResponse(UncheckedBaseModel): + type: typing.Optional[str] = None + data: typing.Optional[typing.List[ListCallsWithTranscriptsResponseDataItem]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/calls/types/list_calls_with_transcripts_response_data_item.py b/src/intercom/unstable/calls/types/list_calls_with_transcripts_response_data_item.py new file mode 100644 index 0000000..4994f3f --- /dev/null +++ b/src/intercom/unstable/calls/types/list_calls_with_transcripts_response_data_item.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from .call import Call + + +class ListCallsWithTranscriptsResponseDataItem(Call): + transcript: typing.Optional[typing.List[typing.Dict[str, typing.Optional[typing.Any]]]] = pydantic.Field( + default=None + ) + """ + The call transcript if available, otherwise an empty array. + """ + + transcript_status: typing.Optional[str] = pydantic.Field(default=None) + """ + The status of the transcript if available. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/client.py b/src/intercom/unstable/client.py index 97e8e34..edcf480 100644 --- a/src/intercom/unstable/client.py +++ b/src/intercom/unstable/client.py @@ -5,6 +5,8 @@ from .ai_content.client import AiContentClient, AsyncAiContentClient from .articles.client import ArticlesClient, AsyncArticlesClient from .away_status_reasons.client import AsyncAwayStatusReasonsClient, AwayStatusReasonsClient +from .brands.client import AsyncBrandsClient, BrandsClient +from .calls.client import AsyncCallsClient, CallsClient from .companies.client import AsyncCompaniesClient, CompaniesClient from .contacts.client import AsyncContactsClient, ContactsClient from .conversations.client import AsyncConversationsClient, ConversationsClient @@ -13,9 +15,12 @@ from .data_attributes.client import AsyncDataAttributesClient, DataAttributesClient from .data_events.client import AsyncDataEventsClient, DataEventsClient from .data_export.client import AsyncDataExportClient, DataExportClient +from .emails.client import AsyncEmailsClient, EmailsClient from .export.client import AsyncExportClient, ExportClient from .help_center.client import AsyncHelpCenterClient, HelpCenterClient +from .internal_articles.client import AsyncInternalArticlesClient, InternalArticlesClient from .jobs.client import AsyncJobsClient, JobsClient +from .macros.client import AsyncMacrosClient, MacrosClient from .messages.client import AsyncMessagesClient, MessagesClient from .news.client import AsyncNewsClient, NewsClient from .notes.client import AsyncNotesClient, NotesClient @@ -47,6 +52,8 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self.help_center = HelpCenterClient(client_wrapper=client_wrapper) + self.internal_articles = InternalArticlesClient(client_wrapper=client_wrapper) + self.companies = CompaniesClient(client_wrapper=client_wrapper) self.contacts = ContactsClient(client_wrapper=client_wrapper) @@ -71,6 +78,8 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self.jobs = JobsClient(client_wrapper=client_wrapper) + self.macros = MacrosClient(client_wrapper=client_wrapper) + self.messages = MessagesClient(client_wrapper=client_wrapper) self.news = NewsClient(client_wrapper=client_wrapper) @@ -79,6 +88,8 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self.switch = SwitchClient(client_wrapper=client_wrapper) + self.calls = CallsClient(client_wrapper=client_wrapper) + self.teams = TeamsClient(client_wrapper=client_wrapper) self.ticket_states = TicketStatesClient(client_wrapper=client_wrapper) @@ -91,6 +102,10 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self.visitors = VisitorsClient(client_wrapper=client_wrapper) + self.brands = BrandsClient(client_wrapper=client_wrapper) + + self.emails = EmailsClient(client_wrapper=client_wrapper) + @property def with_raw_response(self) -> RawUnstableClient: """ @@ -118,6 +133,8 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self.help_center = AsyncHelpCenterClient(client_wrapper=client_wrapper) + self.internal_articles = AsyncInternalArticlesClient(client_wrapper=client_wrapper) + self.companies = AsyncCompaniesClient(client_wrapper=client_wrapper) self.contacts = AsyncContactsClient(client_wrapper=client_wrapper) @@ -142,6 +159,8 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self.jobs = AsyncJobsClient(client_wrapper=client_wrapper) + self.macros = AsyncMacrosClient(client_wrapper=client_wrapper) + self.messages = AsyncMessagesClient(client_wrapper=client_wrapper) self.news = AsyncNewsClient(client_wrapper=client_wrapper) @@ -150,6 +169,8 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self.switch = AsyncSwitchClient(client_wrapper=client_wrapper) + self.calls = AsyncCallsClient(client_wrapper=client_wrapper) + self.teams = AsyncTeamsClient(client_wrapper=client_wrapper) self.ticket_states = AsyncTicketStatesClient(client_wrapper=client_wrapper) @@ -162,6 +183,10 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self.visitors = AsyncVisitorsClient(client_wrapper=client_wrapper) + self.brands = AsyncBrandsClient(client_wrapper=client_wrapper) + + self.emails = AsyncEmailsClient(client_wrapper=client_wrapper) + @property def with_raw_response(self) -> AsyncRawUnstableClient: """ diff --git a/src/intercom/unstable/conversations/client.py b/src/intercom/unstable/conversations/client.py index 793fb32..30c409c 100644 --- a/src/intercom/unstable/conversations/client.py +++ b/src/intercom/unstable/conversations/client.py @@ -148,6 +148,7 @@ def retrieve_conversation( id: int, *, display_as: typing.Optional[str] = None, + include_translations: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Conversation: """ @@ -170,6 +171,9 @@ def retrieve_conversation( display_as : typing.Optional[str] Set to plaintext to retrieve conversation messages in plain text. + include_translations : typing.Optional[bool] + If set to true, conversation parts will be translated to the detected language of the conversation. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -190,7 +194,9 @@ def retrieve_conversation( display_as="plaintext", ) """ - _response = self._raw_client.retrieve_conversation(id, display_as=display_as, request_options=request_options) + _response = self._raw_client.retrieve_conversation( + id, display_as=display_as, include_translations=include_translations, request_options=request_options + ) return _response.data def update_conversation( @@ -881,6 +887,7 @@ async def retrieve_conversation( id: int, *, display_as: typing.Optional[str] = None, + include_translations: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> Conversation: """ @@ -903,6 +910,9 @@ async def retrieve_conversation( display_as : typing.Optional[str] Set to plaintext to retrieve conversation messages in plain text. + include_translations : typing.Optional[bool] + If set to true, conversation parts will be translated to the detected language of the conversation. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -932,7 +942,7 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.retrieve_conversation( - id, display_as=display_as, request_options=request_options + id, display_as=display_as, include_translations=include_translations, request_options=request_options ) return _response.data diff --git a/src/intercom/unstable/conversations/raw_client.py b/src/intercom/unstable/conversations/raw_client.py index 5c4343a..1c00622 100644 --- a/src/intercom/unstable/conversations/raw_client.py +++ b/src/intercom/unstable/conversations/raw_client.py @@ -223,6 +223,7 @@ def retrieve_conversation( id: int, *, display_as: typing.Optional[str] = None, + include_translations: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Conversation]: """ @@ -245,6 +246,9 @@ def retrieve_conversation( display_as : typing.Optional[str] Set to plaintext to retrieve conversation messages in plain text. + include_translations : typing.Optional[bool] + If set to true, conversation parts will be translated to the detected language of the conversation. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -258,6 +262,7 @@ def retrieve_conversation( method="GET", params={ "display_as": display_as, + "include_translations": include_translations, }, request_options=request_options, ) @@ -1347,6 +1352,7 @@ async def retrieve_conversation( id: int, *, display_as: typing.Optional[str] = None, + include_translations: typing.Optional[bool] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Conversation]: """ @@ -1369,6 +1375,9 @@ async def retrieve_conversation( display_as : typing.Optional[str] Set to plaintext to retrieve conversation messages in plain text. + include_translations : typing.Optional[bool] + If set to true, conversation parts will be translated to the detected language of the conversation. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -1382,6 +1391,7 @@ async def retrieve_conversation( method="GET", params={ "display_as": display_as, + "include_translations": include_translations, }, request_options=request_options, ) diff --git a/src/intercom/unstable/data_attributes/__init__.py b/src/intercom/unstable/data_attributes/__init__.py index de4ec31..581c1dd 100644 --- a/src/intercom/unstable/data_attributes/__init__.py +++ b/src/intercom/unstable/data_attributes/__init__.py @@ -2,20 +2,6 @@ # isort: skip_file -from .types import ( - CreateDataAttributeRequestDataType, - CreateDataAttributeRequestModel, - DataAttribute, - DataAttributeDataType, - DataAttributeModel, - LisDataAttributesRequestModel, -) +from .types import DataAttribute, DataAttributeDataType, DataAttributeModel, LisDataAttributesRequestModel -__all__ = [ - "CreateDataAttributeRequestDataType", - "CreateDataAttributeRequestModel", - "DataAttribute", - "DataAttributeDataType", - "DataAttributeModel", - "LisDataAttributesRequestModel", -] +__all__ = ["DataAttribute", "DataAttributeDataType", "DataAttributeModel", "LisDataAttributesRequestModel"] diff --git a/src/intercom/unstable/data_attributes/client.py b/src/intercom/unstable/data_attributes/client.py index a97376e..c929202 100644 --- a/src/intercom/unstable/data_attributes/client.py +++ b/src/intercom/unstable/data_attributes/client.py @@ -6,8 +6,6 @@ from ...core.request_options import RequestOptions from ..types.data_attribute_list import DataAttributeList from .raw_client import AsyncRawDataAttributesClient, RawDataAttributesClient -from .types.create_data_attribute_request_data_type import CreateDataAttributeRequestDataType -from .types.create_data_attribute_request_model import CreateDataAttributeRequestModel from .types.data_attribute import DataAttribute from .types.lis_data_attributes_request_model import LisDataAttributesRequestModel @@ -71,38 +69,14 @@ def lis_data_attributes( return _response.data def create_data_attribute( - self, - *, - name: str, - model: CreateDataAttributeRequestModel, - data_type: CreateDataAttributeRequestDataType, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, - request_options: typing.Optional[RequestOptions] = None, + self, *, request: typing.Optional[typing.Any] = None, request_options: typing.Optional[RequestOptions] = None ) -> DataAttribute: """ You can create a data attributes for a `contact` or a `company`. Parameters ---------- - name : str - The name of the data attribute. - - model : CreateDataAttributeRequestModel - The model that the data attribute belongs to. - - data_type : CreateDataAttributeRequestDataType - The type of data stored for this attribute. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : typing.Optional[typing.Any] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -120,30 +94,17 @@ def create_data_attribute( token="YOUR_TOKEN", ) client.unstable.data_attributes.create_data_attribute( - name="Mithril Shirt", - model="company", - data_type="string", + request={"key": "value"}, ) """ - _response = self._raw_client.create_data_attribute( - name=name, - model=model, - data_type=data_type, - description=description, - options=options, - messenger_writable=messenger_writable, - request_options=request_options, - ) + _response = self._raw_client.create_data_attribute(request=request, request_options=request_options) return _response.data def update_data_attribute( self, id: int, *, - archived: typing.Optional[bool] = OMIT, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, + request: typing.Optional[typing.Any] = None, request_options: typing.Optional[RequestOptions] = None, ) -> DataAttribute: """ @@ -159,17 +120,7 @@ def update_data_attribute( id : int The data attribute id - archived : typing.Optional[bool] - Whether the attribute is to be archived or not. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : typing.Optional[typing.Any] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -188,19 +139,10 @@ def update_data_attribute( ) client.unstable.data_attributes.update_data_attribute( id=1, - archived=False, - description="Just a plain old ring", - options=["options", "options"], + request={"key": "value"}, ) """ - _response = self._raw_client.update_data_attribute( - id, - archived=archived, - description=description, - options=options, - messenger_writable=messenger_writable, - request_options=request_options, - ) + _response = self._raw_client.update_data_attribute(id, request=request, request_options=request_options) return _response.data @@ -268,38 +210,14 @@ async def main() -> None: return _response.data async def create_data_attribute( - self, - *, - name: str, - model: CreateDataAttributeRequestModel, - data_type: CreateDataAttributeRequestDataType, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, - request_options: typing.Optional[RequestOptions] = None, + self, *, request: typing.Optional[typing.Any] = None, request_options: typing.Optional[RequestOptions] = None ) -> DataAttribute: """ You can create a data attributes for a `contact` or a `company`. Parameters ---------- - name : str - The name of the data attribute. - - model : CreateDataAttributeRequestModel - The model that the data attribute belongs to. - - data_type : CreateDataAttributeRequestDataType - The type of data stored for this attribute. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : typing.Optional[typing.Any] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -322,33 +240,20 @@ async def create_data_attribute( async def main() -> None: await client.unstable.data_attributes.create_data_attribute( - name="Mithril Shirt", - model="company", - data_type="string", + request={"key": "value"}, ) asyncio.run(main()) """ - _response = await self._raw_client.create_data_attribute( - name=name, - model=model, - data_type=data_type, - description=description, - options=options, - messenger_writable=messenger_writable, - request_options=request_options, - ) + _response = await self._raw_client.create_data_attribute(request=request, request_options=request_options) return _response.data async def update_data_attribute( self, id: int, *, - archived: typing.Optional[bool] = OMIT, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, + request: typing.Optional[typing.Any] = None, request_options: typing.Optional[RequestOptions] = None, ) -> DataAttribute: """ @@ -364,17 +269,7 @@ async def update_data_attribute( id : int The data attribute id - archived : typing.Optional[bool] - Whether the attribute is to be archived or not. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : typing.Optional[typing.Any] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -398,20 +293,11 @@ async def update_data_attribute( async def main() -> None: await client.unstable.data_attributes.update_data_attribute( id=1, - archived=False, - description="Just a plain old ring", - options=["options", "options"], + request={"key": "value"}, ) asyncio.run(main()) """ - _response = await self._raw_client.update_data_attribute( - id, - archived=archived, - description=description, - options=options, - messenger_writable=messenger_writable, - request_options=request_options, - ) + _response = await self._raw_client.update_data_attribute(id, request=request, request_options=request_options) return _response.data diff --git a/src/intercom/unstable/data_attributes/raw_client.py b/src/intercom/unstable/data_attributes/raw_client.py index 8e33e37..ab43b41 100644 --- a/src/intercom/unstable/data_attributes/raw_client.py +++ b/src/intercom/unstable/data_attributes/raw_client.py @@ -15,8 +15,6 @@ from ..errors.unprocessable_entity_error import UnprocessableEntityError from ..types.data_attribute_list import DataAttributeList from ..types.error import Error -from .types.create_data_attribute_request_data_type import CreateDataAttributeRequestDataType -from .types.create_data_attribute_request_model import CreateDataAttributeRequestModel from .types.data_attribute import DataAttribute from .types.lis_data_attributes_request_model import LisDataAttributesRequestModel @@ -90,38 +88,14 @@ def lis_data_attributes( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) def create_data_attribute( - self, - *, - name: str, - model: CreateDataAttributeRequestModel, - data_type: CreateDataAttributeRequestDataType, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, - request_options: typing.Optional[RequestOptions] = None, + self, *, request: typing.Optional[typing.Any] = None, request_options: typing.Optional[RequestOptions] = None ) -> HttpResponse[DataAttribute]: """ You can create a data attributes for a `contact` or a `company`. Parameters ---------- - name : str - The name of the data attribute. - - model : CreateDataAttributeRequestModel - The model that the data attribute belongs to. - - data_type : CreateDataAttributeRequestDataType - The type of data stored for this attribute. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : typing.Optional[typing.Any] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -134,14 +108,7 @@ def create_data_attribute( _response = self._client_wrapper.httpx_client.request( "data_attributes", method="POST", - json={ - "name": name, - "model": model, - "data_type": data_type, - "description": description, - "options": options, - "messenger_writable": messenger_writable, - }, + json=request, headers={ "content-type": "application/json", }, @@ -189,10 +156,7 @@ def update_data_attribute( self, id: int, *, - archived: typing.Optional[bool] = OMIT, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, + request: typing.Optional[typing.Any] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[DataAttribute]: """ @@ -208,17 +172,7 @@ def update_data_attribute( id : int The data attribute id - archived : typing.Optional[bool] - Whether the attribute is to be archived or not. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : typing.Optional[typing.Any] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -231,12 +185,7 @@ def update_data_attribute( _response = self._client_wrapper.httpx_client.request( f"data_attributes/{jsonable_encoder(id)}", method="PUT", - json={ - "archived": archived, - "description": description, - "options": options, - "messenger_writable": messenger_writable, - }, + json=request, headers={ "content-type": "application/json", }, @@ -369,38 +318,14 @@ async def lis_data_attributes( raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) async def create_data_attribute( - self, - *, - name: str, - model: CreateDataAttributeRequestModel, - data_type: CreateDataAttributeRequestDataType, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, - request_options: typing.Optional[RequestOptions] = None, + self, *, request: typing.Optional[typing.Any] = None, request_options: typing.Optional[RequestOptions] = None ) -> AsyncHttpResponse[DataAttribute]: """ You can create a data attributes for a `contact` or a `company`. Parameters ---------- - name : str - The name of the data attribute. - - model : CreateDataAttributeRequestModel - The model that the data attribute belongs to. - - data_type : CreateDataAttributeRequestDataType - The type of data stored for this attribute. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : typing.Optional[typing.Any] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -413,14 +338,7 @@ async def create_data_attribute( _response = await self._client_wrapper.httpx_client.request( "data_attributes", method="POST", - json={ - "name": name, - "model": model, - "data_type": data_type, - "description": description, - "options": options, - "messenger_writable": messenger_writable, - }, + json=request, headers={ "content-type": "application/json", }, @@ -468,10 +386,7 @@ async def update_data_attribute( self, id: int, *, - archived: typing.Optional[bool] = OMIT, - description: typing.Optional[str] = OMIT, - options: typing.Optional[typing.Sequence[str]] = OMIT, - messenger_writable: typing.Optional[bool] = OMIT, + request: typing.Optional[typing.Any] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[DataAttribute]: """ @@ -487,17 +402,7 @@ async def update_data_attribute( id : int The data attribute id - archived : typing.Optional[bool] - Whether the attribute is to be archived or not. - - description : typing.Optional[str] - The readable description you see in the UI for the attribute. - - options : typing.Optional[typing.Sequence[str]] - To create list attributes. Provide a set of hashes with `value` as the key of the options you want to make. `data_type` must be `string`. - - messenger_writable : typing.Optional[bool] - Can this attribute be updated by the Messenger + request : typing.Optional[typing.Any] request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -510,12 +415,7 @@ async def update_data_attribute( _response = await self._client_wrapper.httpx_client.request( f"data_attributes/{jsonable_encoder(id)}", method="PUT", - json={ - "archived": archived, - "description": description, - "options": options, - "messenger_writable": messenger_writable, - }, + json=request, headers={ "content-type": "application/json", }, diff --git a/src/intercom/unstable/data_attributes/types/__init__.py b/src/intercom/unstable/data_attributes/types/__init__.py index 2f1a58f..0764e89 100644 --- a/src/intercom/unstable/data_attributes/types/__init__.py +++ b/src/intercom/unstable/data_attributes/types/__init__.py @@ -2,18 +2,9 @@ # isort: skip_file -from .create_data_attribute_request_data_type import CreateDataAttributeRequestDataType -from .create_data_attribute_request_model import CreateDataAttributeRequestModel from .data_attribute import DataAttribute from .data_attribute_data_type import DataAttributeDataType from .data_attribute_model import DataAttributeModel from .lis_data_attributes_request_model import LisDataAttributesRequestModel -__all__ = [ - "CreateDataAttributeRequestDataType", - "CreateDataAttributeRequestModel", - "DataAttribute", - "DataAttributeDataType", - "DataAttributeModel", - "LisDataAttributesRequestModel", -] +__all__ = ["DataAttribute", "DataAttributeDataType", "DataAttributeModel", "LisDataAttributesRequestModel"] diff --git a/src/intercom/unstable/data_attributes/types/create_data_attribute_request_model.py b/src/intercom/unstable/data_attributes/types/create_data_attribute_request_model.py deleted file mode 100644 index cc5c9b6..0000000 --- a/src/intercom/unstable/data_attributes/types/create_data_attribute_request_model.py +++ /dev/null @@ -1,5 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -CreateDataAttributeRequestModel = typing.Union[typing.Literal["contact", "company"], typing.Any] diff --git a/src/intercom/unstable/emails/__init__.py b/src/intercom/unstable/emails/__init__.py new file mode 100644 index 0000000..adc1484 --- /dev/null +++ b/src/intercom/unstable/emails/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import EmailList, EmailSetting + +__all__ = ["EmailList", "EmailSetting"] diff --git a/src/intercom/unstable/emails/client.py b/src/intercom/unstable/emails/client.py new file mode 100644 index 0000000..cbcb564 --- /dev/null +++ b/src/intercom/unstable/emails/client.py @@ -0,0 +1,171 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.request_options import RequestOptions +from .raw_client import AsyncRawEmailsClient, RawEmailsClient +from .types.email_list import EmailList +from .types.email_setting import EmailSetting + + +class EmailsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawEmailsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawEmailsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawEmailsClient + """ + return self._raw_client + + def list_emails(self, *, request_options: typing.Optional[RequestOptions] = None) -> EmailList: + """ + Lists all sender email address settings for the workspace + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EmailList + Successful response + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.emails.list_emails() + """ + _response = self._raw_client.list_emails(request_options=request_options) + return _response.data + + def retrieve_email(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmailSetting: + """ + Fetches a specific email setting by its unique identifier + + Parameters + ---------- + id : str + The unique identifier of the email setting + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EmailSetting + Successful response + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.emails.retrieve_email( + id="id", + ) + """ + _response = self._raw_client.retrieve_email(id, request_options=request_options) + return _response.data + + +class AsyncEmailsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawEmailsClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawEmailsClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawEmailsClient + """ + return self._raw_client + + async def list_emails(self, *, request_options: typing.Optional[RequestOptions] = None) -> EmailList: + """ + Lists all sender email address settings for the workspace + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EmailList + Successful response + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.emails.list_emails() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_emails(request_options=request_options) + return _response.data + + async def retrieve_email(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> EmailSetting: + """ + Fetches a specific email setting by its unique identifier + + Parameters + ---------- + id : str + The unique identifier of the email setting + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + EmailSetting + Successful response + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.emails.retrieve_email( + id="id", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.retrieve_email(id, request_options=request_options) + return _response.data diff --git a/src/intercom/unstable/emails/raw_client.py b/src/intercom/unstable/emails/raw_client.py new file mode 100644 index 0000000..6d26d00 --- /dev/null +++ b/src/intercom/unstable/emails/raw_client.py @@ -0,0 +1,240 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.jsonable_encoder import jsonable_encoder +from ...core.request_options import RequestOptions +from ...core.unchecked_base_model import construct_type +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.error import Error +from .types.email_list import EmailList +from .types.email_setting import EmailSetting + + +class RawEmailsClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_emails(self, *, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[EmailList]: + """ + Lists all sender email address settings for the workspace + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[EmailList] + Successful response + """ + _response = self._client_wrapper.httpx_client.request( + "emails", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EmailList, + construct_type( + type_=EmailList, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def retrieve_email( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[EmailSetting]: + """ + Fetches a specific email setting by its unique identifier + + Parameters + ---------- + id : str + The unique identifier of the email setting + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[EmailSetting] + Successful response + """ + _response = self._client_wrapper.httpx_client.request( + f"emails/{jsonable_encoder(id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EmailSetting, + construct_type( + type_=EmailSetting, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawEmailsClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_emails( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[EmailList]: + """ + Lists all sender email address settings for the workspace + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[EmailList] + Successful response + """ + _response = await self._client_wrapper.httpx_client.request( + "emails", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EmailList, + construct_type( + type_=EmailList, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def retrieve_email( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[EmailSetting]: + """ + Fetches a specific email setting by its unique identifier + + Parameters + ---------- + id : str + The unique identifier of the email setting + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[EmailSetting] + Successful response + """ + _response = await self._client_wrapper.httpx_client.request( + f"emails/{jsonable_encoder(id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + EmailSetting, + construct_type( + type_=EmailSetting, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/unstable/emails/types/__init__.py b/src/intercom/unstable/emails/types/__init__.py new file mode 100644 index 0000000..7c69dc2 --- /dev/null +++ b/src/intercom/unstable/emails/types/__init__.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .email_list import EmailList +from .email_setting import EmailSetting + +__all__ = ["EmailList", "EmailSetting"] diff --git a/src/intercom/unstable/emails/types/email_list.py b/src/intercom/unstable/emails/types/email_list.py new file mode 100644 index 0000000..1547f3f --- /dev/null +++ b/src/intercom/unstable/emails/types/email_list.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel +from .email_setting import EmailSetting + + +class EmailList(UncheckedBaseModel): + """ + A list of email settings + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + The type of object + """ + + data: typing.Optional[typing.List[EmailSetting]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/emails/types/email_setting.py b/src/intercom/unstable/emails/types/email_setting.py new file mode 100644 index 0000000..09c11db --- /dev/null +++ b/src/intercom/unstable/emails/types/email_setting.py @@ -0,0 +1,72 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel + + +class EmailSetting(UncheckedBaseModel): + """ + Represents a sender email address configuration + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + The type of object + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + Unique email setting identifier + """ + + email: typing.Optional[str] = pydantic.Field(default=None) + """ + Full sender email address + """ + + verified: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the email address has been verified + """ + + domain: typing.Optional[str] = pydantic.Field(default=None) + """ + Domain portion of the email address + """ + + brand_id: typing.Optional[str] = pydantic.Field(default=None) + """ + Associated brand identifier + """ + + forwarding_enabled: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether email forwarding is active + """ + + forwarded_email_last_received_at: typing.Optional[int] = pydantic.Field(default=None) + """ + Unix timestamp of last forwarded email received (null if never) + """ + + created_at: typing.Optional[int] = pydantic.Field(default=None) + """ + Unix timestamp of creation + """ + + updated_at: typing.Optional[int] = pydantic.Field(default=None) + """ + Unix timestamp of last modification + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/export/client.py b/src/intercom/unstable/export/client.py index 17a3049..a3b9cc8 100644 --- a/src/intercom/unstable/export/client.py +++ b/src/intercom/unstable/export/client.py @@ -64,10 +64,7 @@ def enqueue_a_new_reporting_data_export_job( ) client.unstable.export.enqueue_a_new_reporting_data_export_job( dataset_id="conversation", - attribute_ids=[ - "conversation.id", - "conversation.first_user_conversation_part_created_at", - ], + attribute_ids=["conversation_id", "conversation_started_at"], start_time=1717490000, end_time=1717510000, ) @@ -165,10 +162,7 @@ async def enqueue_a_new_reporting_data_export_job( async def main() -> None: await client.unstable.export.enqueue_a_new_reporting_data_export_job( dataset_id="conversation", - attribute_ids=[ - "conversation.id", - "conversation.first_user_conversation_part_created_at", - ], + attribute_ids=["conversation_id", "conversation_started_at"], start_time=1717490000, end_time=1717510000, ) diff --git a/src/intercom/unstable/help_center/types/help_center.py b/src/intercom/unstable/help_center/types/help_center.py index 0933074..93df1fb 100644 --- a/src/intercom/unstable/help_center/types/help_center.py +++ b/src/intercom/unstable/help_center/types/help_center.py @@ -47,6 +47,16 @@ class HelpCenter(UncheckedBaseModel): The display name of the Help Center only seen by teammates. """ + url: typing.Optional[str] = pydantic.Field(default=None) + """ + The URL for the help center, if you have a custom domain then this will show the URL using the custom domain. + """ + + custom_domain: typing.Optional[str] = pydantic.Field(default=None) + """ + Custom domain configured for the help center + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/unstable/internal_articles/__init__.py b/src/intercom/unstable/internal_articles/__init__.py new file mode 100644 index 0000000..7c622b6 --- /dev/null +++ b/src/intercom/unstable/internal_articles/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import InternalArticleListItem, InternalArticleSearchResponse, InternalArticleSearchResponseData + +__all__ = ["InternalArticleListItem", "InternalArticleSearchResponse", "InternalArticleSearchResponseData"] diff --git a/src/intercom/unstable/internal_articles/client.py b/src/intercom/unstable/internal_articles/client.py new file mode 100644 index 0000000..7b1bf13 --- /dev/null +++ b/src/intercom/unstable/internal_articles/client.py @@ -0,0 +1,539 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.request_options import RequestOptions +from ..articles.types.internal_article import InternalArticle +from ..types.create_internal_article_request import CreateInternalArticleRequest +from ..types.deleted_internal_article_object import DeletedInternalArticleObject +from ..types.internal_article_list import InternalArticleList +from .raw_client import AsyncRawInternalArticlesClient, RawInternalArticlesClient +from .types.internal_article_search_response import InternalArticleSearchResponse + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class InternalArticlesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawInternalArticlesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawInternalArticlesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawInternalArticlesClient + """ + return self._raw_client + + def list_internal_articles(self, *, request_options: typing.Optional[RequestOptions] = None) -> InternalArticleList: + """ + You can fetch a list of all internal articles by making a GET request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticleList + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.internal_articles.list_internal_articles() + """ + _response = self._raw_client.list_internal_articles(request_options=request_options) + return _response.data + + def create_internal_article( + self, + *, + request: typing.Optional[CreateInternalArticleRequest] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> InternalArticle: + """ + You can create a new internal article by making a POST request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request : typing.Optional[CreateInternalArticleRequest] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + internal article created + + Examples + -------- + from intercom import Intercom + from intercom.unstable import CreateInternalArticleRequest + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.internal_articles.create_internal_article( + request=CreateInternalArticleRequest( + title="Thanks for everything", + body="Body of the Article", + author_id=991266252, + owner_id=991266252, + ), + ) + """ + _response = self._raw_client.create_internal_article(request=request, request_options=request_options) + return _response.data + + def retrieve_internal_article( + self, id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> InternalArticle: + """ + You can fetch the details of a single internal article by making a GET request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + Internal article found + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.internal_articles.retrieve_internal_article( + id=1, + ) + """ + _response = self._raw_client.retrieve_internal_article(id, request_options=request_options) + return _response.data + + def update_internal_article( + self, + id: int, + *, + title: typing.Optional[str] = OMIT, + body: typing.Optional[str] = OMIT, + author_id: typing.Optional[int] = OMIT, + owner_id: typing.Optional[int] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> InternalArticle: + """ + You can update the details of a single internal article by making a PUT request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the internal article which is given by Intercom. + + title : typing.Optional[str] + The title of the article. + + body : typing.Optional[str] + The content of the article. + + author_id : typing.Optional[int] + The id of the author of the article. + + owner_id : typing.Optional[int] + The id of the author of the article. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.internal_articles.update_internal_article( + id=1, + title="Christmas is here!", + body="

New gifts in store for the jolly season

", + ) + """ + _response = self._raw_client.update_internal_article( + id, title=title, body=body, author_id=author_id, owner_id=owner_id, request_options=request_options + ) + return _response.data + + def delete_internal_article( + self, id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> DeletedInternalArticleObject: + """ + You can delete a single internal article by making a DELETE request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the internal article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeletedInternalArticleObject + successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.internal_articles.delete_internal_article( + id=1, + ) + """ + _response = self._raw_client.delete_internal_article(id, request_options=request_options) + return _response.data + + def search_internal_articles( + self, *, folder_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> InternalArticleSearchResponse: + """ + You can search for internal articles by making a GET request to `https://api.intercom.io/internal_articles/search`. + + Parameters + ---------- + folder_id : typing.Optional[str] + The ID of the folder to search in. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticleSearchResponse + Search successful + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.internal_articles.search_internal_articles() + """ + _response = self._raw_client.search_internal_articles(folder_id=folder_id, request_options=request_options) + return _response.data + + +class AsyncInternalArticlesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawInternalArticlesClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawInternalArticlesClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawInternalArticlesClient + """ + return self._raw_client + + async def list_internal_articles( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> InternalArticleList: + """ + You can fetch a list of all internal articles by making a GET request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticleList + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.internal_articles.list_internal_articles() + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_internal_articles(request_options=request_options) + return _response.data + + async def create_internal_article( + self, + *, + request: typing.Optional[CreateInternalArticleRequest] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> InternalArticle: + """ + You can create a new internal article by making a POST request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request : typing.Optional[CreateInternalArticleRequest] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + internal article created + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + from intercom.unstable import CreateInternalArticleRequest + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.internal_articles.create_internal_article( + request=CreateInternalArticleRequest( + title="Thanks for everything", + body="Body of the Article", + author_id=991266252, + owner_id=991266252, + ), + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.create_internal_article(request=request, request_options=request_options) + return _response.data + + async def retrieve_internal_article( + self, id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> InternalArticle: + """ + You can fetch the details of a single internal article by making a GET request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + Internal article found + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.internal_articles.retrieve_internal_article( + id=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.retrieve_internal_article(id, request_options=request_options) + return _response.data + + async def update_internal_article( + self, + id: int, + *, + title: typing.Optional[str] = OMIT, + body: typing.Optional[str] = OMIT, + author_id: typing.Optional[int] = OMIT, + owner_id: typing.Optional[int] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> InternalArticle: + """ + You can update the details of a single internal article by making a PUT request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the internal article which is given by Intercom. + + title : typing.Optional[str] + The title of the article. + + body : typing.Optional[str] + The content of the article. + + author_id : typing.Optional[int] + The id of the author of the article. + + owner_id : typing.Optional[int] + The id of the author of the article. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticle + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.internal_articles.update_internal_article( + id=1, + title="Christmas is here!", + body="

New gifts in store for the jolly season

", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.update_internal_article( + id, title=title, body=body, author_id=author_id, owner_id=owner_id, request_options=request_options + ) + return _response.data + + async def delete_internal_article( + self, id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> DeletedInternalArticleObject: + """ + You can delete a single internal article by making a DELETE request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the internal article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + DeletedInternalArticleObject + successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.internal_articles.delete_internal_article( + id=1, + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.delete_internal_article(id, request_options=request_options) + return _response.data + + async def search_internal_articles( + self, *, folder_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> InternalArticleSearchResponse: + """ + You can search for internal articles by making a GET request to `https://api.intercom.io/internal_articles/search`. + + Parameters + ---------- + folder_id : typing.Optional[str] + The ID of the folder to search in. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + InternalArticleSearchResponse + Search successful + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.internal_articles.search_internal_articles() + + + asyncio.run(main()) + """ + _response = await self._raw_client.search_internal_articles( + folder_id=folder_id, request_options=request_options + ) + return _response.data diff --git a/src/intercom/unstable/internal_articles/raw_client.py b/src/intercom/unstable/internal_articles/raw_client.py new file mode 100644 index 0000000..fecfda6 --- /dev/null +++ b/src/intercom/unstable/internal_articles/raw_client.py @@ -0,0 +1,798 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.jsonable_encoder import jsonable_encoder +from ...core.request_options import RequestOptions +from ...core.serialization import convert_and_respect_annotation_metadata +from ...core.unchecked_base_model import construct_type +from ..articles.types.internal_article import InternalArticle +from ..errors.bad_request_error import BadRequestError +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.create_internal_article_request import CreateInternalArticleRequest +from ..types.deleted_internal_article_object import DeletedInternalArticleObject +from ..types.error import Error +from ..types.internal_article_list import InternalArticleList +from .types.internal_article_search_response import InternalArticleSearchResponse + +# this is used as the default value for optional parameters +OMIT = typing.cast(typing.Any, ...) + + +class RawInternalArticlesClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_internal_articles( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[InternalArticleList]: + """ + You can fetch a list of all internal articles by making a GET request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[InternalArticleList] + successful + """ + _response = self._client_wrapper.httpx_client.request( + "internal_articles", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticleList, + construct_type( + type_=InternalArticleList, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def create_internal_article( + self, + *, + request: typing.Optional[CreateInternalArticleRequest] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[InternalArticle]: + """ + You can create a new internal article by making a POST request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request : typing.Optional[CreateInternalArticleRequest] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[InternalArticle] + internal article created + """ + _response = self._client_wrapper.httpx_client.request( + "internal_articles", + method="POST", + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateInternalArticleRequest, direction="write" + ), + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def retrieve_internal_article( + self, id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[InternalArticle]: + """ + You can fetch the details of a single internal article by making a GET request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[InternalArticle] + Internal article found + """ + _response = self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def update_internal_article( + self, + id: int, + *, + title: typing.Optional[str] = OMIT, + body: typing.Optional[str] = OMIT, + author_id: typing.Optional[int] = OMIT, + owner_id: typing.Optional[int] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[InternalArticle]: + """ + You can update the details of a single internal article by making a PUT request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the internal article which is given by Intercom. + + title : typing.Optional[str] + The title of the article. + + body : typing.Optional[str] + The content of the article. + + author_id : typing.Optional[int] + The id of the author of the article. + + owner_id : typing.Optional[int] + The id of the author of the article. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[InternalArticle] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(id)}", + method="PUT", + json={ + "title": title, + "body": body, + "author_id": author_id, + "owner_id": owner_id, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def delete_internal_article( + self, id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[DeletedInternalArticleObject]: + """ + You can delete a single internal article by making a DELETE request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the internal article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[DeletedInternalArticleObject] + successful + """ + _response = self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeletedInternalArticleObject, + construct_type( + type_=DeletedInternalArticleObject, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def search_internal_articles( + self, *, folder_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[InternalArticleSearchResponse]: + """ + You can search for internal articles by making a GET request to `https://api.intercom.io/internal_articles/search`. + + Parameters + ---------- + folder_id : typing.Optional[str] + The ID of the folder to search in. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[InternalArticleSearchResponse] + Search successful + """ + _response = self._client_wrapper.httpx_client.request( + "internal_articles/search", + method="GET", + params={ + "folder_id": folder_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticleSearchResponse, + construct_type( + type_=InternalArticleSearchResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawInternalArticlesClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_internal_articles( + self, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[InternalArticleList]: + """ + You can fetch a list of all internal articles by making a GET request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[InternalArticleList] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + "internal_articles", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticleList, + construct_type( + type_=InternalArticleList, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def create_internal_article( + self, + *, + request: typing.Optional[CreateInternalArticleRequest] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[InternalArticle]: + """ + You can create a new internal article by making a POST request to `https://api.intercom.io/internal_articles`. + + Parameters + ---------- + request : typing.Optional[CreateInternalArticleRequest] + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[InternalArticle] + internal article created + """ + _response = await self._client_wrapper.httpx_client.request( + "internal_articles", + method="POST", + json=convert_and_respect_annotation_metadata( + object_=request, annotation=CreateInternalArticleRequest, direction="write" + ), + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def retrieve_internal_article( + self, id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[InternalArticle]: + """ + You can fetch the details of a single internal article by making a GET request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[InternalArticle] + Internal article found + """ + _response = await self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(id)}", + method="GET", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def update_internal_article( + self, + id: int, + *, + title: typing.Optional[str] = OMIT, + body: typing.Optional[str] = OMIT, + author_id: typing.Optional[int] = OMIT, + owner_id: typing.Optional[int] = OMIT, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[InternalArticle]: + """ + You can update the details of a single internal article by making a PUT request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the internal article which is given by Intercom. + + title : typing.Optional[str] + The title of the article. + + body : typing.Optional[str] + The content of the article. + + author_id : typing.Optional[int] + The id of the author of the article. + + owner_id : typing.Optional[int] + The id of the author of the article. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[InternalArticle] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(id)}", + method="PUT", + json={ + "title": title, + "body": body, + "author_id": author_id, + "owner_id": owner_id, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticle, + construct_type( + type_=InternalArticle, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def delete_internal_article( + self, id: int, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[DeletedInternalArticleObject]: + """ + You can delete a single internal article by making a DELETE request to `https://api.intercom.io/internal_articles/`. + + Parameters + ---------- + id : int + The unique identifier for the internal article which is given by Intercom. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[DeletedInternalArticleObject] + successful + """ + _response = await self._client_wrapper.httpx_client.request( + f"internal_articles/{jsonable_encoder(id)}", + method="DELETE", + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + DeletedInternalArticleObject, + construct_type( + type_=DeletedInternalArticleObject, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def search_internal_articles( + self, *, folder_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[InternalArticleSearchResponse]: + """ + You can search for internal articles by making a GET request to `https://api.intercom.io/internal_articles/search`. + + Parameters + ---------- + folder_id : typing.Optional[str] + The ID of the folder to search in. + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[InternalArticleSearchResponse] + Search successful + """ + _response = await self._client_wrapper.httpx_client.request( + "internal_articles/search", + method="GET", + params={ + "folder_id": folder_id, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + InternalArticleSearchResponse, + construct_type( + type_=InternalArticleSearchResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/unstable/internal_articles/types/__init__.py b/src/intercom/unstable/internal_articles/types/__init__.py new file mode 100644 index 0000000..23336f7 --- /dev/null +++ b/src/intercom/unstable/internal_articles/types/__init__.py @@ -0,0 +1,9 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .internal_article_list_item import InternalArticleListItem +from .internal_article_search_response import InternalArticleSearchResponse +from .internal_article_search_response_data import InternalArticleSearchResponseData + +__all__ = ["InternalArticleListItem", "InternalArticleSearchResponse", "InternalArticleSearchResponseData"] diff --git a/src/intercom/unstable/internal_articles/types/internal_article_list_item.py b/src/intercom/unstable/internal_articles/types/internal_article_list_item.py new file mode 100644 index 0000000..2c24607 --- /dev/null +++ b/src/intercom/unstable/internal_articles/types/internal_article_list_item.py @@ -0,0 +1,67 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel + + +class InternalArticleListItem(UncheckedBaseModel): + """ + The data returned about your internal articles when you list them. + """ + + type: typing.Optional[typing.Literal["internal_article"]] = pydantic.Field(default=None) + """ + The type of object - `internal_article`. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier for the article which is given by Intercom. + """ + + title: typing.Optional[str] = pydantic.Field(default=None) + """ + The title of the article. + """ + + body: typing.Optional[str] = pydantic.Field(default=None) + """ + The body of the article in HTML. + """ + + owner_id: typing.Optional[int] = pydantic.Field(default=None) + """ + The id of the owner of the article. + """ + + author_id: typing.Optional[int] = pydantic.Field(default=None) + """ + The id of the author of the article. + """ + + created_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time when the article was created. + """ + + updated_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time when the article was last updated. + """ + + locale: typing.Optional[str] = pydantic.Field(default=None) + """ + The default locale of the article. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/internal_articles/types/internal_article_search_response.py b/src/intercom/unstable/internal_articles/types/internal_article_search_response.py new file mode 100644 index 0000000..fc34dd7 --- /dev/null +++ b/src/intercom/unstable/internal_articles/types/internal_article_search_response.py @@ -0,0 +1,41 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel +from ...types.cursor_pages import CursorPages +from .internal_article_search_response_data import InternalArticleSearchResponseData + + +class InternalArticleSearchResponse(UncheckedBaseModel): + """ + The results of an Internal Article search + """ + + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) + """ + The type of the object - `list`. + """ + + total_count: typing.Optional[int] = pydantic.Field(default=None) + """ + The total number of Internal Articles matching the search query + """ + + data: typing.Optional[InternalArticleSearchResponseData] = pydantic.Field(default=None) + """ + An object containing the results of the search. + """ + + pages: typing.Optional[CursorPages] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/internal_articles/types/internal_article_search_response_data.py b/src/intercom/unstable/internal_articles/types/internal_article_search_response_data.py new file mode 100644 index 0000000..ebeffb3 --- /dev/null +++ b/src/intercom/unstable/internal_articles/types/internal_article_search_response_data.py @@ -0,0 +1,28 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel +from ...articles.types.internal_article import InternalArticle + + +class InternalArticleSearchResponseData(UncheckedBaseModel): + """ + An object containing the results of the search. + """ + + internal_articles: typing.Optional[typing.List[InternalArticle]] = pydantic.Field(default=None) + """ + An array of Internal Article objects + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/macros/__init__.py b/src/intercom/unstable/macros/__init__.py new file mode 100644 index 0000000..e99ac30 --- /dev/null +++ b/src/intercom/unstable/macros/__init__.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .types import Macro, MacroAvailableOnItem, MacroList, MacroListPages, MacroListPagesNext, MacroVisibleTo + +__all__ = ["Macro", "MacroAvailableOnItem", "MacroList", "MacroListPages", "MacroListPagesNext", "MacroVisibleTo"] diff --git a/src/intercom/unstable/macros/client.py b/src/intercom/unstable/macros/client.py new file mode 100644 index 0000000..2eb97cb --- /dev/null +++ b/src/intercom/unstable/macros/client.py @@ -0,0 +1,275 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.request_options import RequestOptions +from .raw_client import AsyncRawMacrosClient, RawMacrosClient +from .types.macro import Macro +from .types.macro_list import MacroList + + +class MacrosClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._raw_client = RawMacrosClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> RawMacrosClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + RawMacrosClient + """ + return self._raw_client + + def list_macros( + self, + *, + per_page: typing.Optional[int] = None, + starting_after: typing.Optional[str] = None, + updated_since: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> MacroList: + """ + You can fetch a list of all macros (saved replies) in your workspace for use in automating responses. + + The macros are returned in descending order by updated_at. + + **Pagination** + + This endpoint uses cursor-based pagination via the `starting_after` parameter. The cursor is a Base64-encoded JSON array containing `[updated_at, id]` of the last item from the previous page. + + **Placeholder Transformation** + + The API transforms Intercom placeholders to a more standard XML-like format: + - From: `{{user.name | fallback: 'there'}}` + - To: `` + + Parameters + ---------- + per_page : typing.Optional[int] + The number of results per page + + starting_after : typing.Optional[str] + Base64-encoded cursor containing [updated_at, id] for pagination + + updated_since : typing.Optional[int] + Unix timestamp to filter macros updated after this time + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + MacroList + Successful response + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.macros.list_macros( + starting_after="WzE3MTk0OTM3NTcuMCwgIjEyMyJd", + ) + """ + _response = self._raw_client.list_macros( + per_page=per_page, + starting_after=starting_after, + updated_since=updated_since, + request_options=request_options, + ) + return _response.data + + def get_macro(self, id: str, *, request_options: typing.Optional[RequestOptions] = None) -> typing.Optional[Macro]: + """ + You can fetch a single macro (saved reply) by its ID. The macro will only be returned if it is visible to the authenticated user based on its visibility settings. + + **Visibility Rules** + + A macro is returned based on its `visible_to` setting: + - `everyone`: Always visible to all team members + - `specific_teams`: Only visible if the authenticated user belongs to one of the teams specified in `visible_to_team_ids` + + If a macro exists but is not visible to the authenticated user, a 404 error is returned. + + **Placeholder Transformation** + + The API transforms Intercom placeholders to a more standard XML-like format in the `body` field: + - From: `{{user.name | fallback: 'there'}}` + - To: `` + + Default values in placeholders are HTML-escaped for security. + + Parameters + ---------- + id : str + The unique identifier of the macro + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[Macro] + Macro found + + Examples + -------- + from intercom import Intercom + + client = Intercom( + token="YOUR_TOKEN", + ) + client.unstable.macros.get_macro( + id="123", + ) + """ + _response = self._raw_client.get_macro(id, request_options=request_options) + return _response.data + + +class AsyncMacrosClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._raw_client = AsyncRawMacrosClient(client_wrapper=client_wrapper) + + @property + def with_raw_response(self) -> AsyncRawMacrosClient: + """ + Retrieves a raw implementation of this client that returns raw responses. + + Returns + ------- + AsyncRawMacrosClient + """ + return self._raw_client + + async def list_macros( + self, + *, + per_page: typing.Optional[int] = None, + starting_after: typing.Optional[str] = None, + updated_since: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> MacroList: + """ + You can fetch a list of all macros (saved replies) in your workspace for use in automating responses. + + The macros are returned in descending order by updated_at. + + **Pagination** + + This endpoint uses cursor-based pagination via the `starting_after` parameter. The cursor is a Base64-encoded JSON array containing `[updated_at, id]` of the last item from the previous page. + + **Placeholder Transformation** + + The API transforms Intercom placeholders to a more standard XML-like format: + - From: `{{user.name | fallback: 'there'}}` + - To: `` + + Parameters + ---------- + per_page : typing.Optional[int] + The number of results per page + + starting_after : typing.Optional[str] + Base64-encoded cursor containing [updated_at, id] for pagination + + updated_since : typing.Optional[int] + Unix timestamp to filter macros updated after this time + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + MacroList + Successful response + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.macros.list_macros( + starting_after="WzE3MTk0OTM3NTcuMCwgIjEyMyJd", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.list_macros( + per_page=per_page, + starting_after=starting_after, + updated_since=updated_since, + request_options=request_options, + ) + return _response.data + + async def get_macro( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> typing.Optional[Macro]: + """ + You can fetch a single macro (saved reply) by its ID. The macro will only be returned if it is visible to the authenticated user based on its visibility settings. + + **Visibility Rules** + + A macro is returned based on its `visible_to` setting: + - `everyone`: Always visible to all team members + - `specific_teams`: Only visible if the authenticated user belongs to one of the teams specified in `visible_to_team_ids` + + If a macro exists but is not visible to the authenticated user, a 404 error is returned. + + **Placeholder Transformation** + + The API transforms Intercom placeholders to a more standard XML-like format in the `body` field: + - From: `{{user.name | fallback: 'there'}}` + - To: `` + + Default values in placeholders are HTML-escaped for security. + + Parameters + ---------- + id : str + The unique identifier of the macro + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + typing.Optional[Macro] + Macro found + + Examples + -------- + import asyncio + + from intercom import AsyncIntercom + + client = AsyncIntercom( + token="YOUR_TOKEN", + ) + + + async def main() -> None: + await client.unstable.macros.get_macro( + id="123", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.get_macro(id, request_options=request_options) + return _response.data diff --git a/src/intercom/unstable/macros/raw_client.py b/src/intercom/unstable/macros/raw_client.py new file mode 100644 index 0000000..72f1767 --- /dev/null +++ b/src/intercom/unstable/macros/raw_client.py @@ -0,0 +1,408 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing +from json.decoder import JSONDecodeError + +from ...core.api_error import ApiError +from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper +from ...core.http_response import AsyncHttpResponse, HttpResponse +from ...core.jsonable_encoder import jsonable_encoder +from ...core.request_options import RequestOptions +from ...core.unchecked_base_model import construct_type +from ..errors.bad_request_error import BadRequestError +from ..errors.forbidden_error import ForbiddenError +from ..errors.not_found_error import NotFoundError +from ..errors.unauthorized_error import UnauthorizedError +from ..types.error import Error +from .types.macro import Macro +from .types.macro_list import MacroList + + +class RawMacrosClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): + self._client_wrapper = client_wrapper + + def list_macros( + self, + *, + per_page: typing.Optional[int] = None, + starting_after: typing.Optional[str] = None, + updated_since: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[MacroList]: + """ + You can fetch a list of all macros (saved replies) in your workspace for use in automating responses. + + The macros are returned in descending order by updated_at. + + **Pagination** + + This endpoint uses cursor-based pagination via the `starting_after` parameter. The cursor is a Base64-encoded JSON array containing `[updated_at, id]` of the last item from the previous page. + + **Placeholder Transformation** + + The API transforms Intercom placeholders to a more standard XML-like format: + - From: `{{user.name | fallback: 'there'}}` + - To: `` + + Parameters + ---------- + per_page : typing.Optional[int] + The number of results per page + + starting_after : typing.Optional[str] + Base64-encoded cursor containing [updated_at, id] for pagination + + updated_since : typing.Optional[int] + Unix timestamp to filter macros updated after this time + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[MacroList] + Successful response + """ + _response = self._client_wrapper.httpx_client.request( + "macros", + method="GET", + params={ + "per_page": per_page, + "starting_after": starting_after, + "updated_since": updated_since, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + MacroList, + construct_type( + type_=MacroList, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + def get_macro( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[typing.Optional[Macro]]: + """ + You can fetch a single macro (saved reply) by its ID. The macro will only be returned if it is visible to the authenticated user based on its visibility settings. + + **Visibility Rules** + + A macro is returned based on its `visible_to` setting: + - `everyone`: Always visible to all team members + - `specific_teams`: Only visible if the authenticated user belongs to one of the teams specified in `visible_to_team_ids` + + If a macro exists but is not visible to the authenticated user, a 404 error is returned. + + **Placeholder Transformation** + + The API transforms Intercom placeholders to a more standard XML-like format in the `body` field: + - From: `{{user.name | fallback: 'there'}}` + - To: `` + + Default values in placeholders are HTML-escaped for security. + + Parameters + ---------- + id : str + The unique identifier of the macro + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[typing.Optional[Macro]] + Macro found + """ + _response = self._client_wrapper.httpx_client.request( + f"macros/{jsonable_encoder(id)}", + method="GET", + request_options=request_options, + ) + try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[Macro], + construct_type( + type_=typing.Optional[Macro], # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + +class AsyncRawMacrosClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): + self._client_wrapper = client_wrapper + + async def list_macros( + self, + *, + per_page: typing.Optional[int] = None, + starting_after: typing.Optional[str] = None, + updated_since: typing.Optional[int] = None, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[MacroList]: + """ + You can fetch a list of all macros (saved replies) in your workspace for use in automating responses. + + The macros are returned in descending order by updated_at. + + **Pagination** + + This endpoint uses cursor-based pagination via the `starting_after` parameter. The cursor is a Base64-encoded JSON array containing `[updated_at, id]` of the last item from the previous page. + + **Placeholder Transformation** + + The API transforms Intercom placeholders to a more standard XML-like format: + - From: `{{user.name | fallback: 'there'}}` + - To: `` + + Parameters + ---------- + per_page : typing.Optional[int] + The number of results per page + + starting_after : typing.Optional[str] + Base64-encoded cursor containing [updated_at, id] for pagination + + updated_since : typing.Optional[int] + Unix timestamp to filter macros updated after this time + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[MacroList] + Successful response + """ + _response = await self._client_wrapper.httpx_client.request( + "macros", + method="GET", + params={ + "per_page": per_page, + "starting_after": starting_after, + "updated_since": updated_since, + }, + request_options=request_options, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + MacroList, + construct_type( + type_=MacroList, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + + async def get_macro( + self, id: str, *, request_options: typing.Optional[RequestOptions] = None + ) -> AsyncHttpResponse[typing.Optional[Macro]]: + """ + You can fetch a single macro (saved reply) by its ID. The macro will only be returned if it is visible to the authenticated user based on its visibility settings. + + **Visibility Rules** + + A macro is returned based on its `visible_to` setting: + - `everyone`: Always visible to all team members + - `specific_teams`: Only visible if the authenticated user belongs to one of the teams specified in `visible_to_team_ids` + + If a macro exists but is not visible to the authenticated user, a 404 error is returned. + + **Placeholder Transformation** + + The API transforms Intercom placeholders to a more standard XML-like format in the `body` field: + - From: `{{user.name | fallback: 'there'}}` + - To: `` + + Default values in placeholders are HTML-escaped for security. + + Parameters + ---------- + id : str + The unique identifier of the macro + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[typing.Optional[Macro]] + Macro found + """ + _response = await self._client_wrapper.httpx_client.request( + f"macros/{jsonable_encoder(id)}", + method="GET", + request_options=request_options, + ) + try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) + if 200 <= _response.status_code < 300: + _data = typing.cast( + typing.Optional[Macro], + construct_type( + type_=typing.Optional[Macro], # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + Error, + construct_type( + type_=Error, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + construct_type( + type_=typing.Optional[typing.Any], # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) + raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) diff --git a/src/intercom/unstable/macros/types/__init__.py b/src/intercom/unstable/macros/types/__init__.py new file mode 100644 index 0000000..3aa8a61 --- /dev/null +++ b/src/intercom/unstable/macros/types/__init__.py @@ -0,0 +1,12 @@ +# This file was auto-generated by Fern from our API Definition. + +# isort: skip_file + +from .macro import Macro +from .macro_available_on_item import MacroAvailableOnItem +from .macro_list import MacroList +from .macro_list_pages import MacroListPages +from .macro_list_pages_next import MacroListPagesNext +from .macro_visible_to import MacroVisibleTo + +__all__ = ["Macro", "MacroAvailableOnItem", "MacroList", "MacroListPages", "MacroListPagesNext", "MacroVisibleTo"] diff --git a/src/intercom/unstable/macros/types/macro.py b/src/intercom/unstable/macros/types/macro.py new file mode 100644 index 0000000..a36f80e --- /dev/null +++ b/src/intercom/unstable/macros/types/macro.py @@ -0,0 +1,75 @@ +# This file was auto-generated by Fern from our API Definition. + +import datetime as dt +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel +from .macro_available_on_item import MacroAvailableOnItem +from .macro_visible_to import MacroVisibleTo + + +class Macro(UncheckedBaseModel): + """ + A macro is a pre-defined response template (saved reply) that can be used to quickly reply to conversations. + """ + + type: typing.Optional[typing.Literal["macro"]] = pydantic.Field(default=None) + """ + String representing the object's type. Always has the value `macro`. + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier for the macro. + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the macro. + """ + + body: typing.Optional[str] = pydantic.Field(default=None) + """ + The body of the macro in HTML format with placeholders transformed to XML-like format. + """ + + body_text: typing.Optional[str] = pydantic.Field(default=None) + """ + The plain text version of the macro body with original Intercom placeholder format. + """ + + created_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + The time the macro was created in ISO 8601 format. + """ + + updated_at: typing.Optional[dt.datetime] = pydantic.Field(default=None) + """ + The time the macro was last updated in ISO 8601 format. + """ + + visible_to: typing.Optional[MacroVisibleTo] = pydantic.Field(default=None) + """ + Who can view this macro. + """ + + visible_to_team_ids: typing.Optional[typing.List[str]] = pydantic.Field(default=None) + """ + The team IDs that can view this macro when visible_to is set to specific_teams. + """ + + available_on: typing.Optional[typing.List[MacroAvailableOnItem]] = pydantic.Field(default=None) + """ + Where the macro is available for use. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/macros/types/macro_available_on_item.py b/src/intercom/unstable/macros/types/macro_available_on_item.py new file mode 100644 index 0000000..245098a --- /dev/null +++ b/src/intercom/unstable/macros/types/macro_available_on_item.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +MacroAvailableOnItem = typing.Union[typing.Literal["inbox", "messenger"], typing.Any] diff --git a/src/intercom/unstable/macros/types/macro_list.py b/src/intercom/unstable/macros/types/macro_list.py new file mode 100644 index 0000000..b00cf24 --- /dev/null +++ b/src/intercom/unstable/macros/types/macro_list.py @@ -0,0 +1,39 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel +from .macro import Macro +from .macro_list_pages import MacroListPages + + +class MacroList(UncheckedBaseModel): + """ + A paginated list of macros (saved replies) in the workspace. + """ + + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) + """ + Always list + """ + + data: typing.Optional[typing.List[typing.Optional[Macro]]] = pydantic.Field(default=None) + """ + The list of macro objects + """ + + pages: typing.Optional[MacroListPages] = pydantic.Field(default=None) + """ + Pagination information + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/macros/types/macro_list_pages.py b/src/intercom/unstable/macros/types/macro_list_pages.py new file mode 100644 index 0000000..cf734b3 --- /dev/null +++ b/src/intercom/unstable/macros/types/macro_list_pages.py @@ -0,0 +1,38 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel +from .macro_list_pages_next import MacroListPagesNext + + +class MacroListPages(UncheckedBaseModel): + """ + Pagination information + """ + + type: typing.Optional[typing.Literal["pages"]] = pydantic.Field(default=None) + """ + The type of pagination + """ + + per_page: typing.Optional[int] = pydantic.Field(default=None) + """ + Number of results per page + """ + + next: typing.Optional[MacroListPagesNext] = pydantic.Field(default=None) + """ + Cursor for the next page + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/macros/types/macro_list_pages_next.py b/src/intercom/unstable/macros/types/macro_list_pages_next.py new file mode 100644 index 0000000..4ce6398 --- /dev/null +++ b/src/intercom/unstable/macros/types/macro_list_pages_next.py @@ -0,0 +1,27 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ....core.pydantic_utilities import IS_PYDANTIC_V2 +from ....core.unchecked_base_model import UncheckedBaseModel + + +class MacroListPagesNext(UncheckedBaseModel): + """ + Cursor for the next page + """ + + starting_after: typing.Optional[str] = pydantic.Field(default=None) + """ + Base64-encoded cursor containing [updated_at, id] for pagination + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/macros/types/macro_visible_to.py b/src/intercom/unstable/macros/types/macro_visible_to.py new file mode 100644 index 0000000..fd8477c --- /dev/null +++ b/src/intercom/unstable/macros/types/macro_visible_to.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +MacroVisibleTo = typing.Union[typing.Literal["everyone", "specific_teams"], typing.Any] diff --git a/src/intercom/unstable/types/__init__.py b/src/intercom/unstable/types/__init__.py index c9883d2..497cc3a 100644 --- a/src/intercom/unstable/types/__init__.py +++ b/src/intercom/unstable/types/__init__.py @@ -26,6 +26,7 @@ from .assign_conversation_request import AssignConversationRequest from .assign_conversation_request_type import AssignConversationRequestType from .away_status_reason import AwayStatusReason +from .call_list import CallList from .close_conversation_request import CloseConversationRequest from .collection_list import CollectionList from .company_attached_contacts import CompanyAttachedContacts @@ -82,7 +83,17 @@ from .conversation_source_type import ConversationSourceType from .conversation_statistics import ConversationStatistics from .conversation_teammates import ConversationTeammates +from .create_article_request import CreateArticleRequest +from .create_article_request_state import CreateArticleRequestState +from .create_data_attribute_request import CreateDataAttributeRequest +from .create_data_attribute_request_one import CreateDataAttributeRequestOne +from .create_data_attribute_request_one_data_type import CreateDataAttributeRequestOneDataType +from .create_data_attribute_request_options import CreateDataAttributeRequestOptions +from .create_data_attribute_request_options_options_item import CreateDataAttributeRequestOptionsOptionsItem +from .create_internal_article_request import CreateInternalArticleRequest +from .create_or_update_company_request import CreateOrUpdateCompanyRequest from .create_or_update_tag_request import CreateOrUpdateTagRequest +from .create_phone_switch_request import CreatePhoneSwitchRequest from .create_ticket_reply_with_comment_request import CreateTicketReplyWithCommentRequest from .create_ticket_request_assignment import CreateTicketRequestAssignment from .create_ticket_request_body import CreateTicketRequestBody @@ -90,6 +101,8 @@ from .create_ticket_request_contacts_item_email import CreateTicketRequestContactsItemEmail from .create_ticket_request_contacts_item_external_id import CreateTicketRequestContactsItemExternalId from .create_ticket_request_contacts_item_id import CreateTicketRequestContactsItemId +from .create_ticket_type_request import CreateTicketTypeRequest +from .create_ticket_type_request_category import CreateTicketTypeRequestCategory from .cursor_pages import CursorPages from .custom_action_finished import CustomActionFinished from .custom_action_finished_action import CustomActionFinishedAction @@ -119,6 +132,7 @@ from .deleted_article_object import DeletedArticleObject from .deleted_collection_object import DeletedCollectionObject from .deleted_company_object import DeletedCompanyObject +from .deleted_internal_article_object import DeletedInternalArticleObject from .deleted_object import DeletedObject from .email_address_header import EmailAddressHeader from .email_message_metadata import EmailMessageMetadata @@ -130,6 +144,7 @@ from .group_translated_content import GroupTranslatedContent from .intercom_version import IntercomVersion from .intercom_version_unstable import IntercomVersionUnstable +from .internal_article_list import InternalArticleList from .linked_object import LinkedObject from .linked_object_list import LinkedObjectList from .linked_object_type import LinkedObjectType @@ -205,10 +220,9 @@ from .translation import Translation from .untag_company_request import UntagCompanyRequest from .untag_company_request_companies_item import UntagCompanyRequestCompaniesItem -from .update_article_request_body import UpdateArticleRequestBody -from .update_article_request_state import UpdateArticleRequestState -from .update_ticket_type_request_body import UpdateTicketTypeRequestBody -from .update_ticket_type_request_category import UpdateTicketTypeRequestCategory +from .update_data_attribute_request_body import UpdateDataAttributeRequestBody +from .update_data_attribute_request_options import UpdateDataAttributeRequestOptions +from .update_data_attribute_request_options_options_item import UpdateDataAttributeRequestOptionsOptionsItem from .visitor import Visitor from .visitor_avatar import VisitorAvatar from .visitor_companies import VisitorCompanies @@ -249,6 +263,7 @@ "AssignConversationRequest", "AssignConversationRequestType", "AwayStatusReason", + "CallList", "CloseConversationRequest", "CollectionList", "CompanyAttachedContacts", @@ -305,7 +320,17 @@ "ConversationSourceType", "ConversationStatistics", "ConversationTeammates", + "CreateArticleRequest", + "CreateArticleRequestState", + "CreateDataAttributeRequest", + "CreateDataAttributeRequestOne", + "CreateDataAttributeRequestOneDataType", + "CreateDataAttributeRequestOptions", + "CreateDataAttributeRequestOptionsOptionsItem", + "CreateInternalArticleRequest", + "CreateOrUpdateCompanyRequest", "CreateOrUpdateTagRequest", + "CreatePhoneSwitchRequest", "CreateTicketReplyWithCommentRequest", "CreateTicketRequestAssignment", "CreateTicketRequestBody", @@ -313,6 +338,8 @@ "CreateTicketRequestContactsItemEmail", "CreateTicketRequestContactsItemExternalId", "CreateTicketRequestContactsItemId", + "CreateTicketTypeRequest", + "CreateTicketTypeRequestCategory", "CursorPages", "CustomActionFinished", "CustomActionFinishedAction", @@ -342,6 +369,7 @@ "DeletedArticleObject", "DeletedCollectionObject", "DeletedCompanyObject", + "DeletedInternalArticleObject", "DeletedObject", "EmailAddressHeader", "EmailMessageMetadata", @@ -353,6 +381,7 @@ "GroupTranslatedContent", "IntercomVersion", "IntercomVersionUnstable", + "InternalArticleList", "LinkedObject", "LinkedObjectList", "LinkedObjectType", @@ -424,10 +453,9 @@ "Translation", "UntagCompanyRequest", "UntagCompanyRequestCompaniesItem", - "UpdateArticleRequestBody", - "UpdateArticleRequestState", - "UpdateTicketTypeRequestBody", - "UpdateTicketTypeRequestCategory", + "UpdateDataAttributeRequestBody", + "UpdateDataAttributeRequestOptions", + "UpdateDataAttributeRequestOptionsOptionsItem", "Visitor", "VisitorAvatar", "VisitorCompanies", diff --git a/src/intercom/unstable/types/activity_log_activity_type.py b/src/intercom/unstable/types/activity_log_activity_type.py index 48d6405..d0fc757 100644 --- a/src/intercom/unstable/types/activity_log_activity_type.py +++ b/src/intercom/unstable/types/activity_log_activity_type.py @@ -4,7 +4,8 @@ ActivityLogActivityType = typing.Union[ typing.Literal[ - "admin_assignment_limit_change", + "admin_conversation_assignment_limit_change", + "admin_ticket_assignment_limit_change", "admin_away_mode_change", "admin_deletion", "admin_deprovisioned", diff --git a/src/intercom/unstable/types/activity_log_metadata.py b/src/intercom/unstable/types/activity_log_metadata.py index dd417f6..17aaae9 100644 --- a/src/intercom/unstable/types/activity_log_metadata.py +++ b/src/intercom/unstable/types/activity_log_metadata.py @@ -57,6 +57,16 @@ class ActivityLogMetadata(UncheckedBaseModel): The name of the Admin who initiated the activity. """ + conversation_assignment_limit: typing.Optional[int] = pydantic.Field(default=None) + """ + The conversation assignment limit value for an admin. + """ + + ticket_assignment_limit: typing.Optional[int] = pydantic.Field(default=None) + """ + The ticket assignment limit value for an admin. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/intercom/unstable/types/call_list.py b/src/intercom/unstable/types/call_list.py new file mode 100644 index 0000000..9feaa0f --- /dev/null +++ b/src/intercom/unstable/types/call_list.py @@ -0,0 +1,41 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from ..calls.types.call import Call +from .cursor_pages import CursorPages + + +class CallList(UncheckedBaseModel): + """ + A paginated list of calls. + """ + + type: typing.Optional[str] = pydantic.Field(default=None) + """ + String representing the object's type. Always has the value `list`. + """ + + data: typing.Optional[typing.List[Call]] = pydantic.Field(default=None) + """ + A list of calls. + """ + + total_count: typing.Optional[int] = pydantic.Field(default=None) + """ + Total number of items available. + """ + + pages: typing.Optional[CursorPages] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/types/conversation_rating.py b/src/intercom/unstable/types/conversation_rating.py index 4455b68..807baf2 100644 --- a/src/intercom/unstable/types/conversation_rating.py +++ b/src/intercom/unstable/types/conversation_rating.py @@ -29,6 +29,11 @@ class ConversationRating(UncheckedBaseModel): The time the rating was requested in the conversation being rated. """ + updated_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time the rating was last updated. + """ + contact: typing.Optional[ContactReference] = None teammate: typing.Optional[Reference] = None diff --git a/src/intercom/unstable/types/update_article_request_body.py b/src/intercom/unstable/types/create_article_request.py similarity index 82% rename from src/intercom/unstable/types/update_article_request_body.py rename to src/intercom/unstable/types/create_article_request.py index 504e124..067205b 100644 --- a/src/intercom/unstable/types/update_article_request_body.py +++ b/src/intercom/unstable/types/create_article_request.py @@ -6,15 +6,15 @@ from ...core.pydantic_utilities import IS_PYDANTIC_V2 from ...core.unchecked_base_model import UncheckedBaseModel from .article_translated_content import ArticleTranslatedContent -from .update_article_request_state import UpdateArticleRequestState +from .create_article_request_state import CreateArticleRequestState -class UpdateArticleRequestBody(UncheckedBaseModel): +class CreateArticleRequest(UncheckedBaseModel): """ - You can Update an Article + You can create an Article """ - title: typing.Optional[str] = pydantic.Field(default=None) + title: str = pydantic.Field() """ The title of the article.For multilingual articles, this will be the title of the default language's content. """ @@ -29,17 +29,17 @@ class UpdateArticleRequestBody(UncheckedBaseModel): The content of the article. For multilingual articles, this will be the body of the default language's content. """ - author_id: typing.Optional[int] = pydantic.Field(default=None) + author_id: int = pydantic.Field() """ The id of the author of the article. For multilingual articles, this will be the id of the author of the default language's content. Must be a teammate on the help center's workspace. """ - state: typing.Optional[UpdateArticleRequestState] = pydantic.Field(default=None) + state: typing.Optional[CreateArticleRequestState] = pydantic.Field(default=None) """ Whether the article will be `published` or will be a `draft`. Defaults to draft. For multilingual articles, this will be the state of the default language's content. """ - parent_id: typing.Optional[str] = pydantic.Field(default=None) + parent_id: typing.Optional[int] = pydantic.Field(default=None) """ The id of the article's parent collection or section. An article without this field stands alone. """ diff --git a/src/intercom/unstable/types/create_article_request_state.py b/src/intercom/unstable/types/create_article_request_state.py new file mode 100644 index 0000000..2b13f57 --- /dev/null +++ b/src/intercom/unstable/types/create_article_request_state.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateArticleRequestState = typing.Union[typing.Literal["published", "draft"], typing.Any] diff --git a/src/intercom/unstable/types/create_data_attribute_request.py b/src/intercom/unstable/types/create_data_attribute_request.py new file mode 100644 index 0000000..cd76eee --- /dev/null +++ b/src/intercom/unstable/types/create_data_attribute_request.py @@ -0,0 +1,8 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .create_data_attribute_request_one import CreateDataAttributeRequestOne +from .create_data_attribute_request_options import CreateDataAttributeRequestOptions + +CreateDataAttributeRequest = typing.Union[CreateDataAttributeRequestOptions, CreateDataAttributeRequestOne] diff --git a/src/intercom/unstable/types/create_data_attribute_request_one.py b/src/intercom/unstable/types/create_data_attribute_request_one.py new file mode 100644 index 0000000..9733ced --- /dev/null +++ b/src/intercom/unstable/types/create_data_attribute_request_one.py @@ -0,0 +1,21 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .create_data_attribute_request_one_data_type import CreateDataAttributeRequestOneDataType + + +class CreateDataAttributeRequestOne(UncheckedBaseModel): + data_type: typing.Optional[CreateDataAttributeRequestOneDataType] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/data_attributes/types/create_data_attribute_request_data_type.py b/src/intercom/unstable/types/create_data_attribute_request_one_data_type.py similarity index 76% rename from src/intercom/unstable/data_attributes/types/create_data_attribute_request_data_type.py rename to src/intercom/unstable/types/create_data_attribute_request_one_data_type.py index c2471b7..0689e73 100644 --- a/src/intercom/unstable/data_attributes/types/create_data_attribute_request_data_type.py +++ b/src/intercom/unstable/types/create_data_attribute_request_one_data_type.py @@ -2,6 +2,6 @@ import typing -CreateDataAttributeRequestDataType = typing.Union[ +CreateDataAttributeRequestOneDataType = typing.Union[ typing.Literal["string", "integer", "float", "boolean", "datetime", "date"], typing.Any ] diff --git a/src/intercom/unstable/types/create_data_attribute_request_options.py b/src/intercom/unstable/types/create_data_attribute_request_options.py new file mode 100644 index 0000000..fb2bcf9 --- /dev/null +++ b/src/intercom/unstable/types/create_data_attribute_request_options.py @@ -0,0 +1,25 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .create_data_attribute_request_options_options_item import CreateDataAttributeRequestOptionsOptionsItem + + +class CreateDataAttributeRequestOptions(UncheckedBaseModel): + data_type: typing.Optional[typing.Literal["options"]] = None + options: typing.List[CreateDataAttributeRequestOptionsOptionsItem] = pydantic.Field() + """ + Array of objects representing the options of the list, with `value` as the key and the option as the value. At least two options are required. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/data_attributes/types/update_data_attribute_request_options_item.py b/src/intercom/unstable/types/create_data_attribute_request_options_options_item.py similarity index 82% rename from src/intercom/data_attributes/types/update_data_attribute_request_options_item.py rename to src/intercom/unstable/types/create_data_attribute_request_options_options_item.py index 1b3cfe8..018f7f6 100644 --- a/src/intercom/data_attributes/types/update_data_attribute_request_options_item.py +++ b/src/intercom/unstable/types/create_data_attribute_request_options_options_item.py @@ -7,8 +7,8 @@ from ...core.unchecked_base_model import UncheckedBaseModel -class UpdateDataAttributeRequestOptionsItem(UncheckedBaseModel): - value: str +class CreateDataAttributeRequestOptionsOptionsItem(UncheckedBaseModel): + value: typing.Optional[str] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/intercom/unstable/types/create_internal_article_request.py b/src/intercom/unstable/types/create_internal_article_request.py new file mode 100644 index 0000000..c7710e4 --- /dev/null +++ b/src/intercom/unstable/types/create_internal_article_request.py @@ -0,0 +1,42 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class CreateInternalArticleRequest(UncheckedBaseModel): + """ + You can create an Internal Article + """ + + title: str = pydantic.Field() + """ + The title of the article. + """ + + body: typing.Optional[str] = pydantic.Field(default=None) + """ + The content of the article. + """ + + author_id: int = pydantic.Field() + """ + The id of the author of the article. + """ + + owner_id: int = pydantic.Field() + """ + The id of the owner of the article. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/types/create_or_update_company_request.py b/src/intercom/unstable/types/create_or_update_company_request.py new file mode 100644 index 0000000..b2b278f --- /dev/null +++ b/src/intercom/unstable/types/create_or_update_company_request.py @@ -0,0 +1,67 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class CreateOrUpdateCompanyRequest(UncheckedBaseModel): + """ + You can create or update a Company + """ + + name: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the Company + """ + + company_id: typing.Optional[str] = pydantic.Field(default=None) + """ + The company id you have defined for the company. Can't be updated + """ + + plan: typing.Optional[str] = pydantic.Field(default=None) + """ + The name of the plan you have associated with the company. + """ + + size: typing.Optional[int] = pydantic.Field(default=None) + """ + The number of employees in this company. + """ + + website: typing.Optional[str] = pydantic.Field(default=None) + """ + The URL for this company's website. Please note that the value specified here is not validated. Accepts any string. + """ + + industry: typing.Optional[str] = pydantic.Field(default=None) + """ + The industry that this company operates in. + """ + + custom_attributes: typing.Optional[typing.Dict[str, str]] = pydantic.Field(default=None) + """ + A hash of key/value pairs containing any other data about the company you want Intercom to store. + """ + + remote_created_at: typing.Optional[int] = pydantic.Field(default=None) + """ + The time the company was created by you. + """ + + monthly_spend: typing.Optional[int] = pydantic.Field(default=None) + """ + How much revenue the company generates for your business. Note that this will truncate floats. i.e. it only allow for whole integers, 155.98 will be truncated to 155. Note that this has an upper limit of 2**31-1 or 2147483647.. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/types/create_phone_switch_request.py b/src/intercom/unstable/types/create_phone_switch_request.py new file mode 100644 index 0000000..902e5d0 --- /dev/null +++ b/src/intercom/unstable/types/create_phone_switch_request.py @@ -0,0 +1,30 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .custom_attributes import CustomAttributes + + +class CreatePhoneSwitchRequest(UncheckedBaseModel): + """ + You can create an phone switch + """ + + phone: str = pydantic.Field() + """ + Phone number in E.164 format, that will receive the SMS to continue the conversation in the Messenger. + """ + + custom_attributes: typing.Optional[CustomAttributes] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/types/update_ticket_type_request_body.py b/src/intercom/unstable/types/create_ticket_type_request.py similarity index 67% rename from src/intercom/unstable/types/update_ticket_type_request_body.py rename to src/intercom/unstable/types/create_ticket_type_request.py index 69b7dbb..59105ab 100644 --- a/src/intercom/unstable/types/update_ticket_type_request_body.py +++ b/src/intercom/unstable/types/create_ticket_type_request.py @@ -5,16 +5,16 @@ import pydantic from ...core.pydantic_utilities import IS_PYDANTIC_V2 from ...core.unchecked_base_model import UncheckedBaseModel -from .update_ticket_type_request_category import UpdateTicketTypeRequestCategory +from .create_ticket_type_request_category import CreateTicketTypeRequestCategory -class UpdateTicketTypeRequestBody(UncheckedBaseModel): +class CreateTicketTypeRequest(UncheckedBaseModel): """ - The request payload for updating a ticket type. - You can copy the `icon` property for your ticket type from [Twemoji Cheatsheet](https://twemoji-cheatsheet.vercel.app/) + The request payload for creating a ticket type. + You can copy the `icon` property for your ticket type from [Twemoji Cheatsheet](https://twemoji-cheatsheet.vercel.app/) """ - name: typing.Optional[str] = pydantic.Field(default=None) + name: str = pydantic.Field() """ The name of the ticket type. """ @@ -24,7 +24,7 @@ class UpdateTicketTypeRequestBody(UncheckedBaseModel): The description of the ticket type. """ - category: typing.Optional[UpdateTicketTypeRequestCategory] = pydantic.Field(default=None) + category: typing.Optional[CreateTicketTypeRequestCategory] = pydantic.Field(default=None) """ Category of the Ticket Type. """ @@ -34,11 +34,6 @@ class UpdateTicketTypeRequestBody(UncheckedBaseModel): The icon of the ticket type. """ - archived: typing.Optional[bool] = pydantic.Field(default=None) - """ - The archived status of the ticket type. - """ - is_internal: typing.Optional[bool] = pydantic.Field(default=None) """ Whether the tickets associated with this ticket type are intended for internal use only or will be shared with customers. This is currently a limited attribute. diff --git a/src/intercom/unstable/types/create_ticket_type_request_category.py b/src/intercom/unstable/types/create_ticket_type_request_category.py new file mode 100644 index 0000000..be7783a --- /dev/null +++ b/src/intercom/unstable/types/create_ticket_type_request_category.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +CreateTicketTypeRequestCategory = typing.Union[typing.Literal["Customer", "Back-office", "Tracker"], typing.Any] diff --git a/src/intercom/unstable/types/deleted_internal_article_object.py b/src/intercom/unstable/types/deleted_internal_article_object.py new file mode 100644 index 0000000..3aeb4c3 --- /dev/null +++ b/src/intercom/unstable/types/deleted_internal_article_object.py @@ -0,0 +1,37 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class DeletedInternalArticleObject(UncheckedBaseModel): + """ + Response returned when an object is deleted + """ + + id: typing.Optional[str] = pydantic.Field(default=None) + """ + The unique identifier for the internal article which you provided in the URL. + """ + + object: typing.Optional[typing.Literal["internal_article"]] = pydantic.Field(default=None) + """ + The type of object which was deleted. - internal_article + """ + + deleted: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the internal article was deleted successfully or not. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/types/intercom_version.py b/src/intercom/unstable/types/intercom_version.py index 85214bf..fb77e59 100644 --- a/src/intercom/unstable/types/intercom_version.py +++ b/src/intercom/unstable/types/intercom_version.py @@ -21,6 +21,9 @@ "2.9", "2.10", "2.11", + "2.12", + "2.13", + "2.14", "Unstable", ], typing.Any, diff --git a/src/intercom/unstable/types/internal_article_list.py b/src/intercom/unstable/types/internal_article_list.py new file mode 100644 index 0000000..930fbf9 --- /dev/null +++ b/src/intercom/unstable/types/internal_article_list.py @@ -0,0 +1,40 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from ..internal_articles.types.internal_article_list_item import InternalArticleListItem +from .cursor_pages import CursorPages + + +class InternalArticleList(UncheckedBaseModel): + """ + This will return a list of internal articles for the App. + """ + + type: typing.Optional[typing.Literal["list"]] = pydantic.Field(default=None) + """ + The type of the object - `list`. + """ + + pages: typing.Optional[CursorPages] = None + total_count: typing.Optional[int] = pydantic.Field(default=None) + """ + A count of the total number of internal articles. + """ + + data: typing.Optional[typing.List[InternalArticleListItem]] = pydantic.Field(default=None) + """ + An array of Internal Article objects + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/types/update_data_attribute_request_body.py b/src/intercom/unstable/types/update_data_attribute_request_body.py new file mode 100644 index 0000000..c2e56ce --- /dev/null +++ b/src/intercom/unstable/types/update_data_attribute_request_body.py @@ -0,0 +1,7 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +from .update_data_attribute_request_options import UpdateDataAttributeRequestOptions + +UpdateDataAttributeRequestBody = typing.Union[UpdateDataAttributeRequestOptions, typing.Optional[typing.Any]] diff --git a/src/intercom/unstable/types/update_data_attribute_request_options.py b/src/intercom/unstable/types/update_data_attribute_request_options.py new file mode 100644 index 0000000..e74a340 --- /dev/null +++ b/src/intercom/unstable/types/update_data_attribute_request_options.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel +from .update_data_attribute_request_options_options_item import UpdateDataAttributeRequestOptionsOptionsItem + + +class UpdateDataAttributeRequestOptions(UncheckedBaseModel): + options: typing.List[UpdateDataAttributeRequestOptionsOptionsItem] = pydantic.Field() + """ + Array of objects representing the options of the list, with `value` as the key and the option as the value. At least two options are required. + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/unstable/types/update_data_attribute_request_options_options_item.py b/src/intercom/unstable/types/update_data_attribute_request_options_options_item.py new file mode 100644 index 0000000..3033676 --- /dev/null +++ b/src/intercom/unstable/types/update_data_attribute_request_options_options_item.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2 +from ...core.unchecked_base_model import UncheckedBaseModel + + +class UpdateDataAttributeRequestOptionsOptionsItem(UncheckedBaseModel): + value: typing.Optional[str] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/intercom/visitors/client.py b/src/intercom/visitors/client.py index aca44b6..5ae6c04 100644 --- a/src/intercom/visitors/client.py +++ b/src/intercom/visitors/client.py @@ -30,7 +30,9 @@ def with_raw_response(self) -> RawVisitorsClient: """ return self._raw_client - def find(self, *, user_id: str, request_options: typing.Optional[RequestOptions] = None) -> Visitor: + def find( + self, *, user_id: str, request_options: typing.Optional[RequestOptions] = None + ) -> typing.Optional[Visitor]: """ You can fetch the details of a single visitor. @@ -44,7 +46,7 @@ def find(self, *, user_id: str, request_options: typing.Optional[RequestOptions] Returns ------- - Visitor + typing.Optional[Visitor] successful Examples @@ -63,7 +65,7 @@ def find(self, *, user_id: str, request_options: typing.Optional[RequestOptions] def update( self, *, request: UpdateVisitorRequest, request_options: typing.Optional[RequestOptions] = None - ) -> Visitor: + ) -> typing.Optional[Visitor]: """ Sending a PUT request to `/visitors` will result in an update of an existing Visitor. @@ -80,7 +82,7 @@ def update( Returns ------- - Visitor + typing.Optional[Visitor] successful Examples @@ -92,7 +94,7 @@ def update( ) client.visitors.update( request=UpdateVisitorRequestWithId( - id="667d61cc8a68186f43bafe95", + id="6762f30c1bb69f9f2193bc5e", name="Gareth Bale", ), ) @@ -174,7 +176,9 @@ def with_raw_response(self) -> AsyncRawVisitorsClient: """ return self._raw_client - async def find(self, *, user_id: str, request_options: typing.Optional[RequestOptions] = None) -> Visitor: + async def find( + self, *, user_id: str, request_options: typing.Optional[RequestOptions] = None + ) -> typing.Optional[Visitor]: """ You can fetch the details of a single visitor. @@ -188,7 +192,7 @@ async def find(self, *, user_id: str, request_options: typing.Optional[RequestOp Returns ------- - Visitor + typing.Optional[Visitor] successful Examples @@ -215,7 +219,7 @@ async def main() -> None: async def update( self, *, request: UpdateVisitorRequest, request_options: typing.Optional[RequestOptions] = None - ) -> Visitor: + ) -> typing.Optional[Visitor]: """ Sending a PUT request to `/visitors` will result in an update of an existing Visitor. @@ -232,7 +236,7 @@ async def update( Returns ------- - Visitor + typing.Optional[Visitor] successful Examples @@ -249,7 +253,7 @@ async def update( async def main() -> None: await client.visitors.update( request=UpdateVisitorRequestWithId( - id="667d61cc8a68186f43bafe95", + id="6762f30c1bb69f9f2193bc5e", name="Gareth Bale", ), ) diff --git a/src/intercom/visitors/raw_client.py b/src/intercom/visitors/raw_client.py index 03a4bd0..4181d53 100644 --- a/src/intercom/visitors/raw_client.py +++ b/src/intercom/visitors/raw_client.py @@ -26,7 +26,9 @@ class RawVisitorsClient: def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper - def find(self, *, user_id: str, request_options: typing.Optional[RequestOptions] = None) -> HttpResponse[Visitor]: + def find( + self, *, user_id: str, request_options: typing.Optional[RequestOptions] = None + ) -> HttpResponse[typing.Optional[Visitor]]: """ You can fetch the details of a single visitor. @@ -40,7 +42,7 @@ def find(self, *, user_id: str, request_options: typing.Optional[RequestOptions] Returns ------- - HttpResponse[Visitor] + HttpResponse[typing.Optional[Visitor]] successful """ _response = self._client_wrapper.httpx_client.request( @@ -52,11 +54,13 @@ def find(self, *, user_id: str, request_options: typing.Optional[RequestOptions] request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Visitor, + typing.Optional[Visitor], construct_type( - type_=Visitor, # type: ignore + type_=typing.Optional[Visitor], # type: ignore object_=_response.json(), ), ) @@ -90,7 +94,7 @@ def find(self, *, user_id: str, request_options: typing.Optional[RequestOptions] def update( self, *, request: UpdateVisitorRequest, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[Visitor]: + ) -> HttpResponse[typing.Optional[Visitor]]: """ Sending a PUT request to `/visitors` will result in an update of an existing Visitor. @@ -107,7 +111,7 @@ def update( Returns ------- - HttpResponse[Visitor] + HttpResponse[typing.Optional[Visitor]] successful """ _response = self._client_wrapper.httpx_client.request( @@ -123,11 +127,13 @@ def update( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return HttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Visitor, + typing.Optional[Visitor], construct_type( - type_=Visitor, # type: ignore + type_=typing.Optional[Visitor], # type: ignore object_=_response.json(), ), ) @@ -244,7 +250,7 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): async def find( self, *, user_id: str, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[Visitor]: + ) -> AsyncHttpResponse[typing.Optional[Visitor]]: """ You can fetch the details of a single visitor. @@ -258,7 +264,7 @@ async def find( Returns ------- - AsyncHttpResponse[Visitor] + AsyncHttpResponse[typing.Optional[Visitor]] successful """ _response = await self._client_wrapper.httpx_client.request( @@ -270,11 +276,13 @@ async def find( request_options=request_options, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Visitor, + typing.Optional[Visitor], construct_type( - type_=Visitor, # type: ignore + type_=typing.Optional[Visitor], # type: ignore object_=_response.json(), ), ) @@ -308,7 +316,7 @@ async def find( async def update( self, *, request: UpdateVisitorRequest, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[Visitor]: + ) -> AsyncHttpResponse[typing.Optional[Visitor]]: """ Sending a PUT request to `/visitors` will result in an update of an existing Visitor. @@ -325,7 +333,7 @@ async def update( Returns ------- - AsyncHttpResponse[Visitor] + AsyncHttpResponse[typing.Optional[Visitor]] successful """ _response = await self._client_wrapper.httpx_client.request( @@ -341,11 +349,13 @@ async def update( omit=OMIT, ) try: + if _response is None or not _response.text.strip(): + return AsyncHttpResponse(response=_response, data=None) if 200 <= _response.status_code < 300: _data = typing.cast( - Visitor, + typing.Optional[Visitor], construct_type( - type_=Visitor, # type: ignore + type_=typing.Optional[Visitor], # type: ignore object_=_response.json(), ), )