Archive for the ‘Code’ Category

Jeff Park

Bring your code into the conversation with the HipChat Bitbucket integration

By Jeff Park | 4 months ago | 7 Comments

If you’re a Bitbucket user, we’ve got some great news for you. We’ve worked with the Bitbucket team to create a new integration to provide more useful information about your repositories within your HipChat rooms. 

The new integration includes notifications for the following actions:

  • Commits – when a new commit is pushed, or commented on
  • Pull requests – when a pull request is created, commented on, merged, or declined
  • Issues – when an issue is created, updated, or commented on

By piping notifications into your chat room, you can hold a conversation about latest commits, pull requests, and issues with your developers right away. HipChat lets you host lightweight code reviews right within your chat room and ship code faster.

Bitbucket notifications in HipChat

This integration is pre-installed on all HipChat groups. You can find instructions on how to configure the new integration in our documentation.

If you’re new to Bitbucket, be sure to check it out – unlimited private Git or Mercurial repositories. Host your code in the cloud, for free.

Don Brown

Embedding HipChat

By Don Brown | 1 year ago | 6 Comments

Ever wanted to embed a little chat panel into your page? Well, now you can with the jQuery HipChat Plugin:

  1. Write this:
    $(function() {
        url: "YOUR_GUEST_ACCESS_URL",
        timezone: "PST"
  2. To embed this:

Digging Deeper

There are actually several things going on here.

First, we added a “minimal mode”, which renders the web client without chrome whether you are a guest or normal user. Second, we added an “anonymous mode” that allows a guest to instantly connect to a room with minimal hassle. For more information on these and other new parameters, see the embedding HipChat knowledge base article.

Under the covers, the jQuery plugin is basically creating an iframe with both minimal and anonymous mode enabled. By default, the plugin will stick a “Chat” button on an area of the page. When clicked, the button will open up a new anonymous chat session. However, if you don’t use jQuery or want full control, you can use the new query parameters in the guest access URL.

This effort is but one of several new features we’ll be announcing soon to make integrating and even building on HipChat easy and accessible. If you are a developer and have ideas on how the HipChat integration experience could be improved, please don’t hesitate to let us know in the comments or, better yet, the suggestions forum!

Chris Rivers

Performance Tuning iOS – Making Mobile Fast

By Chris Rivers | 2 years ago | 0 Comments

Disclaimer: The following post is intended for a somewhat technical audience. If you come across any unfamiliar words or phrases, please refer to your local software developer.

The problem

Our iOS app has suffered from pretty abysmal performance issues for any groups with more than a couple dozen users and rooms. Since joining Atlassian, we’ve experienced the issue first hand even more acutely (the Atlassian HipChat group has hundreds of users and rooms). We had to do something about it.

The analysis

Before any good performance update comes the part where you close your eyes and get the raw numbers about how slow your current app is. Some of our findings:

  1. Avoid blocking HTTP requests. Before we could even try to connect to our chat servers, we had to hit an HTTP API to get user and server information. This request alone would take ~1.5 seconds to complete on WiFi and a whopping 3s on average for a 3G connection.
  2. Minimize round trips to the server. XMPP has a well-defined spec for securing the chat connection. Unfortunately, it involves no less than 3 back-and-forths between the client and server. Add authentication and session setup onto that and you end up with a good 6 back and forths.
  3. Avoid updating the UI when getting lots of data. Apart from basic network latency, the other thing that makes the app slow is doing the actual work of reading XMPP and setting up all the stuff you actually see. This turned out to be costing a ton of resources since each time we received a user’s presence (the data that tells us whether they’re available/away/dnd, etc), we would update the Lobby (assuming you were viewing the Lobby, which was quite likely since that’s where the app opens to). Calculated out, it turned out that we were spending 12-15 seconds just handling everyone’s presence for a big group like Atlassian. Definitely unacceptable.
  4. Stringprep –  Y U SO SLOW. Most XMPP libraries use a process called “stringprep” when creating JID objects (JIDs are the unique user identifying strings used in XMPP). Stringprep ensures that your JIDs are valid and conform to the spec. Unfortunately, we found that stringprep was responsible for nearly 50% of our CPU usage on the phone (we create lots of JIDs). Fortunately, we run a closed system where we can validate JIDs beforehand. This became the easiest fix of all: remove stringprep :)
  5. iOS offers a sophisticated local storage for a reason. Before this update, we made minimal use of local storage on the phone. The problem was that we were just clearing it out completely when you reconnected. Not exactly the best use of the Core Data framework

The changes

  1. Previously on connection, something like this happened (times are for a 3G connection in San Francisco):
    1. PHONE: HTTP Request to get info about which chat server to connect to (~1-3 seconds)
    2. WEB SERVER: “Here’s the information you requested – use it to connect to SERVER”
    3. PHONE: “Hey SERVER, I’m gonna start a session” *(0.3 seconds)
    4. SERVER: “Ok – but first we gotta make sure nobody can snoop on our conversation. Let’s use something called TLS”
    5. PHONE: “Oh, ok, I know TLS! I officially request we secure using TLS” (0.3 seconds)
    6. SERVER: “You may proceed” … <at this point, the TLS handshake happens and all data sent and received is encrypted> (0.4 – 0.6 seconds)
    7. PHONE: “Phew – ok, let’s start that connection again” (0.3 seconds)
    8. SERVER: “Connection started, but first, you need to authenticate”
    9. PHONE: “Got it – here’s the username/password info my user provided” (0.3 seconds)
    10. SERVER: “Glorious success! Your credentials were correct.”
    11. PHONE: “Great, let’s really start a chat session now” (0.3 seconds)
    12. SERVER: “Sure thing – but wait, I need an identifier for this session so I can tell it apart from that connection you made from your desktop”
    13. PHONE: “Oh, ok – how about we call it the ‘iphone’ session?” (0.3 seconds)
    14. SERVER: “That is acceptable – here is your full identifying string…”
    15. PHONE: “Cool, now I officially am starting a session…” <after this we actually start getting chat data> Total time: 3.2s – 5.4s – just to start getting actual chat data from the server
  2. On a 3G connection, when each request to the server can take up to several hundred milliseconds, this is pretty terrible. So we set out to reduce the number of required requests as much as possible. This is what we came up with:
    1. <we already know the server to hit, no need to ask WEB SERVER anymore> <the SSL handshake happens as soon as we open the connection to SERVER> (0.4 seconds) PHONE:  “Hey SERVER, let’s start a session” (0.3 seconds)
    2. SERVER: “Sure thing – connection has been opened. Please choose an auth method: <includes a special HipChat-only auth>”
    3. PHONE: “Here’s the authentication data, including the identifier for my session” (0.3 seconds)
    4. SERVER: “Excellent – authentication validated. Here is your full identifying string. You may now request data” Total time: 1 second
  3. Finally, the other major app slowdown happened when we received the flood of initial presences right after logging in. These triggered a cascading update of displayed data in the Lobby. And as anyone who has done UI performance tuning before, having lots of display drawing to do can cripple a user experience. Our solution: have the server let us know when the flood of presences is done, then update the UI. The result: 80% fewer cycles spent during the connection process.

For the future…

Unfortunately, when we began writing the iOS app, it was on the cusp of the release of iOS 4 (which plagued some devices with performance problems), so we were hesitant to use any of the brand-new features. We still have work to do to move our app over to ARC. We still don’t make nearly enough use of Grand Central Dispatch (mostly because we don’t use the most current version of XMPPFramework). We also have some server improvements to make that will let us further speed up the app for really big teams. XMPP offers a spec for roster versioning which could replace the full roster refreshes we do now. This is just a first step to making the app more usable for larger teams (and part of how we’re making sure that our Native OSX App is going to be lightning fast). The update is available on the App Store today. Download it and let us know what you think!

Garret Heaton

Capistrano notifications in HipChat

By Garret Heaton | 4 years ago | 9 Comments

Our friends at Mojo Tech recently released a simple Ruby wrapper for the HipChat API which has special support for Capistrano, a popular deployment framework. After adding a few lines to your Capistrano scripts you’ll receive room messages during deployments, rollbacks, and migrations.

To install the gem, run:

$ gem install hipchat

Then add the following to your Capistrano script:

require 'hipchat/capistrano'

set :hipchat_token, "your token"
set :hipchat_room_name, "your room"
set :hipchat_announce, false # notify users?

Pretty easy! Check out the project page for more details.

By the way, we have integrations with other services such as GitHub, Heroku, and MailChimp as well as API libraries in other languages. Let us know if you’ve done something cool with our API that you’d like to share.

Garret Heaton

XCode tips for TextMate users

By Garret Heaton | 4 years ago | 0 Comments

Switching from TextMate to XCode to work on the upcoming HipChat iPhone app has been a little painful. TextMate has some incredibly helpful features that I feel very unproductive without. Luckily some of them can be enabled or emulated. Here’s what we’ve found:

Go to File (Command-T)

TextMate's Go to File popup - so awesome!

The Go to File popup is probably TextMate’s most beloved feature. After using it for a while it seems amazing that its not part of every IDE out there. XCode’s “Open quickly” (Command-Shift-D) doesn’t cut it because it doesn’t do partial matching on the filename.

There are two options (both paid tools) for adding this functionality to XCode:

  1. PeepOpen — $12, beta software, great potential but not actively maintained
  2. Code Pilot — $30, more mature and full of other nice features

If you want to bind either tool to Command-T you’ll need to unbind XCode’s default key binding for the “Show Fonts” dialog first. To do that, open your XCode preferences and clear out option shown here.

Key Bindings

The “Delete line” (Control-K) and “Duplicate line” (Control-Shift-D) shortcuts can be added system wide by placing the following in ~/Library/KeyBindings/PBKeyBinding.dict:

    "^$K" = (
    "^$D" = (

Full details and other options are available in this Stack Overflow post.


TextMate's Twilight theme in XCode

Using the same theme in all your IDEs can make it a lot easier to jump between them seamlessly. Here’s a tool you can use to convert your existing TextMate theme to work in XCode: XThemes.

There’s also a downloadable version of the Twilight theme for XCode here.


Unfortunately there’s no way to get a tab-based display in XCode, so you’ll have to get good at switching between files using your Command-T replacement or via one of the suggestions here.

We hope these tips can make you a little more productive in XCode. If you’re looking for more make sure you check out this Stack Overflow thread. Oh and keep an eye out for the HipChat iPhone app.