Custom Module
Hi all - anyone had any luck in getting a custom module going in 1.x or want to give it a shot with me?
I'm looking to implement the Aral Balkan's XAuthTwitterEngine and really am not sure how to make that happen. (there's a reason I stear clear of objective-c … :s)
If we can walk through this publicly, it should help others with both Twitter auth and extending Ti.
Aral's project is:
http://github.com/aral/XAuthTwitterEngine
Jeff's temp docs for implementing a module:
http://www.codestrong.com/timobile/module_sdk_09/
Let me know if you are game - dying to get this in my app (and my head)
13 Answers
-
Here ya go. I finally got xauth working properly.
You must first register your app with twitter:
http://twitter.com/oauth_clients/newThen, email them and request xauth as your authentication type (took less than a day for them to set it up).
You'll need these two includes:
http://oauth.googlecode.com/svn/code/javascript/oauth.js
http://oauth.googlecode.com/svn/code/javascript/sha1.jsThis is the code to retrieve your oauth_token and oauth_secret_token:
//un = username var //pw = password var var requestUrl = 'https://api.twitter.com/oauth/access_token'; var ck = 'Consumer Key Here -- get this when you register with twitter'; var cks = 'Consumer Secret -- get this when you register with twitter'; var accessor = {consumerSecret: cks}; var message = { method: "POST", action: requestUrl, parameters: [ ['oauth_signature_method', 'HMAC-SHA1'], ['oauth_consumer_key', ck], ['oauth_version', '1.0'], ['x_auth_username', un], ['x_auth_password', pw], ['x_auth_mode', 'client_auth'], ['format', 'json'] ] }; OAuth.setTimestampAndNonce(message); OAuth.setParameter(message, "oauth_timestamp", OAuth.timestamp()); OAuth.SignatureMethod.sign(message, accessor); finalUrl = OAuth.addToURL(message.action, message.parameters); function getTokens(){ var xhr = Titanium.Network.createHTTPClient(); xhr.onload = function() { //parse response into separate vars var uri = this.responseText; var queryString = {}; uri.replace( new RegExp("([^?=&]+)(=([^&]*))?", "g"), function($0, $1, $2, $3) { queryString[$1] = $3; }); //get 'oauth_token' var ftoken = queryString['oauth_token']; //get 'oauth_token_secret' var fstoken = queryString['oauth_token_secret']; } xhr.open('POST', finalUrl); xhr.send(); } getTokens();
From here, use the tokens to make your requests – same as an OAuth Request
Hope that's helpful.
Michael
-
I've created a working custom module in 1.0, based on the template link you mentioned: http://www.codestrong.com/timobile/module_sdk_09/.
Jeff says in this thread: https://developer.appcelerator.com/question/3841/custom-module-example that he's doing a more complete example, though.
-
any chance you would share your project? Maybe just a stripped down version that I could just see how all the pieces go together?
-
At this point I've tried everything I can think of.
After testing build in Ti, the module dir shows up in my project root. I get the detecting third-party module msg, but I'm assuming this is due to the tiapp.xml addition.
I reference it from my app.js:
var mymodule = Titanium.Myfirst;Ti.API.info('module ------------------------- > '+ typeof mymodule);
But only get undefined.
In case this points to what the heck I'm missing:
http://pastie.org/880725
Any pointers?
-
Hey - this looks promising:
http://developer.appcelerator.com/doc/mobile/iphone/module_sdk
I believe this is new.
-
Funny, I had a custom module working for a few minutes in 1.0, but since 1.1 was released, I can't get it to work anymore. I always get "undefined" just like you do. I even tried going back to 1.0, but it's never worked for me since.
-
Here ya go. I finally got xauth working properly.
You must first register your app with twitter:
http://twitter.com/oauth_clients/newThen, email them and request xauth as your authentication type (took less than a day for them to set it up).
You'll need these two includes:
http://oauth.googlecode.com/svn/code/javascript/oauth.js
http://oauth.googlecode.com/svn/code/javascript/sha1.jsThis is the code to retrieve your oauth_token and oauth_secret_token:
//un = username var //pw = password var var requestUrl = 'https://api.twitter.com/oauth/access_token'; var ck = 'Consumer Key Here -- get this when you register with twitter'; var cks = 'Consumer Secret -- get this when you register with twitter'; var accessor = {consumerSecret: cks}; var message = { method: "POST", action: requestUrl, parameters: [ ['oauth_signature_method', 'HMAC-SHA1'], ['oauth_consumer_key', ck], ['oauth_version', '1.0'], ['x_auth_username', un], ['x_auth_password', pw], ['x_auth_mode', 'client_auth'], ['format', 'json'] ] }; OAuth.setTimestampAndNonce(message); OAuth.setParameter(message, "oauth_timestamp", OAuth.timestamp()); OAuth.SignatureMethod.sign(message, accessor); finalUrl = OAuth.addToURL(message.action, message.parameters); function getTokens(){ var xhr = Titanium.Network.createHTTPClient(); xhr.onload = function() { //parse response into separate vars var uri = this.responseText; var queryString = {}; uri.replace( new RegExp("([^?=&]+)(=([^&]*))?", "g"), function($0, $1, $2, $3) { queryString[$1] = $3; }); //get 'oauth_token' var ftoken = queryString['oauth_token']; //get 'oauth_token_secret' var fstoken = queryString['oauth_token_secret']; } xhr.open('POST', finalUrl); xhr.send(); } getTokens();
From here, use the tokens to make your requests – same as an OAuth Request
Hope that's helpful.
Michael
-
Thanks Michael, I finally got around to trying this out but am getting:
Script Error = Can't find variable: document at oauth.js (line 304).
Before I can even make a request.
edit: Managed to hack it out in a webview to get the 'finalUrl' generated and then passed back up to Ti but attempting to get tokens I get :
{"type":"error","source":{},"error":"Error Domain=ASIHTTPRequestErrorDomain Code=3 UserInfo=0x512a140 "Authentication needed""}
my call:
var xhr = Titanium.Network.createHTTPClient(); xhr.onload = function () { Ti.API.info('response received'); //parse response into separate vars var uri = this.responseText; var queryString = {}; uri.replace( new RegExp("([^?=&]+)(=([^&]*))?", "g"), function ($0, $1, $2, $3) { queryString[$1] = $3; }); //get 'oauth_token' var ftoken = queryString['oauth_token']; //get 'oauth_token_secret' var fstoken = queryString['oauth_token_secret']; } xhr.onerror = function (e) { Ti.API.info(JSON.stringify(e)); }; data = { 'x_auth_username':getURLVar(uri, 'x_auth_username'), 'x_auth_password':getURLVar(uri, 'x_auth_password'), 'x_auth_mode': 'client_auth' }; var uri = e.finalUrl; xhr.open('POST', uri); var authString = 'OAuth oauth_consumer_key="' + getURLVar(uri, 'oauth_consumer_key') + '", oauth_nonce="' + getURLVar(uri, 'oauth_nonce') + '", oauth_signature_method="' + getURLVar(uri, 'oauth_signature_method') + '", oauth_signature="' + getURLVar(uri, 'oauth_signature') + '", oauth_timestamp="' + getURLVar(uri, 'oauth_timestamp') + '", oauth_version="' + getURLVar(uri, 'oauth_version') + '"'; xhr.setRequestHeader('Authorization', authString); xhr.send(data);
-
Hi Nick,
Try commenting out the last line in OAuth.js
//OAuth.correctTimestampFromSrc();
Since xAuth doesn't need to actually go to the 'allow/deny' page on somewhere like twitter, the lookup on the 'document' is not needed.
xAuth allows us to imply the user 'allowing' the 'connection' with an application and their account, negating the need for the mobile version of the Authorization page.
Once you have that set up, you MUST dispose of the users' username and password and ONLY store the token and token_secret returned from the xAuth request.
After that, you can then go ahead and use OAuth as normal.
Eg, to make a post, you need to use code similar to Michael's xAuth request like this:
// .. given that you already have 'oauth_consumer_secret' and 'oauth_consumer_key' // when registering your app with your OAuth provider... // And after using xAuth to get the 'oauth_token' and 'oauth_token_secret' for your user (and your app) // using the code from Michaeal... Ti.include('oauth.js'); Ti.include('sha1.js'); function sendTweet(tweet){ var requestUrl = 'https://api.twitter.com/1/statuses/update.json'; var accessor = {tokenSecret: oauth_token_secret,consumerSecret: oauth_consumer_secret}; var message = { method: "POST", action: requestUrl, parameters: [ ['oauth_signature_method', 'HMAC-SHA1'], ['oauth_consumer_key', oauth_consumer_key], ['oauth_version', '1.0'], ['oauth_token', oauth_token], ['format', 'json'], ['status', tweet] ] }; OAuth.setTimestampAndNonce(message); OAuth.setParameter(message, "oauth_timestamp", OAuth.timestamp()); OAuth.SignatureMethod.sign(message, accessor); var postingUrl = OAuth.addToURL(message.action, message.parameters); var xhr = Titanium.Network.createHTTPClient(); xhr.onload = function(){ //parse response into separate vars var reply = this.responseText; Ti.API.info('the response to the tweet was: '); Ti.API.info(reply); // parse/eval this and let your user know it all went OK, and update/ do whatever... }; xhr.open('POST', postingUrl); xhr.send(); } // usage: sendTweet('hello from my app!');
hope this helps! :)
-
I think I am getting close to this working. Any thoughts? I am getting the following in the console window after calling setUpAuthPerams() and getTokens();
password = mypassword;
username = "myusernamet";
}
[ERROR] listener callback is of a non-supported type: NSNull
} -
so I have all the above code in place. When I call getTokens() I get the following error.
[ERROR] listener callback is of a non-supported type: NSNull
any thoughts as to why?
-
10 lines of code with the OAuth Adapter:
var oAuthAdapter = new OAuthAdapter( '<your-consumer-secret>', '<your-consumer-key>', 'HMAC-SHA1'); // load the access token for the service (if previously saved) oAuthAdapter.loadAccessToken('twitter'); oAuthAdapter.send('https://api.twitter.com/1/statuses/update.json', [['status', 'hey @ziodave, I successfully tested the #oauth adapter with #twitter and @appcelerator #titanium!']], 'Twitter', 'Published.', 'Not published.'); // if the client is not authorized, ask for authorization. the previous tweet will be sent automatically after authorization if (oAuthAdapter.isAuthorized() == false) { // this function will be called as soon as the application is authorized var receivePin = function() { // get the access token with the provided pin/oauth_verifier oAuthAdapter.getAccessToken('http://twitter.com/oauth/access_token'); // save the access token oAuthAdapter.saveAccessToken('twitter'); }; // show the authorization UI and call back the receive PIN function oAuthAdapter.showAuthorizeUI('http://twitter.com/oauth/authorize?oauth_token=' + oAuthAdapter.getRequestToken('http://twitter.com/oauth/request_token', [['oauth_callback', 'oob']]), receivePin, PinFinder.twitter); }
-
I'm a late comer to the xAuth discussion and I would like to ask if I understand the concept correctly. Are the steps as follows:
- Get oAuth/xAuth credentials from twitter.com
- Implement the code added by Michael Ferguson to getTockens()
- Use Tocken and TockenSecret from step 2 with code added by Kosso to sendTweet()
Thanks