erusev / parsedown

Better Markdown Parser in PHP
https://parsedown.org
MIT License
14.69k stars 1.12k forks source link

Automatically embed Twitter #761

Closed Cannonb4ll closed 2 years ago

Cannonb4ll commented 4 years ago

Hi!

I have tried many things to get Twitter embed automatically working. I made this regex to identify the twitter status string:

/^https?:\/\/twitter\.com\/(?:#!\/)?(\w+)\/status(?:es)?\/(\d+)(?:\/.*)?$/

The problem is that I am unable to generate the proper HTML to display the tweet. It seems that the Twitter embed HTML is a bit more complicated and has sub-nested elements.

Can someone guide me in the proper direction?

taufik-nurrohman commented 4 years ago

Hook onto the inlineUrl() method and then check if URL is from Twitter from the href property using your pattern:

protected function inlineUrl($Excerpt) {
    if (!$Inline = parent::inlineUrl($Excerpt)) {
        return;
    }
    $href = $Inline['element']['attributes']['href'];
    if (preg_match('/ ... /', $href, $matches)) {
        // Replace link markup into embed code
        $Inline['element'] = array( ... );
    }
    return $Inline;
}
Cannonb4ll commented 4 years ago

@taufik-nurrohman Thanks, I came that far indeed. But the problem with the twitter embed is that it uses sub-elements and I am unsure how to render those..

Example Twitter HTML:

<blockquote class="twitter-tweet">
    <p lang="en" dir="ltr">Today is launch day 👀</p>&mdash; Documentator (@Documentator_io) 
    <a href="https://twitter.com/Documentator_io/status/1245609692312698880?ref_src=twsrc%5Etfw">April 2, 2020</a>
</blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
taufik-nurrohman commented 4 years ago

Fetch the tweet data by its ID with CURL → https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/get-statuses-show-id

And then build the block quote element from the JSON returned.

Cannonb4ll commented 4 years ago

Performance wise not a fan of that solution doing a cURL each time. I could cache it, but it seems unnecessary to be honest.

Maybe anyone else has a solution? 🤝

terrylan commented 4 years ago

Here's what I came up with on PHP:

$tweeter="jack";
$tweetID ="1247616214769086465";
$url = "https://publish.twitter.com/oembed?url=https://twitter.com/$tweeter/status/$tweetID";
$contents = file_get_contents($url);
$tweet = json_decode($contents, true);
echo $tweet['html'];

The $url will pull the json file from twitter. Then the json_decode() will turn the content to array and $tweet['html'] will display the blockquote part. The blockqoute surprisingly includes the js script https://platform.twitter.com/widgets.js, so pulling just the ['html'] from the array will do. Below code is the json content using PHP var_dump().

array(11) {
  ["url"]=>
  string(51) "https://twitter.com/jack/status/1247616214769086465"
  ["author_name"]=>
  string(4) "jack"
  ["author_url"]=>
  string(24) "https://twitter.com/jack"
  ["html"]=>
  string(686) "<blockquote class="twitter-tweet"><p lang="en" dir="ltr">I’m moving $1B of my Square equity (~28% of my wealth) to <a href="https://twitter.com/hashtag/startsmall?src=hash&amp;ref_src=twsrc%5Etfw">#startsmall</a> LLC to fund global COVID-19 relief. After we disarm this pandemic, the focus will shift to girl’s health and education, and UBI. It will operate transparently, all flows tracked here: <a href="https://t.co/hVkUczDQmz">https://t.co/hVkUczDQmz</a></p>&mdash; jack (@jack) <a href="https://twitter.com/jack/status/1247616214769086465?ref_src=twsrc%5Etfw">April 7, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
"
  ["width"]=>
  int(550)
  ["height"]=>
  NULL
  ["type"]=>
  string(4) "rich"
  ["cache_age"]=>
  string(10) "3153600000"
  ["provider_name"]=>
  string(7) "Twitter"
  ["provider_url"]=>
  string(19) "https://twitter.com"
  ["version"]=>
  string(3) "1.0"
}

With this may I suggest a twitter render using this markdown? If it's not too much to ask. [tweet](jack:1247616214769086465)

I hope I explained it properly.

Thank you!