AS3 Yammer Library

For the past few months I have been working on an AS3 library that wraps the Yammer API for use in Flash, Flex, and AIR projects. The biggest hurdle was making the application work for the web. As it is now, for Flash projects, you still need to be targeting Flash player 10 so that you can upload the ByteArray information file attachments. The second hurdle was creating an easy Oauth flow that doesn’t add items to the header that would violate the Flash player security, something you don’t have to worry about when creating AIR applications.

With that work out of the way, I would like to introduce an AS3 Yammer API library that communicates with the Yammer service. The as3yammerlib is hosted on GitHub and the source code is publicly available. To use the library you will need your own consumer key and secret for the Yammer API available from Yammer’s developer site. The library is also dependent on the as3corelib for doing JSON parsing and as3-signals for broadcasting events.

I put together a Flex web-based example using Flex Builder 4 that walks you through the Oauth process and retrieves messages for the logged in user. To use the code, just create a new Flex project and paste the Main.mxml file in your main application file and create another mxml for the MessageItemRenderer file within the same directory:

Main.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/halo"
               xmlns:ns="library://ns.adobe.com/flex/mx"
               creationComplete="init()"
               minWidth="1024" minHeight="768">


    <fx:Script>
        <![CDATA[
            import com.yammer.api.Yammer;
            import com.yammer.api.events.YammerEvent;
            import com.yammer.api.vo.Oauth;
            import com.yammer.api.vo.YammerCurrentUser;
            import com.yammer.api.vo.YammerError;
            import com.yammer.api.vo.YammerMessageList;
            import com.yammer.api.vo.YammerTab;

            import mx.collections.ArrayCollection;
            import mx.controls.Alert;

            private var oauthToken:String;
            private var oauthSecret:String;

            // your consumer key and secret go here
            private var consumerKey:String = "your consumer key";
            private var consumerSecret:String = "your consumer secret";

            private var service:Yammer;

            [Bindable] private var currentUser:YammerCurrentUser;

            private function init():void
            {
                this.service = new Yammer(this.consumerKey, this.consumerSecret);
                this.service.errorReceived.add(errorReceived);

                // we have tokens stored
                if(oauthToken && oauthSecret){
                    service.setOuthTokens(oauthToken, oauthSecret);
                    this.getCurrentUser();
                }
            }

            // get request token from service.
            private function getRequestToken():void
            {
                service.resultsReceived.add(requestTokenReceived);
                service.requestToken();
            }

            // submit the virify pin from the web site
            private function getAccessToken(verify_pin:String):void
            {
                service.resultsReceived.add(accessTokenReceived);
                service.accessToken(verify_pin);
            }

            // sends user to browser page to retrieve verification pin.
            private function sendAuthorizationRequest():void
            {
                service.sendAuthorizationRequest(); // open browser window
            }

            private function getCurrentUser():void
            {
                service.resultsReceived.add(currentUserReceived);
                service.getCurrentUser();
                return;
            }

            public function getMessages(tab:YammerTab):void
            {
                service.resultsReceived.add(messageListReceived);
                service.getMessages(tab.url);
                return;
            }

            private function requestTokenReceived(value:Oauth):void
            {
                service.resultsReceived.remove(requestTokenReceived);
                Alert.show("Request tokens received: " + value.oauth_token);
            }

            private function accessTokenReceived(value:Oauth):void
            {
                service.resultsReceived.remove(accessTokenReceived);
                Alert.show("Access tokens received:: token: " + value.oauth_token + " secret: " + value.oauth_token_secret);
                this.getCurrentUser();
            }

            private function currentUserReceived(value:YammerCurrentUser):void
            {
                service.resultsReceived.remove(currentUserReceived);
                currentUser = value;
                var tab:YammerTab = currentUser.tabs[0]; // get first user tab, usually My Feed
                this.getMessages(tab);
            }

            private function messageListReceived(value:YammerMessageList):void
            {
                service.resultsReceived.remove(messageListReceived);
                var messagelist:YammerMessageList = value;
                var messages:ArrayCollection = new ArrayCollection(messagelist.getMessages());
                messageList.dataProvider = messages;
            }

            private function errorReceived(error:YammerError):void
            {
                Alert.show("Yammer Service Error: " + error.errorMessage);
            }

        ]]>
    </fx:Script>

    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>

    <s:Button label="1. Request Token" click="getRequestToken()" width="120" x="10" y="10"/>

    <s:Button label="2. Open Browser" click="sendAuthorizationRequest()" width="120" x="138" y="10"/>

    <s:TextInput id="pinInput" text="3. Paste Pin" width="120" textAlign="center" focusIn="pinInput.text = ''" x="266" y="10"/>

    <s:Button label="4. Access Token" click="getAccessToken(pinInput.text)" width="120" x="394" y="10"/>

    <s:List id="messageList" x="10" y="113" width="563" height="337" itemRenderer="MessageItemRenderer"/>

    <ns:Image source="{currentUser.mugshot_url}" width="48" height="48" x="11" y="45"/>

    <s:Label text="{currentUser.full_name}" x="67" y="50"  fontSize="14"/>

    <s:Label text="{currentUser.job_title}" x="67" y="72"  fontSize="11"/>

</s:Application>

MessageItemRenderer.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer width="100%"
           xmlns:fx="http://ns.adobe.com/mxml/2009"
           xmlns:s="library://ns.adobe.com/flex/spark"
           xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:ns="library://ns.adobe.com/flex/mx">

    <fx:Script>
        <![CDATA[
            import com.yammer.api.utils.MessageUtilities;
            import com.yammer.api.vo.YammerMessage;

            [Bindable] private var message:YammerMessage;

            override public function set data(value:Object):void
            {
                super.data = value;
                message = data as YammerMessage;
            }

            /**
             *  override set data to set
             */
            override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
            {
                super.updateDisplayList(unscaledWidth,unscaledHeight);
            }
        ]]>
    </fx:Script>

    <s:Rect left="0" bottom="1" right="0" height="1">
        <s:fill>
            <s:SolidColor color="0x000000" alpha=".2"/>
        </s:fill>
    </s:Rect>

    <s:HGroup width="100%" height="100%" paddingTop="5" paddingBottom="5" paddingRight="5" paddingLeft="5">

        <ns:Image source="{message.sender.mugshot_url}" width="48" height="48"/>

        <s:VGroup width="100%" height="100%">

            <s:Label  text="{message.sender.full_name}" maxDisplayedLines="1" left="10" top="10" right="26"  fontWeight="bold" color="#000000"/>

            <s:RichEditableText id="richEdTxt" text="{message.body_plain}" width="100%" editable="false" selectable="false" focusEnabled="false" />

            <s:HGroup width="100%" paddingTop="2">
                <s:Label text="{message.created_at}"/>
            </s:HGroup>

        </s:VGroup>

    </s:HGroup>

</s:ItemRenderer>

I am sure there are lots of ways to improve the library, but this one is a pretty simple start with lots of functionality. Please let me know if you find any errors and feel free to fork this version and add any improvements to the code.

-Mr

3 Comments

Comments are closed.