Wednesday, October 10, 2012

Add a Twitter flavor to your Sugar!

Following my presentation "Sugar + SocialCRM" during the CRM Acceleration in Paris last month, I presented quick & smart ways to bring cool Social interaction to Sugar. Sugar 7 will come with great features as well, but why waiting for April 2013. Start today!

In this post I will address how to quickly add a Twitter Feed based on the Twitter name of an Account or a Contact and a Twitter Search. In future posts, I will present the Facepile and the Twitterpile. Then the Klout integration, and the Google Map mashup.

The expected result will be getting an iFrame on the account page showing the Twitter identity of the Account and the last Tweets he posted:

And also a Twitter search based on the Account Twitter Name:

Let's start with a simple page!

We are working with the Account but the same behavior can easily be added to the Contact.

Step 1 
In the Sugar Studio, add a text field called twittername. This is basically the Account Twitter "screen name". Add the field to the page layout. Then I am assuming that someone in your company will fill the value for the account. How to find it? Just make a Twitter search with the account name, I guarantee you that you will find immediately the company Twitter account if they have one.

Step 2
Download JQuery.
In your Sugar root directory, create those directories 
/social/js/jquery/1.8.1
/social/twitter/minitwitter
Adapt the jquery version number to the version you have downloaded.

Step 3
I chose a JavaScript library called MiniTwitter (relying on JQuery):
Why JavaScript? Because this is the fastest way to retrieve the data from Twitter. The web server is delivering to your browser the page content, then your browser is taking care of the dialog with Twitter. The calls are asynchronous, so it will not slow down the rendering of the page.
MiniTwitter is very easy to use. See the examples on their front page. 

Wanna show the last Tweets from Lady Gaga on your blog? Ok, I know that you do not want, nobody wants it! Stop whining, let's choose a better example and get the lastest tweets from Simone Simons, the lead singer of the Dutch band Epica :)

JavaScript code:
$('.content_tweets').miniTwitter('SimoneSimons');


HTML:
<div class="content_tweets"> </div>

See the last 5 Tweets from Simone Simons:
Mini Tweets
Remark:
There is a fix to be made in MiniTwitter, file jquery.minitwitter.js:
line 132
obj.avatar = '<div class="tweet"><div class="avatar"><a '+rel()+' '+target()+' class="mt_avatar" href="'+obj.userUrl+'"><img src="'+obj.image+'" alt="'+obj.realName+'\'s avatar" border="0"/></a></div>';
 
add the width and height parameters to avoid surprises; Twitter might show very big avatars pics, you never know, so it is good to force the pic size.
obj.avatar = '<div class="tweet"><div class="avatar"><a '+rel()+' '+target()+' class="mt_avatar" href="'+obj.userUrl+'"><img src="'+obj.image+'" alt="'+obj.realName+'\'s avatar" border="0" width="48" height="48" /></a></div>';

Step 4
Let's create a very simple PHP page getTweets-simple.php to show the last tweet from any Twitter account:
<html>
<head>
<script language="javascript" src="/social/js/jquery/1.8.1/jquery.min.js" type="text/javascript"></script>
<script language="javascript" src="/social/twitter/minitwitter/jquery.minitwitter.js" type="text/javascript"></script>
<link href="/social/twitter/minitwitter/jquery.minitwitter.css" media="all" rel="stylesheet" type="text/css"/> 
<link rel="stylesheet" type="text/css" href="/social/social.css" />
<style type="text/css" media="screen">
  #custom-tweet-button a {
    display: block;
    padding: 2px 5px 2px 20px;
    background: url('https://twitter.com/favicons/favicon.ico') 1px center no-repeat;
    border: 1px solid #ccc;
    max-width:500px;
  }
</style>
</head>
<body>
<?php
$twitterName 
= (isset($_GET['twitterName']))?$_GET['twitterName']:'';
if (
$twitterName=='') {
    echo 
'<h2>Please provide a Twitter Name</h2>';
    echo 
'</body></html>';
    exit;
}
?><div class="tweets"> <div class="tweets_header">Mini <a href="http://minitwitter.webdevdesigner.com">Tweets</a></div> <div class="content_tweets"> </div> <div class="tweets_footer"> <a href="#"><span id="bird"></span></a> </div> </div>
<script type='text/javascript'>
jQuery(".content_tweets").miniTwitter("<?php echo $twitterName ?>");
</script>
</body>
</html>

Call the page: http://yourserver.com/social/getTweets-simple.php?twitterName=sugarcrm

Now let's write a get Tweets / search page
The page will take 2 parameters: TwitterName for retrieving Tweets from an account or search for making a search.
Let's add a cool box to enable the user to write a Tweet to the Twitter account or a new Tweet containing the search pattern as a hashtag.
And let's add a nice box at the top on the page to get all the basic information on the Twitter account.

PHP page getTweets.php:
<html>
<head>
<script language="javascript" src="/social/js/jquery/1.8.1/jquery.min.js" type="text/javascript"></script>
<script language="javascript" src="/social/twitter/minitwitter/jquery.minitwitter.js" type="text/javascript"></script>
<link href="/social/twitter/minitwitter/jquery.minitwitter.css" media="all" rel="stylesheet" type="text/css"/> 
<link rel="stylesheet" type="text/css" href="/social/social.css" />
<style type="text/css" media="screen">
  #custom-tweet-button a {
    display: block;
    padding: 2px 5px 2px 20px;
    background: url('https://twitter.com/favicons/favicon.ico') 1px center no-repeat;
    border: 1px solid #ccc;
    max-width:500px;
  }
</style>
</head>
<body>
<?php// input parameters: twitterName or search$twitterName = (isset($_GET['twitterName']))?$_GET['twitterName']:'';$search = (isset($_GET['search']))?$_GET['search']:'';
if ((
$twitterName=='')&&($search=='')) {
    echo 
'<h2>Please provide a Twitter Name or a search pattern</h2>';
    echo 
'</body></html>';
    exit;
}
$tweetbtn='';
if (
$search!='') {
    echo 
"
    <div align='center'>
    <form name='f1' action='getTweets.php' method='GET'>
    <input type='text' name='search' value='$search' class='inputText' />&nbsp;&nbsp;&nbsp;
    <input type='submit' name='btns' id='btns' value='search' class='inputBtn' />
    </form>
    </div>"
;
    if (
$search[0]=='#'$search substr($search,1);
    
$tweetbtn="?button_hashtag=$search";
}
if (
$twitterName!='') {
    echo 
"<div class='tweets' id='infoUserAccount'><div align='center'><img src='/social/twitter/wait.gif' width='48' height='48' border='0' /></div></div><br/>\n";
    
$tweetbtn="?screen_name=$twitterName";
?><div class="tweets"> <div class="tweets_header">Mini <a href="http://minitwitter.webdevdesigner.com">Tweets</a></div> <div class="content_tweets"> </div> <div class="tweets_footer"> <a href="#"><span id="bird"></span></a> </div> </div>

<script type='text/javascript'>
<?php 
if ($twitterName!='') { ?>jQuery(".content_tweets").miniTwitter("<?php echo $twitterName ?>");
var url = '/social/twitter/getUserInfoTwitter.php?twitterName=<?php echo $twitterName ?>';
$.get(url, function(data){
document.getElementById('infoUserAccount').innerHTML='<b>' + data.name + '</b><br/>' + 
    '<a href="https://www.twitter.com/#!/'+data.screen_name+'" target="_blank">@' + data.screen_name + '</a><br/>' + 
    data.description + '<br/>' + 
    data.location + '<br/>' + 
    data.statuses_count + ' Tweets<br/>' + 
    data.friends_count + ' Following<br/>' + 
    data.followers_count + ' Followers<br/>' + 
    data.listed_count + ' Listed<br/>';
}, "json");
<?php } else { ?>jQuery(".content_tweets").miniTwitter({query: "<?php echo $search ?>"});
<?php ?><br/>
</script> 
<div id="custom-tweet-button" align="center">
  <a href="https://twitter.com/intent/tweet<?php echo $tweetbtn ?>" target="_blank">Tweet</a>
</div>
</body>
</html>

In order to get the information on the Twitter account, we are making another asynchronous call to Twitter using JQuery. The page is called getUserInfoTwitter.php and it is doing a REST call to Twitter. E.g. the call http://api.twitter.com/1/users/show/sugarcrm.json will return in a JSON format the information on the Twitter account SugarCRM. But for a cross scripting security issue, you cannot address directly Twitter, you are calling a PHP script located on your server.

getUserInfoTwitter.php
<?php
 function loadURL_cURL($ip,$uri$timeout){
   
$header=array("Host:".$uri);
   
$ch curl_init();
   
curl_setopt($chCURLOPT_URL$ip);
   
curl_setopt($chCURLOPT_HEADERfalse);
   
curl_setopt($chCURLOPT_HTTPHEADER$header);
   
curl_setopt($chCURLOPT_CONNECTTIMEOUT$timeout);
   
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
   
$return_data curl_exec($ch);
   
curl_close($ch);
   return 
$return_data;
}
$twitterName = (isset($_GET['twitterName']))?$_GET['twitterName']:'';if ($twitterName=='') exit;
// get informations on the user
echo loadURL_cURL("http://199.59.149.232/1/users/show/".$twitterName.".json""api.twitter.com"30);?>

Remark
you should not use this exact syntax. I am meeting important DNS resolution failures in my Linux box so I decided to hard code the IP address in the call, which is a worse practice.

You should replace with this code:
<?php
$twitterName 
= (isset($_GET['twitterName']))?$_GET['twitterName']:'';
if (
$twitterName=='') exit;// get informations on the user$url "http://api.twitter.com/1/users/show/".$twitterName.".json";$userInfo curl_init();curl_setopt($userInfoCURLOPT_URL$url);curl_setopt($userInfoCURLOPT_RETURNTRANSFERTRUE);$userInfo curl_exec($userInfo);echo $userInfo;?>


Now you might want to call the page to get the SugarCRM Twitter account page.
http://yourserveur.com/social/twitter/getUserInfoTwitter.php?twitterName=sugarcrm
On the top, you get the twitter account information, then the last 5 tweets:
 If you click on the Tweet link at the bottom, you get the usual new Tweet page, hosted by Twitter, with the recipient pre-filed:


Let's make a search with the pattern SugarCRM.  
http://yourserveur.com/social/twitter/getUserInfoTwitter.php?search=sugarcrm
On the top, you get the search box, you may change the pattern:

If you click on the Tweet button, you are sending a Tweet with the pattern as a hashtag:

Ok, that's nice, now I want this cool features in my Sugar!

This is easy :) Let's create 2 iFrame fields. The first one for the account Tweets, the second one for the search.

The Tweets field
Type: iFrame
Name: tweets
Generated URL: checked
Default value: http://yourserveur.com/social/twitter/getUserInfoTwitter.php?twitterName={twittername_c}
Height: 400



The Tweets Search field
Type: iFrame
Name: tweetssearch
Generated URL: checked
Default value: http://yourserveur.com/social/twitter/getUserInfoTwitter.php?search={twittername_c}
Height: 400


Create a new tab for each field, and test.

Now this is your turn to play :D
Let me know how you are doing!

Monday, October 8, 2012

Slideshare - my last public presentations

My last public presentations are available on http://www.slideshare.net.


Sugar + SocialCRM - SugarCRM Acceleration Paris - 13 Sep 2012
Presentation delivered in Paris (French)




SugarCRM edition communautaire vs commerciale
Webcast (French), the recording will be posted soon to the SugarCRM web site.

Open World Forum 2012

Hi, sorry for not blogging those last (very busy) days.

I will attend a panel on Thursday 11th October at the Open World Forum in Paris. The topic is "Open Source Web Application on The Cloud".
Links:
The Open World Forum web site,
my session.

And I will post asap the source codes I presented during my session "Sugar + SocialCRM" at the CRM Acceleration in Paris on 13th September.