GithubHelp home page GithubHelp logo

op-engineering / link-preview-js Goto Github PK

View Code? Open in Web Editor NEW
721.0 11.0 119.0 978 KB

⛓ Extract web links information: title, description, images, videos, etc. [via OpenGraph], runs on mobiles and node.

License: MIT License

JavaScript 0.45% TypeScript 99.02% Shell 0.52%
parsing extract js-library extract-information nodejs react-native http javascript typescript link

link-preview-js's Introduction

Link Preview JS

npm i link-preview-js

Before creating an issue

It's more than likely there is nothing wrong with the library:

  • It's very simple; fetch HTML, parse HTML, and search for OpenGraph HTML tags.
  • Unless HTML or the OpenGraph standard change, the library will not break
  • If the target website you are trying to preview redirects you to a login page the preview will fail, because it will parse the login page
  • If the target website does not have OpenGraph tags the preview will most likely fail, there are some fallbacks but in general, it will not work
  • You cannot preview (fetch) another web page from YOUR web page. This is an intentional security feature of browsers called CORS

If you use this library and find it useful please consider sponsoring me, open source takes a lot of time and effort.

Link Preview

Allows you to extract information from an HTTP URL/link (or parse an HTML string) and retrieve meta information such as title, description, images, videos, etc. via OpenGraph tags.

GOTCHAs

  • You cannot request a different domain from your web app (Browsers block cross-origin-requests). If you don't know how same-origin-policy works, here is a good intro, therefore this library works on Node.js and certain mobile run-times (Cordova or React-Native).
  • This library acts as if the user would visit the page, sites might re-direct you to sign-up pages, consent screens, etc. You can try to change the user-agent header (try with google-bot or with Twitterbot), but you need to work around these issues yourself.

API

getLinkPreview: you have to pass a string, doesn't matter if it is just a URL or a piece of text that contains a URL, the library will take care of parsing it and returning the info o the first valid HTTP(S) URL info it finds.

getPreviewFromContent: useful for passing a pre-fetched Response object from an existing async/etc. call. Refer to the example below for required object values.

import { getLinkPreview, getPreviewFromContent } from "link-preview-js";

// pass the link directly
getLinkPreview("https://www.youtube.com/watch?v=MejbOFk7H6c").then((data) =>
  console.debug(data)
);

////////////////////////// OR //////////////////////////

// pass a chunk of text
getLinkPreview(
  "This is a text supposed to be parsed and the first link displayed https://www.youtube.com/watch?v=MejbOFk7H6c"
).then((data) => console.debug(data));

////////////////////////// OR //////////////////////////

// pass a pre-fetched response object
// The passed response object should include, at minimum:
// {
//   data: '<!DOCTYPE...><html>...',     // response content
//   headers: {
//     ...
//     // should include content-type
//     content-type: "text/html; charset=ISO-8859-1",
//     ...
//   },
//   url: 'https://domain.com/'          // resolved url
// }
yourAjaxCall(url, (response) => {
  getPreviewFromContent(response).then((data) => console.debug(data));
});

Options

Additionally, you can pass an options object which should add more functionality to the parsing of the link

Property Name Result
imagesPropertyType (optional) (ex: 'og') Fetches images only with the specified property, meta[property='${imagesPropertyType}:image']
headers (optional) (ex: { 'user-agent': 'googlebot', 'Accept-Language': 'en-US' }) Add request headers to fetch call
timeout (optional) (ex: 1000) Timeout for the request to fail
followRedirects (optional) (default 'error') For security reasons, the library does not automatically follow redirects ('error' value), a malicious agent can exploit redirects to steal data, posible values: ('error', 'follow', 'manual')
handleRedirects (optional) (with followRedirects 'manual') When followRedirects is set to 'manual' you need to pass a function that validates if the redirectinon is secure, below you can find an example
resolveDNSHost (optional) Function that resolves the final address of the detected/parsed URL to prevent SSRF attacks
getLinkPreview("https://www.youtube.com/watch?v=MejbOFk7H6c", {
  imagesPropertyType: "og", // fetches only open-graph images
  headers: {
    "user-agent": "googlebot", // fetches with googlebot crawler user agent
    "Accept-Language": "fr-CA", // fetches site for French language
    // ...other optional HTTP request headers
  },
  timeout: 1000
}).then(data => console.debug(data));

SSRF Concerns

Doing requests on behalf of your users or using user-provided URLs is dangerous. One of such attack is trying to fetch a domain that redirects to localhost so the users get the contents of your server (doesn't affect mobile runtimes). To mitigate this attack you can use the resolveDNSHost option:

// example how to use node's dns resolver
const dns = require("node:dns");
getLinkPreview("http://maliciousLocalHostRedirection.com", {
  resolveDNSHost: async (url: string) => {
    return new Promise((resolve, reject) => {
      const hostname = new URL(url).hostname;
      dns.lookup(hostname, (err, address, family) => {
        if (err) {
          reject(err);
          return;
        }

        resolve(address); // if address resolves to localhost or '127.0.0.1' library will throw an error
      });
    });
  },
}).catch((e) => {
  // will throw a detected redirection to localhost
});

This might add some latency to your request but prevents loopback attacks.

Redirections

Same to SSRF, following redirections is dangerous, the library errors by default when the response tries to redirect the user. There are however some simple redirections that are valid (e.g. HTTP to HTTPS) and you might want to allow them, you can do it via:

await getLinkPreview(`http://google.com/`, {
  followRedirects: `manual`,
  handleRedirects: (baseURL: string, forwardedURL: string) => {
    const urlObj = new URL(baseURL);
    const forwardedURLObj = new URL(forwardedURL);
    if (
      forwardedURLObj.hostname === urlObj.hostname ||
      forwardedURLObj.hostname === "www." + urlObj.hostname ||
      "www." + forwardedURLObj.hostname === urlObj.hostname
    ) {
      return true;
    } else {
      return false;
    }
  },
});

Response

Returns a Promise that resolves with an object describing the provided link. The info object returned varies depending on the content type (MIME type) returned in the HTTP response (see below for variations of response). Rejects with an error if the response can not be parsed or if there was no URL in the text provided.

Text/HTML URL

{
  url: "https://www.youtube.com/watch?v=MejbOFk7H6c",
  title: "OK Go - Needing/Getting - Official Video - YouTube",
  siteName: "YouTube",
  description: "Buy the video on iTunes: https://itunes.apple.com/us/album/needing-getting-bundle-ep/id508124847 See more about the guitars at: http://www.gretschguitars.com...",
  images: ["https://i.ytimg.com/vi/MejbOFk7H6c/maxresdefault.jpg"],
  mediaType: "video.other",
  contentType: "text/html",
  charset: "utf-8"
  videos: [],
  favicons:["https://www.youtube.com/yts/img/favicon_32-vflOogEID.png","https://www.youtube.com/yts/img/favicon_48-vflVjB_Qk.png","https://www.youtube.com/yts/img/favicon_96-vflW9Ec0w.png","https://www.youtube.com/yts/img/favicon_144-vfliLAfaB.png","https://s.ytimg.com/yts/img/favicon-vfl8qSV2F.ico"]
}

Image URL

{
  url: "https://media.npr.org/assets/img/2018/04/27/gettyimages-656523922nunes-4bb9a194ab2986834622983bb2f8fe57728a9e5f-s1100-c15.jpg",
  mediaType: "image",
  contentType: "image/jpeg",
  favicons: [ "https://media.npr.org/favicon.ico" ]
}

Audio URL

{
  url: "https://ondemand.npr.org/anon.npr-mp3/npr/atc/2007/12/20071231_atc_13.mp3",
  mediaType: "audio",
  contentType: "audio/mpeg",
  favicons: [ "https://ondemand.npr.org/favicon.ico" ]
}

Video URL

{
  url: "https://www.w3schools.com/html/mov_bbb.mp4",
  mediaType: "video",
  contentType: "video/mp4",
  favicons: [ "https://www.w3schools.com/favicon.ico" ]
}

Application URL

{
  url: "https://assets.curtmfg.com/masterlibrary/56282/installsheet/CME_56282_INS.pdf",
  mediaType: "application",
  contentType: "application/pdf",
  favicons: [ "https://assets.curtmfg.com/favicon.ico" ]
}

License

MIT license

link-preview-js's People

Contributors

aaydin-tr avatar andresouza avatar ankitwandx avatar anshuman64 avatar brunokiafuka avatar bryansum avatar dependabot[bot] avatar doelgonzo avatar doeltw avatar itaibs avatar jvdheijden92 avatar lautarovc avatar legendar avatar luan0ap avatar lucidtheory avatar maxim-kolesnikov avatar megantaylor avatar nicolas-amabile avatar ospfranco avatar owjsub avatar prscms avatar ricocrivelli avatar sg5 avatar shubhamgoyal avatar skarian avatar stevenpal avatar uriva avatar wuori avatar yonathan06 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

link-preview-js's Issues

How to add a timeout to requests?

I'm trying to deal with links of closed sites like this one: bac.onec.dz.
If you try it here you will not gonna get a response form the server, because the site is closed, so it should be a timeout there.
That's my code (USING EXPRESS.JS):

app.get("/api", async function(request, response) {
  var url = request.query.url;
  if (url) {
    url = decodeURIComponent(url);
    if (!url.match(/^[a-zA-Z]+:\/\//)) url = "http://" + url;
    console.log(url);
    const data = await getLinkPreview(url).catch(err => response.send('URL Error'));
    if (data) response.send(data);
  } else {
    response.send("Query Error");
  }
});

And that's the project link: https://glitch.com/edit/#!/embed-js .
So how? and thanks :)

2.0.2 is completely busted

Try any url, same error. 2.0.0 & 2.0.1 work fine

This PR is the likely culprit #59

  err: Error: link-preview-js could not fetch link information TypeError: doc is not a function
      at C:\Users\Eric\workspace\suggestionbox\server\node_modules\link-preview-js\build\index.js:297:27
      at step (C:\Users\Eric\workspace\suggestionbox\server\node_modules\link-preview-js\build\index.js:33:23)
      at Object.next (C:\Users\Eric\workspace\suggestionbox\server\node_modules\link-preview-js\build\index.js:14:53)
      at fulfilled (C:\Users\Eric\workspace\suggestionbox\server\node_modules\link-preview-js\build\index.js:5:58)
      at processTicksAndRejections (internal/process/task_queues.js:97:5)

Use parseTextResponse when no content type

The current behavior is that an error is thrown if there is no content type header, or if it is not recognized.
Some websites does not send content type header (I have no idea why) or an unknown one for this library. For example https://mjml.io/try-it-live

Suggest a more tolerant approach and use parseTextResponse instead of throwing an error

CORB error message

Having this error messages:
Failed to load https://www.youtube.com/watch?v=MejbOFk7H6c: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

Cross-Origin Read Blocking (CORB) blocked cross-origin response https://www.youtube.com/watch?v=MejbOFk7H6c with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details.

Is there a fix or workaround for this?

[Bug] Instagram links have "Login * Instagram" without an image or description when previously they were showing both image and description

Describe the bug
This library was working great yesterday when I used an IG link to a public profile like https://www.instagram.com/p/CJ_qZYbF0A-/?igshid=1ge8l6mihp1xi, but today when I'm doing that, this is the data that is being returned

Object {
  "contentType": "text/html",
  "description": "Welcome back to Instagram. Sign in to check out what your friends, family & interests have been capturing & sharing around the world.",
  "favicons": Array [
    "https://www.instagram.com/static/images/ico/favicon-192.png/68d99ba29cc8.png",
    "https://www.instagram.com/static/images/ico/favicon.ico/36b3ee2d91ed.ico",
  ],
  "images": Array [],
  "mediaType": "website",
  "siteName": undefined,
  "title": "
Login • Instagram
",
  "url": "https://www.instagram.com/accounts/login/",
  "videos": Array [],
}

Expected behavior
For another link in the same public profile, https://www.instagram.com/reel/CKEzTVbFo_t/?igshid=rk2gmwdkxxqw, the data is returned as expected, with an image and description:

Object {
  "contentType": "text/html",
  "description": "feedmi_ • Original Audio",
  "favicons": Array [
    "https://www.instagram.com/static/images/ico/favicon-192.png/68d99ba29cc8.png",
    "https://www.instagram.com/static/images/ico/favicon.ico/36b3ee2d91ed.ico",
  ],
  "images": Array [
    "https://scontent-dfw5-1.cdninstagram.com/v/t51.2885-15/e35/139016296_454367992259185_875994249021980597_n.jpg?_nc_ht=scontent-dfw5-1.cdninstagram.com&_nc_cat=101&_nc_ohc=KYNMB1IkUFkAX-MwYmA&tp=1&oh=356ad26b1e9c84194b8bacbc28b0ce2f&oe=60322F73",
  ],
  "mediaType": "video",
  "siteName": "Instagram",
  "title": "feedmi_ on Instagram: Extra thick & gooey CEREAL COOKIES ft @heb’s Cerealology Fig & Nut Crunch cereal! 🍪 Did a little experimenting in the kitchen & these…",
  "url": "https://www.instagram.com/reel/CKEzTVbFo_t/?igshid=1mczqfx4hv5vk",
  "videos": Array [
    Object {
      "height": "1137",
      "secureUrl": "https://scontent-dfw5-2.cdninstagram.com/v/t50.2886-16/139529888_338872643819508_5061516141997524761_n.mp4?_nc_ht=scontent-dfw5-2.cdninstagram.com&_nc_cat=100&_nc_ohc=FUixYdUpUQsAX_41KVp&oe=60329B42&oh=eded19a7254e9175758248a25efe1160",
      "type": "video/mp4",
      "url": "https://scontent-dfw5-2.cdninstagram.com/v/t50.2886-16/139529888_338872643819508_5061516141997524761_n.mp4?_nc_ht=scontent-dfw5-2.cdninstagram.com&_nc_cat=100&_nc_ohc=FUixYdUpUQsAX_41KVp&oe=60329B42&oh=eded19a7254e9175758248a25efe1160",
      "width": "640",
    },
  ],
}

Smartphone (please complete the following information):

  • Device: iPhone XR
  • OS: 14.4
  • Running from React Native application

Youtube link return as website

Describe the bug
Youtube link return as website.

To Reproduce
Steps to reproduce the behavior:
getLinkPreview(link) .then(data => { console.log(data });

Expected behavior
Returns
{ url: "https://www.youtube.com/watch?v=MejbOFk7H6c", title: "OK Go - Needing/Getting - Official Video - YouTube", siteName: "YouTube", description: "Buy the video on iTunes: https://itunes.apple.com/us/album/needing-getting-bundle-ep/id508124847 See more about the guitars at: http://www.gretschguitars.com...", images: ["https://i.ytimg.com/vi/MejbOFk7H6c/maxresdefault.jpg"], mediaType: "video.other", contentType: "text/html; charset=utf-8" videos: [], favicons:["https://www.youtube.com/yts/img/favicon_32-vflOogEID.png","https://www.youtube.com/yts/img/favicon_48-vflVjB_Qk.png","https://www.youtube.com/yts/img/favicon_96-vflW9Ec0w.png","https://www.youtube.com/yts/img/favicon_144-vfliLAfaB.png","https://s.ytimg.com/yts/img/favicon-vfl8qSV2F.ico"] }

Screenshots
image

Unable to build

Attempting to run npm build with this package gives the following error: Failed to minify the code from this file: ./node_modules/react-native-link-preview/index.js:10

Here are the dependencies in my package.json:

"dependencies": {
    "firebase": "^4.3.0",
    "react": "^15.6.1",
    "react-dom": "^15.6.1",
    "react-native": "^0.47.1",
    "react-native-link-preview": "^1.2.0"
  },
  "devDependencies": {
    "react-scripts": "1.0.11"
  },

Happy to provide any extra info you need.

rename package name

This is generic enough to have react-native on the name

can we rename or create a new package that has a generic name?

link-preview?
link-preview-og?

Cannot read property 'parent' of undefined (react-native)

Describe the bug
Promise is rejected when trying to get the preview of any link. (iOS && Android)

To Reproduce
Steps to reproduce the behavior:

  1. import LinkPreview from 'link-preview-js';
  2. LinkPreview.getPreview('https://www.google.com').then(data => console.log('preview', data));

Expected behavior
Resolving the promise

Smartphone (please complete the following information):

  • Device: iPhone 6S
  • OS: iOS 12.4.1
  • React-Native: 0.61.5
  • link-preview-js: 1.6.0

Additional context

Unhandled promise rejection TypeError: Cannot read property 'parent' of undefined
    at Function.exports.update (parse.js:55)
    at module.exports (parse.js:17)
    at Function.exports.load (static.js:19)
    at parseTextResponse (index.js:112)
    at index.js:58
    at run (es6.promise.js:75)
    at es6.promise.js:92
    at flush (_microtask.js:18)
    at tryCallOne (core.js:37)
    at core.js:123

I'm not really sure, but I think the issue comes from cheerio-without-node-native.
Do you know if your project runs fine on react-native or does it need some tweaking to work ?

FaceBookPreview

Hi i am using Linkpreview Npm in that Doesn' show facebook Details correctly

[Bug] Fails to return correct info on youtube link on a react-native environment

Describe the bug
When using youtube link on react-native, youtube somehow redirects into the home page of the mobile version, effectively loosing all information relevant to the user

To Reproduce
Steps to reproduce the behavior:

  1. Use a youtube link with link-preview-js while on a react-native env (emulator reproduces the issue)
  2. The returned response will not contain the video information

Expected behavior
The returned object contains the video link and correct preview

Additional context
I don't think the problem lies within this library but rather, youtube taking a look into the user-agent and then redirecting the request into their mobile site which then returns the home page and not the right video link... which is all very stupid and convoluted but we can thank google for taking over the web

What url format are supported?

When I use the following text: D sad da winstonscoffee.com dsds I get this error. So what king of url formats are accepted?

Error: link-preview-js did not receive a valid a url or text
    at Object.<anonymous> (/Users/long1eu/IdeaProjects/yitnow/yitnow_api/grpc/node_modules/link-preview-js/build/index.js:259:31)
    at step (/Users/long1eu/IdeaProjects/yitnow/yitnow_api/grpc/node_modules/link-preview-js/build/index.js:33:23)
    at Object.next (/Users/long1eu/IdeaProjects/yitnow/yitnow_api/grpc/node_modules/link-preview-js/build/index.js:14:53)
    at /Users/long1eu/IdeaProjects/yitnow/yitnow_api/grpc/node_modules/link-preview-js/build/index.js:8:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/long1eu/IdeaProjects/yitnow/yitnow_api/grpc/node_modules/link-preview-js/build/index.js:4:12)
    at Object.getLinkPreview (/Users/long1eu/IdeaProjects/yitnow/yitnow_api/grpc/node_modules/link-preview-js/build/index.js:246:12)
    at _linkPreview (/Users/long1eu/IdeaProjects/yitnow/yitnow_api/grpc/dist/controllers/helpers/link_marker.js:39:14)
    at Object.linkPreview (/Users/long1eu/IdeaProjects/yitnow/yitnow_api/grpc/dist/controllers/helpers/link_marker.js:64:16)
    at Campaigns.createCampaignObject (/Users/long1eu/IdeaProjects/yitnow/yitnow_api/grpc/dist/controllers/yitnow/campaigns.js:89:36)

Error: link-preview-js could not fetch link information TypeError: Cannot read property 'parent' of undefined

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Enter the url https://www.google.com

return new Promise((resolve, reject) => { getLinkPreview('https://www.google.com').then(res => { resolve(res); }) .catch(err => { return null; }) });

Expected behavior
A complete details about the link

Screenshots
Screenshot 2020-01-24 at 11 29 29 AM

Smartphone (please complete the following information):

  • Device: iPhone 6s Plus
  • OS: iOS 13
  • React-native application
    "react-native": "^0.60.5",
    "link-preview-js": "^2.0.1",

Design Question

Hi all,

I have a design question regarding using this in my app.

Shuold the link preview be called when the user is creating a new post and then saved in the database to be retreieved for all future read requets?

OR

Should be called for every read request (i.e everytime a user views the feed? )

Appreciate any answers. Thanks

XMLHttpRequest is not defined

It looks like #29 broke support for node, specifically since XMLHttpRequest isn't a built-in for node.

I'm using v1.2.1 for now.

SyntaxError: Cannot use import statement outside a module since version 2.1.1

Describe the bug
I'm getting the following build time error when attempting to use the package in a locally running node app:

/node_modules/link-preview-js/build/index.js:10
import cheerio from "cheerio-without-node-native";
^^^^^^

SyntaxError: Cannot use import statement outside a module

Initially I thought it was my config but rolling back to version 2.1.0 (the one with the security issues) works fine. This leads me to believe that its something to do with the internal usage of Cheerio.

React-Native-Link-Preview did not find a link in the text

Describe the bug
This bug only happens on android platform. All working links tested on iOS return an error on Android.
The error is React-Native-Link-Preview did not find a link in the text

I am not sure why that happens on Android.

To Reproduce

const getUrlData = async () => {
    try {
      const data = await LinkPreview.getPreview(props.url);
      console.log('url data', data);
      setUrlData({
        ...data,
        images: data.mediaType == 'image' ? data.url : data.images[0],
      });
    } catch (error) {
      console.error(error);
      Alert.alert('Link is invalid', '', [
        { text: 'OK', onPress: () => props.removeUrl(props.urlIndex) },
      ]);
    }
    setIsLoading(false);
  };

Expected behavior
Link and other metadata returned

Screenshots
image

Desktop (please complete the following information):

  • OS: MacOS Catalina

Smartphone (please complete the following information):

  • Device: Android Emulator

Additional context

Compile to ES5 and publish to NPM

I'm trying to compile a project using this module, but upon running npm run build I get:


Creating an optimized production build...
Failed to compile.

Failed to minify the code from this file: 

 	./node_modules/react-native-link-preview/index.js:7 

Read more here: http://bit.ly/2tRViJ9

from: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-build-fails-to-minify

Some third-party packages don't compile their code to ES5 before publishing to npm. This often causes problems in the ecosystem because neither browsers (except for most modern versions) nor some tools currently support all ES6 features. We recommend to publish code on npm as ES5 at least for a few more years.


To resolve this:
Open an issue on the dependency's issue tracker and ask that the package be published pre-compiled.```

Please pre-compile and publish 

buildToolsVersion error on Android

Hey, could you please update buildToolsVersion because I've get an error The SDK Build Tools revision (23.0.1) is too low for project ':react-native-link-preview'. Minimum required is 25.0.0

support meta name="" as a possible alternative to meta property="" for title, siteName, mediaType, images, videos

the name attribute on a meta tag is equally valid and arguably more widely used. it should be supported as an alternative to the property attribute.

this is being done in a couple of places already (description checks for the name attribute first, then looks for the property attribute, for example) and could easily be expanded for the other properties.

i'd be happy to work on a PR for this, if its an acceptable idea.

A problem with Cloudflare.

Describe the bug
I was working on an embeds system, and because sometimes link-preview-js gives a valid image/favicon URL and sometimes not, and sometimes there is no URL at all, I tried to test it alone to check if its mediaType is an image.
The problem is that link-preview-js won't work with some Cloudflare protected domains, you will see on the title: Access denied | domain used Cloudflare to restrict access.
For example: Discord, the main page should work without any problem, but its favicon URL has this problem.

To Reproduce
Steps to reproduce the behavior:

  1. Go to this URL.
  2. See the result:

image

Expected behavior
Something like this:

image.

Screenshots
The embed:

image

Desktop (please complete the following information):
Smartphone (please complete the following information):

Node:

  • Node version: 10.x
  • Link-preview-js version: ^2.0.1

Additional context

How to fake location?

I'm using this library and it works great. However I have some problems. My server located in Germany. But my users locate different places. For example I live in Turkey but when I make a request it returns german language. How Can I fake my location?

Support links that do not contain http/https prefix.

Is your feature request related to a problem? Please describe.
Currently, the lib only supports full URLs (https//).

Describe the solution you'd like
Allow any URL format to be supported, by extending the URL extractor.

ie: [github.com | https://github.com | * ].

Describe alternatives you've considered
N/A

Additional context
N/A

not working for android

react-native-link-preview return empty response['images'] in case of android works fine in ios

Version 2.1.5 broke our usage of require

Hello,

With version 2.1.5 (or 2.1.4) there was this change in the package.json:

  "exports": {
    "import": "build/index.js"
  },

We are using this awesome library in our CommonJS node service and import the main functions like this:

const {getLinkPreview} = require('link-preview-js');

Now with the newest changes we are getting this error

internal/modules/cjs/loader.js:595
    throw new ERR_PACKAGE_PATH_NOT_EXPORTED(
    ^

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main resolved in /our-service/node_modules/link-preview-js/package.json

Adding

  "exports": {
    "require": "./build/index.js",
    "import": "build/index.js"
  },

to the package.json seems to resolve the issue as it probably makes the exports available for require too.

I am quite new to the "exports" property in the package.json and the js import world, so I am not sure if there was an intention to only make this lib available for ES modules? Or is it possible to have this change in the library? Would be happy to provide a proper PR if needed as well.
Or is there another way that we can require the functions?

Thank you in advance on your opinion / advice!

Fetch images?

Hi!

First of, great package. Works like a charm!
One thing I'm missing is fetching image links. It would be nice it the package did this.

Like this one:
https://i.imgur.com/lEzmnXr.jpg

I would like it because it somehow expected when posting and image in e.g. a feed (where I use this) that it would be fetched. Thoughts?

Different response

Hello, I was testing it, it works fine for most of the sites but when trying youtube and your example this is what I get

title: "YouTube",
description: undefined,
mediaType: "website", 
images: Array[0],
description : undefined,
images : Array[0],
mediaType : "website",
title : "YouTube",
url : "https://www.youtube.com/watch?v=MejbOFk7H6c",
videos : Array[0],

Maximum call stack size exceeded

For some reason when I run this:
let response = await LinkPreview.getPreview(https://i.imgur.com/LDFO6YV.png);

I get:
RangeError: Maximum call stack size exceeded [0] at Object.exports.getName (C:\Users\project\packages\server\node_modules\domutils\lib\traversal.js:22:27)

'React/RCTDefines.h' file not found

With version 1.3.4, when I try to build within Xcode (expo detached mode, react-native link done), I have this error coming from RNReactNativeLinkPreview.h -> #import "RCTBridgeModule.h" -> #import <React/RCTDefines.h>

'React/RCTDefines.h' file not found

As stated here, I have the Header Search Paths set with Pods/Headers/Public/React

You can give it another go, but add some more complex tests to make sure nothing breaks, here is the code for the test I used:

You can give it another go, but add some more complex tests to make sure nothing breaks, here is the code for the test I used:

it(`should extract link info from URL without protocol prefixes 3`, async () => {
    const largeString = `"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
    Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC
    
    "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"
    1914 translation by H. Rackham
    
    "But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"
    Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC
    
    "At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."
    1914 translation by H. Rackham
    
    "On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains.
    
    [email protected]

    github.com/ospfranco/link-preview-js
    `;

    const linkInfo: any = await getLinkPreview(
      largeString,
      { headers: { "Accept-Language": `en-US` } },
    );

    expect(linkInfo.url).toEqual(`https://github.com/ospfranco/link-preview-js`);
    expect(linkInfo.siteName).toEqual(`GitHub`);
    expect(linkInfo.title).toEqual(`ospfranco/link-preview-js`);
    expect(linkInfo.description).toBeTruthy();
    expect(linkInfo.mediaType).toEqual(`object`);
    expect(linkInfo.images.length).toEqual(1);
    expect(linkInfo.images[0]).toBeTruthy();
    expect(linkInfo.videos.length).toEqual(0);
    expect(linkInfo.favicons[0]).not.toBe(``);
    expect(linkInfo.contentType.toLowerCase()).toEqual(
      `text/html; charset=utf-8`,
    );
  });

Originally posted by @ospfranco in #64 (comment)

Unknown MIME type for URL

Hello @ospfranco,
when I run the following code:
LinkPreview.getPreview('https://www.macys.com/shop/product/jaywalker-mens-animal-print-jacket?ID=5219568&CategoryID=80617') .then(data => console.debug(data));

I always get the following Promise Rejection. No matter which URL I use or even if its just a string:
Possible Unhandled Promise Rejection (id: 0): Object { "error": "React-Native-Preview-Link: Unknown MIME type for URL.", }

Is there something obvious I'm missing?

support optional proxy url

we're using a proxy url to get around CORS, would be really cool if we could pass the proxy url in via the options object, to be used for the fetch request. the response should retain the original url.

i'd be happy to work on a PR for this if its an acceptable idea.

RN 0.63.X might be imcompatible (cheerio-without-native)

According to this ticket:

cheeriojs/cheerio#1169

Cheerio-without-native will have issues on the latest version of react-native, cheerio-without-native has been thouroughly abandoned by now... I'm considering also closing the project, since I don't have time to create my own parsing library.

In any case, need to look it up and see if there is anything that could be done.

fetch call crashing android

Using react-native 0.38 the fetch call seems to be the cause of a crash on Android for certain URLs, ones that point directly to binary files such as images or pdf docs.

screen shot 2016-12-12 at 10 07 38 am

We attempted replacing this library with the react-native-page-previewer library only to find we received the same crash, after investigating we realised that the crash was coming from react-natives fetch and only occurs when in either release mode or if in debug mode without connecting to remote debugger.
Here's a URL that crashes when fetching: https://static.mailchimp.com/web/features/mc-features-report.jpg

We've managed to work around this bug by replacing the rn fetch call with react-native-fetch-blob library

if(detectedUrl) {
        RNFetchBlob.fetch('GET', detectedUrl)
        .then(response => response.text())
        .then(text => {
          resolve(this._parseResponse(text, detectedUrl))
        })
        .catch(err =>
          reject(err)
      )

Get youtube channel name - react native

Hi,
I was using react-native-link-preview before. I've one use case where I want the name of the youtube channel. So, i forked the lib and got the channel id using the below line...
channel_id = doc('button[class="yt-uix-button yt-uix-button-size-default yt-uix-button-subscribe-branded yt-uix-button-has-icon no-icon-markup yt-uix-subscription-button yt-can-buffer yt-uix-servicelink vve-check"]').attr('data-channel-external-id');

But after the library update, there's some issue with the channel id...

Can anyone plz help?
Thanks!

Access Denied on Android

1. Response on android (WORKS ON IOS):

{
url: 'https://www.zomato.com',
title: 'Access Denied',
description: undefined,
mediaType: 'website',
images: [],
videos: []
}

2. Even most of the time the 'images' array is empty for valid urls.

 The 'title' field returns correct names but 'images' array is empty.

Unable to build on android

I am getting this error while loading js bundle
Unable to resolve module streamfrom/Users/shubhnik/repos/rides_project/node_modules/cheerio-without-node-native/node_modules/parse5/lib/parser/parser_stream.js: Module stream does not exist in the Haste module map

Versions:
"react-native-link-preview": "^1.4.0",
"react-native": "0.56.0",

What could I be doing wrong? Let me know if more information is needed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.