简体   繁体   English

如何使用 API 将图片发布到 Instagram

[英]How to post pictures to instagram using API

I am building a php application which needs to post the user uploaded picture directly to Instagram, but after a quick search i found that there is no such function in the API:( and it feels weird... because they should provide one. I am not sure if there is any other way (except the apps for android and iOS) to upload picture using php. Kindly give me any sort of idea if there is any possibility.我正在构建一个 php 应用程序,该应用程序需要将用户上传的图片直接发布到 Instagram,但经过快速搜索后,我发现 API 中没有这样的 function。我不确定是否有任何其他方式(android 和 iOS 的应用程序除外)使用 php 上传图片。如果有任何可能,请给我任何想法。

I also read this,我也读过这个,

How do I share a link and photo with Instagram using PHP 如何使用 PHP 与 Instagram 共享链接和照片

Update:更新:

Instagram are now banning accounts and removing the images based on this method. Instagram 现在正在禁止帐户并基于此方法删除图像。 Please use with caution.请谨慎使用。


It seems that everyone who has answered this question with something along the lines of it can't be done is somewhat correct.似乎每个回答这个问题的人都回答了一些类似的事情it can't be done在某种程度上是正确的。 Officially, you cannot post a photo to Instagram with their API.正式地,您不能使用他们的 API 将照片发布到 Instagram。 However, if you reverse engineer the API, you can.但是,如果您对 API 进行反向工程,则可以。

function SendRequest($url, $post, $post_data, $user_agent, $cookies) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://i.instagram.com/api/v1/'.$url);
    curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

    if($post) {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    }

    if($cookies) {
        curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');            
    } else {
        curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
    }

    $response = curl_exec($ch);
    $http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

   return array($http, $response);
}

function GenerateGuid() {
     return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', 
            mt_rand(0, 65535), 
            mt_rand(0, 65535), 
            mt_rand(0, 65535), 
            mt_rand(16384, 20479), 
            mt_rand(32768, 49151), 
            mt_rand(0, 65535), 
            mt_rand(0, 65535), 
            mt_rand(0, 65535));
}

function GenerateUserAgent() {  
     $resolutions = array('720x1280', '320x480', '480x800', '1024x768', '1280x720', '768x1024', '480x320');
     $versions = array('GT-N7000', 'SM-N9000', 'GT-I9220', 'GT-I9100');
     $dpis = array('120', '160', '320', '240');

     $ver = $versions[array_rand($versions)];
     $dpi = $dpis[array_rand($dpis)];
     $res = $resolutions[array_rand($resolutions)];

     return 'Instagram 4.'.mt_rand(1,2).'.'.mt_rand(0,2).' Android ('.mt_rand(10,11).'/'.mt_rand(1,3).'.'.mt_rand(3,5).'.'.mt_rand(0,5).'; '.$dpi.'; '.$res.'; samsung; '.$ver.'; '.$ver.'; smdkc210; en_US)';
 }

function GenerateSignature($data) {
     return hash_hmac('sha256', $data, 'b4a23f5e39b5929e0666ac5de94c89d1618a2916');
}

function GetPostData($filename) {
    if(!$filename) {
        echo "The image doesn't exist ".$filename;
    } else {
        $post_data = array('device_timestamp' => time(), 
                        'photo' => '@'.$filename);
        return $post_data;
    }
}


// Set the username and password of the account that you wish to post a photo to
$username = 'ig_username';
$password = 'ig_password';

// Set the path to the file that you wish to post.
// This must be jpeg format and it must be a perfect square
$filename = 'pictures/test.jpg';

// Set the caption for the photo
$caption = "Test caption";

// Define the user agent
$agent = GenerateUserAgent();

// Define the GuID
$guid = GenerateGuid();

// Set the devide ID
$device_id = "android-".$guid;

/* LOG IN */
// You must be logged in to the account that you wish to post a photo too
// Set all of the parameters in the string, and then sign it with their API key using SHA-256
$data ='{"device_id":"'.$device_id.'","guid":"'.$guid.'","username":"'.$username.'","password":"'.$password.'","Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"}';
$sig = GenerateSignature($data);
$data = 'signed_body='.$sig.'.'.urlencode($data).'&ig_sig_key_version=4';
$login = SendRequest('accounts/login/', true, $data, $agent, false);

if(strpos($login[1], "Sorry, an error occurred while processing this request.")) {
    echo "Request failed, there's a chance that this proxy/ip is blocked";
} else {            
    if(empty($login[1])) {
        echo "Empty response received from the server while trying to login";
    } else {            
        // Decode the array that is returned
        $obj = @json_decode($login[1], true);

        if(empty($obj)) {
            echo "Could not decode the response: ".$body;
        } else {
            // Post the picture
            $data = GetPostData($filename);
            $post = SendRequest('media/upload/', true, $data, $agent, true);    

            if(empty($post[1])) {
                 echo "Empty response received from the server while trying to post the image";
            } else {
                // Decode the response 
                $obj = @json_decode($post[1], true);

                if(empty($obj)) {
                    echo "Could not decode the response";
                } else {
                    $status = $obj['status'];

                    if($status == 'ok') {
                        // Remove and line breaks from the caption
                        $caption = preg_replace("/\r|\n/", "", $caption);

                        $media_id = $obj['media_id'];
                        $device_id = "android-".$guid;
                        $data = '{"device_id":"'.$device_id.'","guid":"'.$guid.'","media_id":"'.$media_id.'","caption":"'.trim($caption).'","device_timestamp":"'.time().'","source_type":"5","filter_type":"0","extra":"{}","Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"}';   
                        $sig = GenerateSignature($data);
                        $new_data = 'signed_body='.$sig.'.'.urlencode($data).'&ig_sig_key_version=4';

                       // Now, configure the photo
                       $conf = SendRequest('media/configure/', true, $new_data, $agent, true);

                       if(empty($conf[1])) {
                           echo "Empty response received from the server while trying to configure the image";
                       } else {
                           if(strpos($conf[1], "login_required")) {
                                echo "You are not logged in. There's a chance that the account is banned";
                            } else {
                                $obj = @json_decode($conf[1], true);
                                $status = $obj['status'];

                                if($status != 'fail') {
                                    echo "Success";
                                } else {
                                    echo 'Fail';
                                }
                            }
                        }
                    } else {
                        echo "Status isn't okay";
                    }
                }
            }
        }
    }
}

Just copy and paste the code above in your text editor, change the few variables accordingly and VOILA!只需将上面的代码复制并粘贴到您的文本编辑器中,相应地更改几个变量,瞧! I wrote an article about this and I've done it many times.我写了一篇关于这个的文章,我已经做过很多次了。 See a demo here .在此处查看演示。

If you read the link you shared, the accepted answer is:如果您阅读了共享的链接,则接受的答案是:

You cannot post pictures to Instagram via the API.您不能通过 API 将图片发布到 Instagram。

Instagram have now said this: Instagram现在这样说:

Now you can post your content using Instagram APIs (New) effects from 26th Jan 2021 !现在,您可以从 2021 年 1 月 26 日起使用 Instagram API(新)效果发布您的内容!

https://developers.facebook.com/blog/post/2021/01/26/introducing-instagram-content-publishing-api/ https://developers.facebook.com/blog/post/2021/01/26/introducing-instagram-content-publishing-api/

Hopefully you have some luck here.希望你在这里有一些运气。

UPDATE It is now possible:更新现在可以:

https://developers.facebook.com/docs/instagram-api/guides/content-publishing https://developers.facebook.com/docs/instagram-api/guides/content-publishing

The Content Publishing API is a subset of Instagram Graph API endpoints that allow you to publish media objects.内容发布 API 是 Instagram Graph API 端点的子集,允许您发布媒体对象。 Publishing media objects with this API is a two step process — you first create a media object container, then publish the container on your Business Account.使用此 API 发布媒体对象是一个两步过程 - 您首先创建一个媒体对象容器,然后在您的企业帐户上发布该容器。

Instagram now allows businesses to schedule their posts, using the new Content Publishing Beta endpoints. Instagram 现在允许企业使用新的 Content Publishing Beta 端点来安排他们的帖子。

https://developers.facebook.com/blog/post/2018/01/30/instagram-graph-api-updates/ https://developers.facebook.com/blog/post/2018/01/30/instagram-graph-api-updates/

However, this blog post - https://business.instagram.com/blog/instagram-api-features-updates - makes it clear that they are only opening that API to their Facebook Marketing Partners or Instagram Partners.但是,这篇博文 - https://business.instagram.com/blog/instagram-api-features-updates - 清楚地表明他们只向他们的 Facebook 营销合作伙伴或 Instagram 合作伙伴开放该 API。

To get started with scheduling posts, please work with one of our Facebook Marketing Partners or Instagram Partners.要开始安排帖子,请与我们的 Facebook 营销合作伙伴或 Instagram 合作伙伴之一合作。

This link from Facebook - https://developers.facebook.com/docs/instagram-api/content-publishing - lists it as a closed beta.这个来自 Facebook 的链接 - https://developers.facebook.com/docs/instagram-api/content-publishing - 将其列为封闭测试版。

The Content Publishing API is in closed beta with Facebook Marketing Partners and Instagram Partners only. Content Publishing API 仅与 Facebook 营销合作伙伴和 Instagram 合作伙伴进行封闭测试。 We are not accepting new applicants at this time.我们目前不接受新的申请者。

But this is how you would do it:但这就是你的做法:

You have a photo at...你有一张照片在...

https://www.example.com/images/bronz-fonz.jpg

You want to publish it with the hashtag "#BronzFonz".您想使用标签“#BronzFonz”发布它。

You could use the /user/media edge to create the container like this:您可以使用/user/media边缘来创建容器,如下所示:

POST graph.facebook.com 
  /17841400008460056/media?
    image_url=https%3A%2F%2Fwww.example.com%2Fimages%2Fbronz-fonz.jpg&
    caption=%23BronzFonz

This would return a container ID (let's say 17889455560051444), which you would then publish using the /user/media_publish edge, like this:这将返回一个容器 ID(比如说 17889455560051444),然后您将使用 /user/media_publish 边缘发布它,如下所示:

POST graph.facebook.com
  /17841405822304914/media_publish
    ?creation_id=17889455560051444

This example from the docs .这个例子来自docs

I tried using IFTTT and many other services but all were doing things or post from Instagram to another platform not to Instagram.我尝试使用 IFTTT 和许多其他服务,但所有人都在做事或从 Instagram 发布到另一个平台而不是 Instagram。 I read more to found Instagram does not provide any such API as of now.我阅读更多内容发现 Instagram 目前不提供任何此类 API。

Using blue stack is again involving heavy installation and doing things manually only.使用蓝色堆栈再次涉及繁重的安装和仅手动执行操作。

However, you can use your Google Chrome on the desktop version to make a post on Instagram.但是,您可以使用桌面版 Google Chrome 在 Instagram 上发帖。 It needs a bit tweak.它需要一点调整。

  1. Open your chrome and browse Instagram.com打开你的 chrome 浏览 Instagram.com
  2. Go to inspect element by right clicking on chrome.通过右键单击 chrome 来检查元素。
  3. From top right corener menu drop down on developer tools, select more tool.从开发人员工具的右上角 corener 菜单下拉菜单中,选择更多工具。
  4. Further select network conditions.进一步选择网络条件。
  5. In the network selection section, see the second section there named user agent.在网络选择部分,请参阅第二部分,其中命名为用户代理。
  6. Uncheck select automatically , and select chrome for Android from the list of given user agent.取消选中自动选择,然后从给定的用户代理列表中选择chrome for Android
  7. Refresh your Instagram.com page.刷新您的 Instagram.com 页面。

You will notice a change in UI and the option to make a post on Instagram.您会注意到 UI 的变化以及在 Instagram 上发帖的选项。 Your life is now easy.你现在的生活很轻松。 Let me know an easier way if you can find any.如果您能找到任何方法,请告诉我一个更简单的方法。

在此处输入图像描述

I wrote on https://www.inteligentcomp.com/2018/11/how-to-upload-to-instagram-from-pc-mac.html about it.我在https://www.inteligentcomp.com/2018/11/how-to-upload-to-instagram-from-pc-mac.html上写了关于它的文章。

Working Screenshot工作截图

在此处输入图像描述

For anyone who is searching for a solution about posting to Instagram using AWS lambda and puppeteer ( chrome-aws-lambda ).对于正在寻找有关使用AWS lambdapuppeteer ( chrome-aws-lambda ) 发布到 Instagram 的解决方案的任何人。 Noted that this solution allow you to post 1 photo for each post only .请注意,此解决方案仅允许您为每个帖子发布 1 张照片 If you are not using lambda, just replace chrome-aws-lambda with puppeteer .如果您不使用 lambda,只需将chrome-aws-lambda替换为puppeteer

For the first launch of lambda, it is normal that will not work because instagram detects “Suspicious login attempt” .首次启动 lambda 时,由于 instagram 检测到“可疑登录尝试”而无法正常工作。 Just goto instagram page using your PC and approve it , everything should be fine.只需使用您的 PC 转到 Instagram 页面并批准它,一切都应该没问题。

Here's my code, feel free to optimize it:这是我的代码,请随时优化:

// instagram.js
const chromium = require('chrome-aws-lambda');

const username = process.env.IG_USERNAME;
const password = process.env.IG_PASSWORD;

module.exports.post = async function(fileToUpload, caption){
    const browser = await chromium.puppeteer.launch({
        args: [...chromium.args, '--window-size=520,700'],
        defaultViewport: chromium.defaultViewport,
        executablePath: await chromium.executablePath,
        headless: false,
        ignoreHTTPSErrors: true,
    });
    const page = await browser.newPage();
    await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) FxiOS/7.5b3349 Mobile/14F89 Safari/603.2.4');
    await page.goto('https://www.instagram.com/', {waitUntil: 'networkidle2'});
    
    const [buttonLogIn] = await page.$x("//button[contains(., 'Log In')]");
    if (buttonLogIn) {
        await buttonLogIn.click();
    }

    await page.waitFor('input[name="username"]');
    await page.type('input[name="username"]', username)
    await page.type('input[name="password"]', password)
    await page.click('form button[type="submit"]');

    await page.waitFor(3000);
    const [buttonSaveInfo] = await page.$x("//button[contains(., 'Not Now')]");
    if (buttonSaveInfo) {
        await buttonSaveInfo.click();
    }

    await page.waitFor(3000);
    const [buttonNotificationNotNow] = await page.$x("//button[contains(., 'Not Now')]");
    const [buttonNotificationCancel] = await page.$x("//button[contains(., 'Cancel')]");
    if (buttonNotificationNotNow) {
        await buttonNotificationNotNow.click();
    } else if (buttonNotificationCancel) {
        await buttonNotificationCancel.click(); 
    }

    await page.waitFor('form[enctype="multipart/form-data"]');
    const inputUploadHandle = await page.$('form[enctype="multipart/form-data"] input[type=file]');

    await page.waitFor(5000);
    const [buttonPopUpNotNow] = await page.$x("//button[contains(., 'Not Now')]");
    const [buttonPopUpCancel] = await page.$x("//button[contains(., 'Cancel')]");
    if (buttonPopUpNotNow) {
        await buttonPopUpNotNow.click();
    } else if (buttonPopUpCancel) {
        await buttonPopUpCancel.click(); 
    }

    await page.click('[data-testid="new-post-button"]')
    await inputUploadHandle.uploadFile(fileToUpload);

    await page.waitFor(3000);
    const [buttonNext] = await page.$x("//button[contains(., 'Next')]");
    await buttonNext.click();

    await page.waitFor(3000);
    await page.type('textarea', caption);

    const [buttonShare] = await page.$x("//button[contains(., 'Share')]");
    await buttonShare.click();
    await page.waitFor(3000);

    return true;
};
// handler.js

await instagram.post('/tmp/image.png', '#text');

it must be local file path, if it is url, download it to /tmp folder first .必须是本地文件路径,如果是url, 请先下载到/tmp文件夹

Updated:更新:

Instagram is blocking all suspicious login attempt now unless you approve it manually every time it executed. Instagram 现在正在阻止所有可疑的登录尝试,除非您每次执行时都手动批准它。 To solve that, better to save your cookies as json and import it to puppeteer.为了解决这个问题,最好将您的 cookie 保存为 json 并将其导入 puppeteer。

对于发现此问题的用户,您可以使用 iPhone 挂钩将照片传递到 iPhone 上的 Instagram 共享流程(从您的应用程序到过滤器屏幕):http: //help.instagram.com/355896521173347除此之外,目前没有方式在 api 的版本 1 中。

If it has a UI, it has an "API".如果它有一个 UI,它就有一个“API”。 Let's use the following example: I want to publish the pic I use in any new blog post I create.让我们使用以下示例:我想发布我在我创建的任何新博客文章中使用的图片。 Let's assume is Wordpress.假设是 Wordpress。

  1. Create a service that is constantly monitoring your blog via RSS.创建一个通过 RSS 持续监控您的博客的服务。
  2. When a new blog post is posted, download the picture.发布新博客文章时,请下载图片。
  3. (Optional) Use a third party API to apply some overlays and whatnot to your pic. (可选)使用第三方 API 将一些叠加层等应用到您的图片。
  4. Place the photo in a well-known location on your PC or server.将照片放在您的 PC 或服务器上的已知位置。
  5. Configure Chrome (read above) so that you can use the browser as a mobile.配置 Chrome(阅读上文),以便您可以将浏览器用作移动设备。
  6. Using Selenium (or any other of those libraries), simulate the entire process of posting on Instagram.使用 Selenium(或任何其他此类库),模拟在 Instagram 上发布的整个过程。
  7. Done.完毕。 You should have it.你应该拥有它。

There is no API to post photo to instagram using API , But there is a simple way is that install google extension " User Agent " it will covert your browser to android mobile chrome version .没有使用 API 将照片发布到 instagram 的 API,但有一种简单的方法是安装 google 扩展程序“用户代理”,它会将您的浏览器转换为 android 移动 chrome 版本。 Here is the extension link https://chrome.google.com/webstore/detail/user-agent-switcher/clddifkhlkcojbojppdojfeeikdkgiae?utm_source=chrome-ntp-icon这是扩展链接https://chrome.google.com/webstore/detail/user-agent-switcher/clddifkhlkcojbojppdojfeeikdkgiae?utm_source=chrome-ntp-icon

just click on extension icon and choose chrome for android and open Instagram.com只需单击扩展图标并选择 chrome for android 并打开 Instagram.com

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM