crm-integration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
<objective> Integrate with CRM platforms for sales automation workflows:
  1. Close CRM - Daily driver for SMB sales (simplest API, best value)
  2. HubSpot - Marketing + Sales alignment with rich ecosystem
  3. Salesforce - Enterprise requirements and complex workflows
  4. Cross-CRM Sync - Bidirectional sync with conflict resolution
Key deliverables:
  • API client setup with proper authentication
  • CRUD operations for leads, contacts, deals, activities
  • Webhook handlers for real-time sync
  • Pipeline automation and reporting </objective>
<quick_start> Close CRM (API Key Auth):
python
import httpx

class CloseClient:
    BASE_URL = "https://api.close.com/api/v1"

    def __init__(self, api_key: str):
        self.client = httpx.Client(
            base_url=self.BASE_URL,
            auth=(api_key, ""),  # Basic auth, password empty
            timeout=30.0,
        )

    def create_lead(self, data: dict) -> dict:
        response = self.client.post("/lead/", json=data)
        response.raise_for_status()
        return response.json()

    def search_leads(self, query: str) -> list:
        response = self.client.post("/data/search/", json={
            "query": {"type": "query_string", "value": query},
            "results_limit": 100
        })
        return response.json()["data"]
<目标> 与CRM平台集成以实现销售自动化工作流:
  1. Close CRM - 中小企业销售的日常工具(API最简单,性价比最高)
  2. HubSpot - 营销与销售协同的丰富生态系统
  3. Salesforce - 满足企业级需求与复杂工作流
  4. 跨CRM同步 - 带冲突解决的双向同步
核心交付成果:
  • 配置正确认证的API客户端
  • 线索、联系人、交易、活动的CRUD操作
  • 实时同步的Webhook处理器
  • 销售流程自动化与报表功能 </目标>
<快速开始> Close CRM(API密钥认证):
python
import httpx

class CloseClient:
    BASE_URL = "https://api.close.com/api/v1"

    def __init__(self, api_key: str):
        self.client = httpx.Client(
            base_url=self.BASE_URL,
            auth=(api_key, ""),  # Basic auth, password empty
            timeout=30.0,
        )

    def create_lead(self, data: dict) -> dict:
        response = self.client.post("/lead/", json=data)
        response.raise_for_status()
        return response.json()

    def search_leads(self, query: str) -> list:
        response = self.client.post("/data/search/", json={
            "query": {"type": "query_string", "value": query},
            "results_limit": 100
        })
        return response.json()["data"]

Usage

Usage

close = CloseClient(os.environ["CLOSE_API_KEY"]) leads = close.search_leads("company:Coperniq")

**HubSpot (Python SDK):**
```python
from hubspot import HubSpot
from hubspot.crm.contacts import SimplePublicObjectInputForCreate

client = HubSpot(access_token=os.environ["HUBSPOT_ACCESS_TOKEN"])
close = CloseClient(os.environ["CLOSE_API_KEY"]) leads = close.search_leads("company:Coperniq")

**HubSpot(Python SDK):**
```python
from hubspot import HubSpot
from hubspot.crm.contacts import SimplePublicObjectInputForCreate

client = HubSpot(access_token=os.environ["HUBSPOT_ACCESS_TOKEN"])

Create contact

Create contact

contact = client.crm.contacts.basic_api.create( SimplePublicObjectInputForCreate(properties={ "email": "user@example.com", "firstname": "Jane", "lastname": "Smith" }) ) print(f"Created: {contact.id}")

**Salesforce (JWT Bearer):**
```python
import jwt
from datetime import datetime, timedelta

class SalesforceClient:
    def __init__(self, client_id: str, username: str, private_key: str):
        self.auth_url = "https://login.salesforce.com"
        self._authenticate(client_id, username, private_key)

    def _authenticate(self, client_id, username, private_key):
        payload = {
            "iss": client_id,
            "sub": username,
            "aud": self.auth_url,
            "exp": int((datetime.utcnow() + timedelta(minutes=3)).timestamp())
        }
        assertion = jwt.encode(payload, private_key, algorithm="RS256")

        response = httpx.post(f"{self.auth_url}/services/oauth2/token", data={
            "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
            "assertion": assertion
        })
        self.access_token = response.json()["access_token"]
        self.instance_url = response.json()["instance_url"]
</quick_start>
<success_criteria> A CRM integration is successful when:
  • API authentication works without errors
  • CRUD operations complete for all entity types
  • Rate limits are respected (Close: 100 req/10s, HubSpot: varies by tier)
  • Webhooks fire and process correctly
  • Data syncs bidirectionally without duplicates </success_criteria>
<crm_comparison>
contact = client.crm.contacts.basic_api.create( SimplePublicObjectInputForCreate(properties={ "email": "user@example.com", "firstname": "Jane", "lastname": "Smith" }) ) print(f"Created: {contact.id}")

**Salesforce(JWT Bearer认证):**
```python
import jwt
from datetime import datetime, timedelta

class SalesforceClient:
    def __init__(self, client_id: str, username: str, private_key: str):
        self.auth_url = "https://login.salesforce.com"
        self._authenticate(client_id, username, private_key)

    def _authenticate(self, client_id, username, private_key):
        payload = {
            "iss": client_id,
            "sub": username,
            "aud": self.auth_url,
            "exp": int((datetime.utcnow() + timedelta(minutes=3)).timestamp())
        }
        assertion = jwt.encode(payload, private_key, algorithm="RS256")

        response = httpx.post(f"{self.auth_url}/services/oauth2/token", data={
            "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
            "assertion": assertion
        })
        self.access_token = response.json()["access_token"]
        self.instance_url = response.json()["instance_url"]
</快速开始>
<成功标准> CRM集成成功的标志:
  • API认证无错误
  • 所有实体类型的CRUD操作可完成
  • 遵守请求频率限制(Close:10秒100次请求,HubSpot:根据套餐层级不同)
  • Webhook可正常触发并处理
  • 数据可双向同步且无重复 </成功标准>
<CRM平台对比>

Platform Comparison

平台对比

FeatureCloseHubSpotSalesforce
AuthAPI KeyOAuth 2.0 / Private AppJWT Bearer
Rate Limit100 req/10s100-200 req/10s by tier100k req/day
Best ForSMB sales, simplicityMarketing + SalesEnterprise
Starting Price$49/user/moFree (limited)$25/user/mo
API AccessAll plansStarter+ ($45+)All plans
WebhooksAll plansPro+ ($800+)All plans
功能CloseHubSpotSalesforce
认证方式API密钥OAuth 2.0 / 私有应用JWT Bearer
请求频率限制10秒100次请求10秒100-200次请求(依套餐而定)每日10万次请求
最佳适用场景中小企业销售、追求简洁营销与销售协同企业级应用
起始价格49美元/用户/月免费版(功能有限)25美元/用户/月
API访问权限所有套餐入门版及以上(45美元起)所有套餐
Webhook支持所有套餐专业版及以上(800美元起)所有套餐

Entity Mapping

实体映射

ConceptCloseHubSpotSalesforce
Company
lead
company
Account
Person
contact
contact
Contact
/
Lead
Deal
opportunity
deal
Opportunity
Activity
activity
engagement
Task
/
Event
Custom Field
custom.cf_xxx
properties
Field__c
概念CloseHubSpotSalesforce
公司
lead
company
Account
联系人
contact
contact
Contact
/
Lead
交易
opportunity
deal
Opportunity
活动
activity
engagement
Task
/
Event
自定义字段
custom.cf_xxx
properties
Field__c

Pipeline Stage Mapping

销售流程阶段映射

StageCloseHubSpotSalesforce
New
Lead
appointmentscheduled
Prospecting
Qualified
Contacted
qualifiedtobuy
Qualification
Demo
Opportunity
presentationscheduled
Needs Analysis
Proposal
Proposal
decisionmakerboughtin
Proposal/Price Quote
Won
Won
closedwon
Closed Won
Lost
Lost
closedlost
Closed Lost
</crm_comparison>
<close_patterns>
阶段CloseHubSpotSalesforce
新线索
Lead
appointmentscheduled
Prospecting
已筛选
Contacted
qualifiedtobuy
Qualification
演示阶段
Opportunity
presentationscheduled
Needs Analysis
提案阶段
Proposal
decisionmakerboughtin
Proposal/Price Quote
已成交
Won
closedwon
Closed Won
已丢失
Lost
closedlost
Closed Lost
</CRM平台对比>
<Close CRM集成模式>

Close CRM (Daily Driver)

Close CRM(日常工具)

Query Language (for Smart Views)

查询语言(用于智能视图)

python
undefined
python
undefined

Leads with no activity in 30 days

Leads with no activity in 30 days

'sort:date_updated asc date_updated < "30 days ago"'
'sort:date_updated asc date_updated < "30 days ago"'

High-value opportunities

High-value opportunities

'opportunities.value >= 50000 opportunities.status_type:active'
'opportunities.value >= 50000 opportunities.status_type:active'

Custom field filtering

Custom field filtering

'custom.cf_industry = "MEP Contractor"'
'custom.cf_industry = "MEP Contractor"'

Multiple trade types (your ICP)

Multiple trade types (your ICP)

'custom.cf_trades:HVAC OR custom.cf_trades:Electrical'
undefined
'custom.cf_trades:HVAC OR custom.cf_trades:Electrical'
undefined

Core Operations

核心操作

python
undefined
python
undefined

Create lead with contacts

Create lead with contacts

lead = close.create_lead({ "name": "ABC Mechanical", "url": "https://abcmech.com", "contacts": [{ "name": "John Smith", "title": "Owner", "emails": [{"email": "john@abcmech.com", "type": "office"}], "phones": [{"phone": "555-1234", "type": "office"}] }], "custom.cf_tier": "Gold", "custom.cf_source": "sales-agent" })
lead = close.create_lead({ "name": "ABC Mechanical", "url": "https://abcmech.com", "contacts": [{ "name": "John Smith", "title": "Owner", "emails": [{"email": "john@abcmech.com", "type": "office"}], "phones": [{"phone": "555-1234", "type": "office"}] }], "custom.cf_tier": "Gold", "custom.cf_source": "sales-agent" })

Create opportunity

Create opportunity

opp = close._request("POST", "/opportunity/", json={ "lead_id": lead["id"], "value": 50000, "confidence": 50, "status_id": "stat_xxx" # Pipeline stage })
opp = close._request("POST", "/opportunity/", json={ "lead_id": lead["id"], "value": 50000, "confidence": 50, "status_id": "stat_xxx" # Pipeline stage })

Log activity

Log activity

close._request("POST", "/activity/note/", json={ "lead_id": lead["id"], "note": "Initial discovery call - interested in demo" })
undefined
close._request("POST", "/activity/note/", json={ "lead_id": lead["id"], "note": "Initial discovery call - interested in demo" })
undefined

Rate Limit Headers (RFC-compliant)

请求频率限制头(符合RFC标准)

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704067200
See
reference/close-deep-dive.md
for query language, Smart Views, sequences, and reporting. </close_patterns>
<hubspot_patterns>
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704067200
如需查询语言、智能视图、序列和报表的详细信息,请查看
reference/close-deep-dive.md
。 </Close CRM集成模式>
<HubSpot集成模式>

HubSpot Integration

HubSpot集成

Python SDK Pattern

Python SDK模式

python
from hubspot import HubSpot
from hubspot.crm.deals import SimplePublicObjectInputForCreate
from hubspot.crm.contacts import PublicObjectSearchRequest

client = HubSpot(access_token=os.environ["HUBSPOT_ACCESS_TOKEN"])
python
from hubspot import HubSpot
from hubspot.crm.deals import SimplePublicObjectInputForCreate
from hubspot.crm.contacts import PublicObjectSearchRequest

client = HubSpot(access_token=os.environ["HUBSPOT_ACCESS_TOKEN"])

Create deal with association

Create deal with association

deal = client.crm.deals.basic_api.create( SimplePublicObjectInputForCreate(properties={ "dealname": "Enterprise Deal", "amount": "50000", "dealstage": "appointmentscheduled", "pipeline": "default" }) )
deal = client.crm.deals.basic_api.create( SimplePublicObjectInputForCreate(properties={ "dealname": "Enterprise Deal", "amount": "50000", "dealstage": "appointmentscheduled", "pipeline": "default" }) )

Search contacts by email domain

Search contacts by email domain

search = PublicObjectSearchRequest( filter_groups=[{ "filters": [{ "propertyName": "email", "operator": "CONTAINS", "value": "@example.com" }] }], properties=["email", "firstname", "lastname"], limit=50 ) results = client.crm.contacts.search_api.do_search(search)
undefined
search = PublicObjectSearchRequest( filter_groups=[{ "filters": [{ "propertyName": "email", "operator": "CONTAINS", "value": "@example.com" }] }], properties=["email", "firstname", "lastname"], limit=50 ) results = client.crm.contacts.search_api.do_search(search)
undefined

Association Types

关联类型

FromToType ID
ContactCompany1
ContactDeal4
CompanyDeal6
DealContact3
See
reference/hubspot-patterns.md
for batch operations, custom properties, and workflows. </hubspot_patterns>
<salesforce_patterns>
来源目标类型ID
联系人公司1
联系人交易4
公司交易6
交易联系人3
如需批量操作、自定义属性和工作流的详细信息,请查看
reference/hubspot-patterns.md
。 </HubSpot集成模式>
<Salesforce集成模式>

Salesforce Integration

Salesforce集成

SOQL Query Patterns

SOQL查询模式

sql
-- Parent-child relationship (Contacts of Account)
SELECT Id, Name, (SELECT LastName, Email FROM Contacts)
FROM Account WHERE Industry = 'Technology'

-- Child-parent relationship
SELECT Id, FirstName, Account.Name, Account.Industry
FROM Contact WHERE Account.Industry = 'Technology'

-- Semi-join (Accounts with open Opportunities)
SELECT Id, Name FROM Account
WHERE Id IN (SELECT AccountId FROM Opportunity WHERE IsClosed = false)
sql
-- Parent-child relationship (Contacts of Account)
SELECT Id, Name, (SELECT LastName, Email FROM Contacts)
FROM Account WHERE Industry = 'Technology'

-- Child-parent relationship
SELECT Id, FirstName, Account.Name, Account.Industry
FROM Contact WHERE Account.Industry = 'Technology'

-- Semi-join (Accounts with open Opportunities)
SELECT Id, Name FROM Account
WHERE Id IN (SELECT AccountId FROM Opportunity WHERE IsClosed = false)

REST API v59.0

REST API v59.0

python
def create_opportunity(self, data: dict) -> dict:
    """Required: Name, StageName, CloseDate."""
    response = self.client.post(
        f"{self.instance_url}/services/data/v59.0/sobjects/Opportunity/",
        headers={"Authorization": f"Bearer {self.access_token}"},
        json=data
    )
    return response.json()
python
def create_opportunity(self, data: dict) -> dict:
    """Required: Name, StageName, CloseDate."""
    response = self.client.post(
        f"{self.instance_url}/services/data/v59.0/sobjects/Opportunity/",
        headers={"Authorization": f"Bearer {self.access_token}"},
        json=data
    )
    return response.json()

Composite API (batch up to 200 records)

Composite API (batch up to 200 records)

def composite_create(self, records: list) -> dict: return self.client.post( f"{self.instance_url}/services/data/v59.0/composite/sobjects", json={"allOrNone": False, "records": records} )

> See `reference/salesforce-patterns.md` for JWT setup, Platform Events, and bulk API.
</salesforce_patterns>

<webhook_patterns>
def composite_create(self, records: list) -> dict: return self.client.post( f"{self.instance_url}/services/data/v59.0/composite/sobjects", json={"allOrNone": False, "records": records} )

> 如需JWT配置、平台事件和批量API的详细信息,请查看 `reference/salesforce-patterns.md`。
</Salesforce集成模式>

<Webhook处理模式>

Webhook Handlers

Webhook处理器

Close Webhook (FastAPI)

Close Webhook(FastAPI实现)

python
from fastapi import FastAPI, Request, HTTPException
import hmac, hashlib

app = FastAPI()

@app.post("/webhooks/close")
async def close_webhook(request: Request):
    body = await request.body()
    signature = request.headers.get("Close-Sig")

    expected = hmac.new(
        CLOSE_WEBHOOK_SECRET.encode(), body, hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected):
        raise HTTPException(401, "Invalid signature")

    data = await request.json()
    event_type = data["event"]["event_type"]

    handlers = {
        "lead.created": handle_lead_created,
        "opportunity.status_changed": handle_opp_stage_change,
    }

    if handler := handlers.get(event_type):
        await handler(data["event"]["data"])

    return {"status": "ok"}
python
from fastapi import FastAPI, Request, HTTPException
import hmac, hashlib

app = FastAPI()

@app.post("/webhooks/close")
async def close_webhook(request: Request):
    body = await request.body()
    signature = request.headers.get("Close-Sig")

    expected = hmac.new(
        CLOSE_WEBHOOK_SECRET.encode(), body, hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected):
        raise HTTPException(401, "Invalid signature")

    data = await request.json()
    event_type = data["event"]["event_type"]

    handlers = {
        "lead.created": handle_lead_created,
        "opportunity.status_changed": handle_opp_stage_change,
    }

    if handler := handlers.get(event_type):
        await handler(data["event"]["data"])

    return {"status": "ok"}

Close Webhook Events

Close Webhook事件

lead.created, lead.updated, lead.deleted, lead.status_changed
contact.created, contact.updated
opportunity.created, opportunity.status_changed
activity.note.created, activity.call.created, activity.email.created
unsubscribed_email.created
</webhook_patterns>
<sync_architecture>
lead.created, lead.updated, lead.deleted, lead.status_changed
contact.created, contact.updated
opportunity.created, opportunity.status_changed
activity.note.created, activity.call.created, activity.email.created
unsubscribed_email.created
</Webhook处理模式>
<跨CRM同步架构>

Cross-CRM Sync

跨CRM同步

Architecture

架构

┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│   Close     │────▶│  Sync Layer  │◀────│  HubSpot    │
│  (Primary)  │◀────│  (Postgres)  │────▶│  (Marketing)│
└─────────────┘     └──────────────┘     └─────────────┘
┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│   Close     │────▶│  Sync Layer  │◀────│  HubSpot    │
│  (Primary)  │◀────│  (Postgres)  │────▶│  (Marketing)│
└─────────────┘     └──────────────┘     └─────────────┘

Sync Record Schema

同步记录表结构

sql
CREATE TABLE crm_sync_records (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    entity_type VARCHAR(50) NOT NULL,
    close_id VARCHAR(100) UNIQUE,
    hubspot_id VARCHAR(100) UNIQUE,
    salesforce_id VARCHAR(100) UNIQUE,
    email VARCHAR(255),
    company_name VARCHAR(255),
    last_synced_at TIMESTAMPTZ,
    sync_source VARCHAR(50),
    sync_hash VARCHAR(64)
);

CREATE INDEX idx_sync_email ON crm_sync_records(email);
sql
CREATE TABLE crm_sync_records (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    entity_type VARCHAR(50) NOT NULL,
    close_id VARCHAR(100) UNIQUE,
    hubspot_id VARCHAR(100) UNIQUE,
    salesforce_id VARCHAR(100) UNIQUE,
    email VARCHAR(255),
    company_name VARCHAR(255),
    last_synced_at TIMESTAMPTZ,
    sync_source VARCHAR(50),
    sync_hash VARCHAR(64)
);

CREATE INDEX idx_sync_email ON crm_sync_records(email);

Conflict Resolution

冲突解决策略

python
from enum import Enum

class ConflictStrategy(Enum):
    CLOSE_WINS = "close"      # Close is source of truth
    LAST_WRITE_WINS = "lww"   # Most recent update wins

def resolve_conflict(close_record, hubspot_record, strategy):
    if strategy == ConflictStrategy.CLOSE_WINS:
        merged = close_record.copy()
        for key, value in hubspot_record.items():
            if key not in merged or not merged[key]:
                merged[key] = value
        return merged
See
reference/sync-patterns.md
for deduplication, migration scripts, and bulk sync. </sync_architecture>
<file_locations>
python
from enum import Enum

class ConflictStrategy(Enum):
    CLOSE_WINS = "close"      # Close is source of truth
    LAST_WRITE_WINS = "lww"   # Most recent update wins

def resolve_conflict(close_record, hubspot_record, strategy):
    if strategy == ConflictStrategy.CLOSE_WINS:
        merged = close_record.copy()
        for key, value in hubspot_record.items():
            if key not in merged or not merged[key]:
                merged[key] = value
        return merged
如需去重、迁移脚本和批量同步的详细信息,请查看
reference/sync-patterns.md
。 </跨CRM同步架构>
<文件位置>

Reference Files

参考文件

CRM-Specific:
  • reference/close-deep-dive.md
    - Query language, Smart Views, sequences, reporting
  • reference/hubspot-patterns.md
    - SDK patterns, batch operations, workflows
  • reference/salesforce-patterns.md
    - JWT auth, SOQL, Platform Events, bulk API
Operations:
  • reference/sync-patterns.md
    - Cross-CRM sync, deduplication, migration
  • reference/automation.md
    - Webhook setup, sequences, workflows
Templates:
  • templates/close-client.py
    - Full Close API client
  • templates/hubspot-client.py
    - HubSpot SDK wrapper
  • templates/sync-service.py
    - Cross-CRM sync service </file_locations>
<routing>
CRM专属文件:
  • reference/close-deep-dive.md
    - 查询语言、智能视图、序列、报表
  • reference/hubspot-patterns.md
    - SDK模式、批量操作、工作流
  • reference/salesforce-patterns.md
    - JWT认证、SOQL、平台事件、批量API
操作相关文件:
  • reference/sync-patterns.md
    - 跨CRM同步、去重、迁移
  • reference/automation.md
    - Webhook配置、序列、工作流
模板文件:
  • templates/close-client.py
    - 完整的Close API客户端
  • templates/hubspot-client.py
    - HubSpot SDK封装
  • templates/sync-service.py
    - 跨CRM同步服务 </文件位置>
<请求处理指引>

Request Routing

请求处理规则

User wants CRM integration: → Ask which CRM (Close recommended for simplicity) → Provide auth setup + basic CRUD
User wants Close CRM: → Provide API key setup, query language → Reference:
reference/close-deep-dive.md
User wants HubSpot: → Provide SDK setup, search patterns → Reference:
reference/hubspot-patterns.md
User wants Salesforce: → Provide JWT auth, SOQL patterns → Reference:
reference/salesforce-patterns.md
User wants sync between CRMs: → Provide sync architecture, conflict resolution → Reference:
reference/sync-patterns.md
User wants webhooks: → Provide handler pattern for specified CRM → Include signature verification </routing>
<env_setup>
用户需要CRM集成: → 询问目标CRM(推荐Close CRM以追求简洁) → 提供认证配置和基础CRUD操作
用户需要Close CRM集成: → 提供API密钥配置、查询语言 → 参考文件:
reference/close-deep-dive.md
用户需要HubSpot集成: → 提供SDK配置、查询模式 → 参考文件:
reference/hubspot-patterns.md
用户需要Salesforce集成: → 提供JWT认证、SOQL查询模式 → 参考文件:
reference/salesforce-patterns.md
用户需要跨CRM同步: → 提供同步架构、冲突解决策略 → 参考文件:
reference/sync-patterns.md
用户需要Webhook: → 提供对应CRM的处理器模式 → 包含签名验证 </请求处理指引>
<环境配置>

Environment Variables

环境变量

bash
undefined
bash
undefined

Close CRM

Close CRM

export CLOSE_API_KEY="api_xxx" export CLOSE_WEBHOOK_SECRET="whsec_xxx"
export CLOSE_API_KEY="api_xxx" export CLOSE_WEBHOOK_SECRET="whsec_xxx"

HubSpot

HubSpot

export HUBSPOT_ACCESS_TOKEN="pat-xxx"
export HUBSPOT_ACCESS_TOKEN="pat-xxx"

Salesforce

Salesforce

export SF_CLIENT_ID="xxx" export SF_USERNAME="user@company.com" export SF_PRIVATE_KEY_PATH="./salesforce.key" export SF_INSTANCE_URL="https://yourorg.my.salesforce.com"

```bash
export SF_CLIENT_ID="xxx" export SF_USERNAME="user@company.com" export SF_PRIVATE_KEY_PATH="./salesforce.key" export SF_INSTANCE_URL="https://yourorg.my.salesforce.com"

```bash

Install dependencies

Install dependencies

pip install httpx pyjwt hubspot-api-client python-dotenv
</env_setup>

<example_session>
pip install httpx pyjwt hubspot-api-client python-dotenv
</环境配置>

<示例会话>

Example Session

示例会话

User: "I need to push enriched leads from my sales-agent to Close CRM"
Claude:
  1. Here's the pattern for pushing enriched data to Close:
python
async def push_to_close(close_client, enriched_data: dict) -> str:
    lead_data = {
        "name": enriched_data["company_name"],
        "url": enriched_data.get("website"),
        "custom.cf_tier": enriched_data["tier"],
        "custom.cf_source": "sales-agent",
        "contacts": [{
            "name": c["name"],
            "title": c.get("title"),
            "emails": [{"email": c["email"]}] if c.get("email") else []
        } for c in enriched_data.get("contacts", [])]
    }

    result = close_client.create_lead(lead_data)
    return result["id"]
  1. Make sure you have these custom fields in Close:
    • cf_tier
      (choices: Gold, Silver, Bronze)
    • cf_source
      (choices: sales-agent, inbound, referral)
  2. Rate limit: 100 requests per 10 seconds. Add
    asyncio.sleep(0.1)
    between requests for bulk imports. </example_session>
用户: "我需要将销售代理提供的已补全线索推送到Close CRM"
Claude:
  1. 以下是将已补全数据推送到Close CRM的模式:
python
async def push_to_close(close_client, enriched_data: dict) -> str:
    lead_data = {
        "name": enriched_data["company_name"],
        "url": enriched_data.get("website"),
        "custom.cf_tier": enriched_data["tier"],
        "custom.cf_source": "sales-agent",
        "contacts": [{
            "name": c["name"],
            "title": c.get("title"),
            "emails": [{"email": c["email"]}] if c.get("email") else []
        } for c in enriched_data.get("contacts", [])]
    }

    result = close_client.create_lead(lead_data)
    return result["id"]
  1. 请确保Close CRM中已创建以下自定义字段:
    • cf_tier
      (选项:Gold、Silver、Bronze)
    • cf_source
      (选项:sales-agent、inbound、referral)
  2. 请求频率限制:10秒100次请求。批量导入时,请在请求之间添加
    asyncio.sleep(0.1)
    。 </示例会话>