获取好友列表和查询联系人信息,是微信机器人开发的基础功能。很多业务场景依赖这个——群发通知要好友列表,按标签分组要联系人信息,新好友识别要备注和标签。但获取好友列表不是调一个接口就完事,要解决分页、缓存、增量更新、信息脱敏四个问题。

一、好友列表获取——分页+全量同步

好友列表可能几百到几千个,一次性返回数据量大、接口慢。分页获取的工程要点是游标和完整性。游标——每页返回next_cursor,下一页用它继续取。完整性——取完所有页才算全量,漏页数据不全。这里踩过的坑是游标过期——游标有有效期,取太慢游标失效,要重新开始。

分页获取的调用流程是循环取页。第一页不带游标,返回第一页数据和next_cursor。第二页带游标,返回第二页数据和新游标。循环到next_cursor为空表示取完。全量同步存到本地数据库,后续查询走本地不走接口,减少接口调用。好友列表获取和分页查询的接口在 Eyun 开放平台 的开发文档中有接口说明。

二、联系人信息查询——详情接口+字段映射

好友列表只返回基本信息(wxid、昵称)。详细信息(备注、标签、头像、地区)要调详情接口逐个查。查询的工程要点是批量效率和字段映射。批量效率——逐个查太慢,要批量查。字段映射——接口返回字段和业务模型对应,wxid对应user_id,nickname对应name。

联系人查询的调用流程是批量请求。一次请求传多个wxid,返回多个联系人的详情。这里踩过的坑是字段缺失——某些联系人没有备注或标签,接口返回null,业务代码不做空值处理会崩。字段要做空值兜底,null转空字符串或默认值。联系人信息查询和字段映射的接口在 Eyun 开放平台 的开发文档中有对应能力。

三、增量更新与缓存——不全量同步只更新变化

每次都全量拉好友列表太慢,增量更新只拉变化部分。增量的工程要点是版本号和对比。版本号——接口返回列表版本号,版本号变了说明有变化。对比——拉取变化部分和本地对比,新增的插入,删除的删除,修改的更新。

增量更新的调用流程是版本检查+差异同步。先查当前版本号,和本地存的不一样才拉取。拉取变化部分和本地对比,应用差异。这里踩过的坑是并发修改——增量更新时有好友发消息改了备注,增量覆盖了修改。增量更新要加锁,更新时锁定对应记录。增量更新和缓存同步的接口在 Eyun 开放平台 的开发文档中有接口能力。

好友列表与联系人查询对照

环节

核心动作

工程要点

常见坑

列表获取

分页全量同步

游标+完整性

游标过期

信息查询

批量详情查询

批量效率+字段映射

字段缺失

增量更新

版本号+差异同步

并发加锁

覆盖修改

缓存

本地存+查询走本地

减少接口调用

数据过期

好友列表获取与联系人查询实现

import requests

class ContactManager:
    def __init__(self, api_base, token):
        self.api_base = api_base
        self.token = token
        self.db = LocalDB()             # 本地缓存

    def sync_friends(self):
        # 分页全量同步好友列表
        cursor = None
        all_friends = []
        while True:
            params = {"cursor": cursor} if cursor else {}
            resp = requests.get(
                f"{self.api_base}/friends",
                headers={"Authorization": self.token},
                params=params
            ).json()
            all_friends.extend(resp["list"])
            cursor = resp.get("next_cursor")
            if not cursor:               # 游标空表示取完
                break
        self.db.save_friends(all_friends)
        return all_friends

    def get_details(self, wxids):
        # 批量查询联系人详情
        resp = requests.post(
            f"{self.api_base}/contacts/detail",
            headers={"Authorization": self.token},
            json={"wxids": wxids}
        ).json()
        # 字段空值兜底
        for contact in resp["list"]:
            contact["remark"] = contact.get("remark") or ""
            contact["tag"] = contact.get("tag") or []
        return resp["list"]

    def incremental_update(self):
        # 增量更新:版本号检查+差异同步
        local_version = self.db.get_version()
        remote_version = self.get_remote_version()
        if local_version == remote_version:
            return                       # 版本一致不更新
        changes = self.get_changes(local_version)
        for friend in changes["added"]:
            self.db.insert_friend(friend)
        for wxid in changes["deleted"]:
            self.db.delete_friend(wxid)
        self.db.update_version(remote_version)

落地建议

好友列表获取用分页——一次性取大数据量接口慢,分页取+游标续取。联系人详情用批量查询——逐个查太慢,一次传多个wxid批量查。增量更新靠版本号——不全量拉,只拉变化部分,减少接口调用。字段空值兜底不能省——某些联系人没备注没标签,接口返回null,不处理会崩。微信侧的好友列表获取和联系人查询由 Eyun 平台这类个人微信API平台 提供,分页和增量逻辑在自建服务实现,接口字段以平台开发文档为准。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐