Jump to content

Welcome! You're currently a Guest.

If you'd like to join in the Discussion, or access additional features in our forums, please sign in with your Evernote Account here. Have an Evernote Account but forgot your password? Reset it! Don't have an account yet? Create One! You'll need to set your Display Name before your first post.

Photo

Either a REST interface or some documentation for the AS3 library?

as3 rest actionscript

  • Please log in to reply
8 replies to this topic

#1 Richard Haven

Richard Haven

  • Pip
  • Title: Member
  • Group: Members
  • 48 posts

Posted 25 May 2012 - 06:26 AM

I apologize if I have simply missed the documentation for the ActionScript library (SWC), but I have no idea how to use it. It does not seem to have either examples or class descriptions, and the source code is unlike any standard Flex or ActionScript style that I have seen.

Please point me in the direction of some specific source code examples or point me in the direction of a REST interface: either one is fine.

Thank you for your attention

-R

#2 Aaron P.

Aaron P.

  • Pip
  • Title: Member
  • Group: Members
  • 3 posts

Posted 26 May 2012 - 03:01 PM

I've been struggling with the same issue... so I've been doing some research online, and have come across this Adobe resource for OAuth... I'm still reading through it, so I'm not sure if it's the answer or not... but thought I'd share!

http://blogs.adobe.c...tionscript.html

Good luck!

#3 Aaron P.

Aaron P.

  • Pip
  • Title: Member
  • Group: Members
  • 3 posts

Posted 27 May 2012 - 01:25 AM

So... I'm VERY frustrated with the lack of documentation or examples for the actionscript sdk. Here's the crux of the code I have so far:

protected function evernoteLoginButton_clickHandler(event:MouseEvent):void
  {
   //Try to authenticate the user
   var usrAgent:String = "my-app/1.0";
   var usrStoreUrlRequest:URLRequest = new URLRequest("https://sandbox.evernote.com/");
   var usrStoreTransport:THttpClient = new THttpClient(usrStoreUrlRequest);
   var usrStoreProtocol:TBinaryProtocol = new TBinaryProtocol(usrStoreTransport);
   var usrStoreClient:UserStore = new UserStore(usrStoreProtocol, usrStoreProtocol);
  
   //Version Check
   usrStoreClient.checkVersion(usrAgent,
	com.evernote.edam.userstore.Constants.EDAM_VERSION_MAJOR,
	com.evernote.edam.userstore.Constants.EDAM_VERSION_MINOR,
	handleError,
	handleSuccess);
  }

  private function handleError(err:TTransportError):void
  {
   trace(TAG + ".handleError:obj = " + err.getStackTrace().toString());
  }

  private function handleSuccess(obj:Object=null):void
  {
   if(obj){
	trace(TAG + ".handleSuccess:obj = " + obj.toString());
   }else{
	trace(TAG + ".handleSuccess:obj = null");
   }
  }

When this code gets executed, I get the following console output:


RESPONSE_BUFFER BUFFER length: 5935, [a][a][a][a]...whole bunch more ...[6c][3e][a]
READ BUFFER length: 4, [a][a][a][a]
FAILED-RESPONSE-REQUEST BUFFER length: 86, [80][1][0][1]...whole bunch more ...[0][13][0]
FAILED-RESPONSE BUFFER length: 5935, [a][a][a]...whole bunch more ...[68][74][6d][6c][3e][a]
EvernoteLoginViewLogic.handleError:obj = Error: No more data available.
at org.apache.thrift.transport::THttpClient/read()[/Users/bhall/Documents/Work/Clients/Current/Evernote/dev/gen/org/apache/thrift/transport/THttpClient.as:83]
at org.apache.thrift.transport::TTransport/readAll()[/Users/bhall/Documents/Work/Clients/Current/Evernote/dev/gen/org/apache/thrift/transport/TTransport.as:87]
at org.apache.thrift.protocol::TBinaryProtocol/readAll()[/Users/bhall/Documents/Work/Clients/Current/Evernote/dev/gen/org/apache/thrift/protocol/TBinaryProtocol.as:296]
at org.apache.thrift.protocol::TBinaryProtocol/readStringBody()[/Users/bhall/Documents/Work/Clients/Current/Evernote/dev/gen/org/apache/thrift/protocol/TBinaryProtocol.as:280]
at org.apache.thrift.protocol::TBinaryProtocol/readMessageBegin()[/Users/bhall/Documents/Work/Clients/Current/Evernote/dev/gen/org/apache/thrift/protocol/TBinaryProtocol.as:202]
at Function/<anonymous>()[/Users/bhall/Documents/Work/Clients/Current/Evernote/dev/gen/com/evernote/edam/userstore/UserStore.as:64]
at Function/<anonymous>()[/Users/bhall/Documents/Work/Clients/Current/Evernote/dev/gen/org/apache/thrift/transport/THttpClient.as:100]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()

What am I doing wrong?

Thanks!

#4 dwhogg

dwhogg

  • Pip
  • Title: Member
  • Group: Members
  • 4 posts

Posted 30 May 2012 - 06:13 PM

I am attempting to use StageWebView in AS3 to implement oAuth as described here.

However, since I am running an air app (mobile and desktop), what can I use as the callback parameter?

I have tried "oob" and other variants (how I have used OAuth from mobile for Google for example) but that doesn't seem to work.

I am able to get the temporary credentials response token and then the resource owner auth screen, but then simply receive a "load error" when the user clicks "Allow" (or Decline) which I am assuming is due to my callback being invalid?

Any suggestions?

#5 Aaron P.

Aaron P.

  • Pip
  • Title: Member
  • Group: Members
  • 3 posts

Posted 31 May 2012 - 04:19 AM

Here's the code I used to connect to Evernote and to get fully authenticated. I used the StageWebViewUIComponent that Sonke Rohde posted at http://soenkerohde.c...ew-uicomponent/. The rest of my code is as follows:

package
{
import com.evernote.edam.limits.Constants;
import com.evernote.edam.type.User;
import com.evernote.edam.userstore.AuthenticationResult;
import com.evernote.edam.userstore.Constants;
import com.evernote.edam.userstore.UserStore;
import com.evernote.edam.userstore.UserStoreProcessor;

import flash.desktop.NativeApplication;
import flash.events.ErrorEvent;
import flash.events.Event;
import flash.events.HTTPStatusEvent;
import flash.events.IEventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.LocationChangeEvent;
import flash.events.MouseEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.events.TextEvent;
import flash.geom.Rectangle;
import flash.media.StageWebView;
import flash.net.URLLoader;
import flash.net.URLRequest;

import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.protocol.TProtocolUtil;
import org.apache.thrift.transport.THttpClient;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportError;

import spark.components.Button;
import spark.components.Group;
import spark.components.TextArea;
import spark.components.TextInput;
import spark.components.View;



public class EvernoteLoginViewLogic extends View
{
  private const TAG:String = "EvernoteLoginViewLogic";
  [Bindable] public var evernoteUsernameTextBox:TextInput;
  [Bindable] public var evernotePasswordTextBox:TextInput;
  [Bindable] public var evernoteLoginButton:Button;
  [Bindable] public var accessToken:TextArea;
  [Bindable] public var tokenType:TextInput;
  [Bindable] public var expiresIn:TextInput;
  [Bindable] public var viewPort:Group;
  [Bindable] public var stageWebView:StageWebViewUIComponent;
  [Bindable] public var okButton:Button;
 
  private var usrStoreClient:UserStore;
  private var user:User;
  private var tempToken:String;
  private var authToken:String;
  private var userStoreUrl:String;
  private var loader:URLLoader;
 
 
  public function EvernoteLoginViewLogic()
  {
   super();  
  }
 
  protected function getTempTokenButton_clickHandler(event:MouseEvent):void
  {
   //Try to get access to the UserStore
   var usrAgent:String = "My-App/1.0";
   var usrStoreUrlRequest:URLRequest = new URLRequest(EvernoteImplementationConstants.EvernoteStoreUrl);
  
   var usrStoreTransport:THttpClient = new THttpClient(usrStoreUrlRequest);
   var usrStoreProtocol:TBinaryProtocol = new TBinaryProtocol(usrStoreTransport);
   usrStoreClient = new UserStore(usrStoreProtocol, usrStoreProtocol);
  
   //DO a quick Version Check to make sure we are still compliant!
   usrStoreClient.checkVersion(usrAgent,
    com.evernote.edam.userstore.Constants.EDAM_VERSION_MAJOR,
    com.evernote.edam.userstore.Constants.EDAM_VERSION_MINOR,
    handleError,
    handleSuccess);
  }
 
  private function handleError(err:TTransportError):void
  {
   trace(TAG + ".handleError:obj = " + err.getStackTrace().toString());
  }
 
  private function handleSuccess(obj:Object=null):void
  {
   if(obj){
    trace(TAG + ".handleSuccess:obj = " + obj.toString());
    //The version is good, so now we can get the OAuth authorization token
    getOAuthToken();
   }else{
    trace(TAG + ".handleSuccess:obj = null");
   }
  }
 
  private function getOAuthToken():void
  {
   /**
    *
    * So... there is blessed little info on how to make this happen, except the following:
    *
    * The order of needed operations to get the application token is:
    *    1) User requests to login to Evernote (in my app) (is this a given in our app???)
    *    2) My App Requests temporary credentials from Evernote (Request Token)
    *    3) Evernote Sends temporary credentials to my app (Request Token)
    *    4) My App loads the Evernote login Page for the user to use
    *    5) <already done>
    *    6) Evernote returns the login the authorization pages
    *    7) User grants access to your application via the webpage
    *    8) Evernote redirects the webpage to the callback URL
    *    9) My app recognizes the callback URL and closes the login window
    *   10) My App requests an exchange of temporary credentials for application credentials from Evernote
    *   11) Evernote grants the application token credentials to my app
    *   12) We are off and running!
    *
    * It turns out that the best way to accomplish this is using a combination of URLLoader and the
    *  StageWebView.  I use the URLLoader for interracting with the Evernote servers when I don't need
    *  the user to interact (i.e login or grant permissions). I use the StageWebView when user interaction
    *  is needed.
    **/
//   currentState = "WebsiteState";
  
   // Build up the URL
   var now:Date = new Date();
   
   var oAuthUrl:String = EvernoteImplementationConstants.EvernoteOAuthTempCredentialRequestUrl
	 + "?oauth_consumer_key="
	 + EvernoteImplementationConstants.MyConsumerKey
	 + "&oauth_signature="
	 + EvernoteImplementationConstants.MyConsumerSecret
	 + "&oauth_signature_method="
	 + EvernoteImplementationConstants.EvernoteOAuthSignatureMethod
	 + "&oauth_timestamp="
	 + now.getTime()
	 + "&oauth_nonce="
	 + Math.random()
	 + "&oauth_callback="
	 + EvernoteImplementationConstants.EvernoteOAuthResourceOwnerAuthUrl;
  
   // set up the URLLoader
   loader = new URLLoader();
  
   // set up the listeners for the URLLoader
   loader.addEventListener(Event.COMPLETE, getTempTokenCompleteHandler);
   loader.addEventListener(Event.OPEN, openHandler);
   loader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
   loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
   loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
   loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
  
   // set up the URL that we want to go to
   var urlRequest:URLRequest = new URLRequest(oAuthUrl);
  
   try {
    // Let's try loading the URL using the loader
    loader.load(urlRequest);
   } catch (error:Error) {
    trace(TAG + ".getOAuthToken: Unable to load requested document.");
   }
  }
 
  private function getTempTokenCompleteHandler(event:Event):void {
   var loader:URLLoader = URLLoader(event.target);
   trace(TAG + ":getTempTokenCompleteHandler: " + loader.data);
  
   //We should have a valid token
   var rawData:String = loader.data;
  
  
   //If we have a temp token
   if(rawData.search("oauth_callback_confirmed=true") >= 0){
    //We have received the temp token
    //Let's pull out the token data
    
    var tokenStart:Number = rawData.search("aaronpatty.");
    var tokenEnd:Number = rawData.search("&oauth_token_secret");
    tempToken = rawData.substring(tokenStart, tokenEnd);
   
    currentState = "ResultsState";
    accessToken.text = tempToken;
    tokenType.text = "Temporary Authorization Token";
    expiresIn.text = "???";
   
    trace(TAG + ".completeHandler: TempToken=" + tempToken);
   
    // Now we wait for the user to click the OK button!
   
   }else if(rawData.search("&edam_noteStoreUrl") >= 0){
   
    // We have successfully received access to the user's account! YEAH!
    // Let's pull out the token and other data
    
    var tokenStart:Number = "oauth_token=".length;
    var tokenEnd:Number = rawData.search("&oauth_token_secret=");
    authToken = rawData.substring(tokenStart, tokenEnd);
    trace(TAG + "getTempTokenCompleteHandler: AuthToken=" + authToken);
   
    var userNoteStoreUrlStart:Number = rawData.search("&edam_noteStoreUrl=") + "&edam_noteStoreUrl=".length;
    userStoreUrl = rawData.substring(userNoteStoreUrlStart); // Grab the rest of the string including the edam_userId
    trace(TAG + "getTempTokenCompleteHandler: UserStoreUrl=" + userStoreUrl);
    stageWebView.hide();
    stageWebView.removeEventListener(Event.COMPLETE, userAccessCompleteHandler);
    stageWebView.removeEventListener(ErrorEvent.ERROR, userAccessErrorHandler);
    stageWebView.removeEventListener(LocationChangeEvent.LOCATION_CHANGING, userAccessLocationChangingHandler);
    stageWebView.removeEventListener(LocationChangeEvent.LOCATION_CHANGE, userAccessLocationChangeHandler);
    stageWebView.dispose();
   
    currentState = "ResultsState";
    accessToken.text = authToken;
    tokenType.text = "UserStore Authorization Token";
    expiresIn.text = "365 Days!";
   
    // We are done! We can now access the UserStore all we want!
   }  
  }
 
  private function openHandler(event:Event):void {
   trace(TAG + ":openHandler: " + event);
  }
 
  private function progressHandler(event:ProgressEvent):void {
   trace(TAG + ":progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
  }
 
  private function securityErrorHandler(event:SecurityErrorEvent):void {
   trace(TAG + ":securityErrorHandler: " + event);
  }
 
  private function httpStatusHandler(event:HTTPStatusEvent):void {
   trace(TAG + ":httpStatusHandler: " + event);
  }
 
  private function ioErrorHandler(event:IOErrorEvent):void {
   trace(TAG + ":ioErrorHandler: " + event);
  }
 
  protected function okButton_clickHandler(event:MouseEvent):void
  {
   if(authToken){
    NativeApplication.nativeApplication.exit();
   }
   // Switch to the WebsiteState
   currentState = "WebsiteState";
  
  }
 
  protected function userLoginButton_clickHandler(event:MouseEvent):void
  {
   // We have the temp token... now it's time to have the user
   // give us authorization to use their account in our app!
  
  
   // Build up the URL
   var now:Date = new Date();
   var oAuthUrl:String = EvernoteImplementationConstants.EvernoteOAuthResourceOwnerAuthUrl
    + "?oauth_token="
    + tempToken;
  
   // Add the listeners to the StageWebView
   stageWebView.addEventListener(Event.COMPLETE, userAccessCompleteHandler);
   stageWebView.addEventListener(ErrorEvent.ERROR, userAccessErrorHandler);
   stageWebView.addEventListener(LocationChangeEvent.LOCATION_CHANGING, userAccessLocationChangingHandler);
   stageWebView.addEventListener(LocationChangeEvent.LOCATION_CHANGE, userAccessLocationChangeHandler);
 
   // Go to the URL
   stageWebView.url = oAuthUrl;
   okButton.label = "Exit";
  }
 
  protected function userAccessCompleteHandler(event:Event):void
  {
   trace(TAG + ".userAccessCompleteHandler: " + event.toString());
  }
 
  protected function userAccessLocationChangingHandler(event:LocationChangeEvent):void
  {
   trace(TAG + ".userAccessLocationChangingHandler: " + event.toString());
  }
 
  protected function userAccessLocationChangeHandler(event:LocationChangeEvent ):void
  {
   trace(TAG + ".userAccessLocationChangeHandler: " + event.toString());
   // Watch for the oauth_verifier
  
   
   var verifierStart:Number = event.location.search("&oauth_verifier=")+ "&oauth_verifier=".length;
   if(verifierStart > 0){
    // We have been allowed access!
    // Now get the verifier string
    var verifier:String = event.location.substring(verifierStart);
   
    // Now that we have the verifier, we can request the official Authorization Token
    // Build up the URL
    var now:Date = new Date();
    
    var oAuthUrl:String = EvernoteImplementationConstants.EvernoteOAuthTempCredentialRequestUrl
	 + "?oauth_consumer_key="
	 + EvernoteImplementationConstants.MyConsumerKey
	 + "&oauth_signature="
	 + EvernoteImplementationConstants.MyConsumerSecret
	 + "&oauth_signature_method="
	 + EvernoteImplementationConstants.EvernoteOAuthSignatureMethod
	 + "&oauth_timestamp="
	 + now.getTime()
	 + "&oauth_nonce="
	 + Math.random()
	 + "&oauth_token="
	 + tempToken
	 + "&oauth_verifier="
	 + verifier;
   
    stageWebView.enabled = false;
   
    // set up the URL that we want to go to
    var urlRequest:URLRequest = new URLRequest(oAuthUrl);
   
    try {
	 // Let's try loading the URL using the loader
	 loader.load(urlRequest);
    } catch (error:Error) {
	 trace(TAG + ".getOAuthToken: Unable to load requested document.");
    }
   }
  }
 
  protected function userAccessErrorHandler(event:Event):void
  {
   trace(TAG + ".userAccessErrorHandler: " + event.toString());
  }
}
}



And, here's the code for the user interface (view):

<?xml version="1.0" encoding="utf-8"?>
<local:EvernoteLoginViewLogic xmlns:fx="http://ns.adobe.com/mxml/2009"
		 xmlns:local="*"
		 xmlns:s="library://ns.adobe.com/flex/spark"
		 currentState="LoginState" title="EvernoteLoginView">

<fx:Script>
</fx:Script>

<local:states>
  <s:State name="LoginState"/>
  <s:State name="ResultsState"/>
  <s:State name="WebsiteState"/>
</local:states>
<fx:Declarations>
  <!--  DO NOT PLACE ANYTHING HERE!
  All scripting should be done in the EvernoteLoginViewLogic.as class! -->
</fx:Declarations>

<!--<s:Group id="viewPort" width="100%" height="100%"
    left.ResultsState="0" top.ResultsState="0">
  <s:Rect width="100%" height="100%"
    left.LoginState="0" top.LoginState="0">
   <s:fill>
    <s:SolidColor color="#cecece" />
   </s:fill>
  </s:Rect>
</s:Group>-->

<s:Label includeIn="LoginState" fontSize="50" horizontalCenter="0" text="Evernote Login"
    verticalCenter="-300"/>
<s:Button id="getTempTokenButton" includeIn="LoginState" label="Get Temp Token"
	 click="getTempTokenButton_clickHandler(event)" fontSize="36" horizontalCenter="0"
	 verticalCenter="0"/>
<s:Label includeIn="ResultsState" top="10" fontWeight="bold" horizontalCenter="0"
    text="Token Response"/>
<s:VGroup includeIn="ResultsState" top="40" horizontalCenter="0">
  <s:Label x="10" text="Access Token"/>
  <s:Scroller x="10" y="41" width="95%" height="256">
   <s:VGroup width="100%" height="100%">
    <s:TextArea id="accessToken" width="100%" height="100%"/>
   </s:VGroup>
  </s:Scroller>
  <s:Label x="10" text="Token Type"/>
  <s:TextInput id="tokenType" y="229" width="95%" horizontalCenter="0" />
  <s:Label x="10"  text="Expires In"/>
  <s:TextInput id="expiresIn" y="323" width="95%" horizontalCenter="0" />
  <s:Group width="100%">
   <s:Button id="okButton" includeIn="ResultsState" label="OK"
	   click="okButton_clickHandler(event)" horizontalCenter="0"
	   verticalCenter="0"/>
  </s:Group>
</s:VGroup>
<local:StageWebViewUIComponent id="stageWebView" includeIn="WebsiteState" top="100" width="100%"
		   height="500" horizontalCenter="0"/>
<s:Button id="userLoginButton" includeIn="WebsiteState" top="10"
	 label="Have User Login to Evernote" click="userLoginButton_clickHandler(event)"
	 horizontalCenter="0"/>

</local:EvernoteLoginViewLogic>



It's not a pretty UI, nor has the code been cleaned up at all, but it works.

Good luck!

#6 Richard Haven

Richard Haven

  • Pip
  • Title: Member
  • Group: Members
  • 48 posts

Posted 31 May 2012 - 09:54 PM

Update: I have gotten the AS3 api to compile (one has to remove the naive directory names in the src/)

Now, off to access using the developers token and then the OAuth

Thanks for everyone's contributions

#7 Richard Haven

Richard Haven

  • Pip
  • Title: Member
  • Group: Members
  • 48 posts

Posted 08 June 2012 - 02:11 AM

Instead of trying to provide native code libraries for a wide selection of languages, I recommend that EN create a REST interface.

We are struggling with apparent bugs in the ActionScript API (see http://discussion.ev...799#entry143799), and time is running out for the contest.

Cheers

#8 Richard Haven

Richard Haven

  • Pip
  • Title: Member
  • Group: Members
  • 48 posts

Posted 09 June 2012 - 05:10 PM

Here's the code I used to connect to Evernote and to get fully authenticated...



Where is EvernoteImplementationConstants ?

#9 vogttho

vogttho

  • Pip
  • Title: Member
  • Group: Members
  • 2 posts

Posted 19 June 2013 - 12:48 PM

So what is the status here? I tried to use the as3 library but I failed. there is still no documentation and the only example I found is the one from Aron P.

 

It works so far but I am not sure if the AS Library will be supported in the future

 

Here are the missing constants:

 

 

    public const EvernoteStoreUrl:String = "https://sandbox.evernote.com/edam/user";
    public const EvernoteOAuthTempCredentialRequestUrl:String = "https://sandbox.evernote.com/oauth";
    public const MyConsumerKey:String = "xxxxxx";
    public const MyConsumerSecret:String = "xxxxxx";
    public const EvernoteOAuthSignatureMethod:String = "PLAINTEXT";
    public const EvernoteOAuthResourceOwnerAuthUrl:String = "https://sandbox.ever...om/OAuth.action";






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Clip to Evernote