From 16b4f44f3202454c50d9f03f17b415e6fc555a6e Mon Sep 17 00:00:00 2001 From: David Pearson Date: Mon, 7 Jan 2013 17:01:39 -0500 Subject: [PATCH] Initial commit --- .gitignore | 1 + README.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++ getaccesstoken.js | 58 +++++++++++++++++++++++++++++++++++++++++++++ identica.js | 21 +++++++++++++++++ package.json | 18 ++++++++++++++ 5 files changed, 158 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 getaccesstoken.js create mode 100644 identica.js create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/README.md b/README.md new file mode 100644 index 0000000..018fae0 --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +## Various Tools for Identi.ca + Node.js ## + +I wanted to get [@NFLScoreBot](http://twitter.com/nflscorebot) working with [identi.ca](http://identi.ca). Unfortunately, there's no pre-rolled library, so I kind of hacked this together for use with the excellent [ntwitter](https://github.com/AvianFlu/ntwitter). + +This is pretty much a collection of random code that I found useful. Your mileage may vary. + +### Setup ### + +Run `npm install` and you're golden. + +### Generating access tokens ### + +First, you need to [create](http://identi.ca/settings/oauthapps/new) an application (or use an [existing](http://identi.ca/settings/oauthapps) one). + +Then, you can use the `getaccesstoken.js` script from this repository to grab the necessary token and secret. Just run the script, supplying your consumer key and secret as command line arguments, like: + + node getaccesstoken.js CONSUMER_KEY CONSUMER_SECRET + +When run, a browser window should pop up and ask you to log in to identi.ca and approve the application. Do what it says and wait a moment, and your access token and secret should be displayed in the same browser window. + +### Using identi.ca with ntwitter ### + +While ntwitter supports (I use the term loosely; it isn't actually advertised anywhere) proxies and third-party services, it's not the most graceful at doing so. There are basically two ways to get it working: + +1. Given an already-created `Twitter` instance `twit`, the following code'll do the trick: + + twit.options["request_token_url"]="https://identi.ca/api/oauth/request_token"; + twit.options["access_token_url"]="https://identi.ca/api/oauth/access_token"; + twit.options["authenticate_url"]="https://identi.ca/api/oauth/authorize"; + twit.options["authorize_url"]="https://identi.ca/api/oauth/authorize"; + twit.options["rest_base"]="https://identi.ca/api"; + twit.options["search_base"]="http://identi.ca/api"; + +2. If you're willing to keep a copy of the ntwitter source in your app, you can edit the URLs in ntwitter/lib/keys.js. + +### What works with identi.ca + ntwitter ### + +Everything supported by the [Twitter-compatible API](http://status.net/wiki/Twitter-compatible_API) should work. However, only authentication and posting status updates (including status updates with locations) has been explicitly tested. + +*Note: identi.ca, as far as I can tell, does not support the streaming APIs.* + +### TODO ### + + * Better error handling in getaccesstoken.js + * Comprehensively test ntwitter for identi.ca compatibility. + +### Third Party Code ### + +This code makes use of [node-open](https://github.com/jjrdn/node-open), which is Copyright 2012 Jay Jordan, and [request](https://github.com/mikeal/request), which is Copyright 2012 Mikeal Rogers. + +### Legal ### + + Copyright (c) 2012, David Pearson + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/getaccesstoken.js b/getaccesstoken.js new file mode 100644 index 0000000..5b5f543 --- /dev/null +++ b/getaccesstoken.js @@ -0,0 +1,58 @@ +/* Copyright 2012-2013 David Pearson. + * + * BSD License. + */ + +var http=require("http"); +var open=require("open"); +var querystring=require("querystring"); +var request=require("request"); +var url=require("url"); + +var callback="http://localhost:1234/"; +var reqTokenURL="https://identi.ca/api/oauth/request_token"; +var accessTokenURL="https://identi.ca/api/oauth/access_token"; +var authURL="https://identi.ca/api/oauth/authorize"; + +if (process.argv.length<4) { + console.log("USAGE: node getaccesstoken.js CONSUMER_KEY CONSUMER_SECRET"); + return; +} + +var consumerKey=process.argv[2]; +var consumerSecret=process.argv[3]; + +var oauthToken=""; +var oauthTokenSecret=""; + +var serverHasResponded=false; +var server=null; + +request.post({url:reqTokenURL, oauth:{"callback":callback, "consumer_key":consumerKey, "consumer_secret":consumerSecret}}, function (e, res, retBody) { + var body=querystring.parse(retBody); + oauthToken=body["oauth_token"]; + oauthTokenSecret=body["oauth_token_secret"]; + + open(authURL+"?oauth_token="+oauthToken); + + server=http.createServer(responseListener).listen(1234); +}); + +function responseListener (req, response) { + if (serverHasResponded) { + return; + } + + serverHasResponded=true; + + var qs=querystring.parse(url.parse(req.url).query); + var oauth={"consumer_key":consumerKey, "consumer_secret":consumerSecret, "token":oauthToken, "token_secret":oauthTokenSecret, "verifier":qs["oauth_verifier"]}; + + request.post({url:accessTokenURL, oauth:oauth}, function (e, res, retBody) { + var body=querystring.parse(retBody); + + response.writeHead(200, {"Content-Type":"text/html"}); + response.end("Oauth InformationConsumer Key: "+consumerKey+"
Consumer Secret: "+consumerSecret+"

Access Token: "+body["oauth_token"]+"
Access Token Secret: "+body["oauth_token_secret"]+""); + server.close(); + }); +} \ No newline at end of file diff --git a/identica.js b/identica.js new file mode 100644 index 0000000..691023f --- /dev/null +++ b/identica.js @@ -0,0 +1,21 @@ +/* Copyright 2013 David Pearson. + * + * BSD License. + */ + +var ntwitter=require("ntwitter"); + +function identica (opts) { + var twit=new ntwitter(opts); + + twit.options["request_token_url"]="https://identi.ca/api/oauth/request_token"; + twit.options["access_token_url"]="https://identi.ca/api/oauth/access_token"; + twit.options["authenticate_url"]="https://identi.ca/api/oauth/authorize"; + twit.options["authorize_url"]="https://identi.ca/api/oauth/authorize"; + twit.options["rest_base"]="https://identi.ca/api"; + twit.options["search_base"]="http://identi.ca/api"; + + return twit; +} + +module.exports=identica; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..0de090f --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "identica", + "description":"Utilities and a wrapper for using the identi.ca Twitter-compatible API from node", + "author": { + "name":"David Pearson", + "url":"http://dpearson.me" + }, + "version": "0.0.1", + + "dependencies": { + "open":"0.0.2", + "request":"2.12.0" + }, + + "bin": { + "getaccesstoken.js":"getaccesstoken" + } +} \ No newline at end of file