Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
The home of Sprint.ly's outbound services integration.
Python Makefile
Branch: master

Merge pull request #21 from sprintly/nicholasserra-name-issues

Don't throw error when user doesn't have last_name set
latest commit 6f5230bfd4
@chrisforrette chrisforrette authored

README.mkd

Build Status

Overview

This is the home of Sprint.ly's outbound service integration. If you've ever wished Sprint.ly would send notifications to another service, you're in the right place. All of our service integrations are open source so anyone can write a hook for their favorite service.

How it Works

  1. A user creates, modifies, or deletes an Item, Comment, Favorite, or Block on Sprint.ly.
  2. Sprint.ly loads up any enabled outbound services enabled for the given product.
  3. Sprint.ly loads each Service class passing in any configuration options set by the user.
  4. Sprint.ly runs the Service.send() method passing in a payload Python dict.
  5. Service.send() handles posting the outbound ping to the 3rd party service.

How to Contribute

  1. Fork this repository.
  2. Create a file in sprint.ly-services/lookout/services/ named YourService.py.
  3. Create a class named Service.
  4. In your class's __doc__ put YourService on the top line, a blank line, and then as much Markdown as you like for installation instructions.
  5. Add tests for your service to tests/test_services.py
  6. Send us a pull request with which options you need us to collect and what you wish them to be named.
  7. We'll review, merge, and deploy.

Running Tests

To run tests you'll need to install the required modules in requirements.txt, then run make test from the project root directory.

Payload

When your Service.send() method is ran, Sprint.ly will pass a single argument, payload, to your method. This Python dict will have four keys in it: action, product, attributes, and model.

  • action (enum) The action that was performed on the given model. Will be one of: created, updated, or deleted.
  • product (dict) The product that the model belongs to.
  • attributes (dict) A hash of the model's attributes.
  • model (enum) The name of the model. Will be one of: Item, Comment, Favorite, or Block.

Models

Currently, Sprint.ly sends out four models: Item, Comment, Favorite, and Block. Whenever an action is taken on Sprint.ly that creates, modifies, or deletes one of these models, an event will be sent to your service.

Item

{
    "action": "created",
    "attributes": {
        "archived": false, 
        "assigned_to": {
            "created_at": "2011-06-07T21:10:52+00:00", 
            "email": "joe@example.com", 
            "first_name": "Joe", 
            "id": 1111, 
            "last_login": "2012-07-26T23:16:55+00:00", 
            "last_name": "Stump"
        }, 
        "created_at": "2012-08-13T23:14:26+00:00", 
        "created_by": {
            "created_at": "2011-06-07T21:10:52+00:00", 
            "email": "joe@example.com", 
            "first_name": "Joe", 
            "id": 1111, 
            "last_login": "2012-07-26T23:16:55+00:00", 
            "last_name": "Stump"
        }, 
        "description": "", 
        "email": {
            "discussion": "discussion-1111@example.com", 
            "files": "files-1111@example.com"
        }, 
        "last_modified": "2012-08-13T23:14:27+00:00", 
        "number": 1212, 
        "product": {
            "archived": false, 
            "id": 1111, 
            "name": "sprint.ly"
        }, 
        "score": "~", 
        "short_url": "http://sprint.ly/i/1/116550/", 
        "status": "backlog", 
        "title": "As a user, I want outbound service hooks so that I will see new items announced in Campfire or HipChat.", 
        "type": "story", 
        "what": "outbound service hooks", 
        "who": "user", 
        "why": "I will see new items announced in Campfire or HipChat"
    }, 
    "model": "Item", 
    "product": {
        "admin": false, 
        "archived": false, 
        "created_at": "2011-06-07T21:44:36+00:00", 
        "email": {
            "backlog": "backlog-1111@example.com", 
            "defects": "defects-1111@example.com", 
            "stories": "stories-1111@example.com", 
            "tasks": "tasks-1111@example.com", 
            "tests": "tests-1111@example.com"
        }, 
        "id": 1111, 
        "name": "sprint.ly"
    }
}

Comment

{
    "action": "created",
    "attributes": {
        "body": "Hey guys, what's the status on this?", 
        "created_at": "2012-08-13T23:21:52+00:00", 
        "created_by": {
            "created_at": "2011-06-07T21:10:52+00:00", 
            "email": "joe@example.com", 
            "first_name": "Joe", 
            "id": 1111, 
            "last_login": "2012-07-26T23:16:55+00:00", 
            "last_name": "Stump"
        }, 
        "id": 1111, 
        "item": {
            "archived": false, 
            "assigned_to": {
                "created_at": "2012-01-06T23:07:20+00:00", 
                "email": "craig@example.com", 
                "first_name": "Craig", 
                "id": 1111, 
                "last_login": "2012-06-25T11:09:26+00:00", 
                "last_name": "Pattison"
            }, 
            "created_at": "2012-06-23T21:24:40+00:00", 
            "created_by": {
                "created_at": "2011-06-07T21:10:52+00:00", 
                "email": "joe@example.com", 
                "first_name": "Joe", 
                "id": 1111, 
                "last_login": "2012-07-26T23:16:55+00:00", 
                "last_name": "Stump"
            }, 
            "description": "Right now when the application is booting up we have a white spinner. Let's change the spinner to our running man that glows from black to blue and back again.", 
            "email": {
                "discussion": "discussion-1111@example.com", 
                "files": "files-1111@example.com"
            }, 
            "last_modified": "2012-08-12T22:58:34+00:00", 
            "number": 1212, 
            "product": {
                "archived": false, 
                "id": 1111, 
                "name": "sprint.ly"
            }, 
            "progress": {
                "started_at": "2012-06-25T08:55:36+00:00"
            }, 
            "score": "M", 
            "short_url": "http://sprint.ly/i/1/91594/", 
            "status": "in-progress", 
            "tags": [
                "ios", 
                "ipad"
            ], 
            "title": "Change the spinner to our glowing running man.", 
            "type": "task"
        }, 
        "last_modified": "2012-08-13T23:21:52+00:00", 
        "type": "comment"
    }, 
    "model": "Comment", 
    "product": {
        "admin": false, 
        "archived": false, 
        "created_at": "2011-06-07T21:44:36+00:00", 
        "email": {
            "backlog": "backlog-1111@example.com", 
            "defects": "defects-1111@example.com", 
            "stories": "stories-1111@example.com", 
            "tasks": "tasks-1111@example.com", 
            "tests": "tests-1111@example.com"
        }, 
        "id": 1111, 
        "name": "sprint.ly"
    }
}

Favorite

{
    "action": "created",
    "attributes": {
        "created_at": "2012-08-12T23:01:33+00:00", 
        "id": 1111, 
        "item": {
            "archived": false, 
            "assigned_to": {
                "created_at": "2011-06-08T17:16:58+00:00", 
                "email": "graham@example.com", 
                "first_name": "Graham", 
                "id": 1111, 
                "last_login": "2012-07-18T00:06:37+00:00", 
                "last_name": "Blache"
            }, 
            "created_at": "2012-05-09T01:16:25+00:00", 
            "created_by": {
                "created_at": "2011-06-07T21:10:52+00:00", 
                "email": "joe@example.com", 
                "first_name": "Joe", 
                "id": 1111, 
                "last_login": "2012-07-26T23:16:55+00:00", 
                "last_name": "Stump"
            }, 
            "description": "", 
            "email": {
                "discussion": "discussion-1111@example.com", 
                "files": "files-1111@example.com"
            }, 
            "last_modified": "2012-08-12T23:01:33+00:00", 
            "number": 1111, 
            "product": {
                "archived": false, 
                "id": 1111, 
                "name": "sprint.ly"
            }, 
            "progress": {
                "started_at": "2012-07-12T16:40:11+00:00"
            }, 
            "score": "XL", 
            "short_url": "http://sprint.ly/i/1111/1111/", 
            "status": "in-progress", 
            "tags": [
                "post-launch"
            ], 
            "title": "As a user, I want a global filter UI so that I can use filters on the dashboard and timelines.", 
            "type": "story", 
            "what": "a global filter UI", 
            "who": "user", 
            "why": "I can use filters on the dashboard and timelines"
        }, 
        "user": {
            "created_at": "2011-06-07T21:10:52+00:00", 
            "email": "joe@example.com", 
            "first_name": "Joe", 
            "id": 1111,
            "last_login": "2012-07-26T23:16:55+00:00", 
            "last_name": "Stump"
        }
    }, 
    "model": "Favorite", 
    "product": {
        "admin": false, 
        "archived": false, 
        "created_at": "2011-06-07T21:44:36+00:00", 
        "email": {
            "backlog": "backlog-1111@example.com", 
            "defects": "defects-1111@example.com", 
            "stories": "stories-1111@example.com", 
            "tasks": "tasks-1111@example.com", 
            "tests": "tests-1111@example.com"
        }, 
        "id": 1111, 
        "name": "sprint.ly"
    }
}

Block

{
    "action": "created",
    "attributes": {
        "blocked": {
            "archived": false, 
            "assigned_to": {
                "created_at": "2011-06-07T21:10:52+00:00", 
                "email": "joe@example.com", 
                "first_name": "Joe", 
                "id": 1111,
                "last_login": "2012-07-26T23:16:55+00:00", 
                "last_name": "Stump"
            }, 
            "created_at": "2012-03-30T00:57:20+00:00", 
            "created_by": {
                "created_at": "2011-06-07T21:10:52+00:00", 
                "email": "joe@example.com", 
                "first_name": "Joe", 
                "id": 1, 
                "last_login": "2012-07-26T23:16:55+00:00", 
                "last_name": "Stump"
            }, 
            "description": "Send out an email if the person's CC expires soon.", 
            "email": {
                "discussion": "discussion-1111@example.com", 
                "files": "files-1111@example.com"
            }, 
            "last_modified": "2012-08-12T22:53:48+00:00", 
            "number": 2222, 
            "product": {
                "archived": false, 
                "id": 1111, 
                "name": "sprint.ly"
            }, 
            "score": "M", 
            "short_url": "http://sprint.ly/i/1111/1111/", 
            "status": "backlog", 
            "tags": [
                "billing"
            ], 
            "title": "As a customer, I want to be notified before my CC expires so that I can update my billing details.", 
            "type": "story", 
            "what": "to be notified before my CC expires", 
            "who": "customer", 
            "why": "I can update my billing details"
        }, 
        "created_at": "2012-08-12T22:53:47+00:00", 
        "id": 1111, 
        "item": {
            "archived": false, 
            "assigned_to": {
                "created_at": "2012-01-06T23:07:20+00:00", 
                "email": "craig@example.com", 
                "first_name": "Craig", 
                "id": 1111, 
                "last_login": "2012-06-25T11:09:26+00:00", 
                "last_name": "Pattison"
            }, 
            "created_at": "2012-06-23T21:24:40+00:00", 
            "created_by": {
                "created_at": "2011-06-07T21:10:52+00:00", 
                "email": "joe@example.com", 
                "first_name": "Joe", 
                "id": 1111, 
                "last_login": "2012-07-26T23:16:55+00:00", 
                "last_name": "Stump"
            }, 
            "description": "Right now when the application is booting up we have a white spinner. Let's change the spinner to our running man that glows from black to blue and back again.", 
            "email": {
                "discussion": "discussion-1111@example.com", 
                "files": "files-1111@example.com"
            }, 
            "last_modified": "2012-08-12T22:53:48+00:00", 
            "number": 2222, 
            "product": {
                "archived": false, 
                "id": 1111, 
                "name": "sprint.ly"
            }, 
            "progress": {
                "started_at": "2012-06-25T08:55:36+00:00"
            }, 
            "score": "M", 
            "short_url": "http://sprint.ly/i/1111/1111/", 
            "status": "in-progress", 
            "tags": [
                "ios", 
                "ipad"
            ], 
            "title": "Change the spinner to our glowing running man.", 
            "type": "task"
        }, 
        "unblocked": false, 
        "user": {
            "created_at": "2011-06-07T21:10:52+00:00", 
            "email": "joe@example.com", 
            "first_name": "Joe", 
            "id": 1111, 
            "last_login": "2012-07-26T23:16:55+00:00", 
            "last_name": "Stump"
        }
    }, 
    "model": "Block", 
    "product": {
        "admin": false, 
        "archived": false, 
        "created_at": "2011-06-07T21:44:36+00:00", 
        "email": {
            "backlog": "backlog-1111@example.com", 
            "defects": "defects-1111@example.com", 
            "stories": "stories-1111@example.com", 
            "tasks": "tasks-1111@example.com", 
            "tests": "tests-1111@example.com"
        }, 
        "id": 1111, 
        "name": "sprint.ly"
    }
}
Something went wrong with that request. Please try again.