diff --git a/README.md b/README.md index 2dfb882..5245db6 100644 --- a/README.md +++ b/README.md @@ -116,24 +116,32 @@ messages too. You'll need to examine `event.message.is_echo` in your handlers. ### Sending responses to the user -You're given a `reply` in event emitters (see above): +You're given a `reply` function in event emitters. When called, it sends the +first argument, `responseObject`, back to Messenger to the user: - reply(responseObject) + messenger.on('text', ({ reply, text }) => { + reply(responseObject) + }) -The original syntax will also work: +The classic syntax will also work if you only have one page: - messenger.send(senderId, responseObject) + messenger.on('text', ({ senderId, text }) => { + messenger.send(senderId, responseObject) + }) or if you have multiple Pages, you can send responses like: - messenger.pageSend(pageId, senderId, responseObject) + messenger.on('text', ({ senderId, text, session }) => { + const pageId = magic() + messenger.pageSend(pageId, senderId, responseObject) + }) Some factories for generating `responseObject` are available at the top level and are also available in a `responses` object if you need a namespace: const { Text, Image, Generic, ImageQuickReply } = require('launch-vehicle-fbm'); const { responses } = require('launch-vehicle-fbm'); - // responses.Text, responses.Image, responses.Generic, responses.ImageQuickReply etc. + // responses.Text, responses.Image, responses.Generic, etc. The most common response is text: @@ -149,8 +157,16 @@ The full list: * `new Image('https://i.imgur.com/ehSTCkO.gif')` * `new Generic(elements[])` https://developers.facebook.com/docs/messenger-platform/send-api-reference/generic-template -* `new ImageQuickReply('https://i.imgur.com/ehSTCkO.gif', quickReplies[])` NOTE: the syntax for quick replies may change in the future since it's orthogonal to `Text` and `Image`. -https://developers.facebook.com/docs/messenger-platform/send-api-reference/quick-replies + +`Text` and `Image` can have [quick replies](https://developers.facebook.com/docs/messenger-platform/send-api-reference/quick-replies): + + const text = new Text('Where are you?').quickReplies([{ content_type: 'location' }]) + + const image = new Image('https://i.imgur.com/izwcQLS.jpg' + .quickReplies([ + { content_type: 'text', title: 'yes', payload: 'yes' }, + { content_type: 'text', title: 'no', payload: 'no' } + ]) #### `Text` translation diff --git a/package-lock.json b/package-lock.json index e7fa2a5..c0e6859 100644 --- a/package-lock.json +++ b/package-lock.json @@ -71,8 +71,23 @@ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", "requires": { - "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.15.tgz", + "mime-types": "2.1.17", "negotiator": "0.6.1" + }, + "dependencies": { + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "requires": { + "mime-db": "1.30.0" + } + } } }, "acorn": { @@ -110,9 +125,9 @@ } }, "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz", + "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=", "dev": true }, "align-text": { @@ -204,6 +219,11 @@ "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", "dev": true }, + "async": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", + "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -407,14 +427,14 @@ } }, "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.0.tgz", + "integrity": "sha512-0BMM/2hG3ZaoPfR6F+h/oWpZtsh3b/s62TjSM6MGCJWEbJDN1acqCXvyhhZsDSVFklpebUoQ5O1kKC7lOzrn9g==", "dev": true, "requires": { "ansi-styles": "3.2.0", "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" + "supports-color": "4.5.0" }, "dependencies": { "ansi-styles": { @@ -433,9 +453,9 @@ "dev": true }, "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", "dev": true, "requires": { "has-flag": "2.0.0" @@ -508,7 +528,8 @@ "dev": true }, "colors": { - "version": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" }, "combined-stream": { @@ -519,13 +540,10 @@ } }, "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": "1.0.1" - } + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true }, "component-emitter": { "version": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", @@ -574,9 +592,9 @@ } }, "config": { - "version": "1.26.2", - "resolved": "https://registry.npmjs.org/config/-/config-1.26.2.tgz", - "integrity": "sha1-JGYpEWjYr64Kroq5nqTUJy9SDK4=", + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/config/-/config-1.27.0.tgz", + "integrity": "sha1-OrMNAID/dvQHwvR6wTJq39kIr18=", "requires": { "json5": "0.4.0", "os-homedir": "1.0.2" @@ -658,7 +676,8 @@ } }, "cycle": { - "version": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=" }, "d": { @@ -761,9 +780,9 @@ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", "dev": true }, "doctrine": { @@ -915,14 +934,14 @@ } }, "eslint": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.7.2.tgz", - "integrity": "sha1-/29fUZOEiifum2J74+c/ucteZi4=", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.9.0.tgz", + "integrity": "sha1-doedJ0BoJhsZH+Dy9Wx0wvQgjos=", "dev": true, "requires": { "ajv": "5.2.3", "babel-code-frame": "6.26.0", - "chalk": "2.1.0", + "chalk": "2.2.0", "concat-stream": "1.6.0", "cross-spawn": "5.1.0", "debug": "3.1.0", @@ -955,7 +974,7 @@ "semver": "5.4.1", "strip-ansi": "4.0.0", "strip-json-comments": "2.0.1", - "table": "4.0.1", + "table": "4.0.2", "text-table": "0.2.0" }, "dependencies": { @@ -1062,9 +1081,9 @@ } }, "eslint-plugin-import": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", - "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", + "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", "dev": true, "requires": { "builtin-modules": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -1195,12 +1214,13 @@ } }, "express": { - "version": "4.15.5", - "resolved": "https://registry.npmjs.org/express/-/express-4.15.5.tgz", - "integrity": "sha1-ZwI1ypWYiQpa6BcLg9tyK4Qu2Sc=", + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", + "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", "requires": { "accepts": "1.3.4", "array-flatten": "1.1.1", + "body-parser": "1.18.2", "content-disposition": "0.5.2", "content-type": "1.0.4", "cookie": "0.3.1", @@ -1210,22 +1230,23 @@ "encodeurl": "1.0.1", "escape-html": "1.0.3", "etag": "1.8.1", - "finalhandler": "1.0.6", + "finalhandler": "1.1.0", "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "on-finished": "2.3.0", "parseurl": "1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "1.1.5", - "qs": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "proxy-addr": "2.0.2", + "qs": "6.5.1", "range-parser": "1.2.0", - "send": "0.15.6", - "serve-static": "1.12.6", - "setprototypeof": "1.0.3", + "safe-buffer": "5.1.1", + "send": "0.16.1", + "serve-static": "1.13.1", + "setprototypeof": "1.1.0", "statuses": "1.3.1", "type-is": "1.6.15", - "utils-merge": "1.0.0", + "utils-merge": "1.0.1", "vary": "1.1.2" }, "dependencies": { @@ -1234,8 +1255,23 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz" + "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" } } }, @@ -1272,7 +1308,8 @@ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "eyes": { - "version": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" }, "fast-deep-equal": { @@ -1300,14 +1337,14 @@ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { - "flat-cache": "1.2.2", + "flat-cache": "1.3.0", "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" } }, "finalhandler": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz", - "integrity": "sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", "requires": { "debug": "2.6.9", "encodeurl": "1.0.1", @@ -1323,8 +1360,13 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz" + "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -1338,9 +1380,9 @@ } }, "flat-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", + "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", "dev": true, "requires": { "circular-json": "0.3.3", @@ -1350,9 +1392,9 @@ } }, "flow-bin": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.55.0.tgz", - "integrity": "sha1-kIPakye9jKtrQHbWPYXyJHp+rhs=", + "version": "0.57.3", + "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.57.3.tgz", + "integrity": "sha512-bbB7KLR1bLS0CvHSsKseOGFF6iI2N9ocL14EQv8Hng28ZksD0gNRzR2JopqA3WGrQYJukDU1W4ZuKoBaRuElFA==", "dev": true }, "foreach": { @@ -1380,7 +1422,7 @@ "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", "dev": true, "requires": { - "samsam": "1.2.1" + "samsam": "1.3.0" } }, "formidable": { @@ -1488,16 +1530,10 @@ "version": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", "dev": true }, "handlebars": { @@ -1637,7 +1673,7 @@ "dev": true, "requires": { "ansi-escapes": "3.0.0", - "chalk": "2.1.0", + "chalk": "2.2.0", "cli-cursor": "2.1.0", "cli-width": "2.2.0", "external-editor": "2.0.5", @@ -1658,9 +1694,9 @@ "dev": true }, "ipaddr.js": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz", - "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA=" + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", + "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" }, "is-arrayish": { "version": "0.2.1", @@ -1880,12 +1916,6 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, "json5": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz", @@ -1969,56 +1999,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.12.0.tgz", "integrity": "sha1-K9bcRqBA9Z5obJcu0h2T3FkFMlg=" }, - "lodash._baseassign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "dev": true, - "requires": { - "lodash._basecopy": "3.0.1", - "lodash.keys": "3.1.2" - } - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basecreate": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, "lodash.cond": { "version": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", "dev": true }, - "lodash.create": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", - "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", - "dev": true, - "requires": { - "lodash._baseassign": "3.2.0", - "lodash._basecreate": "3.0.3", - "lodash._isiterateecall": "3.0.9" - } - }, "lodash.endswith": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/lodash.endswith/-/lodash.endswith-4.2.1.tgz", @@ -2043,33 +2028,10 @@ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, "lolex": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.1.2.tgz", - "integrity": "sha1-JpS5U8nqTQE+W4v7qJHJkQJbJik=", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.1.3.tgz", + "integrity": "sha512-BdHq78SeI+6PAUtl4atDuCt7L6E4fab3mSRtqxm4ywaXe4uP7jZ0TTcFNuU20syUjxZc2l7jFqKVMJ+AX0LnpQ==", "dev": true }, "longest": { @@ -2101,7 +2063,8 @@ }, "mime": { "version": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" + "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=", + "dev": true }, "mime-db": { "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.27.0.tgz", @@ -2147,61 +2110,59 @@ } }, "mocha": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", - "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.0.1.tgz", + "integrity": "sha512-evDmhkoA+cBNiQQQdSKZa2b9+W2mpLoj50367lhy+Klnx9OV8XlCIhigUnn1gaTFLQCa0kdNhEGDr0hCXOQFDw==", "dev": true, "requires": { "browser-stdout": "1.3.0", - "commander": "2.9.0", - "debug": "2.6.8", - "diff": "3.2.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", "escape-string-regexp": "1.0.5", - "glob": "7.1.1", - "growl": "1.9.2", + "glob": "7.1.2", + "growl": "1.10.3", "he": "1.1.1", - "json3": "3.3.2", - "lodash.create": "3.1.1", "mkdirp": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "supports-color": "3.1.2" + "supports-color": "4.4.0" }, "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "1.0.0", "inflight": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "minimatch": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "minimatch": "3.0.4", "once": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "path-is-absolute": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" } }, - "ms": { + "has-flag": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz" + } + }, "supports-color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", - "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { - "has-flag": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz" + "has-flag": "2.0.0" } } } @@ -2234,9 +2195,9 @@ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, "nise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.1.0.tgz", - "integrity": "sha512-lIFidCxB0mJGyq1i33tLRNojtMoYX95EAI7WQEU+/ees0w6hvXZQHZ7WD130Tjeh5+YJAUVLfQ3k/s9EA8jj+w==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.1.1.tgz", + "integrity": "sha512-f5DMJB0MqBaSuP2NAwPx7HyVKPdaozds0KsNe9XIP3npKWt/QUg73l5TTLRTSwfG/Y3AB0ktacuxX4QNcg6vVw==", "dev": true, "requires": { "formatio": "1.2.0", @@ -2527,12 +2488,12 @@ } }, "proxy-addr": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz", - "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", + "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", "requires": { "forwarded": "0.1.2", - "ipaddr.js": "1.4.0" + "ipaddr.js": "1.5.2" } }, "pseudomap": { @@ -2812,9 +2773,9 @@ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "samsam": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz", - "integrity": "sha1-7dOQk6MYQ3DLhZJDsr3yVefY6mc=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", "dev": true }, "semver": { @@ -2824,9 +2785,9 @@ "dev": true }, "send": { - "version": "0.15.6", - "resolved": "https://registry.npmjs.org/send/-/send-0.15.6.tgz", - "integrity": "sha1-IPI6nJJbdiq4JwX+L52yUqzkfjQ=", + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", + "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", "requires": { "debug": "2.6.9", "depd": "1.1.1", @@ -2836,8 +2797,8 @@ "etag": "1.8.1", "fresh": "0.5.2", "http-errors": "1.6.2", - "mime": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "ms": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", + "mime": "1.4.1", + "ms": "2.0.0", "on-finished": "2.3.0", "range-parser": "1.2.0", "statuses": "1.3.1" @@ -2848,20 +2809,30 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { - "ms": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz" + "ms": "2.0.0" } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, "serve-static": { - "version": "1.12.6", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.6.tgz", - "integrity": "sha1-uXN3P2NEmTTaVOW+ul4x2fQhFXc=", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", + "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", "requires": { "encodeurl": "1.0.1", "escape-html": "1.0.3", "parseurl": "1.3.2", - "send": "0.15.6" + "send": "0.16.1" } }, "setprototypeof": { @@ -2891,19 +2862,19 @@ "dev": true }, "sinon": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.0.0.tgz", - "integrity": "sha1-pUpfAjeqHdIhXl6ByJtCtQxP22s=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.0.1.tgz", + "integrity": "sha512-4qIY0pCWCvGCJpV/1JkFu9kbsNEZ9O34cG1oru/c7OCDtrEs50Gq/VjkA2ID5ZwLyoNx1i1ws118oh/p6fVeDg==", "dev": true, "requires": { - "diff": "3.2.0", + "diff": "3.3.1", "formatio": "1.2.0", "lodash.get": "4.4.2", - "lolex": "2.1.2", + "lolex": "2.1.3", "native-promise-only": "0.8.1", - "nise": "1.1.0", + "nise": "1.1.1", "path-to-regexp": "1.7.0", - "samsam": "1.2.1", + "samsam": "1.3.0", "text-encoding": "0.6.4", "type-detect": "4.0.3" }, @@ -2926,10 +2897,13 @@ } }, "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "2.0.0" + } }, "sntp": { "version": "2.0.2", @@ -2988,8 +2962,9 @@ } }, "stack-trace": { - "version": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", - "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=" + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" }, "statuses": { "version": "1.3.1", @@ -3100,50 +3075,24 @@ "dev": true }, "table": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.1.tgz", - "integrity": "sha1-qBFsEz+sLGH0pCCrbN9cTWHw5DU=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", + "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.12.0", - "slice-ansi": "0.0.4", + "ajv": "5.2.3", + "ajv-keywords": "2.1.0", + "chalk": "2.2.0", + "lodash": "4.17.4", + "slice-ansi": "1.0.0", "string-width": "2.1.1" }, "dependencies": { - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", + "dev": true } } }, @@ -3269,9 +3218,9 @@ "dev": true }, "utils-merge": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { "version": "3.0.1", @@ -3322,21 +3271,16 @@ "optional": true }, "winston": { - "version": "https://registry.npmjs.org/winston/-/winston-2.3.1.tgz", - "integrity": "sha1-C0hCDZeMAYBM8CMLZIhhWYIloRk=", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.0.tgz", + "integrity": "sha1-gIBQuT1SZh7Z+2wms/DIJnCLCu4=", "requires": { - "async": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", - "colors": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "cycle": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", - "eyes": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "async": "1.0.0", + "colors": "1.0.3", + "cycle": "1.0.3", + "eyes": "0.1.8", "isstream": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "stack-trace": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz" - }, - "dependencies": { - "async": { - "version": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", - "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" - } + "stack-trace": "0.0.10" } }, "winston-slack-transport": { diff --git a/package.json b/package.json index 798cbfa..4698d15 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "scripts": { "lint": "eslint --ignore-path .gitignore .", "pretest": "npm run lint", - "tdd": "NODE_ENV=test env $(cat test.env | xargs) mocha -R dot --recursive --watch --bail", - "test": "NODE_ENV=test env $(cat test.env | xargs) istanbul cover _mocha -- --recursive" + "tdd": "NODE_ENV=test env $(cat test.env | xargs) mocha -R dot --watch --bail", + "test": "NODE_ENV=test env $(cat test.env | xargs) istanbul cover _mocha -- --exit" }, "engines": { "node": ">6.0" @@ -32,27 +32,27 @@ "app-root-dir": "^1.0.2", "body-parser": "^1.18.2", "cacheman": "^2.2.1", - "config": "^1.26.2", + "config": "^1.27.0", "dashbot": "^9.2.0", "debug": "^3.1.0", - "express": "^4.15.5", + "express": "^4.16.2", "express-handlebars": "^3.0.0", "request": "^2.83.0", "request-promise": "^4.2.2", "url-join": "^2.0.2", - "winston": "^2.3.1", + "winston": "^2.4.0", "winston-slack-transport": "^2.0.0" }, "devDependencies": { "@condenast/eslint-config-condenast": "^0.12.0", "chai": "^4.1.2", "chai-http": "^3.0.0", - "eslint": "^4.7.2", - "eslint-plugin-import": "^2.7.0", + "eslint": "^4.9.0", + "eslint-plugin-import": "^2.8.0", "eslint-plugin-mocha": "^4.9.0", - "flow-bin": "^0.55.0", + "flow-bin": "^0.57.3", "istanbul": "^0.4.5", - "mocha": "^3.5.3", - "sinon": "^4.0.0" + "mocha": "^4.0.1", + "sinon": "^4.0.1" } } diff --git a/src/responses.js b/src/responses.js index 8f8c2ad..f6dbea5 100644 --- a/src/responses.js +++ b/src/responses.js @@ -13,13 +13,19 @@ if (fs.existsSync(`${appRootDir}/messages.js`)) { debug('Loaded empty dictionary'); } - // https://developers.facebook.com/docs/messenger-platform/send-api-reference // In order of most -> least commonly used +/*:: +declare type TextButton = { content_type: 'text', title: string, image_url?: string, payload: string } +declare type LocationButton = { content_type: 'location' } +declare type Button = TextButton | LocationButton +*/ + class Text { /*:: codetext: string */ /*:: text: string */ + /*:: quick_replies: Button[] */ constructor(text/*: string */, ...args/*: mixed[] */) { Object.defineProperty(this, 'codetext', { enumerable: false, // This is the default, but here to be explicit @@ -38,15 +44,27 @@ class Text { } this.text = format(newText, ...args); } + + quickReplies(buttons/*: Button[] */) { + this.quick_replies = buttons; + return this; + } } -function Image(url/*: string */) { - this.attachment = { - type: 'image', - payload: { - url - } - }; +class Image { + /*:: attachment: Object */ + /*:: quick_replies: Button[] */ + constructor(url/*: string */) { + this.attachment = { + type: 'image', + payload: { url } + }; + } + + quickReplies(buttons/*: Button[] */) { + this.quick_replies = buttons; + return this; + } } // https://developers.facebook.com/docs/messenger-platform/send-api-reference/generic-template @@ -62,9 +80,10 @@ function Generic(elements/*: Object[] */) { // $FlowFixMe class ImageQuickReply extends Image { - constructor(url/*: string */, options/*: Object[] */) { + constructor(url/*: string */, options/*: Button[] */) { super(url); this.quick_replies = options; + console.log('DEPRECATED: ImageQuickReply is deprecated, use Image(url).quickReplies(options) instead'); } } diff --git a/test/responses.spec.js b/test/responses.spec.js index 0cec9b6..3e71e0e 100644 --- a/test/responses.spec.js +++ b/test/responses.spec.js @@ -1,11 +1,13 @@ +// @flow const assert = require('assert'); const path = require('path'); const appRootDir = require('app-root-dir'); +const { describe, it, beforeEach, afterEach } = require('mocha'); // HACK for Flow const sinon = require('sinon'); const responses = require('../src/responses'); -const Text = responses.Text; +const { Image, Text } = responses; describe('Responses', () => { @@ -42,9 +44,9 @@ describe('Responses', () => { }); describe('Text', () => { - it('constructs something', () => { + it('constructs a text object', () => { const text = new Text('corgi'); - assert.ok(text.text); + assert.deepEqual(text, { text: 'corgi' }); }); it('constructor saves original text on codetext property', () => { @@ -92,5 +94,39 @@ describe('Responses', () => { const text = new Text('tmn', 'Turtles'); assert.strictEqual(text.text, 'tmn Turtles'); }); + + describe('quickReplies', () => { + it('adds .quick_replies property', () => { + const text = new Text('corgi'); + text.quickReplies([{ content_type: 'location' }]); + + assert.deepEqual(text, { text: 'corgi', quick_replies: [{ content_type: 'location' }] }); + }); + + it('is chainable', () => { + const text = new Text('corgi').quickReplies([{ content_type: 'location' }]); + + assert.deepEqual(text, { text: 'corgi', quick_replies: [{ content_type: 'location' }] }); + }); + }); + }); + + describe('Image', () => { + describe('constructor', () => { + it('creates an image attachment', () => { + const image = new Image('https://i.imgur.com/bLV8BPS.jpg'); + + assert.deepEqual(image, { attachment: { payload: { url: 'https://i.imgur.com/bLV8BPS.jpg' }, type: 'image' } }); + }); + }); + + describe('quickReplies', () => { + it('adds chainable .quick_replies property', () => { + const image = new Image('https://i.imgur.com/bLV8BPS.jpg') + .quickReplies([{ content_type: 'location' }]); + + assert.deepEqual(image.quick_replies, [{ content_type: 'location' }]); + }); + }); }); });