Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 52 additions & 1 deletion src/gradient_labs/_conversation_start.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Optional, Dict, Any
from typing import Optional, Dict, Any, List
from datetime import datetime
from enum import Enum

from dataclasses import dataclass
from dataclasses_json import dataclass_json
Expand All @@ -8,6 +9,45 @@
from .conversation import ParticipantType, ConversationChannel, Conversation


class SupportPlatform(str, Enum):
"""Identifies a third-party customer support platform that a customer
can be linked to via a CustomerSupportPlatformIdentifier."""

INTERCOM: str = "intercom"
ZENDESK: str = "zendesk"
SALESFORCE: str = "salesforce"
FRESHCHAT: str = "freshchat"
FRESHDESK: str = "freshdesk"


class CustomerSupportPlatformIdentifierType(str, Enum):
"""Identifies the kind of identifier within a customer support platform,
for platforms that have more than one kind of identifier."""

INTERCOM_LEAD: str = "intercom_lead"
INTERCOM_USER: str = "intercom_user"
ZENDESK_CONVERSATION_USER: str = "zendesk_conversation_user"
ZENDESK_SUPPORT_USER: str = "zendesk_support_user"
SALESFORCE_CONTACT_ID: str = "salesforce_contact_id"
SALESFORCE_ACCOUNT_ID: str = "salesforce_account_id"


@dataclass_json
@dataclass(frozen=True)
class CustomerSupportPlatformIdentifier:
# support_platform identifies the third-party customer support platform
# this identifier belongs to.
support_platform: SupportPlatform

# value is the customer's external identifier in that platform.
value: str

# type optionally identifies which kind of identifier this is, for platforms
# that have more than one kind (e.g. Intercom leads vs. users). Omit for
# platforms that only have a single identifier kind (freshchat, freshdesk).
type: Optional[CustomerSupportPlatformIdentifierType] = None


@dataclass_json
@dataclass(frozen=True)
class StartConversationParams:
Expand Down Expand Up @@ -52,6 +92,13 @@ class StartConversationParams:
# assigned to the specified traffic group, plus any procedures not assigned to any group.
traffic_group_id: Optional[str] = None

# customer_support_platform_identifiers optionally links the customer to their
# record(s) in third-party customer support platforms (e.g. Intercom, Zendesk),
# alongside customer_id.
customer_support_platform_identifiers: Optional[
List[CustomerSupportPlatformIdentifier]
] = None


def start_conversation(
*, client: HttpClient, params: StartConversationParams
Expand All @@ -69,6 +116,10 @@ def start_conversation(
body["conversation_token"] = params.conversation_token
if params.traffic_group_id is not None:
body["traffic_group_id"] = params.traffic_group_id
if params.customer_support_platform_identifiers is not None:
body["customer_support_platform_identifiers"] = [
i.to_dict() for i in params.customer_support_platform_identifiers
]

rsp = client.post(
path="conversations",
Expand Down
8 changes: 7 additions & 1 deletion src/gradient_labs/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@
from ._conversation_rate import rate_conversation, RatingParams
from ._conversation_resume import resume_conversation, ResumeParams
from ._conversation_read import read_conversation, ReadParams
from ._conversation_start import start_conversation, StartConversationParams
from ._conversation_start import (
start_conversation,
StartConversationParams,
SupportPlatform as SupportPlatform,
CustomerSupportPlatformIdentifier as CustomerSupportPlatformIdentifier,
CustomerSupportPlatformIdentifierType as CustomerSupportPlatformIdentifierType,
)
from ._conversation_return_async_tool_result import (
return_async_tool_result,
ReturnAsyncToolResultParams,
Expand Down
85 changes: 85 additions & 0 deletions tests/test_conversation_start.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from unittest.mock import MagicMock

from gradient_labs import (
Client,
Conversation,
ConversationChannel,
CustomerSupportPlatformIdentifier,
CustomerSupportPlatformIdentifierType,
StartConversationParams,
SupportPlatform,
)


def _client_returning(response: dict):
client = Client(api_key="test-key")
post = MagicMock(return_value=response)
client.http_client.post = post
return client, post


def _conversation_response() -> dict:
return {
"id": "conv-123",
"customer_id": "cust-456",
"channel": "web",
"status": "active",
"created": "2024-01-15T10:30:00",
"updated": "2024-01-15T10:30:00",
}


def test_start_conversation():
client, post = _client_returning(_conversation_response())

conversation = client.start_conversation(
params=StartConversationParams(
id="conv-123",
customer_id="cust-456",
channel=ConversationChannel.LIVE_CHAT,
)
)

_, kwargs = post.call_args
body = kwargs["body"]
assert kwargs["path"] == "conversations"
assert body["id"] == "conv-123"
assert body["customer_id"] == "cust-456"
assert body["channel"] == "web"
assert "customer_support_platform_identifiers" not in body

assert isinstance(conversation, Conversation)
assert conversation.id == "conv-123"


def test_start_conversation_includes_customer_support_platform_identifiers():
client, post = _client_returning(_conversation_response())

client.start_conversation(
params=StartConversationParams(
id="conv-123",
customer_id="cust-456",
channel=ConversationChannel.LIVE_CHAT,
customer_support_platform_identifiers=[
CustomerSupportPlatformIdentifier(
support_platform=SupportPlatform.INTERCOM,
type=CustomerSupportPlatformIdentifierType.INTERCOM_USER,
value="6953e162a988d9ef0f73ef9b",
),
CustomerSupportPlatformIdentifier(
support_platform=SupportPlatform.FRESHDESK,
value="fd-789",
),
],
)
)

_, kwargs = post.call_args
body = kwargs["body"]
identifiers = body["customer_support_platform_identifiers"]
assert identifiers[0]["support_platform"] == "intercom"
assert identifiers[0]["type"] == "intercom_user"
assert identifiers[0]["value"] == "6953e162a988d9ef0f73ef9b"
assert identifiers[1]["support_platform"] == "freshdesk"
assert identifiers[1]["type"] is None
assert identifiers[1]["value"] == "fd-789"
Loading