0

I'm using the Twitter API to get top 5 tweets for my app. I need to highlight, or link parts of the tweets differently. Ex, #'s will be orange, @'s will be red and clickable, etc...

From their API, they offer user_timeline endpoint:

https://dev.twitter.com/rest/reference/get/statuses/user_timeline

But the tweets object's text returns with those special characters embedded within it. I don't see options to pull out those @, # and href from the object:

Tweets object:

{ 
   ...
   text: "This is some text @tagName that I'd like to #parse here https://t.co/m9Addr4IlS",
   ...   
}

While I can write my own string parser to look for those things, is there something the Twitter API offers to handle this?


EDIT: <tweets> is an Angular directive that ng-repeats over my tweets from ModulesService. replace doesn't seem to be appending the DOM tags

            scope.getTweets = function() {
                ModulesService.getTweets().success(function(res) {
                    if (res && Array.isArray(res)) {
                        scope.tweets = parseTweets(res);
                    }
                });
            };

            scope.getTweets();

            var parseTweets = function (tweets) {

                tweets.forEach(function (tweet) {

                    tweet.text.replace(/(@[^ ]+)/g, '<a class="user">$1</a>').
                        replace(/(#[^ ]+)/g, '<span class="hash">$1</span>').
                        replace(/(https?:\/\/[^ ]+)/g, '<a href="$1">$1</a>');

                    console.log('tweet!', tweet.text); //does not contain altered HTML
                });

                return tweets;
            };

HTML:

<div ng-repeat="tweet in tweets" class="post-body clearfix">
    {{tweet.text}}
</div>
user3871
  • 12,432
  • 33
  • 128
  • 268

3 Answers3

2

recommended solution

The library twitter-text does the work for you.

As per their examples:

autolink

var twitter = require('twitter-text')
twitter.autoLink(twitter.htmlEscape('#hello < @world >'))

extract entities

var usernames = twttr.txt.extractMentions("Mentioning @twitter and @jack")
// usernames == ["twitter", "jack"]

Using that solution will save you from re-inventing the wheel and will provide you with a stable working code :)

alternative

Inside the tweet object that you receive from the user_timeline API endpoint, the entities property stores the list of urls, hashtags and mentions included inside the tweet. These contain the text content as well as the position (start / end character indices) of each entity.

Example hashtag entity:

"entities": {
  "hashtags": [
    "text": "pleaseRT"
    "indices": [
      6,
      13
    ]
  ]

cf Entities documentation for more info.

Mehdi
  • 7,204
  • 1
  • 32
  • 44
1

Try:

var text = "This is some text @tagName that I'd like to #parse here https://t.co/m9Addr4IlS";
var div = document.getElementsByTagName('div')[0];
div.innerHTML = text.replace(/(@[^ ]+)/g, '<a class="user">$1</a>').
                     replace(/(#[^ ]+)/g, '<span class="hash">$1</span>').
                     replace(/(https?:\/\/[^ ]+)/g, '<a href="$1">$1</a>');
.hash { color: orange; }
.user { color: red; }
<div></div>
jcubic
  • 61,973
  • 54
  • 229
  • 402
  • this is awesome! Thank you. What would be the performance concerns of running multiple regex's for each tweet in the loop? Would it be more performant to use a library, like `twitter-text` as @mef recommended? – user3871 Feb 29 '16 at 15:46
  • I'm using Angular to loop through the response from Twitter. Therefore, I'm looping through the tweets and altering the strings beforehand, but the `replace` doesn't seem to work. See above edit. This is obviously because the HTML tags won't get parsed until rendered to DOM... but in this Angular instance, how can I store the `replaced` values to be `ng-repeated` at a later time? – user3871 Feb 29 '16 at 16:11
  • 1
    @Growler you can try to use `ng-bind-html="tweet.text"` [AngularJS: Insert HTML from a string](http://stackoverflow.com/questions/14761724/angularjs-insert-html-from-a-string) – jcubic Feb 29 '16 at 17:28
  • [AngularJS : Insert HTML into view](http://stackoverflow.com/questions/9381926/angularjs-insert-html-into-view) – jcubic Feb 29 '16 at 17:29
0

Loop over the returned tweets and modify the tweet text according to some conditions:

returnValues.forEach(function (tweet) {
    if (tweet.text.search(/#|@/ig) > -1) {
        var words = obj.text.split(' ');

        var parsedTweetText = words.map(function (word) {
            if (word.indexOf('#') === 0)
                return '<span class="hashtag">' + word + '</span>';
            else if (word.indexOf('@') === 0)
                return '<span class="at-user">' + word + '</span>';
            else
                return word;
        }).join(' ');

        tweet.text = parsedTweetText;
    }
});
bcr
  • 3,791
  • 18
  • 28