Automatically scans DingTalk calendar, group chats, and contacts, extracts contacts, and maintains relationship warmth scores. Compared with the Feishu version, email scanning is removed (DingTalk has no mailbox), and DingTalk contacts search is added as a contact source.
Trigger method
"联系人管理" "CRM" "谁联系过我" "多久没联系" "联系人热度" "关系管理" "联系人"
Warmth score calculation rules
| Dimension | Weight | Calculation method |
|---|---|---|
| Frequency score | 40 points | Number of interactions in the past 90 days, 0 times = 0 points, 20+ times = 40 points, linear interpolation |
| Recency score | 40 points | Days since the last interaction, within 7 days = 40 points, 90+ days = 0 points, linear decrease |
| Importance score | 20 points | High = 20 points, Medium = 12 points, Low = 4 points |
Total score = Frequency score + Recency score + Importance score (0-100)
Data initialization
On first use, automatically create the aitable data tables:
# 创建 Base
dws aitable base create --name "个人CRM" --yes -f json
# 返回 baseId,记为 <crm-base-id>
# 创建联系人主表
dws aitable table create --base-id <crm-base-id> --name "联系人" --yes -f json
# 返回 tableId,记为 <contacts-table-id>
# 创建互动记录表
dws aitable table create --base-id <crm-base-id> --name "互动记录" --yes -f json
# 返回 tableId,记为 <interactions-table-id>
# 添加业务字段(表创建后自动带一个"标题"primaryDoc字段,需额外添加业务字段)
dws aitable field create --base-id <crm-base-id> --table-id <contacts-table-id> --fields '[{"fieldName":"姓名","type":"text"},{"fieldName":"公司","type":"text"},{"fieldName":"职位","type":"text"},{"fieldName":"手机","type":"text"},{"fieldName":"userId","type":"text"},{"fieldName":"来源","type":"text"},{"fieldName":"关系类型","type":"text"},{"fieldName":"重要程度","type":"text"},{"fieldName":"热度分","type":"number"},{"fieldName":"最后联系时间","type":"date"},{"fieldName":"最后联系内容","type":"text"},{"fieldName":"备注","type":"text"}]' --yes -f json
dws aitable field create --base-id <crm-base-id> --table-id <interactions-table-id> --fields '[{"fieldName":"联系人姓名","type":"text"},{"fieldName":"联系人userId","type":"text"},{"fieldName":"互动时间","type":"date"},{"fieldName":"互动类型","type":"text"},{"fieldName":"互动摘要","type":"text"},{"fieldName":"涉及主题","type":"text"}]' --yes -f json
Table 1: Contacts (contacts)
| Field name | Type | Description |
|---|---|---|
| Name | Text | Contact name |
| Company | Text | Company |
| Position | Text | Position/Role |
| Mobile | Text | Contact information |
| userId | Text | DingTalk userId |
| Source | Text | Calendar/Group chat/Contacts/Manual |
| Relationship type | Text | Client/Partner/Colleague/Friend/Industry connection/Other |
| Importance level | Text | High/Medium/Low |
| Warmth score | Number | 0-100 |
| Last contact time | Date | Most recent interaction time |
| Last contact content | Text | Interaction summary |
| Notes | Text | Free-form notes |
Table 2: Interaction records (interactions)
| Field name | Type | Description |
|---|---|---|
| Contact name | Text | Associated contact name |
| Contact userId | Text | Associated contact userId |
| Interaction time | Date | Time when the interaction occurred |
| Interaction type | Text | Calendar/Group chat message/DING/Phone/Other |
| Interaction summary | Text | Brief description of the content |
| Topics involved | Text | Topics discussed |
Working modes
Mode 1: Contact initialization — import from calendar and contacts
Trigger: "Help me build a personal CRM system" / "Initialize contact management"
Workflow:
Step 1: 获取当前用户信息
└── dws contact user get-self --yes -f json
Step 2: 扫描近期日程,提取参与者
├── dws calendar event list --yes -f json → 所有日程
├── 逐个获取日程参与者:
│ dws calendar participant list --event "eventId" --yes -f json
└── 批量获取参与者详细信息(注意:contact user search 仅返回 userId 列表,需二次查询):
dws contact user get --ids "id1,id2,id3" --yes -f json
Step 3: 搜索群聊,提取群成员
├── dws chat search --query "关键词" --yes -f json
└── dws chat group members list --id "openConversationId" --yes -f json
Step 4: 写入联系人表
└── dws aitable record create --base-id <crm-base-id> --table-id <contacts-table-id> --records '[...]' --yes
Step 5: 计算热度分并更新
└── dws aitable record update --base-id <crm-base-id> --table-id <contacts-table-id> --records '[...]' --yes
Mode 2: Interaction Record Import
Trigger: "Import interaction records from calendar" / "Record recent contact interactions"
Workflow:
Step 1: 获取指定时间范围的日程
└── dws calendar event list --yes -f json → AI 过滤时间范围
Step 2: 逐个获取日程详情和参与者
├── dws calendar event get --id "eventId" --yes -f json
└── dws calendar participant list --event "eventId" --yes -f json
Step 3: AI 为每个参与者生成互动记录
├── 互动类型:日程
├── 互动摘要:日程标题 + 描述
├── 涉及主题:AI 从日程描述中提取
└── 更新联系人的最后联系时间和热度分
Step 4: 批量写入互动记录并更新联系人
├── dws aitable record create --base-id <crm-base-id> --table-id <interactions-table-id> --records '[...]' --yes
└── dws aitable record update --base-id <crm-base-id> --table-id <contacts-table-id> --records '[...]' --yes
Mode 3: Contact Query
Trigger: "Who contacted me last month?" / "Who was the last person I talked to at Company XX?"
Workflow:
Step 1: 解析用户查询意图(按时间/公司/热度等维度)
Step 2: 查询 aitable 联系人表
└── dws aitable record query --base-id <crm-base-id> --table-id <contacts-table-id> --limit 50 --yes -f json
Step 3: AI 过滤和排序,格式化输出
Query examples:
| User question | Query method |
|---|---|
| "Who contacted me last month?" | Filter by last contact time within the last 30 days |
| "People at Company XX" | Filter by company field |
| "Important relationships not contacted in over 3 months" | Heat score < 30 and importance = high |
| "The 5 closest relationships" | Sort by heat score descending, take top 5 |
| "Who are the clients?" | Filter by relationship type = client |
Mode 4: Overdue Reminder
Trigger: Automatic execution / "Are there any contacts that need follow-up?"
Workflow:
Step 1: 查询所有重要程度=高或中且热度分 < 30 的联系人
└── dws aitable record query --base-id <crm-base-id> --table-id <contacts-table-id> --yes -f json
Step 2: 生成提醒列表
Step 3: 通过 DING 或群消息发送提醒
└── dws ding message send --robot-code "..." --users "manager6950" --content "N 个重要联系人需要跟进" --type "1" --yes
Mode 5: Manually Add Contact
Trigger: "Add contact Zhang San, Company XX, CTO"
Workflow:
Step 1: 解析联系人信息(姓名、公司、职位等)
Step 2: 尝试在钉钉通讯录中匹配
├── dws contact user search --keyword "张三" --yes -f json
│ 注意:返回格式为 {"userId":["id1","id2"]},仅含 userId 列表,不含姓名等详细信息
│ 或 dws contact user search-mobile --mobile "138..." --yes -f json
└── 如匹配到结果,用返回的 userId 获取完整信息:
dws contact user get --ids "userId1,userId2" --yes -f json
Step 3: 如果匹配到,补充 userId 和详细信息;否则使用手动输入
Step 4: 写入联系人表
└── dws aitable record create --base-id <crm-base-id> --table-id <contacts-table-id> --records '[...]' --yes
Mode 6: Batch Heat Score Update
Trigger: "Update the heat scores of all contacts" / automatic periodic execution
Workflow:
Step 1: 查询所有联系人和互动记录
├── dws aitable record query --base-id <crm-base-id> --table-id <contacts-table-id> --limit 100 --yes -f json
└── dws aitable record query --base-id <crm-base-id> --table-id <interactions-table-id> --limit 500 --yes -f json
Step 2: AI 计算每个联系人的热度分(频率分 + 近期分 + 重要度分)
Step 3: 批量更新
└── dws aitable record update --base-id <crm-base-id> --table-id <contacts-table-id> --records '[...]' --yes
dws CLI Command Reference
Get current user
dws contact user get-self --yes -f json
Search contacts
dws contact user search --keyword "张三" --yes -f json
Search by mobile number
dws contact user search-mobile --mobile "13800000000" --yes -f json
Batch get user information
dws contact user get --ids "user1,user2,user3" --yes -f json
Search departments
dws contact dept search --keyword "技术部" --yes -f json
Get calendar list
dws calendar event list --yes -f json
Get calendar details
dws calendar event get --id "eventId" --yes -f json
Get calendar participants
dws calendar participant list --event "eventId" --yes -f json
Search group chats
dws chat search --query "关键词" --yes -f json
Get group members
dws chat group members list --id "openConversationId" --yes -f json
aitable record operations
# 创建联系人
dws aitable record create --base-id <crm-base-id> --table-id <contacts-table-id> --records '[{"cells":{"标题":"张三-XX科技","姓名":"张三","公司":"XX科技","重要程度":"高","热度分":65}}]' --yes -f json
# 查询联系人
dws aitable record query --base-id <crm-base-id> --table-id <contacts-table-id> --limit 50 --yes -f json
# 更新联系人
dws aitable record update --base-id <crm-base-id> --table-id <contacts-table-id> --records '[{"recordId":"rec_xxx","cells":{"热度分":75,"最后联系时间":"2026-04-06"}}]' --yes -f json
Linked Skills
| Linked Skill | Data interaction | Description |
|---|---|---|
| morning-brief | Provide attendee background | Morning briefing displays meeting participant information |
| business-advisor | Provide contact updates | Business advisory group analyzes network changes |
| meeting-todo | Provide assignee information | Identify the identity of to-do assignees |
Notes
- All
dwscommands must include the--yesflag - DingTalk contacts search only returns members the current user has permission to view, not the full set
- Heat score updates are recommended to run automatically once a week (can be configured via CronCreate)
dws aitable record create/update's--recordsparameter must be in JSON array format- Contact names may be inconsistent between the contacts directory and aitable; use userId as the unique identifier
- Contact search
contact user searchonly returns a list of userIds, without detailed information such as names. If detailed information is needed, pass the returned userId tocontact user get --idsto get complete information contact dept searchmay return empty results for small organizations (sole proprietorships, etc.), which is normal
Known Issues
contact user searchThe return format is{"userId":["id1","id2"]}rather than complete user information, requiring a secondary querycontact user get --idsto obtain detailed information such as name and companychat searchReturning empty results for keywords that do not match any group chat is normal behavior