Simple Facebook / Codeigniter Authorization

On a Codeigniter project I’m working on, I wanted to have Twitter and Facebook logins available. Luckily, right around the time I was starting the project, Elliot Haughin released libraries for both Twitter and Facebook. The Twitter library worked almost instantly and is quite brilliant. However, the Facebook library was causing me some problem.

Looking through the Facebook Developer pages, it seemed like a fairly straight-forward process to get a User’s Facebook auth tokens… and with CI2 having querystring support now, I thought I could do everything in a simple Facebook controller.  Here’s what I got:

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/**
 * Name:  Simple Facebook Codeigniter Login
 *
 * Author: Terry Matula
 *         terrymatula@gmail.com
 *         @terrymatula

 * Created:  03.31.2011
 *
 * Description:  An easy way to use Facebook to login
 *
 * Requirements: PHP5 or above
 *
 */
class Facebook extends CI_Controller {

    public $appid;
    public $apisecret;

    public function __construct()
    {
        parent::__construct();
        // replace these with Application ID and Application Secret.
        $this->appid = '12345';
        $this->apisecret = '123abc123';
    }

    /**
     * if you have a Facebook login button on your site, link it here
     */
    public function index()
    {
        // set the page you want Facebook to send the user back to
        $callback = site_url('facebook/confirm');
        // create the FB auth url to redirect the user to. 'scope' is
        // a comma sep list of the permissions you want. then direct them to it
        $url = "https://graph.facebook.com/oauth/authorize?client_id={$this->appid}&redirect_uri={$callback}&scope=email,publish_stream";
        redirect($url);
    }

    /**
     * Get tokens from FB then exchanges them for the User login tokens
     */
    public function confirm()
    {
        // get the code from the querystring
        $redirect = site_url('facebook/confirm');
        $code = $this->input->get('code');
        if ($code)
        {
            // now to get the auth token. '__getpage' is just a CURL method
            $gettoken = "https://graph.facebook.com/oauth/access_token?client_id={$this->appid}&redirect_uri={$redirect}&client_secret={$this->apisecret}&code={$code}";
            $return = $this->__getpage($gettoken);
            // if CURL didn't return a valid 200 http code, die
            if (!$return)
                die('Error getting token');
            // put the token into the $access_token variable
            parse_str($return);
            // now you can save the token to a database, and use it to access the user's graph
            // for example, this will return all their basic info.  check the FB Dev docs for more.
            $infourl = "https://graph.facebook.com/me?access_token=$access_token";
            $return = $this->__getpage($infourl);
            if (!$return)
                die('Error getting info');
            $info = json_decode($return);
            print_r($info);
        }
    }

    /**
     * CURL method to interface with FB API
     * @param string $url
     * @return json
     */
    private function __getpage($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        $return = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        // check if it returns 200, or else return false
        if ($http_code === 200)
        {
            curl_close($ch);
            return $return;
        }
        else
        {
            // store the error. I may want to return this instead of FALSE later
            $error = curl_error($ch);
            curl_close($ch);
            return FALSE;
        }
    }

}


That’s about it. You could put it all in “index()”, but I wanted to separate it a little.

update: Looking at the bit.ly api, it’s actually very similar. i’ll eventually try to make it more generic.

Social Shopping – the problems and some ideas

My wife has been very wary of looking for a sitter/daycare for our 19 month old. Especially since he’s still not talking and not able to communicate his needs clearly. But when a woman in a mom’s groups she belongs to emailed with a recommendation for a sitter, she forwarded the email to me and is considering using her.  It struck me how powerful just one email, from a mom she’s only known for a few weeks, about another women who she’s never met, can be.

Countless sites are attempting this, from Scordit to hollrr and more successfully to Blippy. Even Facebook is getting into the game with Places and it’s couponing system. But all those solutions seem to be lacking… something. Here are the pitfalls as I see them:

  1. They show you all reviews/ratings from everyone. The problem with that is I don’t care what most people think about a product. Though, I do occasionally read some of the more thoughtful reviews on Amazon.
  2. The products/services are show in a “stream”. The Twitter feed/Facebook wall style of presenting status updates just isn’t useful for product recommendations. My friends may buy a new vacuum cleaner today, but I may not need one until next year. However, I still want to get their opinions, and not have to do tedious searches to find them.
  3. You only get one review, and usually just after you got the product. The sites that offer incentives to review/rate products only incentivize the initial review.  To be a truly effective review, I want to see the initial thoughts on the products, plus the thoughts after a month or so of using (or not using) it, and then maybe 6 months or a year later.
  4. They want you to be part of THEIR social network. Here’s the sobering fact… NO ONE is leaving Facebook. At least not for the near future. People are NOT going to your site, signing up, filling in their info, leaving reviews, and “talking” to others on YOUR site. They will stay on Facebook. As the ReadWriteWeb/Google debacle from a few months ago shows, for many people Facebook IS the internet… and your site is not going to change that.

I figure there a few things that a successful social shopping site must have.

  1. First and foremost, it must be a Facebook app. Sure, you can have a regular website for those who want it… but the focus should be on FB and keeping the info within the FB frame.
  2. Finding recommendations needs to be super simple and intuitive. If I’m looking for a TV, I should be able to simply type “TV” and see what my friends have bought. I would also offer an advanced search for power users, so people can drill down into specifications or even expand the social graph beyond just their friends… but the core functionality should be just the basics.
  3. Awesome incentives to post and review. “Badges” are fine, but “20% off a $100 purchase at Best Buy” is GREAT. Also, increase the incentives as time passes – I envision something like Scordit, where you get points for each post or review.  Your first review, or “I just bought ___” post, gets 1 point.  A month later, your second review gets 5 points… a year later, 10 points. The points can then be used to get rewards, for example 100 points gets 10% off a purchase at Amazon… or a $5 gift card from Best Buy.
  4. Assign “importance” to your friends. Over two Facebook account, I have 117 friends. These are all people I know, but honestly, I only truly value the opinions of about 35 or so of them.  In my theoretical Social Shopping app, I should be able to give those friends priority and have their results be first on the list.

    Additionally, it would be cool to give certain friends priority over certain types of purchases — like my more tech-savvy friends having more priority when it comes to computer purchases. In a perfect world, there would be an algorithm that parses the data from your friends, and your interactions with them, and automatically prioritizes them. For example, you have two friends with the jobs listed as “IT specialist”, but you’ve only written on the wall of one of those friends.  So when you search for “computer monitor”, those 2 friends show up first, with the #1 friend on top.

  5. Mobile apps for every platform. If you’re in the store with your iPhone or Android, you should be able to open the app, scan the barcode, and get reviews. If there aren’t any reviews from your friends, you then have the option to view ANY review of the exact product, or your friends’ reviews of similar products. Including something like Google Goggles functionality would also be useful… since some stores don’t always have barcodes on their display items.

These are just a few of my thoughts on the matter. I think the biggest issues are going to be lowering the barrier for entry, and providing good incentives for people to participate.  Blippy gets really close, and has shown some success… but they’re still just not quite there.

Maybe one day I’ll spend a few days hacking out a prototype of my idea.

Motivations To Code

A few months back, I had an idea for a recommendation site for politicians/political candidates. The thought is, a user browses through a list of candidates that they can vote for, then clicks on an icon to “endorse” them.  I also wanted a way to not recommend a candidate by having a “reject” button. Then I would allow the candidates to include a script on their site that listed all their endorsements, ideally replacing/adding to the Endorsements page that many political candidates have on their site.

Basically, it’s a Facebook “Like” button, but with an option to “Not Like”… and all the candidates would be in one place.

The problem is, it’s just me doing all the coding and design, and being new to Austin, I don’t know anyone else that might be interested in helping out.  Add to that, the hours I spend at my  job, and having an 18-month old baby, and  going through a seemingly never-ending move… and it’s difficult to find the time, or the motivation to work on the project.

When I do find time, there will be brief spans of productivity and clarity.  Then eventually, I’ll hit a wall and a particular programming problem will stump me.  Instead of pushing through it with OCD abandon, I’d rather just stop and play with the baby.  This has been a circular pattern that has gone on for the past 9 months or so.

Tonight, I watched The Social Network movie, and the scene about the creation of FaceSmash made me long for the days when I would have an idea and stay up all night working on it.  Like when I bought a copy of “Creating Cool HTML 4 Web Pages” and spend all day and night reading every word, and creating “cool” web pages.  In those days, had I known PHP (or at least PERL), I would’ve had my endorsement site done in a week.  Of course, I didn’t have a full-time  job, a wife, or a baby at the time.

Then, I read the latest Email from Jason Calacanis and I’m not sure whether to be defiant or justified.  He basically argues that entrepreneurship is for single, young people… at least if it’s your first foray into creating something.  In the past, he’s also argued (essentially) that if you’re not working 18 hours a day, you’re not working hard enough. But I think 37 Signals shows that that isn’t always the case.

And no, I  don’t think my little idea would qualify me as an entrepreneur, but I think it is something that would have some appeal. I had also considered rolling it into another idea I’ve been working: creating nice-looking, dynamic web sites for candidates in local elections. In fact, I’ve got TONS of ideas… ideas constantly running through my head. Many times, I’ll spend a week or two on them, get them to a functional place, and stop.  And up until a year or so ago, I would immediately register a domain name to go along with it.

For example, TheMoviePunch.com was going to be a video blog where I reviewed movies, but only having viewed their trailer. Or ReindeerBlog.com was going to be one of Santa’s reindeer anonymously posting about the dark-side of working at the North Pole… and more recently, I was thinking about registering ReindeerLeaks, and then “leaking” documents about Santa, the elves, etc. And why do I own MrShoop.com?

So anyway, I’m now looking for the motivation to get back to coding, or more specifically finishing some coding.  My biggest motivation right now is just about learning new technologies and keeping my skills sharp.  But that doesn’t require a finished product… just a continual process. My hope is that I can blog more, and get these ideas I have out in the wild. At least that way they’re  not just filling up my brain space.