跳转到主要内容
请注意 我们已在 X API v2 中发布一款新的合规工具,名为批量合规。该工具允许您上传包含大量 Post 或用户 id 的数据集,以获取其合规状态,从而确定需要采取哪些措施使您的数据集满足合规要求。
此外,批量合规和合规 firehose 均已更新以支持 Post 编辑。对于合规 firehose,新增了一个“tweet_edit”事件。有关更多详情,请参阅合规数据对象文档。要了解 Edit Post metadata 的工作原理,请参见Edit Posts 基础页面。

概述

Enterprise X 的核心价值之一是捍卫并尊重用户的声音。这包括在用户删除、修改或编辑其在 X 上选择分享的内容时,尊重其期望与意图。我们相信,这对于作为全球最大公共、实时信息平台之一的长期健康发展至关重要。X 将控制权交到用户手中,使个人能够掌控自己的 X 使用体验。我们认为,获取 X 数据的商业用户有责任尊重终端用户的期望与意图。 有关 X 平台上可能发生的合规事件类型的更多信息,请参阅我们的文章:Honoring User Intent on X 任何通过 API 获取并使用 X 数据的开发者或公司都有义务尽一切合理努力来遵循用户内容的变更。该义务涵盖用户事件,例如删除、修改以及共享选项的变更(例如内容变为受保护或被限制)。这也包括用户编辑其 Post 的情况。请参阅Developer Policy中的具体条款和/或你的 X Data Agreement,以了解此义务如何影响你对 X 数据的使用。 X 提供以下解决方案,用于传递这些用户合规事件的信息,以及特定 Post 或 User 是否公开可用的状态。以下是这些解决方案及其通用集成模式的简要概述:

GET statuses/lookup 和 GET users/lookup

  • 格式:REST API。参见:GET statuses/lookupGET users/lookup
  • 这些 endpoint 始终返回任何 Post 编辑的最新版本。引入编辑功能后创建的所有 Post 的 Post 对象都会包含 Post 编辑的 metadata,即使该 Post 实际未被编辑也是如此。
  • 对于所有 Post,在创建超过 30 分钟后的请求将反映该 Post 的最终状态。
  • 按调用方在 API 请求中指定的对象,返回特定 Post 或用户的可用性信息。
  • 可用于对特定一组 Post/用户的当前可用性状态进行临时抽查。
  • 适用于需要在某一特定时间点检查某个 Post 或用户当前状态的客户。
  • 这些 API 为需要检查某段内容可用性的客户提供了实用机制,例如:
    1. 展示 Post
    2. 以 1:1 的方式与某个 Post 或用户进行互动
    3. 通过允许的文件下载将 X 内容分发给第三方
    4. 长期存储 Post

合规 Firehose(仅限 Enterprise)

  • 格式:流式 API。参见:Compliance Firehose
  • 在 X 上提供 合规活动 的实时 stream。这些活动包括 Post 被编辑时的事件。
  • 可用于在平台发生新的合规事件时,维护一组已存储 data 的合规状态。
  • 非常适合在较长时间内摄取并存储大量 X data 的客户。

指南

合规实践最佳指南

建议与最佳实践

  • 构建可存储数值型 Post ID 和 User ID 的数据存储模式:针对某个用户的合规处理需要作用于该用户的所有 Posts。由于所有合规消息仅以数值型 ID 传递,设计存储模式时应基于数值型 ID 维护 Post 与 User 之间的关联。数据使用方需要同时按 Post ID 和 User ID 监控合规事件,并能够相应更新本地数据存储。
  • 构建覆盖所有合规状态的模式:根据各类应用中处理合规活动的方式,可能需要向数据存储中添加其他 metadata。比如,数据使用方可能会在现有数据库中添加 metadata,以便在受到 status_withheld 消息影响的国家/地区限制内容展示。
  • 处理转发删除:转发是一种特殊的 Post,原始消息作为一个对象嵌套在转发中。在这种情况下,转发会引用两个 Post ID——转发本身的 ID,以及原始消息的 ID(位于嵌套对象中)。当原始消息被删除时,会针对原始 ID 发送一条 Post delete 消息。Post 删除事件通常会触发对所有转发的 delete 事件。但在某些情况下可能并不会全部发送,客户端系统应容忍不完整的转发删除。删除原始 ID 一般足以删除所有后续的转发。最佳实践是在存储转发时引用原始的 Post ID,并在收到 Post delete 事件时删除所有被引用的转发。

合规数据对象

Compliance Firehose API

可能的合规事件类型包括 Post(或“status”)事件和 User 事件,下面分别介绍多种类型。   请注意:
  • 此处了解更多关于用户状态(User statuses)的信息;关于已删除 Posts 的开发者政策请见此处
  • Compliance Firehose 已更新,现提供 ‘tweet_edit’ 事件。 
  • 多个与用户相关的 delete、protect 和 suspend 事件不一定是永久性的,且可能在不同状态之间无限切换。这些包括:user_delete、user_undelete、user_protect、user_unprotect,以及 user_suspend、user_unsuspend。
  • 仅当用户未选择对其账户执行 user_undelete 时,user_delete 事件发生后 30 天才会跟随 status_delete 事件。用户可能会撤销一次 user_delete,因此其所有 Posts 在 30 天后的删除可能不会发生。
  • user_suspend 是一种状态,除非发生 user_unsuspend 事件,否则一直保持为真。该状态不受任何 30 天周期的变更影响。
请参阅“Recommended Action”列,了解如何处理每种事件类型,以尊重终端用户的隐私和意图。
Original Message TypeObjectPermanent (Yes/No)Recommended Action
deleteStatusYes删除关联的 Post。
status_withheldStatusYes在 status_withheld 消息列出的特定国家/地区屏蔽关联的 Post。
dropStatusNo将该 Post 从公开视图中移除。
undropStatusNo该 Status 可再次显示并视为公开。
tweet_editStatusYes采纳并在适用时展示最新编辑结果。
user_deleteUserNo屏蔽或删除关联用户的所有 Posts。
user_undeleteUserNo关联用户的所有 Posts 可再次显示并视为公开。
user_protectUserNo屏蔽或删除关联用户的所有 Posts。
user_unprotectUserNo关联用户的所有 Posts 可再次显示并视为公开。
user_suspendUserNo屏蔽或删除关联用户的所有 Posts。
user_unsuspendUserNo关联用户的所有 Posts 可再次显示并视为公开。
scrub_geoUserYes删除 X 为该用户提供、且位于 scrub_geo 消息中指定 Post 之前的所有地理数据。请注意,该用户后续的 Posts 可能包含可使用的地理数据。
user_withheldUserYes在 user_withheld 消息列出的特定国家/地区屏蔽关联用户的 Posts。
deleteFavoriteYes删除关联的 like/favorite。

有效负载示例

请参阅下方针对上表所述各类合规事件的有效负载示例。 Post 编辑
{"tweet_edit":
   {
     "id": "1557445923210514432"
     "initial_tweet_id": "1557433858676740098",
     "edit_tweet_ids": ["1557433858676740098", "1557445923210514432"],
     "timestamp_ms": "1660155761384"
   }
 }
删除 Post
{
  "delete": {
    "status": {
      "id": 601430178305220600,
      "id_str": "601430178305220608",
      "user_id": 3198576760,
      "user_id_str": "3198576760"
    },
    "timestamp_ms": "1432228155593"
  }
}
已限制显示的 Post
{
  "status_withheld": {
    "status": {
      "id": 601430178305220600,
      "id_str": "601430178305220608",
      "user_id": 3198576760,
      "user_id_str": "3198576760"
    },
    "withheld_in_countries": [
      "XY"
    ],
    "timestamp_ms": "1432228155593"
  }
}
丢弃
{
  "drop": {
    "status": {
      "id": 601430178305220600,
      "id_str": "601430178305220600",
      "user_id": 3198576760,
      "user_id_str": "3198576760"
    },
    "timestamp_ms": "1432228155593"
  }
}
撤销删除
{
  "undrop": {
    "status": {
      "id": 601430178305220600,
      "id_str": "601430178305220600",
      "user_id": 3198576760,
      "user_id_str": "3198576760"
    },
    "timestamp_ms": "1432228155593"
  }
}

清除地理信息

{
  "scrub_geo": {
    "user_id": 519761961,
    "up_to_status_id": 411552403083628540,
    "up_to_status_id_str": "411552403083628544",
    "user_id_str": "519761961",
    "timestamp_ms": "1432228180345"
  }
}
删除用户
{
  "user_delete": {
    "id": 771136850,
    "timestamp_ms": "1432228153548"
  }
}
用户撤销删除
{
  "user_undelete": {
    "id": 796250066,
    "timestamp_ms": "1432228149062"
  }
}
用户已隐藏
{
  "user_withheld": {
    "user": {
      "id": 1375036644,
      "id_str": "1375036644"
    },
    "withheld_in_countries": [
      "XY"
    ],
    "timestampMs": "2014-08-27T23:49:41.839+00:00"
  }
}
用户保护
{
  "user_protect": {
    "id": 3182003550,
    "timestamp_ms": "1432228177137"
  }
}
取消用户保护状态
{
  "user_unprotect": {
    "id": 2911076065,
    "timestamp_ms": "1432228180113"
  }
}
用户停用
{
  "user_suspend": {
    "id": 3120539094,
    "timestamp_ms": "1432228194217"
  }
}
解除用户账号暂停
{
  "user_unsuspend": {
    "id": 3293130873,
    "timestamp_ms": "1432228193828"
  }
}

集成 Compliance Firehose

Compliance Firehose 是一款实时流式 API,用于传递在 X 平台上发生的合规事件。若要了解合规事件及其在 X 上的生成方式,请参阅我们的文章:Honoring User Intent on X 需要特别注意的是,Post 和用户事件是分别传递的,且应分别处理(即,某个 Post 的 delete 并不意味着会产生用户事件,反之亦然)。某些用户事件并非永久生效,可能在不同状态之间无限切换。这些包括:user_delete、user_undelete、user_protect、user_unprotect,以及 user_suspend、user_unsuspend。 仅当用户未选择对其账户执行 user_undelete 时,user_delete 之后才会在 30 天后跟随 status_delete。用户可能撤销一次 user_delete,从而导致其所有 Post 在 30 天后不会被删除。 user_suspend 为持续有效的动作,除非发生 user_unsuspend 事件。其状态不受任何 30 天时间周期内的变更影响。 切勿将合规事件直接展示给你的软件用户,或以其他方式将其纳入你的产品或客户体验中。它们仅用于维护合规性并尊重 X 用户的操作。

集成 Compliance Firehose

要将 Compliance Firehose 集成到您的系统,您需要构建一套集成方案,能够执行以下操作:
  1. 为 Compliance Firehose 的每个 streaming API 分区建立流式连接
  2. 处理高数据量——使用异步流程将 stream 摄取与后续处理解耦
  3. 因任何原因断开时自动重新连接到各个 stream 分区
  4. 按照上述指南处理与您已存储的 Post 和 User 数据相关的合规事件

尊重 X 上的用户意图

我们相信,尊重 X 用户的隐私与意图,对这一全球最大、公开、实时的信息平台之一的长期健康至关重要。X 将隐私控制权交到用户手中,使个人能够管理自己的 X 使用体验。作为 X data 的商业使用方,我们共同有责任尊重终端用户的隐私与行为,以维系这种信任与尊重的环境。 在平台上,Post 和用户账户可能发生多种变更,影响其在平台上的呈现方式。影响隐私与意图的操作在 Status(Post)层级和用户层级均有定义。这些操作包括:

用户

操作说明
保护账户X 用户可以随时将其账户设为受保护或取消保护。受保护的账户要求对每位被允许查看其账户 Post 的用户进行手动批准。
欲了解更多信息,请参阅 关于公开和受保护的 Post
删除账户X 用户可以随时决定删除其账户及所有关联的状态消息。X 会在删除后保留账户信息 30 天,以便用户选择撤销删除并重新激活其账户。
清除地理信息X 用户可以随时从过去的 Post 中移除所有位置信息,这称为“scrub geo”。
暂停账户对于违反 X 规则的账户,或怀疑账户被黑客入侵或遭到入侵的情况,X 保留暂停账户的权利。账户暂停仅可由 X 撤销(解除暂停)。
限制账户X 保留在特定国家/地区对某些内容进行事后限制访问的权利。被限制的账户仅可由 X 解除限制。
欲了解更多信息,请参阅 按国家/地区限制的内容

状态

操作描述
删除状态X 用户可以在任何时间删除状态。删除后无法恢复,且会被永久移除。
限制提供状态X 保留在特定国家/地区根据需要限制访问某些内容的权利。被限制提供的状态只能由 X 取消限制。 
有关更多信息,请参阅 按国家/地区限制的内容

跟踪用户和状态的变更

由于上述某项操作,User 或 Status 的状态可能随时发生变化,这将影响 X data 的使用方应如何处理所有相关内容的可用性和隐私。当这些操作发生时,会发送相应的合规消息,指示 Status 或 User 的状态已变更。

API 参考文档

GET compliance/firehose

方法

方法描述
GET /compliance/:stream连接到数据 stream

身份验证

对 Compliance Firehose API 的所有请求都必须使用 HTTP 基本身份验证(HTTP Basic Authentication)。该凭据由用于登录您在 console.gnip.com 帐户的有效电子邮件地址与密码组合构成。每个请求都必须通过 Authorization 头传递凭据。

GET /compliance/:stream

建立到 Compliance firehose 数据 stream 的持久连接,通过该连接传递合规事件。
请求方法HTTP GET
连接类型Keep-Alive
URL可在控制台中该 stream 的 API Help 页面找到,结构类似:


https://gnip-stream.x.com/stream/compliance/accounts/:account_name/publishers/twitter/:stream_label.json?partition=1

注意: 必须包含“partition”参数。要消费完整 stream,你需要连接全部 8 个分区,每个分区占总量的 12.5%。
压缩Gzip。若要以 Gzip 压缩连接到 stream,只需在连接请求中发送 Accept-Encoding 头。该请求头应如下所示:

Accept-Encoding: gzip
字符编码UTF-8
响应格式JSON。请求头应指定响应为 JSON 格式。
请求速率限制每 60 秒 10 次请求。
读取超时在客户端设置读取超时,并确保其值大于 30 秒。
对 Tweet 编辑的支持所有 Tweet 编辑都会触发“tweet_edit”Compliance 事件。详见Compliance Data Objects文档。
Curl 请求示例 以下示例请求通过命令行使用 cURL 完成:
curl --compressed -v -uexample@customer.com "https://gnip-stream.x.com/stream/compliance/accounts/:account_name/publishers/twitter/:stream_label.json?partition=1"
注意: 上述请求仅连接到 Compliance firehose 的 partition=1——要完整消费整个 stream,你需要连接所有 8 个分区。

响应代码

对于这些请求,API 可能返回以下响应。大多数错误代码会在响应正文中附带一段包含更多详细信息的字符串。对于非 200 响应,客户端应尝试重新连接。
状态文本定义
200成功连接已成功建立,新的活动会在到达时持续发送。
401未授权由于凭据无效,HTTP 身份验证失败。请使用你的凭据登录 console.gnip.com,确认你在请求中正确使用了它们。
406不可接受通常发生在客户端未正确包含接受来自 stream 的 gzip 编码所需的请求头时,也可能出现在其他情况下。响应将包含类似于“This connection requires compression. To enable compression, send an ‘Accept-Encoding: gzip’ header in your request and be ready to uncompress the stream as it is read on the client end.”的 JSON 消息。
429请求速率限制你的 App 已超出连接请求的限制。
503服务不可用Twitter 服务器出现问题。请使用指数回退策略重新连接。若在 X API Status Page 上未发布关于此问题的通知,请联系支持。

其他建议与最佳实践

  • 构建可存储数值型 Tweet ID 和 User ID 的数据存储架构:用户级别的消息要求对该用户的所有 Tweets 采取相应操作。由于所有合规消息仅以数值型 ID 投递,必须设计能基于数值型 ID 维护 Tweet 与用户关系的存储架构。数据使用方需要同时按 Tweet ID 和 User ID 监控合规事件,并能够相应更新本地数据存储。
  • 构建涵盖所有合规状态的架构:根据各应用处理合规活动的方式,可能需要向数据存储添加其他 metadata。例如,数据使用方可能会在现有数据库中添加 metadata,以便在受到 status_withheld 消息影响的国家/地区限制内容展示。
  • 处理转发的删除:转发是一种特殊的 Tweet,其中原始消息作为一个对象嵌套在转发内。在这种情况下,一个转发会引用两个 Tweet ID——转发本身的 ID,以及原始消息的 ID(位于嵌套对象中)。当原始消息被删除时,会针对原始 ID 发出 Tweet delete 消息;不会为所有转发分别再发出后续的 delete 消息。删除原始 ID 即可删除所有后续的转发。
I