API

App Directory SDK

API (v2.0, current)

How It Works

JSApi is the App Directory SDK's communication gateway between your app and the Hootsuite dashboard. The API allows app developers to call functions that send events to the Hootsuite dashboard and to receive Hootsuite dashboard event notifications within an app.

Interactions between Hootsuite and your app are enabled by JS Api. The SDK Javascript library, hsp.js, provides functions that drive specific functionality in the Hootsuite dashboard. hsp.js also enables initialization and registration of your app to receive events from the Hootsuite dashboard.

Note: Please ensure your server allows POST requests.

Setup

The following is needed to use the JS API:

  • JS Library - The hsp.js library enables two-way communication between your app and the Hootsuite dashboard. Include this file in your App's primary page:

https://d2l6uygi1pgnys.cloudfront.net/jsapi/2-0/hsp.js

For example, the reference to this file in your primary page would appear as follows:

<script src="https://d2l6uygi1pgnys.cloudfront.net/jsapi/2-0/hsp.js"></script>

API Functions, Events, and Callback

Communication from your app to the Hootsuite dashboard occurs using the functions available in hsp.js.
 
Communication from the Hootsuite dashboard to your app is enabled through events. The events that your app is interested being notified about are registered with calls to the hsp.bind() function indicating the event of interest and the callback function that your app will execute when the event it triggered.

Functions

Events

  • closepopup - Fires when a custom popup opened by your app stream is closed
  • refresh - Fires when the app column is refreshed, either by the user within the stream, or as part of a dashboard refresh
  • sendtoapp - Registering for this event will cause users to see a menu item reading Send to <app stream>… in Twitter and Facebook stream message menus. This event is fired when users click on the menu item
  • sendcomposedmsgtoapp - Adds app plugin to the native Hootsuite social network profile selector. User can send messages to the plugin directly from Hootsuite compose message box
  • sendassignmentupdates - Registering this event will let an app get notified of its assignment updates

Callback

API Functions

This section describes the set of available functions and expected function signatures.

hsp.init(params)

Initializes the JS API and loads the theme CSS files.

params: object:

  • subtitle: (string, optional)
  •  The subtitle of your app, to be displayed in the stream's title.
  • callBack: (function, optional)
     Init will send an error message to the callBack function after initialization. The message is: No Error, if initialization is successful.
  • sendToAppDisableList: Specify the social networks your sendtoapp plugin should not display under (‘facebook’, ‘twitter’, 'instagram', 'youtube')

Example:

hsp.init({
  callBack: function( message ){ console.log('Error: ' + message); 
useTheme: true,
sendToAppDisableList: ['facebook']
});

hsp.bind(eventName, callback)

Registers an event handler for a specified event.

eventName: (string)

Name of the event to handle, can be one of the following:

  • closepopup - Fires when a custom popup opened by your app stream is closed
  • refresh - Fires when the app column is refreshed, either by the user within the stream, or as part of a dashboard refresh
  • sendtoapp - Registering for this event will cause users to see a menu item reading Send to <app stream>...in Twitter and Facebook stream message menus. This event is fired when users click on the menu item

callback: (function)

Function to handle the callback, the function's parameters are determined by the event. See the events section for details on expected callback formats.

Example:

hsp.bind('refresh', function () {
  // code here
});

As stated in the Best Practices section, it makes sense to suppress reloading of the stream while the user interacts with it (e.g. posting messages, expanded details, possibly scroll position not near the top). A possible approach could look something like this:

hsp.bind('refresh', function () {
  // collect any text the user has entered into a comment entry box
  $(".hs_commentEntry textarea").each(function () {
    comments += $(this).val();
  });

  // comment entry boxes are empty and user has not scrolled down more than 15px
  if (comments === '' && $(window).scrollTop() < 15) {
    // code here
  }
});

The use of window.location.reload() is NOT recommended. One of the most elegant solutions would be to poll for any new messages via AJAX and to inject only new messages into the DOM while leaving existing messages untouched.

hsp.getMemberInfo(function(info)

This method is meant to be used in conjunction with the other assignments methods and callbacks (assignItem, resolveItem, Assignment Event Request). Since an assignment can be assigned to a Team or a team member, your app needs to know what Teams your user is a member of.  This can be retrieved using getMemberInfo.

We recommend calling this method after hsp.init.

hsp.getMemberInfo(function(info){
// put code here
});

info object format:
{
"userId":5339913,
"teamIds":[151906,154887]
}

Retain User Details

The hsp.saveData and hsp.getData are designed to be used in conjunction in order to retain user settings from one session to another (ie. user tokens, unique stream settings and filters set by the user in the app). The methods are invoked on a per stream basis against the PID. 

The data can be saved in any string format.

hsp.saveData(function)

hsp.saveData(data, callback); //Saves data in the member app stream, and has the option to get just saved data object in the callback for the app stream to check
hsp.getData(callback); //Retrieves data saved in the member app stream

hsp.saveData(
{
name: 'My Photo Stream',
type:'steam',
uid: 123456,
token: '1a2b3c4d5e6f7g8h9i0j'
},
function(data){
console.log('saved', data);
});

hsp.getData(function(data)

{
console.log('App gets data', data);
});

hsp.clearStatusMessage()

Removes all currently visible status messages.

hsp.composeMessage(message, params)

Opens the Share to Social Networks dialog in the Hootsuite dashboard.

If your post contains an image, consider also incorporating the hsp.attachFiletoMessage method

message: (string)

Twitter message rules apply, eg. to compose a DM to @Hootsuite would be: d hootsuite <your message here>

params: (object, optional):

  • shortenLinks: bool, optional
     Shorten all links found in message with user's default URL shortener (ow.ly / ht.ly / or vanity url). Defaults to false.
  • timestamp: bool OR int, optional
     Open the Scheduler and populate it with the timestamp (in UTC, in seconds) OR if true is passed in, then the Scheduler will open with no default time. Defaults to false. The time is specified in seconds, ie: {scheduleTimestamp: 1460520580}
  • twitterReplyToId: string, optional
     Compose a new tweet in reply to an existing tweet. If a valid string ID is passed in for an existing tweet, then the Composer will treat the new message as part of the conversation. Note: The message will need to contain a valid twitter handle with '@' symbol. Ex: @hootsuite This is a reply!

Example:

hsp.composeMessage( 'message text', { shortenLinks: true } );

hsp.retweet(id, screenName)

Opens the retweet dialog process in the Hootsuite dashboard for tweet with id to be retweeted by screenName.

id: (string)

Twitter's id_str tweetId for the tweet to retweet

screen_name: (string, optional)

The Twitter screen_name you want to retweet with

Example:

hsp.retweet( '369937169529708544', 'Hootsuite' );

hsp.attachFiletoMessage

Send attachments to the Share to Social Networks dialog in the Hootsuite dashboard. Files have a size limit of 5MB.

data: (JSON object)

  • url:  string, required 
  • name:  string, required
  • extension: string, required
  • timestamp: int or string, must be current time in seconds, required
  • token: string, required
    • user_id: string, must be the current user, can be retrieved from url parameter, required
    • timestamp: string, should be the same as the previous timestamp, required
    • url: string, should be the same as the previous url, required
    • secret: string, can be found in the app section of your Dev Portal

Supported File Types:

  • Image files: jpg, jpeg, gif, png
  • Document files: doc, docx, pdf, xls, xlsx, ppt, pptx, odt, ods, odp, txt, rtf, csv, psd, psb, ai, eps, fla, mp3

Example: 

hsp.attachFileToMessage ({
url: 'http://abc.com/abc.jpg',
name: 'abc',
extension: 'jpg',
timestamp: 1434583080,
token: SHA512(user_id + timestamp + url + secret)
});

hsp.customUserInfo(data)

Opens a user info popup window.

data: (JSON object)

Example:

var data = {
  "fullName": "David Chan",
  "screenName": "@chandavid",
  "avatar": "https://d1cmhiswqj5a7e.cloudfront.net/http%3A%2F%2Fplacehold.it%2F30x30%2F444",
  "profileUrl": "https://twitter.com/chandavid",
  "userLocation": "Vancouver, BC",
  "bio": "JavaScript/web/martini developer. Working on @Hootsuite. Making by breaking.",
  "extra": [
    {"label": "Age", "value": "Unknown"},
    {"label": "Gender", "value": "Male"}
  ],
  "links": [
    {"label": "Hootsuite", "url": "https://hootsuite.com"},
    {"label": "Blog", "url": "https://blog.hootsuite.com"}
  ]
};

hsp.showCustomPopup(src, title, width, height)

Shows a modal popup window containing an iFrame showing content from the specified URL. On close the dialog fires the closePopUp() event.

src: (string)

URL of the content to show in the popup

title: (string)

The title displayed on the popup window

width: (int)

The width in pixels of the popup. The width has the following constraints:

  • If not specified, the width defaults to 640 pixels
  • The minimum width is 300 pixels.
  • The maximum width is 900 pixels.

height: (int)

The height in pixels of the popup. The height has the following constraints:

  • If not specified, the height defaults to 445 pixels
  • The minimum height is 225 pixels.
  • The maximum height is 500 pixels.

Example:

hsp.showStatusMessage('Done!', 'success') ;

Important:

Please do not initialize hsp again inside the custom popup. Your popup should not use any hsp functions other than closeCustomPopup(apiKey, pid).

If your popup and app stream/plugin are in the same domain, it is recommended that your popup uses the following javascript function to communicate back to your stream/plugin and run the hsp function: window.parent.frames[apiKey_pid].hsp.some_function()

Note: hsp event binding functions are not available in the custom popup.

hsp.closeCustomPopup(apiKey, pid)

Closes the modal popup window.

Note: Please make sure the iFrame page in the custom popup window and the app stream page are sharing the same domain. You don't need to (and shouldn't) call hsp.init() again in the iFrame page, just include hsp.js and call hsp.closeCustomPopup(apiKey, pid). You can use JavaScript to communicate between the popup and the stream like this:

window.parent.frames["<%= apiKey %>_<%= pid %>"].location.reload();

apiKey: (string)

Your app's API Key

pid: (string)

The pid is associated with each unique installation of an app stream (or plugin). You can get the pid of each app stream from the url request your server gets. For example:

https://demo.ca/stream.html?lang=en&theme=blue_steel&timezone=-25200&pid=60956&uid=136

hsp.showImagePreview(src, externalUrl)

Shows an image in a popup window, optionally linking to an external URL.

src: (string)

Image URL

externalURL: (string)

URL to open if user clicks on the image

hsp.showStatusMessage(message, type)

Shows a notification in the top center of the Hootsuite dashboard.

message: (string)

Should be brief, max. 70 characters.

type: (string):

Can be one of the following:

  • info: Blue background
  • error: Red background
  • warning: Yellow background
  • success: Green background

hsp.updatePlacementSubtitle(name)

Updates the subtitle of the App's stream.

Note: This requires the App Receiver to be set up (see above).

name (str)

Max 35 characters

hsp.showUser(twitterHandle)

Opens a user info popup for the specified Twitter username.

twitterHandle: (string)

Twitter username

Example:

hsp.showUser('hootsuite_help');

showUser.f203dc7a

hsp.showFollowDialog(twitterHandle, isFollow)

Opens a dialog window for following or un-following a Twitter user.

twitterHandle: (string)

Twitter username

isFollow: ("bool string")

"true" to follow, "false" to unfollow.

Example:

hsp.showFollowDialog('hootsuite_help', 'true');

showFollowDialog.ff5cb783

hsp.getTwitterAccounts(callback)

Gets a list (array) of all Twitter profiles (user names) the logged-in user has added to their Hootsuite account.

callback: (function)

Function that accepts an array strings

Example:

// this would log: ["twitteruser_123", "twitter_user_abcd"]
hsp.getTwitterAccounts(console.log);

hsp.assignItem(item)

Assign an item from the app stream. Parameter item is a javascript object that shall contain all necessary information of the item to be assigned. The API Callback URL found in the app's settings within the Dev Portal needs to be present for the function to work.

data: (JSON object)

  • messageID: string, should be the ID of the item, required
  • messageAuthor: string, required
  • messageAuthorAvatar: string, required
  • message: string, required
  • timestamp: int or string, must be current time in seconds, optional

Example:

var data = {
  "messageId": "123456", //required, ID of the item to be assigned
  "messageAuthor": "Joe", //required
  "messageAuthorAvatar": "https://www.somesite.com/useravatar/123.png", //required. Do not include query strings
  "message": "Hi, I'm having an issue with my account",  //required
  "timestamp": "1431023368"  //Unix Timestamp format. Optional, but recommended
}

When an assignment is triggered or updated, the app should display the appropriate CSS (refer to the template for styles).

hsp.resolveItem(item)

Resolve an item from the app stream.

Anatomy:

{
   assignmentId: "654321" //required, ID of the assignment in Hootsuite dashboard from both callbacks
}

API Events

This section describes the set of available events and expected event handler function signatures available by using hsp.bind().

refresh()

Fires when the app column is refreshed, either by the user within the stream, or as part of a dashboard refresh.

callback format: a function with no parameters

Example:

function refreshHandler () { }

Note: The use of window.location.reload() is NOT recommended. One of the most elegant solutions would be to poll for any new messages via AJAX and to inject only new messages into the DOM while leaving existing messages untouched.

sendcomposedmsgtoapp()

Adds app plugin to the native Hootsuite social network selector. User can send messages to the plugin directly from Hootsuite compose message box

NOTE: You need to contact our app directory administration team to enable this event binding for your app plugin

callback format: a javascript object containing the message data

Message object data structure:

Message: (object)
  text: (string)

Example:

function sendComposedMsgToAppHandler (message) {
  // ...
}

closepopup()

Fires when a custom popup opened by your app stream is closed

callback format: a function with no parameters

Example:

function closePopupHandler () {
  // ...
}

sendtoapp()

Registering for this event will cause users to see a menu item reading Send to <app stream>… in Twitter and Facebook stream message menus. This event is fired when users click on the menu item. 

If you want to limit which social networks the plugin displays under, refer to the details for hsp.init

callback format: a javascript object containing the message data

Message object data structure:

TWITTER

Message: (object)
  post: (object)
    network: (string)
    href: (string) url to the original post
    id: (string) external post id
    datetime: (string) iso 8601 datetime format
    source: (string) e.g. Hootsuite
    content: (object)
      body: (string)
      bodyhtml: (string)
    user: (object)
      userid: (string)
      username: (string)
    conversations: (array)
      id: (int/string)
      uid: (int)
      name: (string)
      datetime: (string)
      text: (string)
      source: (string) twitter only
      retweetcount: (string) twitter only 
      geo: (string) twitter only
    attachments: (array)
      items: (array)
        target: (string) url to the resource page
        originurl: (string) url to the actual resource
        thumbnailsrc: (string) url to the thumbnail
      title: (string)
      type: (string) link | video | photoalbum | photo
    "favoritecount":10}
Profile: (object)
  networks: (string)
  created_at (string)
  description (string)
  followers_count (int)
  friends_count (int)
  id (string)
  id_str (string)
  lang (string)
  listed_count (int)
  location (string)
  name (string)
  network (string)
  profile_image_url (string)
  profile_image_url_https (string)
  screen_name (string)
  statuses_count (int)
  time_zone (string)
  url (string)
  utc_offset (int)
  verified (boolean)
  "counts": {
            "likes": 19,
            "shares": 1,
            "replies": 1

FACEBOOK

Message: (object)
  post: (object)
    network: (string)
    href: (string) url to the original post
    id: (string) external post id
    datetime: (string) iso 8601 datetime format
    source: (string)  e.g. Hootsuite
    content: (object)
      body: (string)
      bodyhtml: (string)
    user: (object)
      userid: (string)
      username: (string)
    conversations: (array)
      id: (int/string)
      uid: (int)
      name: (string)
      datetime: (string)
      text: (string)
      source: (string) twitter only
      retweetcount: (string) twitter only 
      geo: (string) twitter only
    attachments: (array)
      items: (array)
        target: (string) url to the resource page
        originurl: (string) url to the actual resource
        thumbnailsrc: (string) url to the thumbnail
      title: (string)
      type: (string) link | video | photoalbum | photo
Profile: (object)
  networks: (string)
  created_at (string)
  description (string)
  followers_count (int)
  friends_count (int)
  id (string)
  id_str (string)
  lang (string)
  listed_count (int)
  location (string)
    id: 
    name:
   concatedName: 
  name (string)
  picture (string)
  website (string)

 

Example message object:


{
    "post": {
        "network": "twitter",
        "href": "https://twitter.com/hootsuite/status/1000000",
        "id": "10000000000000000",
        "datetime": "2015-05-07T17:15:54.000Z",
        "source": "Hootsuite",
        "counts": {
            "likes": 16,
            "shares": 9,
            "replies": null
        },
        "content": {
            "body": "5 minutes is all you need to start a conversation: http://t.co/LO0uGuip7q Learn from our #LightningTalks http://t.co/8tplqYoZM1",
            "bodyhtml": "5 minutes is all you need to start a conversation: http://t.co/LO0uGuip7q Learn from our #LightningTalks http://t.co/8tplqYoZM1"
        },
        "user": {
            "userid": 100000000,
            "username": "hootsuite"
        },
        "attachments": [
            {
                "type": "image",
                "url": "https://pbs.twimg.com/media/CEa01uPWMAE_OwD.jpg",
                "title": "",
                "items": {
                    "target": "https://pbs.twimg.com/media/CEa01uPWMAE_OwD.jpg"
                }
            }
        ],
        "conversation": []
    },
    "profile": {
        "network": "TWITTER",
        "created_at": "Fri Oct 31 22:26:54 +0000 2008",
        "description": "Social media news and tips from the world’s most widely used social relationship platform. Sign up for free: http://t.co/Zmrb0hY23s Support: @Hootsuite_Help",
        "followers_count": 6754899,
        "friends_count": 1594873,
        "id": "100000000",
        "id_str": "100000000",
        "lang": "en",
        "listed_count": 42070,
        "location": "Vancouver, Canada",
        "name": "Hootsuite",
        "profile_image_url": "http://pbs.twimg.com/profile_images/595315902276468736/6KYlfmqu_normal.jpg",
        "profile_image_url_https": "https://pbs.twimg.com/profile_images/595315902276468736/6KYlfmqu_normal.jpg",
        "screen_name": "hootsuite",
        "statuses_count": 20947,
        "time_zone": "Pacific Time (US & Canada)",
        "url": "http://t.co/3Xvuxw2JEG",
        "utc_offset": -25200,
        "verified": true
    }
}

Example:

function sendToAppHandler ( message ) {
  // ...
}

Supported social network streams: These are all of the separate social network streams that support message components to be triggered.

Supported

Twitter: Home, Mentions, Retweets, Followers, Lists, Favourites, My Tweets, Search, Inbox, Outbox, Keyword (Save as Stream)
Facebook: Timeline, Page, Search

sendassignmentupdates()

Item is resolved from Hootsuite dashboard, which sends assignment callbacks to the app.

callback format: a javascript object containing the update information data

Anatomy:

{
  status: "OPEN" || "RESOLVED"
  assignmentId: <assignment ID in Hootsuite dashboard>
  messageId: <message ID of the assigned item>
  toName: <name of the user or team the item is assigned to>
  createdDate: "yyyy-mm-dd hh:mm:ss" //in UTC
  modifiedDate: "yyyy-mm-dd hh:mm:ss" //in UTC
}

API Callback

The SDK provides a backend endpoint for your app.  In order for the app and the Hootsuite dashboard to communicate, you must provide an APICallbackURL in your app within the developer’s portal. Hootsuite will fire a POST request to the provided APICallbackURL to send an event. IMPORTANT NOTE: every request requires the app directory SSO for authentication. 

The assignment API function allows a user to assign an item from your app stream to another Hootsuite user, and reassign or resolve it from both the app stream and the Hootsuite dashboard (even without the app being installed by other users). SSO authentication is required to use the APICallbackURL. 

Assignment Event Request

Every time an assignment is created or updated, a POST request will be sent to the APICallbackURL.

{
  action: "Assignment"
  sso_i: <user_id>
  sso_ts: <timestamp>
  sso_token: <token>
  assignmentId: <assignment ID in Hootsuite dashboard>
  status: "OPEN" || "RESOLVED"
  messageId: <message id of the assigned item that the app provided>
  message: <message context>
toType: <'MEMBER'|'TEAM'>
toTeamId:
toTeamName:
  creatorId: 
  creatorName:
  fromId: 
  fromName:
  toId:
  toName:
  createdDate: "yyyy-mm-dd-hh-mm-ss"
  modifiedDate: "yyyy-mm-dd-hh-mm-ss"
}