Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for instagram #31

Open
pbiggar opened this issue Jan 27, 2024 · 4 comments
Open

add support for instagram #31

pbiggar opened this issue Jan 27, 2024 · 4 comments

Comments

@pbiggar
Copy link
Collaborator

pbiggar commented Jan 27, 2024

I had a real tough time replacing my instagram avatar, as I couldn't figure out how to download it on mobile. I had to go to chrome desktop and use developer tools to get the image.

@thamudi
Copy link
Contributor

thamudi commented Feb 8, 2024

I was looking into how we can do this. And form what I found, there is no "public" way to get specific user information without using a Key which requires a Meta developer account.

I will start looking in their docs "Meta: Instagram basic Display API doc" if its possible to implement this feature.

@thamudi
Copy link
Contributor

thamudi commented Feb 11, 2024

Okay I am at a dead end here.

I was able to find a way to fetch data from Instagram without authentication or using a token. However, this method only works if done locally and does not work when the request is made from a deployed site.

Here is a proof-of-concept repo I made [Link] with a deployed site on render.

The api link used to fetch data from Instagram is https://i.instagram.com/api/v1/users/web_profile_info?username=<enter-your-username-here>.

And in order to get a response you will need to provide the header with a X-Ig-App-Id: 936619743392459

My guess is that Instagram is whitelisting their domains in addition to localhost as well.

I tried to make the request seem like its coming from localhost on the deployed site by using a proxy, but it didn't work as well.

@Drew-Daniels
Copy link

Drew-Daniels commented Mar 13, 2024

Looks like you use their API like this (spoofing the User Agent to look as if it's coming from a mobile device):

$ curl "https://www.instagram.com/api/v1/users/web_profile_info/?username=<YOUR-IG-NAME-HERE>&hl=en" \
      -H "User-Agent: Instagram 126.0.0.25.121 Android (23/6.0.1; 320dpi; 720x1280; samsung; SM-A310F; a3xelte; samsungexynos7580; en_GB; 110937453)" \
      | jq '.data.user.profile_pic_url'

I'm able to get a response back with a URL to my profile picture (under profile_pic_url and profile_pic_url_hd), and for other users, but also a load of other data, so there's probably a way to tweak this so that it returns a subset of that data.

@sahilatahar
Copy link

Hi @thamudi, I've also tried to implement and it works fine on localhost. However, Instagram doesn't allow fetching data from either the client or the server.

Here is what I added in /api/retrive-profile-pic/route.ts

const fetchInstagramProfilePic = async (username: string) => {
  const endpoint = `https://i.instagram.com/api/v1/users/web_profile_info/?username=${username}`;

  const fetchOptions = {
    method: 'GET',
    headers: {
      Accept: '*/*',
      'X-Ig-App-Id': '936619743392459',
      'Sec-Fetch-Mode': 'cors',
      'Sec-Fetch-Dest': 'empty',
      'Sec-Fetch-User': '?1',
    },
  };
  const response = await fetch(endpoint, fetchOptions);

  const contentType = response.headers.get('content-type');

  //! Instagram return HTML after deploying the code
  if (!contentType || !contentType.includes('application/json')) {
    const text = await response.text();
    console.error('Unexpected response:', text);
    throw new Error('Expected JSON, received HTML');
  }

  const json = await response.json();
  if (!response.ok) {
    console.error('Error fetching profile info:', json);
    return null;
  }

  // Fetch the image and return it as base64 to avoid Instagram's CORS error
  const imgResponse = await fetch(json.data.user.profile_pic_url_hd);
  if (!imgResponse.ok) {
    return null;
  }

  const imageBlob = await imgResponse.blob();
  const imageBuffer = await imageBlob.arrayBuffer();
  const imageBufferBase64 = Buffer.from(imageBuffer).toString('base64');
  const imageBase64 = `data:image/jpeg;base64,${imageBufferBase64}`;

  return imageBase64;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants