start blog post

Importing Blog Comments to Disqus

This site is running completely custom blog code, meaning both its features and its flaws are up to me. While I like the flexibility and freedom that comes with, it's often difficult (or impossible) to use third-party blog plugins written for Wordpress, Blogger, or another common platform.

I recently decided migrate my custom comment system to Disqus. I love its user experience on other people's blogs, so why not run it here? Fortunately they provide an API which makes migrating comments a relatively painless process. Figured I'd post my own steps in case it helps others with their own custom blog code. Since custom blogs are by definition unique, there are a couple of assumptions (described in the comments) that depend on how you actually implemented your blog.

<?php
    // this page's output is for our eyes only, set easy debug options
    error_reporting(E_ALL);
    ini_set('display_errors', true);
    set_time_limit(0);
    header('Content-Type: text/plain');

    /**
     * Send a request to the Disqus API and return the response.
     * @param {String} fn     : Disqus API function name
     * @param {String} method : 'get' or 'post', HTTP request method
     * @param {Array}  params : key/value pairs required by the API call
     */
    function makeRequest($fn, $method='get', $params='') {
        $key = 'your Disqus User API key goes here';
        $url = "http://disqus.com/api/$fn/?user_api_key=$key&api_version=1.1";

        // "URLify" the parameters
        if (is_array($params) && count($params)) {
            $temp = array();
            foreach ($params as $k => $v) {
                $k = urlencode($k);
                $v = urlencode($v);
                $temp[] = "$k=$v";
            }
            $params = implode('&', $temp);
        }

        // make the API request
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        if (preg_match('/post/i', $method)) {
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        } else {
            if (!empty($params)) {
                $url = $url . '&' . $params;
            }
            curl_setopt($ch, CURLOPT_URL, $url . '&' . $params);
        }
        $response = curl_exec($ch);

        if (empty($response)) {
            // something went wrong, debug the response
            foreach (array(
                CURLINFO_EFFECTIVE_URL, // the target address
                CURLINFO_HTTP_CODE,     /* If $response is empty, this is likely 400
                                         * which means "bad request". Make sure your
                                         * function name is listed.
                                         */
                CURLINFO_TOTAL_TIME,    // how long it took the request
                CURLINFO_HEADER_OUT     // the complete headers
            ) as $option) {
                echo curl_getinfo($ch, $option) . "\r\n";
            }
        }

        // return as an associative array
        return json_decode($response, true);
    }

    // fetch your Disqus Forum ID
    $response = makeRequest('get_forum_list');
    $forum_id = $response['message'][0]['id'];

    // fetch your Forum API Key (different from your user API key!)
    $response = makeRequest('get_forum_api_key', 'get', array(
        'forum_id' => $forum_id
    ));
    $forum_api_key = $response['message'];

    /**
     * NOTE: $posts is assumed to be an array of all of your blog posts, doesn't 
     * matter what format.Depending on how you implemented your blog, you may be 
     * looping through filenames, database IDs, etc.
     */
    $posts = array();
    foreach ($posts as $post) {
        /**
         * NOTE: $comments is assumed to be an associative array of this post's 
         * comments. Your array keys may be different, just make sure they're
         * reflected that in $params below.
         */
        $comments = array(
            'comment',  // required: the comment we want to import
            'name',     // required: person who commented
            'email',    // required: commenter's email address
            'datetime', // optional: comment timestamp, converted to Disqus' preferred format below 
            'ip',       // optional: commenter's IP address
            'url'       // optional: commenter's own website address
        );
        if (!empty($comments)) {
            // example identifier: "/2010/05/06/importing-blog-comments-to-disqus/"
            $identifier = $post['permalink'];

            // create this post's corresponding Disqus thread...
            $thread = makeRequest('thread_by_identifier', 'post', array(
                'identifier' => $identifier,
                'forum_api_key' => $forum_api_key,
                'title' => ''
            ));
            $thread_id = $thread['message']['thread']['id']; // ...and get its new ID

            // now we can finally import this blog post's comments
            $numComments = 0;
            foreach ($comments as $comment) {
                $params = array(
                    'thread_id' => $thread_id,
                    'message' => $comment['comment'],
                    'author_name' => $comment['name'],
                    'author_email' => $comment['email'],
                    'forum_api_key' => $forum_api_key,
                    'created_at' => date('Y-m-d\TH:i', strtotime($comment['datetime'])),
                    'ip_address' => $comment['ip'],
                    'author_url' => $comment['url'],
                    'state' => 'approved'
                );
                $disqus = makeRequest('create_post', 'post', $params);
                print_r($params); // useful for debugging
                print_r($disqus); // useful for debugging
                $numComments++;
            }
            echo "$numComments comments processed for $identifier\r\n\r\n";
        }
    }
    echo "Done.\r\n";
    exit;
    
?>

var tags = [, ];

  • share this post:
  • email a friend
  • float this post
  • digg this post
  • share on stumbleupon
  • submit to technorati
  • tweet this post

end blog post

most viewed this week

least viewed this week