├── .gitignore ├── README.md ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # thingsapp 2 | 3 | Node module for creating todos in Things.app by Cultured Code. 4 | 5 | ## Installation 6 | 7 | Install using `npm install --save git+ssh://git@github.com/simonbs/thingsapp.git`. 8 | 9 | ## Usage 10 | 11 | When creating an instance of Things, you should pass your account ID and start index. Find these by inspecting HTTP traffic to `https://cloud.culturedcode.com` using [Charles](https://www.charlesproxy.com) or similar. 12 | 13 | The UUID in the requests is your account ID. Consider the following call to the Things Cloud API. 14 | 15 | ``` 16 | https://cloud.culturedcode.com/version/1/history/THIS-IS-YOUR-ACCOUNT-ID/items?start-index=5612 17 | ``` 18 | 19 | In above request, `THIS-IS-YOUR-ACCOUNT-ID` is your account ID and your start index is 5612. 20 | 21 | When you have acquired both your account ID and your start index you can use the thingsapp module as shown below. 22 | 23 | ```javascript 24 | var todo = { 25 | title: 'Pack for vacation', 26 | note: 'GoPro, selfiestick, MacBook charger and tickets' 27 | } 28 | var things = new Things('THIS-IS-YOUR-ACCOUNT-ID', 5612) 29 | things.createTodo(todo, function(err) { 30 | // Handle errors. 31 | }) 32 | ``` 33 | 34 | In your todo you can set the `where` key to either `inbox` or `today` to specify the location of the todo. Default is the inbox. 35 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var uuid4 = require('uuid/v4') 2 | var moment = require('moment') 3 | var request = require('request') 4 | 5 | function Things(accountId, startIndex) { 6 | this.accountId = accountId 7 | this.startIndex = startIndex 8 | } 9 | 10 | Things.prototype.createTodo = function(todo, callback) { 11 | var things = this 12 | this.getCurrentIndex(this.startIndex, function(err, idx) { 13 | if (err) { return callback(err) } 14 | things.constructTodoItem(todo, function(err, todoItem) { 15 | var url = 'https://cloud.culturedcode.com/version/1/history/' + things.accountId + '/items' 16 | if (err) { return callback(err) } 17 | request.post({ 18 | url: url, 19 | json: { 20 | 'current-item-index': idx, 21 | 'items': [ todoItem ], 22 | 'schema': 1 23 | }, 24 | headers: { 25 | 'User-Agent': 'ThingsMac/20808500mas (x86_64; OS X 10.12.2; en_DK)', 26 | 'Content-Type': 'application/json; charset=UTF-8', 27 | 'Content-Encoding': 'UTF-8' 28 | } 29 | }, 30 | function(err, httpResponse, body) { 31 | callback(err) 32 | }) 33 | }) 34 | }) 35 | } 36 | 37 | Things.prototype.constructTodoItem = function(todo, callback) { 38 | title = todo['title'] || 'New todo' 39 | duedate = todo['duedate'] || null 40 | note = todo['note'] || null 41 | destination = todo['where'] || 'inbox' 42 | uid = uuid4().toUpperCase() 43 | now = Date.now() / 1000 44 | if (destination == 'today') { 45 | st = 2 46 | } else if (destination == 'inbox') { 47 | st = 0 48 | } else { 49 | return callback('Unsupported destination \'' + destination + '\'.') 50 | } 51 | if (st == 2) { 52 | sr = moment(moment(new Date()).format('YYYY-MM-DD')).unix() 53 | } else { 54 | sr = null 55 | } 56 | if (note != null) { 57 | note = '' + note + '' 58 | } 59 | item = {} 60 | item[uid] = { 61 | "t": 0, 62 | "e": "Task2", 63 | "p": { 64 | "acrd": null, 65 | "ar": [], 66 | "cd": now, 67 | "dd": duedate, 68 | "dl": [], 69 | "do": 0, 70 | "icc": 0, 71 | "icp": false, 72 | "icsd": null, 73 | "ix": 0, 74 | "md": now, 75 | "nt": note, 76 | "pr": [], 77 | "rr": null, 78 | "rt": [], 79 | "sp": null, 80 | "sr": sr, 81 | "ss": 0, 82 | "st": st, 83 | "tg": [], 84 | "ti": 0, 85 | "tp": 0, 86 | "tr": false, 87 | "tt": title 88 | } 89 | } 90 | callback(null, item) 91 | } 92 | 93 | Things.prototype.getCurrentIndex = function(startIndex, callback) { 94 | url = 'https://thingscloud.appspot.com/version/1/history/' 95 | + this.accountId + '/items?start-index=' + startIndex 96 | request.get({ 97 | url: url, 98 | }, 99 | function(err, httpResponse, body) { 100 | if (err) { return callback(err) } 101 | var json = JSON.parse(body) 102 | callback(null, json['current-item-index']) 103 | }) 104 | } 105 | 106 | module.exports = Things 107 | 108 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thingsapp", 3 | "version": "0.1.0", 4 | "description": "Add todos in Things.app", 5 | "main": "index.js", 6 | "keywords": [ 7 | "things", 8 | "cultured", 9 | "code", 10 | "todo" 11 | ], 12 | "author": "Simon B. Støvring", 13 | "license": "ISC", 14 | "dependencies": { 15 | "moment": "^2.17.1", 16 | "request": "^2.79.0", 17 | "uuid": "^3.0.1" 18 | } 19 | } 20 | --------------------------------------------------------------------------------