以下是 Emerson This 的客座文章。这是一篇针对有兴趣在网站上集成 Instagram 内容的 Web 开发人员的指南。就在几个月前,Instagram 更改了其 API 的可用功能,因此本文旨在解释这些变化,以及现在可以实现的功能,并提供一些示例。
- 第一部分 简要概述了 2016 年 6 月生效的 API 限制,这些限制极大地改变了竞争格局。
- 第二部分 介绍如何开始使用 API。
- 第三部分 提供了使用 API 可以(和不可以)执行的实际操作示例。
第一部分:三分钟了解 Instagram API
为了使用 Instagram API,迟早您必须找到一种方法来完成模糊的 API 客户端注册和授权流程。了解 API 访问限制可以避免浪费大量时间,因为这些限制通常会导致意外的数据,而不是更容易诊断的简单身份验证错误。
臭名昭著的 2016 年 6 月 API 限制
2016 年 6 月 1 日,当 Instagram 大幅限制对 API 的访问时,全球各地的控制台错误都亮了起来。首先要了解的是,这是 Instagram 做出的一个有意的商业决策,旨在防止其 API 用于各种目的。了解这一事实并不能解决控制台中的错误,但如果您理解其意图,它会让限制更容易解决。
沙盒模式与“实时”模式
开发人员与完整 API 访问之间的看门人称为沙盒模式。文档将其描述为开发过程中的一个临时步骤,但绝大多数项目永远不会离开沙盒模式,因为 Instagram 仅针对少数非常具体的用例授予对其 API 的完全访问权限。
- “我的应用程序允许用户使用 Instagram 登录并分享他们自己的内容”
- “我的产品帮助品牌和广告客户了解、管理其受众和媒体权利。”
- “我的产品帮助广播公司和出版商发现内容,获取媒体的数字版权,并以适当的归属分享媒体。”
如果您无法说服 Instagram 的管理者您的应用程序服务于这些特定目的之一,那么如果您将其提交到“上线”,它将被拒绝。因此,将其视为“替补席模式”可能更直观。
在沙盒模式下您可以做什么?
沙盒模式意味着您的 API 调用会进入一个魔法岛,其中仅存在您最近的 20 个帖子。仅此而已。岛上不存在其他人,因此您将看不到之前发布的任何内容或任何其他 Instagram 用户的内容的结果,即使该内容是公开的。您可以邀请其他“沙盒用户”,这会将他们添加到您的魔法岛,但与您一样,该岛上也只存在他们最近的 20 个帖子。

该岛永远不会变得很大,因为您最多只能拥有十个沙盒用户。请花点时间仔细思考一下。在沙盒模式下,您可能想要执行的任何涉及公众内容的操作都将无法实现。
沙盒模式与作用域
关于新限制最常见的混淆之一是将作用域和沙盒模式混淆。沙盒模式控制您的 API 请求可以“看到”什么,将其转移到魔法岛。作用域控制特定令牌可以和不可以用于什么。每个令牌自动以basic
作用域开始。仅具有basic
作用域的令牌可以执行的操作非常少,无论是在沙盒模式还是实时模式下。要查看即使是公共内容,您也需要请求额外的public_content
作用域。沙盒模式参与确定“公共内容”中包含的内容。在沙盒模式下,它将仅包含魔法岛上的帖子,而实时应用程序可以查看 Instagram 上任何公开(在现实世界中)的内容。
最常见的误解是,应用程序需要获得批准才能“上线”才能请求作用域。这是错误的。例如,在沙盒模式下,您需要一个具有public_content
作用域的令牌才能查看其他沙盒用户的帖子,就像已批准的(“实时”)应用程序一样1。从技术上讲,实时应用程序可以执行任何沙盒模式无法执行的操作,只要它只涉及存在于魔法岛上的用户和内容。
注意旧文档!
还值得一提的是,在 2016 年 6 月之前,许多 API 调用过去允许仅使用注册客户端的client_id
进行身份验证。现在,所有请求都需要access_token
。但是,仍然存在大量来自 6 月 1 日之前的插件、文档和教程尚未相应更新。
第二部分将展示如何在 API 限制内设置在沙盒模式下仍然可能的流行 Instagram 集成。
第二部分:如何在网站上使用 Instagram API
注册 API 客户端
在您开始使用 Instagram API 之前,您需要 注册 API 客户端 作为开发人员。如果您尚未注册为开发人员,则系统会提示您在继续注册新的 API 客户端之前进行注册。

配置 API 客户端最关键的部分是在有效重定向 URI字段中输入正确的的值。这是一个 Instagram 将在身份验证工作流程期间使用的 URI 白名单。URI 匹配算法非常严格。因此,您需要确保此处输入的 URI 之一与您在请求令牌时传递的redirect_uri
参数中的 URI完全相同(如下所述)。例如,如果您输入http://mysite.com/oauth
,然后尝试使用mysite.com/oauth
或http://mysite.com/oauth/
请求令牌,则会失败。
注册的 API 客户端会分配一个client ID
和一个client secret
。顾名思义,请勿共享您的客户端密钥。您将使用这两个密钥从 Instagram 请求令牌。
生成访问令牌
如上所述,您需要生成一个令牌来验证对 Instagram API 的请求。基本上有两种方法可以做到这一点:您可以通过编程方式或手动请求令牌。这两种方法都需要您首先注册一个 API 客户端(如上所述)。
使用 OAuth 2 工作流以编程方式生成 Instagram 令牌
Instagram 对 OAuth 2 的实现非常标准,因此如果您有任何使用此身份验证模式的经验,它将非常熟悉。在官方文档中有很好的文档,其中介绍了请求和参数的准确顺序。这是一个快速总结
- 将您的用户重定向到 Instagram 的授权 URL
- 用户授予授权
- Instagram 将用户重定向回您的网站,并附带一个代码
- 将代码发送回 Instagram 以换取令牌
手动生成 Instagram 令牌
在您不需要动态地以不同用户身份访问 API 的情况下,您可以手动生成令牌。
如果您有工具可以发出 POST 请求,并且设置了公共端点来接收来自 Instagram 的重定向,则您可以通过手动执行先前序列中的每个请求来生成令牌。但这可能很繁琐,尤其是在您只需要一个令牌的小型项目中。
最简单的方法是使用像这样的令牌生成工具。在 2016 年 6 月的限制生效之前,有很多这样的资源可供选择,但您会发现其中许多在限制开始时就失效了。InstagramToken.com 仍然有效,它还允许您生成具有特定范围的令牌(在第一部分中解释),如果您尝试执行请求自己的内容以外的任何操作,这一点非常重要。
如何邀请沙盒用户
沙盒用户是您邀请到您的客户端的其他 Instagram 用户。这样做的主要原因是,您的应用将能够“查看”他们的最后 20 个帖子以及您自己的帖子。这在上面沙盒模式与“实时”模式中进行了说明。
您可以从编辑客户端 UI 的“沙盒”选项卡中邀请沙盒用户。

关于邀请沙盒用户的行为的一些快速说明(截至 2016 年 8 月 28 日有效)
一个快速的安全性警告:通常情况下,使用 API 令牌进行客户端请求并不是最佳实践,因为这就像密码一样,恶意用户可以轻松地从源代码中读取它。但是,在沙盒模式下,令牌的作用非常小,因此风险很低。
如何查找您的用户 ID
令人惊讶的是,很难找到用户的数字 ID,而这对于许多流行类型的请求都是必需的。有一些在线资源构建来促进这一点,但在撰写本文时,大多数都已失效。Smash Balloon 拥有一个目前似乎正在运行的免费工具。如果您知道在哪里查找,自己查找 ID 也并不困难。现在这个也失效了。FindInstaID 似乎正在工作。
要查找用户的数字 Instagram ID,首先访问用户的公共 Instagram 页面:https://instagram.com/<username>
。查看此页面的源代码,并在页面底部找到大型的<script>
块。在里面,您将找到一个大型的window._sharedData
对象定义。id
的第一个实例将是用户的数字 ID。每个媒体对象的owner
节点下还有一个user_id
属性。

第三部分:使用 Instagram API 执行操作的示例
如何在您的网站上显示您的 Instagram Feed
此用例并非选定的少数几个将被批准“上线”的用例之一,但幸运的是,这是您在沙盒模式下仍然(大部分)可以执行的少数几件事之一。您将需要一个已注册的 API 客户端 ID 和一个访问令牌(两者都在上面进行了解释)。
让我们使用流行的Instafeed 库将您的 Instagram Feed 添加到网站。
首先手动下载库或使用 bower:bower install instafeed.js
。然后在页面底部的</body>
之前加载脚本。还在您希望图像流显示的任何位置插入<div id="instafeed"></div>
。
<div id="instafeed"></div>
<script src="path/to/instafeed.min.js"></script>
</body>
接下来,您需要使用另一个小型脚本初始化 Instafeed,告诉它您要显示哪些帖子。
<div id="instafeed"></div>
<script src="path/to/instafeed.min.js"></script>
<script>
var feed = new Instafeed({
get: 'user',
userId: USER_ID, // Ex: 1374300081
accessToken: 'YOUR_ACCESS_TOKEN'
});
feed.run();
</script>
</body>
这可用于显示任何已接受邀请成为您的 API 客户端沙盒用户的用户的最后 20 个帖子。
为什么您无法(真正地)显示标签列表
从技术上讲,您可以请求具有特定标签的帖子。没有任何东西阻止您使用与上面显示的相同的工作流程。Instafeed 已经支持标签搜索,因此您可以只传递以下设置
var feed = new Instafeed({
get: 'tagged',
tagName: 'TAG', Ex: // 'cat'
accessToken: 'YOUR_ACCESS_TOKEN'
});
但是,如果您处于沙盒模式,您可能不会看到您期望的结果!
标签的存在是因为它们对来自不同用户的內容进行分组。请记住,在第一部分中,沙盒模式意味着您的 API 请求被重定向到一个魔法岛,在那里只有您和您的一些沙盒用户的最后 20 个帖子存在。这意味着,如果您请求带有#cat标签的帖子(大约有 9000 万个帖子),但您和您的沙盒用户在最近 20 个帖子中没有使用过该标签,则 API 请求将成功,但返回零结果。
底线是,标签 Feed 可能只有在您显示一个对您和您的沙盒用户来说唯一且经常使用的标签时才有意义。
如何在您的网站上嵌入单个帖子
Instagram 希望您使用他们的官方嵌入小部件或他们的嵌入端点中的任何一个,这些端点不需要访问令牌。
获取嵌入小部件代码片段的最简单方法是从帖子的底角的[· · ·]
按钮。点击它以显示您可以复制/粘贴到 HTML 中的代码片段。

该片段将输出类似以下内容。

如果您在想“但这与我的网站其余部分不匹配。” 这就是重点。API 不仅仅返回图像文件的 URL 并非偶然。;)
如何添加点赞或关注按钮
这与上面提到的标签 Feed 属于同一类别。从技术上讲,你可以在沙盒模式下添加/删除点赞,但很少有使用场景有意义,因为在沙盒模式下,你的 API 访问权限仅限于你的沙盒用户。这意味着如果你在你的网站上添加了“点赞”或“关注”按钮,它只会允许你的沙盒用户互相点赞。
如果沙盒模式的限制不是问题,那么添加点赞按钮就像向/media/<MEDIA_ID>/likes
端点发送 POST 请求一样简单。以下示例使用 jQuery 发出 HTTP 请求,但你可以替换为你喜欢的工具。
<button id="like-btn" data-media-id="123456789">Like</button>
<script>
function sendLike(event) {
// Find the media ID in a data attribute for the button
var mediaId = $(event.target).data('media-id');
var token = 'YOUR_TOKEN';
// Build the url
var url = 'https://api.instagram.com/v1/media/';
url += mediaId;
url += '/likes?access_token=' + token;
// Make the request and handle the response
$.post(url).then(function(){
// success
function() { console.log('like request succeeded'); },
// fail
function() { console.log('like request failed'); }
});
}
$('#like-btn').click(sendLike);
</script>
在此代码中,我们为按钮上的点击事件注册了一个监听器。回调函数 sendLike()
在按钮的 data 属性中找到媒体 ID,并用它构建 URL,然后发送请求。
总结
如果你看到这里,说明你已经了解了 Instagram API 的限制,并且知道在限制性沙盒模式下哪些集成是可能的。如果我遗漏了什么,请在下方评论或在 Twitter 上找到我:@emersonthis。
1 我怀疑这种混淆源于 Instagram 的客户端管理 UI 中有一个看起来像是用于请求范围的选项卡,但在沙盒模式下该选项卡是被禁用的。这不是授予范围的方式。相反,这是实时应用如何获得 Instagram 的授权,以从用户那里请求特定范围(即权限)。
2 通知可能被垃圾邮件过滤,或者 Instagram 忘记构建它了。
长话短说,2016年6月的 API 基本上扼杀了我们所有试图创建有用的第三方工具的努力。真可惜。
关于钉子、脑袋和锤子的事情。
我不是阴谋论者。但是我感觉一定有一个最终目标。也许是一个受支持的合作伙伴,他们收集 Instagram 分析数据,而这些数据在某个地方丢失了一块蛋糕。
我希望这些限制是为了打击 Instagram 上的垃圾邮件,但在过去的两个月里,情况根本没有好转。我几乎每天都要举报试图关注我的垃圾邮件账户。
不错的文章。
所以仍然无法使用 API 将新内容发布到我自己的时间线?Instagram 对此的逻辑是什么?顺便说一句,Emerson,你的文章写得很好。
真的,我讨厌它……我真正想做的就是能够获取有关我账户的统计数据……关注者、照片总数——简单的事情。
Instagramtoken.com 说
“https:instagramtoken.com/(完全按照书写方式)必须是客户端的“有效重定向 URI”。
Instagram 说
“您必须输入一个以 http:// 或https://开头的绝对 URI”。
关于 // 有什么建议吗?
感谢你整理了一份关于 Instagram Feed 解决方案和策略的最新指南。
我认为值得指出的是,当用户更改密码或 Instagram 决定(因为令牌过期时间从未显示)并且未发出通知时,令牌似乎会过期……根据他们的文档……
“即使我们的访问令牌未指定过期时间,你的应用也应该处理用户撤销访问权限或 Instagram 在一段时间后令牌过期的情况。如果令牌不再有效,API 响应将包含“error_type=OAuthAccessTokenError”。在这种情况下,你需要重新验证用户以获取新的有效令牌。
换句话说:不要假设你的 access_token 永久有效。”
所以基本上我只能希望捕获错误并采取相应的措施。并且只有当我发现它已过期时(因为 Instagram 不会给你任何关于此的通知,他们为什么要这样做呢?),我需要手动更新我的令牌并相应地更新我的客户端令牌详细信息。似乎无法 100% 以编程方式更新它,因为你始终需要用户进行身份验证,这很麻烦。
使用 instafeed.js 之类的解决方案,我可以使用“error:”回调并执行一些 js 操作来隐藏小部件,以便我不会显示任何损坏的内容,或者也许在我想出它已过期之前显示一个带有静态内容的占位符。
不幸的是,我只能进行客户端实现,并且这个令牌过期似乎非常随机和未知,看起来这将是一场维护噩梦。
有人找到处理过期令牌的更好解决方案吗?我发现了一些插件和第三方解决方案,它们宣传在你的网站上获取你的 Feed,但它们也必须受到同样的限制……它们如何处理意外的过期令牌?我认为即使是服务器端实现也无法避免在令牌过期时进行手动更新……