octonode

nodejs wrapper for github v3 api

octonode

octonode is a library for nodejs to access the github v3 api

npm install octonode
var github = require('octonode');
 
// Then we instantiate a client with or without a token (as show in a later section) 
 
var ghme        = client.me();
var ghuser      = client.user('pksunkara');
var ghrepo      = client.repo('pksunkara/hub');
var ghorg       = client.org('flatiron');
var ghissue     = client.issue('pksunkara/hub', 37);
var ghmilestone = client.milestone('pksunkara/hub', 37);
var ghlabel     = client.label('pksunkara/hub', 'todo');
var ghpr        = client.pr('pksunkara/hub', 37);
var ghgist      = client.gist();
var ghteam      = client.team(37);
 
var ghsearch = client.search();
var client = github.client();
 
client.get('/users/pksunkara', {}, function (errstatusbodyheaders) {
  console.log(body); //json object 
});
var client = github.client('someaccesstoken');
 
client.get('/user', {}, function (errstatusbodyheaders) {
  console.log(body); //json object 
});
var client = github.client({
  username: 'pksunkara',
  password: 'password'
});
 
client.get('/user', {}, function (errstatusbodyheaders) {
  console.log(body); //json object 
});
var client = github.client({
  id: 'abcdefghijklmno',
  secret: 'abcdefghijk'
});
 
client.get('/user', {}, function (errstatusbodyheaders) {
  console.log(body); //json object 
});

Request options can be set by setting defaults on the client. (e.g. Proxies)

var client = github.client();
 
client.requestDefaults['proxy'] = 'https://myproxy.com:1085'

These options are passed though to request, see their API here: https://github.com/mikeal/request#requestoptions-callback

You can set proxies dynamically by using the example above, but Octonode will respect environment proxies by default. Just set this using: export HTTP_PROXY='https://myproxy.com:1085' if you are using the command line

Many of the below use cases use parts of the above code

github.auth.config({
  username: 'pksunkara',
  password: 'password'
}).login(['user', 'repo', 'gist'], function (erridtoken) {
  console.log(id, token);
});
github.auth.config({
  username: 'pksunkara',
  password: 'password'
}).revoke(id, function (err) {
  if (err) throw err;
});
// Web application which authenticates to github 
var http = require('http')
  , url = require('url')
  , qs = require('querystring')
  , github = require('octonode');
 
// Build the authorization config and url 
var auth_url = github.auth.config({
  id: 'mygithubclientid',
  secret: 'mygithubclientsecret'
}).login(['user', 'repo', 'gist']);
 
// Store info to verify against CSRF 
var state = auth_url.match(/&state=([0-9a-z]{32})/i);
 
// Web server 
http.createServer(function (reqres) {
  uri = url.parse(req.url);
  // Redirect to github login 
  if (uri.pathname=='/login') {
    res.writeHead(302, {'Content-Type': 'text/plain', 'Location': auth_url})
    res.end('Redirecting to ' + auth_url);
  }
  // Callback url from github login 
  else if (uri.pathname=='/auth') {
    var values = qs.parse(uri.query);
    // Check against CSRF attacks 
    if (!state || state[1] != values.state) {
      res.writeHead(403, {'Content-Type': 'text/plain'});
      res.end('');
    } else {
      github.auth.login(values.code, function (errtoken) {
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end(token);
      });
    }
  } else {
    res.writeHead(200, {'Content-Type': 'text/plain'})
    res.end('');
  }
}).listen(3000);
 
console.log('Server started on 3000');

You can also check your rate limit status by calling the following.

client.limit(function (errleftmax) {
  console.log(left); // 4999 
  console.log(max);  // 5000 
});

All the callbacks for the following will take first an error argument, then a data argument, like this:

ghme.info(function(errdataheaders) {
  console.log("error: " + err);
  console.log("data: " + data);
  console.log("headers:" + headers);
});

If a function is said to be supporting pagination, then that function can be used in many ways as shown below. Results from the function are arranged in pages.

The page argument is optional and is used to specify which page of issues to retrieve. The perPage argument is also optional and is used to specify how many issues per page.

// Normal usage of function 
ghrepo.issues(callback); //array of first 30 issues 
 
// Using pagination parameters 
ghrepo.issues(2, 100, callback); //array of second 100 issues 
ghrepo.issues(10, callback); //array of 30 issues from page 10 
 
// Pagination parameters can be set with query object too 
ghrepo.issues({
  page: 2,
  per_page: 100,
  state: 'closed'
}, callback); //array of second 100 issues which are closed 

Token/Credentials required for the following:

ghme.info(callback); //json 
ghme.update({
  "name": "monalisa octocat",
  "email": "octocat@github.com",
}, callback);
ghme.emails(callback); //array of emails 

Set emails of the user (POST /user/emails)

ghme.emails(['new1@ma.il', 'new2@ma.il'], callback); //array of emails 
ghme.emails('new@ma.il', callback); //array of emails 
ghme.emails(['new1@ma.il', 'new2@ma.il']);
ghme.emails('new@ma.il');
ghme.followers(callback); //array of github users 

This query supports pagination.

ghme.following(callback); //array of github users 
ghme.following('marak', callback); //boolean 
ghme.follow('marak');
ghme.unfollow('marak');
ghme.keys(callback); //array of keys 
ghme.keys(1, callback); //key 

Create a public key (POST /user/keys)

ghme.keys({"title":"laptop", "key":"ssh-rsa AAA..."}, callback); //key 
ghme.keys(1, {"title":"desktop", "key":"ssh-rsa AAA..."}, callback); //key 
ghme.keys(1);

This query supports pagination.

ghme.starred(callback); //array of repos 
ghme.checkStarred('flatiron/flatiron', callback); //boolean 
ghme.star('flatiron/flatiron');
ghme.unstar('flatiron/flatiron');

This query supports pagination.

ghme.watched(callback); //array of repos 

This query supports pagination.

ghme.orgs(callback); //array of orgs 

This query supports pagination.

ghme.repos(callback); //array of repos 

Create a repository (POST /user/repos)

ghme.repo({
  "name": "Hello-World",
  "description": "This is your first repo",
}, callback); //repo 

Fork a repository (POST /repos/pksunkara/hub/forks)

ghme.fork('pksunkara/hub', callback); //forked repo 

This query supports pagination.

ghme.issues({
  page: 2,
  per_page: 100,
  filter: 'assigned',
  state: 'open',
  sort: 'created'  
}, callback); //array of issues 

No token required for the following

ghuser.info(callback); //json 

This query supports pagination.

ghuser.followers(callback); //array of github users 

This query supports pagination.

ghuser.following(callback); //array of github users 

This query supports pagination.

Optionally, supply an array of Event Types to filter by.

ghuser.events(['PushEvent'], callback); //array of PushEvent events 

Or leave it out to get all Event Types.

ghuser.events(callback); //array of events 

This query supports pagination.

ghuser.orgs(callback); //array of organizations 
ghrepo.info(callback); //json 
ghrepo.collaborators(callback); //array of github users 
ghrepo.collaborators('marak', callback); //boolean 
ghrepo.commits(callback); //array of commits 
ghrepo.commit('18293abcd72', callback); //commit 
ghrepo.tags(callback); //array of tags 
ghrepo.releases(callback); //array of releases 
ghrepo.languages(callback); //array of languages 
ghrepo.contributors(callback); //array of github users 

This query supports pagination.

ghrepo.branches(callback); //array of branches 
ghrepo.branch('master', callback); //branch 

This query supports pagination.

ghrepo.issues(callback); //array of issues 

Create an issue for a repository (POST /repos/pksunkara/hub/issues)

ghrepo.issue({
  "title": "Found a bug",
  "body": "I'm having a problem with this.",
  "assignee": "octocat",
  "milestone": 1,
  "labels": ["Label1", "Label2"]
}, callback); //issue 

This query supports pagination.

ghrepo.milestones(callback); //array of milestones 

Create a milestone for a repository (POST /repos/pksunkara/hub/milestones)

ghrepo.milestone({
  "title": "Sprint 345",
  "description": "The sprint where we fix all the things!",
  "due_on": new Date(2014, 7, 1)
}, callback); //milestone 

This query supports pagination.

ghrepo.labels(callback); //array of labels 

Create a label for a repository (POST /repos/pksunkara/hub/labels)

ghrepo.label({
  "name": "Priority",
  "color": "ff0000",
}, callback); //label 

This query supports pagination.

ghrepo.prs(callback); //array of pull requests 

Create a pull request (POST /repos/pksunkara/hub/pulls)

ghrepo.pr({
  "title": "Amazing new feature",
  "body": "Please pull this in!",
  "head": "octocat:new-feature",
  "base": "master"
}, callback); //pull request 

This query supports pagination.

ghrepo.hooks(callback); //array of hooks 

Create a hook (POST /repos/pksunkara/hub/hooks)

ghrepo.hook({
  "name": "web",
  "active": true,
  "events": ["push", "pull_request"],
  "config": {
    "url": "http://myawesomesite.com/github/events"
  }
}, callback); // hook 
ghrepo.readme(callback); //file 
ghrepo.readme('v0.1.0', callback); //file 
ghrepo.contents('', "myBranch", callback);
ghrepo.contents('lib/index.js', callback); //path 
ghrepo.contents('lib/index.js', 'v0.1.0', callback); //path 
ghrepo.createContents('lib/index.js', 'commit message', 'content', callback); //path 
ghrepo.createContents('lib/index.js', 'commit message', 'content', 'v0.1.0', callback); //path 
ghrepo.updateContents('lib/index.js', 'commit message', 'content', 'put-sha-here', callback); //path 
ghrepo.updateContents('lib/index.js', 'commit message', 'content', 'put-sha-here', 'v0.1.0', callback); //path 
ghrepo.deleteContents('lib/index.js', 'commit message', 'put-sha-here', callback); //path 
ghrepo.deleteContents('lib/index.js', 'commit message', 'put-sha-here', 'v0.1.0', callback); //path 
ghrepo.archive('tarball', callback); //link to archive 
ghrepo.archive('zipball', 'v0.1.0', callback); //link to archive 
ghrepo.blob('18293abcd72', callback); //blob 
ghrepo.stargazers(1, 100, callback); //array of users 
ghrepo.stargazers(10, callback);     //array of users 
ghrepo.stargazers(callback);         //array of users 
ghrepo.teams(callback); //array of teams 
ghrepo.tree('18293abcd72', callback); //tree 
ghrepo.tree('18293abcd72', true, callback); //recursive tree 
ghrepo.destroy();
ghrepo.statuses('master', callback); //array of statuses 

Create status (POST /repos/pksunkara/hub/statuses/SHA)

ghrepo.status('18e129c213848c7f239b93fe5c67971a64f183ff', {
  "state": "success",
  "target_url": "http://ci.mycompany.com/job/hub/3",
  "description": "Build success."
}, callback); // created status 
ghorg.info(callback); //json 

Update an organization (POST /orgs/flatiron)

ghorg.update({
  blog: 'https://blog.com'
}, callback); // org 

This query supports pagination.

ghorg.repos(callback); //array of repos 

Create an organization repository (POST /orgs/flatiron/repos)

ghorg.repo({
  name: 'Hello-world',
  description: 'My first world program'
}, callback); //repo 
ghorg.teams(callback); //array of teams 

This query supports pagination.

ghorg.members(callback); //array of github users 
ghorg.member('pksunkara', callback); //boolean 
ghorg.publicMember('pksunkara', callback); //boolean 
ghorg.memberships('pksunkara', callback); //membership status object indicating state, role, etc. 

Create an organization team (POST /orgs/flatiron/teams)

ghorg.createTeam({
  "name": "new team name",
  "permission": "push",
  "repo_names": [
    "flatiron/utile"
   ]
}, callback);
ghissue.info(callback); //issue 
ghissue.update({
  "title": "Found a bug and I am serious",
}, callback); //issue 

This query supports pagination.

ghissue.comments(callback); //array of comments 
ghmilestone.info(callback); //milestone 
ghmilestone.update({
  "title": "Updated milestone title",
}, callback); //milestone 
ghmilestone.delete(callback); //milestone 
ghlabel.info(callback); //label 
ghlabel.update({
  "color": "000000",
}, callback); //label 
ghlabel.delete(callback); //label 
ghpr.info(callback); //pull request 
ghpr.update({
  'title': 'Wow this pr'
}, callback); //pull request 
ghpr.close(callback); //pull request 
ghpr.merged(callback); //boolean 
ghpr.commits(callback); //array of commits 
ghpr.comments(callback); //array of comments 
ghpr.files(callback); //array of files 

This query supports pagination.

ghgist.list(callback); //array of gists 

This query supports pagination.

ghgist.public(callback); //array of gists 

This query supports pagination.

ghgist.starred(callback); //array of gists 

This query supports pagination.

ghgist.user('pksunkara', callback); //array of gists 
ghgist.get(37, callback); //gist 

Create a gist (POST /gists)

ghgist.create({
  description: "the description",
  files: { ... }
}), callback); //gist 
ghgist.edit(37, {
  description: "hello gist"
}, callback); //gist 
ghgist.delete(37);

Fork a gist (POST /gists/37/forks)

ghgist.fork(37, callback); //gist 
ghgist.star(37);
ghgist.unstar(37);
ghgist.check(37); //boolean 
ghgist.comments(37, callback); //array of comments 

Create a comment (POST /gists/37/comments)

ghgist.comments(37, {
  body: "Just commenting"
}, callback); //comment 
ghgist.comment(1, callback); //comment 

Edit a comment (POST /gists/comments/1)

ghgist.comment(1, {
  body: "lol at commenting"
}, callback); //comment 
ghgist.comment(1);
ghteam.info(callback); //json 
ghteam.members(callback); //array of github users 
ghteam.member('pksunkara', callback); //boolean 
ghteam.addUser("pksunkara", callback); //boolean 
ghteam.removeUser("pksunkara", callback); //boolean 
ghteam.repos(callback); //array of repos 
ghsearch.issues({
  q: 'windows+state:open+repo:pksunkara/hub',
  sort: 'created',
  order: 'asc'
}, callback); //array of search results 
ghsearch.repos({
  q: 'hub+language:go',
  sort: 'created',
  order: 'asc'
}, callback); //array of search results 
ghsearch.users({
  q: 'tom+followers:>100',
  sort: 'created',
  order: 'asc'
}, callback); //array of search results 
ghsearch.code({
  q: 'auth+in:file+repo:pksunkara/hub',
  sort: 'created',
  order: 'asc'
}, callback); //array of search results 
npm test

If you like this project, please watch this and follow me.

Here is a list of Contributors

The following method names use underscore as an example. The library contains camel cased method names.

 
// public repos for unauthenticated, private and public for authenticated 
me.get_watched_repositories(callback);
me.is_watching('repo', callback);
me.start_watching('repo', callback);
me.stop_watching('repo', callback);
 
// organization data 
var org = octonode.Organization('bulletjs');
 
org.update(dict_with_update_properties, callback);
org.get_public_members(callback);
org.is_public_member('user', callback);
org.make_member_public('user', callback);
org.conceal_member('user', callback);
 
org.get_team('team', callback);
org.create_team({name:'', repo_names:'', permission:''}, callback);
org.edit_team({name:'', permission:''}, callback);
org.delete_team('name', callback);
org.get_team_members('team', callback);
org.get_team_member('team', 'user', callback);
org.remove_member_from_team('user', 'team', callback);
org.get_repositories(callback);
org.create_repository({name: ''}, callback);
org.get_team_repositories('team', callback);
org.get_team_repository('team', 'name', callback);
org.add_team_repository('team', 'name', callback);
org.remove_team_repository('team', 'name', callback);
 
var repo = octonode.Repository('pksunkara/octonode');
 
repo.update({name: ''}, callback);
 
// collaborator information 
repo.add_collaborator('name', callback);
repo.remove_collaborator('name', callback);
 
// commit data 
repo.get_commit('sha-id', callback);
repo.get_all_comments(callback);
repo.get_commit_comments('SHA ID', callback);
repo.comment_on_commit({body: '', commit_id: '', line: '', path: '', position: ''}, callback);
repo.get_single_comment('comment id', callback);
repo.edit_single_comment('comment id', callback);
repo.delete_single_comment('comment id', callback);
 
// downloads 
repo.get_downloads(callback);
repo.get_download(callback);
repo.create_download({name: ''}, 'filepath', callback);
repo.delete_download(callback);
 
// keys 
repo.get_deploy_keys(callback);
repo.get_deploy_key('id', callback);
repo.create_deploy_key({title: '', key: ''}, callback);
repo.edit_deploy_key({title: '', key: ''}, callback);
repo.delete_deploy_key('id', callback);
 
// watcher data 
repo.get_watchers(callback);
 
// pull requests 
repo.get_all_pull_request_comments(callback);
repo.get_pull_request_comment('id', callback);
repo.create_pull_request_comment('id', {body:'', commit_id:'', path:'', position:''}, callback);
repo.reply_to_pull_request_comment('id', 'body', callback);
repo.edit_pull_request_comment('id', 'body', callback);
repo.delete_pull_request_comment('id', callback);
repo.get_issues(params, callback);
repo.get_issue('id', callback);
repo.create_issue({title: ''}, callback);
repo.edit_issue({title: ''}, callback);
repo.get_issue_comments('issue', callback);
repo.get_issue_comment('id', callback);
repo.create_issue_comment('id', 'comment', callback);
repo.edit_issue_comment('id', 'comment', callback);
repo.delete_issue_comment('id', callback);
repo.get_issue_events('id', callback);
repo.get_events(callback);
repo.get_event('id', callback);
repo.get_labels(callback);
repo.get_label('id', callback);
repo.create_label('name', 'color', callback);
repo.edit_label('name', 'color', callback);
repo.delete_label('id', callback);
repo.get_issue_labels('issue', callback);
repo.add_labels_to_issue('issue', ['label1', 'label2'], callback);
repo.remove_label_from_issue('issue', 'labelid', callback);
repo.set_labels_for_issue('issue', ['label1', 'label2'], callback);
repo.remove_all_labels_from_issue('issue', callback);
repo.get_labels_for_milestone_issues('milestone', callback);
repo.get_milestones(callback);
repo.get_milestone('id', callback);
repo.create_milestone('title', callback);
repo.edit_milestone('title', callback);
repo.delete_milestone('id', callback);
 
// raw git access 
repo.create_blob('content', 'encoding', callback);
repo.get_commit('sha-id', callback);
repo.create_commit('message', 'tree', [parents], callback);
repo.get_reference('ref', callback);
repo.get_all_references(callback);
repo.create_reference('ref', 'sha', callback);
repo.update_reference('ref', 'sha', force, callback);

I accept pull requests and guarantee a reply back within a day

MIT/X11

Report here. Guaranteed reply within a day.

Pavan Kumar Sunkara (pavan.sss1991@gmail.com)

Follow me on github, twitter