User Tools

Site Tools


tweet_my_door

Introduction

This project was inspired by this article, where the author explains how to fetch your status message from Twitter to an Arduino and show it on a LCD placed at your office door. At the end, a few improvements are mentioned and the complete implementation can be found here. I wanted do basically the same, but did not have the Arduino Ethernet Shield. Instead, I used an embedded system that was in our lab doing nothing.

Hardware and software

Hardware

Software

Twitcurl, library for Twitter API's.

Libcurl, Libcurl dependency.

Perl, for the main script.

Perl module: http://search.cpan.org/~grantm/XML-Simple-2.18/lib/XML/Simple.pm XML::Simple, so you can parse the XML file.

Installing the software

Libcurl:

cd

mkdir scr

cd scr/

wget http://curl.haxx.se/download/curl-7.21.7.tar.gz

tar xvfz curl-7.21.7.tar.gz

cd curl-7.21.7

./configure --prefix=/usr

make

make install

Twitcurl:

cd ../../

mkdir twitcurl

cd twitcurl/

apt-get install g++

apt-get install subversion

svn co http://twitcurl.googlecode.com/svn/branches/libtwitcurl

cd libtwitcurl/

make

cp twitcurl.h oauthlib.h /usr/include/

cp libtwitcurl.so.1.0 /usr/lib/

ln -sf /usr/lib/libtwitcurl.so.1.0 /usr/lib/libtwitcurl.so.1

ln -sf /usr/lib/libtwitcurl.so.1.0 /usr/lib/libtwitcurl.so

Perl (I tried to use cpan, but the system kept getting out of memory):

cd ../../

mkdir perlModules

cd perlModules/

wget http://search.cpan.org/CPAN/authors/id/M/MS/MSCHWERN/ExtUtils-MakeMaker-6.58.tar.gz

tar xvfz ExtUtils-MakeMaker-6.58.tar.gz

cd ExtUtils-MakeMaker-6.58

perl Makefile.PL

make

make install


cd ..

wget http://search.cpan.org/CPAN/authors/id/P/PE/PERIGRIN/XML-NamespaceSupport-1.11.tar.gz

tar xvfz XML-NamespaceSupport-1.11.tar.gz

cd XML-NamespaceSupport-1.11

perl Makefile.PL

make 

make install


cd ..

wget http://search.cpan.org/CPAN/authors/id/G/GR/GRANTM/XML-SAX-0.96.tar.gz

tar xvfz XML-SAX-0.96.tar.gz

cd XML-SAX-0.96

perl Makefile.PL

make

make install


cd ..

wget http://search.cpan.org/CPAN/authors/id/G/GR/GRANTM/XML-Simple-2.18.tar.gz

tar xvfz XML-Simple-2.18.tar.gz

cd XML-Simple-2.18

perl Makefile.PL

make 

make install

LCD:

cd ../../

mkdir lcd

cd lcd

wget ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7260-linux/samples/lcdmesg.c

gcc -o lcdmesg lcdmesg.c

Creating application

Validating your application in Twitter

Sign in to your Twitter account. Go to settings → applications → developers → create new application. Complete the information screen, copy the consumer key and consumer secret. You'll need it next.

Status reader

Create the application that's going to fetch the status and display it on the LCD:

cd /home/src/

mkdir twitterReader

Here's the code for twitterReader.h:

#include <cstdio>
#include <iostream>
#include <fstream>
#include "twitcurl.h"

The code for twitterReader.cpp is this one (update myConsumerKey and myConsumerSecret with data from last step):

#include "twitterReader.h"
 
void printUsage()
{
    printf( "\nUsage:\ntwitterClient -u username -p password\n" );
}
 
int main( int argc, char* argv[] )
{
    std::string userName( "" );
    std::string passWord( "" );
    if( argc > 4 )
    {
        for( int i = 1; i < argc; i += 2 )
        {
            if( 0 == strncmp( argv[i], "-u", strlen("-u") ) )
            {
                userName = argv[i+1];
            }
            else if( 0 == strncmp( argv[i], "-p", strlen("-p") ) )
            {
                passWord = argv[i+1];
            }
        }
        if( ( 0 == userName.length() ) || ( 0 == passWord.length() ) )
        {
            printUsage();
            return 0;
        }
    }
    else
    {
        printUsage();
        return 0;
    }
 
    twitCurl twitterObj;
    std::string tmpStr( "" );
    std::string replyMsg( "" );
 
    /* OAuth flow begins */
    /* Step 0: Set OAuth related params. These are got by registering your app at twitter.com */
    twitterObj.getOAuth().setConsumerKey( std::string( "myConsumerKey" ) );
    twitterObj.getOAuth().setConsumerSecret( std::string( "myConsumerSecret" ) );
 
    /* Step 1: Check if we alredy have OAuth access token from a previous run */
    char szKey[1024];
    std::string myOAuthAccessTokenKey("");
    std::string myOAuthAccessTokenSecret("");
    std::ifstream oAuthTokenKeyIn;
    std::ifstream oAuthTokenSecretIn;
 
    oAuthTokenKeyIn.open( "twitterReader_token_key.txt" );
    oAuthTokenSecretIn.open( "twitterReader_token_secret.txt" );
 
    memset( szKey, 0, 1024 );
    oAuthTokenKeyIn >> szKey;
    myOAuthAccessTokenKey = szKey;
 
    memset( szKey, 0, 1024 );
    oAuthTokenSecretIn >> szKey;
    myOAuthAccessTokenSecret = szKey;
 
    oAuthTokenKeyIn.close();
    oAuthTokenSecretIn.close();
 
    if( myOAuthAccessTokenKey.size() && myOAuthAccessTokenSecret.size() )
    {
        /* If we already have these keys, then no need to go through auth again */
        printf( "\nUsing:\nKey: %s\nSecret: %s\n\n", myOAuthAccessTokenKey.c_str(), myOAuthAccessTokenSecret.c_str() );
 
        twitterObj.getOAuth().setOAuthTokenKey( myOAuthAccessTokenKey );
        twitterObj.getOAuth().setOAuthTokenSecret( myOAuthAccessTokenSecret );
    }
    else
    {
        /* Step 2: Get request token key and secret */
        twitterObj.oAuthRequestToken( tmpStr );
 
        /* Step 3: Ask user to visit web link and get PIN */
        char szOAuthVerifierPin[1024];
        memset( szOAuthVerifierPin, 0, 1024 );
        printf( "\nPlease visit this link in web browser and authorize this application:\n%s", tmpStr.c_str() );
        printf( "\nEnter the PIN provided by twitter: " );
        gets( szOAuthVerifierPin );
        tmpStr = szOAuthVerifierPin;
        twitterObj.getOAuth().setOAuthPin( tmpStr );
 
        /* Step 4: Exchange request token with access token */
        twitterObj.oAuthAccessToken();
 
        /* Step 5: Now, save this access token key and secret for future use without PIN */
        twitterObj.getOAuth().getOAuthTokenKey( myOAuthAccessTokenKey );
        twitterObj.getOAuth().getOAuthTokenSecret( myOAuthAccessTokenSecret );
 
        /* Step 6: Save these keys in a file or wherever */
	std::ofstream oAuthTokenKeyOut;
	std::ofstream oAuthTokenSecretOut;
 
        oAuthTokenKeyOut.open( "twitterReader_token_key.txt" );
        oAuthTokenSecretOut.open( "twitterReader_token_secret.txt" );
 
        oAuthTokenKeyOut.clear();
        oAuthTokenSecretOut.clear();
 
        oAuthTokenKeyOut << myOAuthAccessTokenKey.c_str();
        oAuthTokenSecretOut << myOAuthAccessTokenSecret.c_str();
 
        oAuthTokenKeyOut.close();
        oAuthTokenSecretOut.close();
    }
    /* OAuth flow ends */
 
    /* Set twitter username and password */
    twitterObj.setTwitterUsername( userName );
    twitterObj.setTwitterPassword( passWord );
 
    /* Read status */
 
    if( twitterObj.timelineUserGet( userName, false ) )
    {
        twitterObj.getLastWebResponse( replyMsg );
 
	/* Save response from twitter in a file or wherever */
	std::ofstream replyMsgOut;
	replyMsgOut.open( "twitterReader_reply_message.xml" );
	replyMsgOut.clear();
	replyMsgOut << replyMsg.c_str();
	replyMsgOut.close();
 
        //printf( "\ntwitterClient:: twitCurl::statusUpdate web response:\n%s\n", replyMsg.c_str() );
        printf("\nWeb response saved!\n");
    }
    else
    {
        twitterObj.getLastCurlError( replyMsg );
        printf( "\ntwitterClient:: twitCurl::statusUpdate error:\n%s\n", replyMsg.c_str() );
    }
 
    return 0;
}

This will download a XML file with the response from Twitter.

Save and compile:

g++ -ltwitcurl -o statusReader twitterReader.cpp

Testing

./statusReader -u username -p password

Visit the website and copy the PIN. Check the XML file saved to see the response from Twitter.

Main program

Create a folder for the application:

cd ../../

mkdir tweetMyDoor

cd tweetMyDoor/

Copy the statusReader and lcdmesg programs:

cp ../src/twitterReader/statusReader ./

cp ../src/lcd/lcdmesg ./

Create the main application:

nano tweetMyDoor.pl

Here's the code:

#!/usr/bin/perl
 
# use modules
use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
 
# create object
my $xml = new XML::Simple (ForceArray => 1);
#my $xml = new XML::Simple;
 
while (1) {
 
# first call twitterReader to get timeline from twitter
my $status = system("./statusReader -u username -p password");
 
# read XML file
my $data = $xml->XMLin("twitterReader_reply_message.xml");
#open (MYFILE, '>>data.txt');
#print MYFILE Dumper($data);
#close (MYFILE);
 
# access XML data
print "Last tweet: $data->{'status'}->[0]->{'text'}->[0]\n";
#print "Tweet 2: data->{'status'}->[1]->{'text'}->[0]\n";
 
# update LCD
system("echo $data->{'status'}->[0]->{'text'}->[0] | ./lcdmesg");
 
sleep(180);
 
}

Run it (repeat steps for PIN):

perl tweetMyDoor.pl
tweet_my_door.txt · Last modified: 2017/01/03 21:29 by admin