Skip to content

About

Node library to parse social profile urls out of text.

Resources

Stars

1 star

Watchers

3 watching

Forks

Latest commit

 

History

48 Commits

Folders and files

Repository files navigation

social-profile-url-parser

Node library to parse social profile urls out of text.

npm install @salesflare/social-profile-url-parser
const SocialProfileUrlParser = require('@salesflare/social-profile-url-parser');

const result = SocialProfileUrlParser.parse(`
    slack   angellist   https://angel.co/slack
    SlackHQ twitter     https://twitter.com/SlackHQ
    slack   linkedin    https://www.linkedin.com/company/tiny-speck-inc
`)
result === [
    {
        type: 'angellist',
        type_name: 'AngelList',
        id: 'slack',
        url: 'https://angel.co/slack',
        canonical_url: 'https://angel.co/slack'
    },
    {
        type: 'linkedin',
        type_name: 'LinkedIn',
        id: 'tiny-speck-inc',
        url: 'https://www.linkedin.com/company/tiny-speck-inc',
        kind: 'company',
        canonical_url: 'https://linkedin.com/company/tiny-speck-inc'
    },
    {
        type: 'twitter',
        type_name: 'Twitter',
        id: 'SlackHQ',
        url: 'https://twitter.com/SlackHQ',
        canonical_url: 'https://x.com/SlackHQ'
    }
];

What you get back

parse returns an array with one entry per profile it finds, in the order the types are listed under Supported types rather than the order they appear in the text.

property always present what it holds
type yes The platform, one of the keys under Supported types
type_name yes The platform's display name, for example LinkedIn
id yes The identifying part of the url
url yes The url as it appeared in the text
kind no What the url points at, see kind
canonical_url no The profile in one agreed upon form, see canonical_url

id takes whatever form the platform uses: the profile slug for most types, the subdomain for Tumblr and WordPress, an opaque or numeric id for Blogger, VK, Odnoklassniki and LinkedIn's legacy urls, and the business slug for Yelp. It is returned as it was written, so casing is preserved.

id holds only the identifying part, so a query string and a fragment are left off: facebook.com/slackhq?lang=en has an id of slackhq. The one exception is LinkedIn's profile/view?id= urls, where the id is what follows the ? rather than what precedes it.

url keeps the protocol, subdomain, path, query string and fragment that were written, so you can always show or store the url as it was found. The only thing dropped is punctuation that closed the sentence around it, so a url written as (https://x.com/salesflare). does not come back carrying ).. Use canonical_url when you want to compare two urls.

Results are de-duplicated on type, the kind where the platform has one, and id. A profile that appears twice in the same text written two different ways collapses into one entry, holding the last url seen. Since the query string is not part of id, facebook.com/slackhq and facebook.com/slackhq?lang=en count as the same profile.

kind is part of the identity because an id is only unique within the namespace it was written in, so a person and a company can share one. linkedin.com/in/foo and linkedin.com/company/foo stay two entries: they are two different things that happen to have the same slug. What still collapses is the several wordings a platform has for one kind, since those report the same kind: linkedin.com/company/foo, linkedin.com/organization/foo and linkedin.com/companies/foo are one company.

Deprecated: username

id was called username before 3.0.0. Every result still carries a username property holding the same value throughout 3.x, so existing code keeps working, but it will be removed in 4.0.0. Move to id.

kind

kind says what the url points at, for the four platforms that address more than one thing under the same domain. It is always one of the same four values, whatever the platform calls it in its own urls, so you can branch on it without knowing that a LinkedIn person lives under /in/:

kind matched urls
company Crunchbase /company/ and /organization/, LinkedIn /company/, /companies/ and /organization/
group Facebook /groups/, Flickr /groups/, LinkedIn /groups/
person Crunchbase /person/, Flickr /people/ and /photos/, LinkedIn /in/, /pub/, /people/, /sales/people/ and /profile/view?id=
school LinkedIn /edu/ and /school/

kind is left out for every other type, and for a Facebook url that is not a group, since a plain facebook.com/name can be either a person or a page, and a legacy facebook.com/pages/{slug}/{id} page can belong to a company, a person or anything else.

canonical_url

url is the url as it was found in the text. canonical_url is the same profile in one agreed upon form, so that https://twitter.com/SlackHQ, https://www.x.com/SlackHQ and https://mobile.x.com/SlackHQ all come back as https://x.com/SlackHQ. It normalizes the protocol, the www/mobile/country subdomain, the domain where a platform has more than one, and the path where a platform has several interchangeable forms, for example LinkedIn /companies/ and /organization/ to /company/, and Crunchbase /company/ to /organization/.

canonical_url is left out entirely when the matched url cannot be rewritten without guessing, which is the case for two groups of urls. The first is types whose regex matches things that are not interchangeable: a country site that is a separate site, a subdomain that means something different, or a path segment that is optional and therefore ambiguous. The second is LinkedIn /pub/, /people/, /sales/people/ and /profile/view?id= urls, which carry a legacy or opaque member id rather than a public slug. Those still report a kind, so a url can tell you it is a person without being canonicalizable.

A legacy Facebook facebook.com/pages/{slug}/{id} url does get one: the id is the numeric page id, which resolves at the root, so it canonicalizes to https://facebook.com/{id}. The slug is dropped, it is not the page's current vanity name.

The last column of the table below says which types get one. Always check the field is present before using it.

Supported types

Every type accepts http or https and an optional www., and the types with localized sites also accept a country subdomain such as au.linkedin.com or nl-nl.facebook.com.

type type_name matched urls canonical_url
aboutme About.me about.me/{id} yes
angellist AngelList angel.co/{id} yes
behance Behance behance.com/{id}, behance.net/{id} yes
blogger Blogger blogger.com/profile/{id} yes
coinbase Coinbase coinbase.com/{id} yes
crunchbase CrunchBase crunchbase.com/{person,company,organization}/{id} yes
delicious Delicious delicious.com/{id} yes
digg Digg digg.com/users/{id} yes
dribbble Dribbble dribbble.com/{id} yes
facebook Facebook facebook.com/{id}, fb.com/{id}, facebook.com/groups/{id}, facebook.com/pages/{slug}/{id} yes
flickr Flickr flickr.com/{people,photos,groups}/{id} yes
foursquare Foursquare foursquare.com/{id}, foursquare.com/user/{id} no
github GitHub github.com/{id} yes
gravatar Gravatar gravatar.com/{id} yes
instagram Instagram instagram.com/{id} yes
keybase Keybase keybase.io/{id} yes
lastfm Last.FM last.fm/user/{id}, lastfm.com/user/{id} yes
linkedin LinkedIn linkedin.com/{in,pub,people,company,companies,organization,edu,school,groups}/{id}, linkedin.com/sales/people/{id}, linkedin.com/profile/view?id={id} yes*
medium Medium medium.com/@{id}, medium.com/{id} no
myspace MySpace myspace.com/{id} yes
ok Odnoklassniki ok.ru/{id}, ok.ru/profile/{id} no
pandora Pandora pandora.com/people/{id} yes
pinterest Pinterest pinterest.{tld}/{id} no
plancast Plancast plancast.com/{id} yes
quora Quora quora.com/{id}, quora.com/profile/{id} no
reddit Reddit reddit.com/user/{id} yes
slideshare Slideshare slideshare.net/{id} yes
tumblr Tumblr {id}.tumblr.com yes
twitter Twitter twitter.com/{id}, x.com/{id} yes
vimeo Vimeo vimeo.com/{id} yes
vk VK vk.com/{id} yes
wordpress Wordpress {id}.wordpress.com yes
xing Xing xing.com/{id}, xing.com/profile/{id} no
yahoo Yahoo {profile,me,local}.yahoo.com/{id} no
yelp Yelp yelp.{tld}/biz/{id} no
youtube YouTube youtube.com/{id}, youtube.com/{user,channel,c}/{id} no

* every LinkedIn url except /pub/, /people/, /sales/people/ and /profile/view?id=.

type is the value to store and branch on, since it stays put. type_name is only a display name and may be retitled if a platform rebrands.

x.com is matched as type: 'twitter' so that existing stored profiles keep working. Only canonical_url uses the x.com domain.

About

Node library to parse social profile urls out of text.

Resources

Stars

1 star

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages