├── .gitignore ├── LICENSE ├── README.md ├── config └── config.json ├── index.js ├── package-lock.json ├── package.json └── src ├── pouchDB.js └── puppeteer.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | images/ 39 | 40 | # Typescript v1 declaration files 41 | typings/ 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # Optional eslint cache 47 | .eslintcache 48 | 49 | # Optional REPL history 50 | .node_repl_history 51 | 52 | # Output of 'npm pack' 53 | *.tgz 54 | 55 | # Yarn Integrity file 56 | .yarn-integrity 57 | 58 | # dotenv environment variables file 59 | .env 60 | 61 | # next.js build output 62 | .next 63 | 64 | # idea 65 | .idea/ 66 | 67 | # db 68 | follows/ 69 | followsArchive/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Nicolas Lierman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node-puppeteer-instagram-bot 2 | A simple Node.js Instagram Bot using [Puppeteer.js](https://github.com/GoogleChrome/puppeteer) 3 | 4 | This Instagram Bot will authenticate and login into your Instagram account. By providing a number of hashtags it creates engagement by liking posts and following users. 5 | It uses [PouchDB](https://pouchdb.com/) as a local database to keep track of the users you are following and can unfollow users after a specific amount of days. 6 | 7 | ## How to run the bot 8 | * Download or clone this repo. 9 | * Run *npm install* to install libraries. 10 | * Update the *config.json* file with your credentials and hashtags. 11 | * Run *node index.js*. 12 | 13 | ## In depth guide 14 | A complete guide on how the bot works is [available here](https://glamdevhero.com/2018/07/12/how-to-create-instagram-bot-node-puppeteer/). 15 | 16 | ## Additional info 17 | * This bot does not support two-factor authentication. 18 | * This bot relies on css selectors to navigate the Instagram website. These selectors are defined in the *config.json*. Once in a while Instagram pushes a new design and the selectors need to be updated. There's no guarantee this repo will always have the latest selectors. 19 | * Use responsibly, running this bot 24/24 is not a good idea and will get your account suspended or banned. 20 | -------------------------------------------------------------------------------- /config/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "username": "YOUR USERNAME", 3 | "password": "YOUR PASSWORD", 4 | "hashtags": [ 5 | "love", "instagood", "me", "photooftheday", "instamood", "instadaily", "summer", "smile", "pretty", "food", 6 | "funny", "beach", "bored", "life", "cool", "art", "sunset", "family", "followback" 7 | ], 8 | "settings": { 9 | "run_every_x_hours": 1, 10 | "like_ratio": 0.75, 11 | "follow_ratio": 0.25, 12 | "do_unfollows": true, 13 | "unfollow_after_days": 2, 14 | "headless": true 15 | }, 16 | "selectors": { 17 | "home_to_login_button": ".izU2O a", 18 | "username_field": "input[type=\"text\"]", 19 | "password_field": "input[type=\"password\"]", 20 | "login_button": ".L3NKy", 21 | "post_heart_grey": "span.glyphsSpriteHeart__outline__24__grey_9", 22 | "post_username": "div.e1e1d > h2 > a", 23 | "post_follow_link": "div.bY2yH > button", 24 | "post_like_button": "span.fr66n > button", 25 | "post_follow_button": "span.oW_lN._1OSdk > button", 26 | "post_close_button": "button.ckWGn", 27 | "user_unfollow_button": "span > button", 28 | "user_unfollow_confirm_button": "div.mt3GC > button.aOOlW.-Cab_" 29 | } 30 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | let bot = require('./src/puppeteer'); 2 | let cnf = require('./config/config.json'); 3 | 4 | bot(); 5 | setInterval(bot, cnf.settings.run_every_x_hours * 3600000); 6 | 7 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "insta-node-bot", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abstract-leveldown": { 8 | "version": "4.0.3", 9 | "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-4.0.3.tgz", 10 | "integrity": "sha512-qsIHFQy0u17JqSY+3ZUT+ykqxYY17yOfvAsLkFkw8kSQqi05d1jyj0bCuSX6sjYlXuY9cKpgUt5EudQdP4aXyA==", 11 | "requires": { 12 | "xtend": "~4.0.0" 13 | } 14 | }, 15 | "agent-base": { 16 | "version": "4.2.1", 17 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", 18 | "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", 19 | "requires": { 20 | "es6-promisify": "^5.0.0" 21 | } 22 | }, 23 | "ansi-regex": { 24 | "version": "2.1.1", 25 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 26 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 27 | }, 28 | "aproba": { 29 | "version": "1.2.0", 30 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 31 | "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" 32 | }, 33 | "are-we-there-yet": { 34 | "version": "1.1.5", 35 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", 36 | "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", 37 | "requires": { 38 | "delegates": "^1.0.0", 39 | "readable-stream": "^2.0.6" 40 | } 41 | }, 42 | "argsarray": { 43 | "version": "0.0.1", 44 | "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz", 45 | "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs=" 46 | }, 47 | "async-limiter": { 48 | "version": "1.0.0", 49 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", 50 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" 51 | }, 52 | "balanced-match": { 53 | "version": "1.0.0", 54 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 55 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 56 | }, 57 | "bindings": { 58 | "version": "1.3.0", 59 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", 60 | "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" 61 | }, 62 | "bl": { 63 | "version": "1.2.2", 64 | "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", 65 | "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", 66 | "requires": { 67 | "readable-stream": "^2.3.5", 68 | "safe-buffer": "^5.1.1" 69 | } 70 | }, 71 | "brace-expansion": { 72 | "version": "1.1.11", 73 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 74 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 75 | "requires": { 76 | "balanced-match": "^1.0.0", 77 | "concat-map": "0.0.1" 78 | } 79 | }, 80 | "buffer-alloc": { 81 | "version": "1.2.0", 82 | "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", 83 | "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", 84 | "requires": { 85 | "buffer-alloc-unsafe": "^1.1.0", 86 | "buffer-fill": "^1.0.0" 87 | } 88 | }, 89 | "buffer-alloc-unsafe": { 90 | "version": "1.1.0", 91 | "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", 92 | "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" 93 | }, 94 | "buffer-fill": { 95 | "version": "1.0.0", 96 | "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", 97 | "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" 98 | }, 99 | "buffer-from": { 100 | "version": "1.1.0", 101 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", 102 | "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==" 103 | }, 104 | "chownr": { 105 | "version": "1.0.1", 106 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", 107 | "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" 108 | }, 109 | "clone-buffer": { 110 | "version": "1.0.0", 111 | "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", 112 | "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" 113 | }, 114 | "code-point-at": { 115 | "version": "1.1.0", 116 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 117 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 118 | }, 119 | "concat-map": { 120 | "version": "0.0.1", 121 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 122 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 123 | }, 124 | "concat-stream": { 125 | "version": "1.6.2", 126 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 127 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 128 | "requires": { 129 | "buffer-from": "^1.0.0", 130 | "inherits": "^2.0.3", 131 | "readable-stream": "^2.2.2", 132 | "typedarray": "^0.0.6" 133 | } 134 | }, 135 | "console-control-strings": { 136 | "version": "1.1.0", 137 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 138 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" 139 | }, 140 | "core-util-is": { 141 | "version": "1.0.2", 142 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 143 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 144 | }, 145 | "debug": { 146 | "version": "3.1.0", 147 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 148 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 149 | "requires": { 150 | "ms": "2.0.0" 151 | } 152 | }, 153 | "decompress-response": { 154 | "version": "3.3.0", 155 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", 156 | "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", 157 | "requires": { 158 | "mimic-response": "^1.0.0" 159 | } 160 | }, 161 | "deep-extend": { 162 | "version": "0.6.0", 163 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 164 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" 165 | }, 166 | "deferred-leveldown": { 167 | "version": "3.0.0", 168 | "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-3.0.0.tgz", 169 | "integrity": "sha512-ajbXqRPMXRlcdyt0TuWqknOJkp1JgQjGB7xOl2V+ebol7/U11E9h3/nCZAtN1M7djmAJEIhypCUc1tIWxdQAuQ==", 170 | "requires": { 171 | "abstract-leveldown": "~4.0.0" 172 | } 173 | }, 174 | "delegates": { 175 | "version": "1.0.0", 176 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 177 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" 178 | }, 179 | "detect-libc": { 180 | "version": "1.0.3", 181 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", 182 | "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" 183 | }, 184 | "double-ended-queue": { 185 | "version": "2.1.0-0", 186 | "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", 187 | "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" 188 | }, 189 | "encoding-down": { 190 | "version": "4.0.1", 191 | "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-4.0.1.tgz", 192 | "integrity": "sha512-AlSE+ugBIpLL0i9if2SlnOZ4oWj/XvBb8tw2Ie/pFB73vdYs5O/6plRyqIgjbZbz8onaL20AAuMP87LWbP56IQ==", 193 | "requires": { 194 | "abstract-leveldown": "^4.0.0", 195 | "level-codec": "^8.0.0", 196 | "level-errors": "^1.0.4", 197 | "xtend": "^4.0.1" 198 | }, 199 | "dependencies": { 200 | "level-codec": { 201 | "version": "8.0.0", 202 | "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-8.0.0.tgz", 203 | "integrity": "sha512-gNZlo1HRHz0BWxzGCyNf7xntAs2HKOPvvRBWtXsoDvEX4vMYnSTBS6ZnxoaiX7nhxSBPpegRa8CQ/hnfGBKk3Q==" 204 | } 205 | } 206 | }, 207 | "end-of-stream": { 208 | "version": "1.4.1", 209 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", 210 | "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", 211 | "requires": { 212 | "once": "^1.4.0" 213 | } 214 | }, 215 | "end-stream": { 216 | "version": "0.1.0", 217 | "resolved": "https://registry.npmjs.org/end-stream/-/end-stream-0.1.0.tgz", 218 | "integrity": "sha1-MgA/P0OKKwFDFoE3+PpumGbIHtU=", 219 | "requires": { 220 | "write-stream": "~0.4.3" 221 | } 222 | }, 223 | "errno": { 224 | "version": "0.1.7", 225 | "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", 226 | "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", 227 | "requires": { 228 | "prr": "~1.0.1" 229 | } 230 | }, 231 | "es6-denodeify": { 232 | "version": "0.1.5", 233 | "resolved": "https://registry.npmjs.org/es6-denodeify/-/es6-denodeify-0.1.5.tgz", 234 | "integrity": "sha1-MdTV/pxVA+ElRgQ5MQ4WoqPznB8=" 235 | }, 236 | "es6-promise": { 237 | "version": "4.2.4", 238 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", 239 | "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==" 240 | }, 241 | "es6-promisify": { 242 | "version": "5.0.0", 243 | "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", 244 | "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", 245 | "requires": { 246 | "es6-promise": "^4.0.3" 247 | } 248 | }, 249 | "expand-template": { 250 | "version": "1.1.1", 251 | "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.1.tgz", 252 | "integrity": "sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg==" 253 | }, 254 | "extract-zip": { 255 | "version": "1.6.7", 256 | "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", 257 | "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", 258 | "requires": { 259 | "concat-stream": "1.6.2", 260 | "debug": "2.6.9", 261 | "mkdirp": "0.5.1", 262 | "yauzl": "2.4.1" 263 | }, 264 | "dependencies": { 265 | "debug": { 266 | "version": "2.6.9", 267 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 268 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 269 | "requires": { 270 | "ms": "2.0.0" 271 | } 272 | } 273 | } 274 | }, 275 | "fast-future": { 276 | "version": "1.0.2", 277 | "resolved": "https://registry.npmjs.org/fast-future/-/fast-future-1.0.2.tgz", 278 | "integrity": "sha1-hDWpqqAteSSNF9cE52JZMB2ZKAo=" 279 | }, 280 | "fd-slicer": { 281 | "version": "1.0.1", 282 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", 283 | "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", 284 | "requires": { 285 | "pend": "~1.2.0" 286 | } 287 | }, 288 | "fetch-cookie": { 289 | "version": "0.7.0", 290 | "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.7.0.tgz", 291 | "integrity": "sha512-Mm5pGlT3agW6t71xVM7vMZPIvI7T4FaTuFW4jari6dVzYHFDb3WZZsGpN22r/o3XMdkM0E7sPd1EGeyVbH2Tgg==", 292 | "requires": { 293 | "es6-denodeify": "^0.1.1", 294 | "tough-cookie": "^2.3.1" 295 | } 296 | }, 297 | "fs-constants": { 298 | "version": "1.0.0", 299 | "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", 300 | "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" 301 | }, 302 | "fs.realpath": { 303 | "version": "1.0.0", 304 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 305 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 306 | }, 307 | "gauge": { 308 | "version": "2.7.4", 309 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", 310 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", 311 | "requires": { 312 | "aproba": "^1.0.3", 313 | "console-control-strings": "^1.0.0", 314 | "has-unicode": "^2.0.0", 315 | "object-assign": "^4.1.0", 316 | "signal-exit": "^3.0.0", 317 | "string-width": "^1.0.1", 318 | "strip-ansi": "^3.0.1", 319 | "wide-align": "^1.1.0" 320 | } 321 | }, 322 | "github-from-package": { 323 | "version": "0.0.0", 324 | "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", 325 | "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" 326 | }, 327 | "glob": { 328 | "version": "7.1.2", 329 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 330 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 331 | "requires": { 332 | "fs.realpath": "^1.0.0", 333 | "inflight": "^1.0.4", 334 | "inherits": "2", 335 | "minimatch": "^3.0.4", 336 | "once": "^1.3.0", 337 | "path-is-absolute": "^1.0.0" 338 | } 339 | }, 340 | "has-unicode": { 341 | "version": "2.0.1", 342 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 343 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" 344 | }, 345 | "https-proxy-agent": { 346 | "version": "2.2.1", 347 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", 348 | "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", 349 | "requires": { 350 | "agent-base": "^4.1.0", 351 | "debug": "^3.1.0" 352 | } 353 | }, 354 | "immediate": { 355 | "version": "3.0.6", 356 | "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", 357 | "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" 358 | }, 359 | "inflight": { 360 | "version": "1.0.6", 361 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 362 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 363 | "requires": { 364 | "once": "^1.3.0", 365 | "wrappy": "1" 366 | } 367 | }, 368 | "inherits": { 369 | "version": "2.0.3", 370 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 371 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 372 | }, 373 | "ini": { 374 | "version": "1.3.5", 375 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 376 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" 377 | }, 378 | "is-fullwidth-code-point": { 379 | "version": "1.0.0", 380 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 381 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 382 | "requires": { 383 | "number-is-nan": "^1.0.0" 384 | } 385 | }, 386 | "isarray": { 387 | "version": "1.0.0", 388 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 389 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 390 | }, 391 | "level": { 392 | "version": "3.0.2", 393 | "resolved": "https://registry.npmjs.org/level/-/level-3.0.2.tgz", 394 | "integrity": "sha512-2qYbbiptPsPWGUI+AgB1gTNXqIjPpALRqrQyNx1zWYNZxhhuzEj/IE4Unu9weEBnsUEocfYe56xOGlAceb8/Fg==", 395 | "requires": { 396 | "level-packager": "^2.0.2", 397 | "leveldown": "^3.0.0", 398 | "opencollective-postinstall": "^2.0.0" 399 | } 400 | }, 401 | "level-codec": { 402 | "version": "7.0.1", 403 | "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", 404 | "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==" 405 | }, 406 | "level-errors": { 407 | "version": "1.1.2", 408 | "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.1.2.tgz", 409 | "integrity": "sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w==", 410 | "requires": { 411 | "errno": "~0.1.1" 412 | } 413 | }, 414 | "level-iterator-stream": { 415 | "version": "2.0.3", 416 | "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz", 417 | "integrity": "sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig==", 418 | "requires": { 419 | "inherits": "^2.0.1", 420 | "readable-stream": "^2.0.5", 421 | "xtend": "^4.0.0" 422 | } 423 | }, 424 | "level-packager": { 425 | "version": "2.1.1", 426 | "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-2.1.1.tgz", 427 | "integrity": "sha512-6l3G6dVkmdvHwOJrEA9d9hL6SSFrzwjQoLP8HsvohOgfY/8Z9LyTKNCM5Gc84wtsUWCuIHu6r+S6WrCtTWUJCw==", 428 | "requires": { 429 | "encoding-down": "~4.0.0", 430 | "levelup": "^2.0.0" 431 | }, 432 | "dependencies": { 433 | "levelup": { 434 | "version": "2.0.2", 435 | "resolved": "https://registry.npmjs.org/levelup/-/levelup-2.0.2.tgz", 436 | "integrity": "sha512-us+nTLUyd/eLnclYYddOCdAVw1hnymGx/9p4Jr5ThohStsjLqMVmbYiz6/SYFZEPXNF+AKQSvh6fA2e2KZpC8w==", 437 | "requires": { 438 | "deferred-leveldown": "~3.0.0", 439 | "level-errors": "~1.1.0", 440 | "level-iterator-stream": "~2.0.0", 441 | "xtend": "~4.0.0" 442 | } 443 | } 444 | } 445 | }, 446 | "level-write-stream": { 447 | "version": "1.0.0", 448 | "resolved": "https://registry.npmjs.org/level-write-stream/-/level-write-stream-1.0.0.tgz", 449 | "integrity": "sha1-P3+7Z5pVE3wP6zA97nZuEu4Twdw=", 450 | "requires": { 451 | "end-stream": "~0.1.0" 452 | } 453 | }, 454 | "leveldown": { 455 | "version": "3.0.0", 456 | "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-3.0.0.tgz", 457 | "integrity": "sha512-CA2mRUDTgVscTDOCvHSgYvksqj1VW7g3ss2idWfITSB7l201ahQJ81cwLTupW76idbjpx7zmmmpdttYnnHWWtA==", 458 | "requires": { 459 | "abstract-leveldown": "~4.0.0", 460 | "bindings": "~1.3.0", 461 | "fast-future": "~1.0.2", 462 | "nan": "~2.8.0", 463 | "prebuild-install": "^2.1.0" 464 | } 465 | }, 466 | "levelup": { 467 | "version": "3.0.1", 468 | "resolved": "https://registry.npmjs.org/levelup/-/levelup-3.0.1.tgz", 469 | "integrity": "sha512-TrrLDPC/BfP35ei2uK+L6Cc7kpI1NxIChwp+BUB6jrHG3A8gtrr9jx1UZ9bi2w1O6VN7jYO4LUoq1iKRP5AREg==", 470 | "requires": { 471 | "deferred-leveldown": "~4.0.0", 472 | "level-errors": "~2.0.0", 473 | "level-iterator-stream": "~2.0.0", 474 | "xtend": "~4.0.0" 475 | }, 476 | "dependencies": { 477 | "abstract-leveldown": { 478 | "version": "5.0.0", 479 | "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", 480 | "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", 481 | "requires": { 482 | "xtend": "~4.0.0" 483 | } 484 | }, 485 | "deferred-leveldown": { 486 | "version": "4.0.2", 487 | "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz", 488 | "integrity": "sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww==", 489 | "requires": { 490 | "abstract-leveldown": "~5.0.0", 491 | "inherits": "^2.0.3" 492 | } 493 | }, 494 | "level-errors": { 495 | "version": "2.0.0", 496 | "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.0.tgz", 497 | "integrity": "sha512-AmY4HCp9h3OiU19uG+3YWkdELgy05OTP/r23aNHaQKWv8DO787yZgsEuGVkoph40uwN+YdUKnANlrxSsoOaaxg==", 498 | "requires": { 499 | "errno": "~0.1.1" 500 | } 501 | } 502 | } 503 | }, 504 | "ltgt": { 505 | "version": "2.2.1", 506 | "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", 507 | "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" 508 | }, 509 | "mime": { 510 | "version": "2.3.1", 511 | "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", 512 | "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==" 513 | }, 514 | "mimic-response": { 515 | "version": "1.0.0", 516 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", 517 | "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=" 518 | }, 519 | "minimatch": { 520 | "version": "3.0.4", 521 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 522 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 523 | "requires": { 524 | "brace-expansion": "^1.1.7" 525 | } 526 | }, 527 | "minimist": { 528 | "version": "0.0.8", 529 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 530 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 531 | }, 532 | "mkdirp": { 533 | "version": "0.5.1", 534 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 535 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 536 | "requires": { 537 | "minimist": "0.0.8" 538 | } 539 | }, 540 | "ms": { 541 | "version": "2.0.0", 542 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 543 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 544 | }, 545 | "nan": { 546 | "version": "2.8.0", 547 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", 548 | "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=" 549 | }, 550 | "node-abi": { 551 | "version": "2.4.3", 552 | "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.3.tgz", 553 | "integrity": "sha512-b656V5C0628gOOA2kwcpNA/bxdlqYF9FvxJ+qqVX0ctdXNVZpS8J6xEUYir3WAKc7U0BH/NRlSpNbGsy+azjeg==", 554 | "requires": { 555 | "semver": "^5.4.1" 556 | } 557 | }, 558 | "node-fetch": { 559 | "version": "2.1.2", 560 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", 561 | "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" 562 | }, 563 | "noop-logger": { 564 | "version": "0.1.1", 565 | "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", 566 | "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" 567 | }, 568 | "npmlog": { 569 | "version": "4.1.2", 570 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", 571 | "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", 572 | "requires": { 573 | "are-we-there-yet": "~1.1.2", 574 | "console-control-strings": "~1.1.0", 575 | "gauge": "~2.7.3", 576 | "set-blocking": "~2.0.0" 577 | } 578 | }, 579 | "number-is-nan": { 580 | "version": "1.0.1", 581 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 582 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 583 | }, 584 | "object-assign": { 585 | "version": "4.1.1", 586 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 587 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 588 | }, 589 | "once": { 590 | "version": "1.4.0", 591 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 592 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 593 | "requires": { 594 | "wrappy": "1" 595 | } 596 | }, 597 | "opencollective-postinstall": { 598 | "version": "2.0.0", 599 | "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.0.tgz", 600 | "integrity": "sha512-XAe80GycLe2yRGnJsUtt+EO5lk06XYRQt4kJJe53O2kJHPZJOZ+XMF/b47HW96e6LhfKVpwnXVr/s56jhV98jg==" 601 | }, 602 | "os-homedir": { 603 | "version": "1.0.2", 604 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", 605 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" 606 | }, 607 | "path-is-absolute": { 608 | "version": "1.0.1", 609 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 610 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 611 | }, 612 | "pend": { 613 | "version": "1.2.0", 614 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 615 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" 616 | }, 617 | "pouchdb": { 618 | "version": "7.0.0", 619 | "resolved": "https://registry.npmjs.org/pouchdb/-/pouchdb-7.0.0.tgz", 620 | "integrity": "sha512-vVZyn6SmVxYLbUmzQwU5nW1APIq/sAJ13DlYZqIJRJUUUtGy3X0F79G9/3d9StvJwfWBA/aMGPnRV2eQAp+MKA==", 621 | "requires": { 622 | "argsarray": "0.0.1", 623 | "buffer-from": "1.1.0", 624 | "clone-buffer": "1.0.0", 625 | "double-ended-queue": "2.1.0-0", 626 | "fetch-cookie": "0.7.0", 627 | "immediate": "3.0.6", 628 | "inherits": "2.0.3", 629 | "level": "3.0.2", 630 | "level-codec": "7.0.1", 631 | "level-write-stream": "1.0.0", 632 | "leveldown": "3.0.0", 633 | "levelup": "3.0.1", 634 | "ltgt": "2.2.1", 635 | "node-fetch": "^2.0.0", 636 | "readable-stream": "1.0.33", 637 | "spark-md5": "3.0.0", 638 | "through2": "2.0.3", 639 | "uuid": "3.2.1", 640 | "vuvuzela": "1.0.3" 641 | }, 642 | "dependencies": { 643 | "isarray": { 644 | "version": "0.0.1", 645 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 646 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 647 | }, 648 | "readable-stream": { 649 | "version": "1.0.33", 650 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", 651 | "integrity": "sha1-OjYN1mwbHX/UcFOJhg7aHQ9hEmw=", 652 | "requires": { 653 | "core-util-is": "~1.0.0", 654 | "inherits": "~2.0.1", 655 | "isarray": "0.0.1", 656 | "string_decoder": "~0.10.x" 657 | } 658 | }, 659 | "string_decoder": { 660 | "version": "0.10.31", 661 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 662 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 663 | } 664 | } 665 | }, 666 | "prebuild-install": { 667 | "version": "2.5.3", 668 | "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.5.3.tgz", 669 | "integrity": "sha512-/rI36cN2g7vDQnKWN8Uzupi++KjyqS9iS+/fpwG4Ea8d0Pip0PQ5bshUNzVwt+/D2MRfhVAplYMMvWLqWrCF/g==", 670 | "requires": { 671 | "detect-libc": "^1.0.3", 672 | "expand-template": "^1.0.2", 673 | "github-from-package": "0.0.0", 674 | "minimist": "^1.2.0", 675 | "mkdirp": "^0.5.1", 676 | "node-abi": "^2.2.0", 677 | "noop-logger": "^0.1.1", 678 | "npmlog": "^4.0.1", 679 | "os-homedir": "^1.0.1", 680 | "pump": "^2.0.1", 681 | "rc": "^1.1.6", 682 | "simple-get": "^2.7.0", 683 | "tar-fs": "^1.13.0", 684 | "tunnel-agent": "^0.6.0", 685 | "which-pm-runs": "^1.0.0" 686 | }, 687 | "dependencies": { 688 | "minimist": { 689 | "version": "1.2.0", 690 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 691 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 692 | } 693 | } 694 | }, 695 | "process-nextick-args": { 696 | "version": "2.0.0", 697 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 698 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" 699 | }, 700 | "progress": { 701 | "version": "2.0.0", 702 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", 703 | "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=" 704 | }, 705 | "proxy-from-env": { 706 | "version": "1.0.0", 707 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", 708 | "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=" 709 | }, 710 | "prr": { 711 | "version": "1.0.1", 712 | "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", 713 | "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" 714 | }, 715 | "psl": { 716 | "version": "1.1.28", 717 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.28.tgz", 718 | "integrity": "sha512-+AqO1Ae+N/4r7Rvchrdm432afjT9hqJRyBN3DQv9At0tPz4hIFSGKbq64fN9dVoCow4oggIIax5/iONx0r9hZw==" 719 | }, 720 | "pump": { 721 | "version": "2.0.1", 722 | "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", 723 | "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", 724 | "requires": { 725 | "end-of-stream": "^1.1.0", 726 | "once": "^1.3.1" 727 | } 728 | }, 729 | "punycode": { 730 | "version": "1.4.1", 731 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 732 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 733 | }, 734 | "puppeteer": { 735 | "version": "1.5.0", 736 | "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.5.0.tgz", 737 | "integrity": "sha512-eELwFtFxL+uhmg4jPZOZXzSrPEYy4CaYQNbcchBbfxY+KjMpnv6XGf/aYWaQG49OTpfi2/DMziXtDM8XuJgoUA==", 738 | "requires": { 739 | "debug": "^3.1.0", 740 | "extract-zip": "^1.6.6", 741 | "https-proxy-agent": "^2.2.1", 742 | "mime": "^2.0.3", 743 | "progress": "^2.0.0", 744 | "proxy-from-env": "^1.0.0", 745 | "rimraf": "^2.6.1", 746 | "ws": "^5.1.1" 747 | } 748 | }, 749 | "rc": { 750 | "version": "1.2.8", 751 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 752 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 753 | "requires": { 754 | "deep-extend": "^0.6.0", 755 | "ini": "~1.3.0", 756 | "minimist": "^1.2.0", 757 | "strip-json-comments": "~2.0.1" 758 | }, 759 | "dependencies": { 760 | "minimist": { 761 | "version": "1.2.0", 762 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 763 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 764 | } 765 | } 766 | }, 767 | "readable-stream": { 768 | "version": "2.3.6", 769 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 770 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 771 | "requires": { 772 | "core-util-is": "~1.0.0", 773 | "inherits": "~2.0.3", 774 | "isarray": "~1.0.0", 775 | "process-nextick-args": "~2.0.0", 776 | "safe-buffer": "~5.1.1", 777 | "string_decoder": "~1.1.1", 778 | "util-deprecate": "~1.0.1" 779 | } 780 | }, 781 | "rimraf": { 782 | "version": "2.6.2", 783 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 784 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 785 | "requires": { 786 | "glob": "^7.0.5" 787 | } 788 | }, 789 | "safe-buffer": { 790 | "version": "5.1.2", 791 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 792 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 793 | }, 794 | "semver": { 795 | "version": "5.5.0", 796 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", 797 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" 798 | }, 799 | "set-blocking": { 800 | "version": "2.0.0", 801 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 802 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" 803 | }, 804 | "shuffle-array": { 805 | "version": "1.0.1", 806 | "resolved": "https://registry.npmjs.org/shuffle-array/-/shuffle-array-1.0.1.tgz", 807 | "integrity": "sha1-xP88/nTRb5NzBZIwGyXmV3sSiYs=" 808 | }, 809 | "signal-exit": { 810 | "version": "3.0.2", 811 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 812 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 813 | }, 814 | "simple-concat": { 815 | "version": "1.0.0", 816 | "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", 817 | "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" 818 | }, 819 | "simple-get": { 820 | "version": "2.8.1", 821 | "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", 822 | "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", 823 | "requires": { 824 | "decompress-response": "^3.3.0", 825 | "once": "^1.3.1", 826 | "simple-concat": "^1.0.0" 827 | } 828 | }, 829 | "spark-md5": { 830 | "version": "3.0.0", 831 | "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.0.tgz", 832 | "integrity": "sha1-NyIifFTi+vJLHcbZM8wUTm9xv+8=" 833 | }, 834 | "string-width": { 835 | "version": "1.0.2", 836 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 837 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 838 | "requires": { 839 | "code-point-at": "^1.0.0", 840 | "is-fullwidth-code-point": "^1.0.0", 841 | "strip-ansi": "^3.0.0" 842 | } 843 | }, 844 | "string_decoder": { 845 | "version": "1.1.1", 846 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 847 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 848 | "requires": { 849 | "safe-buffer": "~5.1.0" 850 | } 851 | }, 852 | "strip-ansi": { 853 | "version": "3.0.1", 854 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 855 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 856 | "requires": { 857 | "ansi-regex": "^2.0.0" 858 | } 859 | }, 860 | "strip-json-comments": { 861 | "version": "2.0.1", 862 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 863 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 864 | }, 865 | "tar-fs": { 866 | "version": "1.16.3", 867 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", 868 | "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", 869 | "requires": { 870 | "chownr": "^1.0.1", 871 | "mkdirp": "^0.5.1", 872 | "pump": "^1.0.0", 873 | "tar-stream": "^1.1.2" 874 | }, 875 | "dependencies": { 876 | "pump": { 877 | "version": "1.0.3", 878 | "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", 879 | "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", 880 | "requires": { 881 | "end-of-stream": "^1.1.0", 882 | "once": "^1.3.1" 883 | } 884 | } 885 | } 886 | }, 887 | "tar-stream": { 888 | "version": "1.6.1", 889 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", 890 | "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", 891 | "requires": { 892 | "bl": "^1.0.0", 893 | "buffer-alloc": "^1.1.0", 894 | "end-of-stream": "^1.0.0", 895 | "fs-constants": "^1.0.0", 896 | "readable-stream": "^2.3.0", 897 | "to-buffer": "^1.1.0", 898 | "xtend": "^4.0.0" 899 | } 900 | }, 901 | "through2": { 902 | "version": "2.0.3", 903 | "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", 904 | "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", 905 | "requires": { 906 | "readable-stream": "^2.1.5", 907 | "xtend": "~4.0.1" 908 | } 909 | }, 910 | "to-buffer": { 911 | "version": "1.1.1", 912 | "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", 913 | "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" 914 | }, 915 | "tough-cookie": { 916 | "version": "2.4.3", 917 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 918 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 919 | "requires": { 920 | "psl": "^1.1.24", 921 | "punycode": "^1.4.1" 922 | } 923 | }, 924 | "tunnel-agent": { 925 | "version": "0.6.0", 926 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 927 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 928 | "requires": { 929 | "safe-buffer": "^5.0.1" 930 | } 931 | }, 932 | "typedarray": { 933 | "version": "0.0.6", 934 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 935 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" 936 | }, 937 | "util-deprecate": { 938 | "version": "1.0.2", 939 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 940 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 941 | }, 942 | "uuid": { 943 | "version": "3.2.1", 944 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", 945 | "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" 946 | }, 947 | "vuvuzela": { 948 | "version": "1.0.3", 949 | "resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz", 950 | "integrity": "sha1-O+FF5YJxxzylUnndhR8SpoIRSws=" 951 | }, 952 | "which-pm-runs": { 953 | "version": "1.0.0", 954 | "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", 955 | "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" 956 | }, 957 | "wide-align": { 958 | "version": "1.1.3", 959 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 960 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 961 | "requires": { 962 | "string-width": "^1.0.2 || 2" 963 | } 964 | }, 965 | "wrappy": { 966 | "version": "1.0.2", 967 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 968 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 969 | }, 970 | "write-stream": { 971 | "version": "0.4.3", 972 | "resolved": "https://registry.npmjs.org/write-stream/-/write-stream-0.4.3.tgz", 973 | "integrity": "sha1-g8yMA0fQr2BXqThitOOuAd5cgcE=", 974 | "requires": { 975 | "readable-stream": "~0.0.2" 976 | }, 977 | "dependencies": { 978 | "readable-stream": { 979 | "version": "0.0.4", 980 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-0.0.4.tgz", 981 | "integrity": "sha1-8y124/uGM0SlSNeZIwBxc2ZbO40=" 982 | } 983 | } 984 | }, 985 | "ws": { 986 | "version": "5.2.1", 987 | "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.1.tgz", 988 | "integrity": "sha512-2NkHdPKjDBj3CHdnAGNpmlliryKqF+n9MYXX7/wsVC4yqYocKreKNjydPDvT3wShAZnndlM0RytEfTALCDvz7A==", 989 | "requires": { 990 | "async-limiter": "~1.0.0" 991 | } 992 | }, 993 | "xtend": { 994 | "version": "4.0.1", 995 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 996 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" 997 | }, 998 | "yauzl": { 999 | "version": "2.4.1", 1000 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", 1001 | "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", 1002 | "requires": { 1003 | "fd-slicer": "~1.0.1" 1004 | } 1005 | } 1006 | } 1007 | } 1008 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "insta-node-bot", 3 | "version": "1.0.0", 4 | "description": "Instagram bot with Node.js and Puppeteer", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "author": "Nicolas Lierman", 10 | "license": "ISC", 11 | "dependencies": { 12 | "pouchdb": "^7.0.0", 13 | "puppeteer": "^1.5.0", 14 | "shuffle-array": "^1.0.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/pouchDB.js: -------------------------------------------------------------------------------- 1 | let PouchDB = require('pouchdb'); 2 | 3 | let db = new PouchDB('follows'); 4 | let db_archive = new PouchDB('followsArchive'); 5 | 6 | let addFollow = async function (username) { 7 | return db.put({_id: username, added: new Date().getTime()}); 8 | }; 9 | 10 | let getFollows = async function () { 11 | return db.allDocs({include_docs: true}); 12 | }; 13 | 14 | let unFollow = async function (username) { 15 | return new Promise(function (resolve, reject) { 16 | db.get(username).then(doc => { 17 | return db.remove(doc); 18 | }).then(() => { 19 | return db_archive.put({_id: username}); 20 | }).then(() => { 21 | resolve(true); 22 | }).catch(e => reject(e)); 23 | }); 24 | }; 25 | 26 | let inArchive = async function (username) { 27 | return db_archive.get(username); 28 | }; 29 | 30 | module.exports.addFollow = addFollow; 31 | module.exports.inArchive = inArchive; 32 | module.exports.getFollows = getFollows; 33 | module.exports.unFollow = unFollow; 34 | 35 | -------------------------------------------------------------------------------- /src/puppeteer.js: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer'); 2 | const shuffle = require('shuffle-array'); 3 | 4 | let ops = require('../src/pouchDB'); 5 | let cnf = require('../config/config.json'); 6 | 7 | let run = async function () { 8 | 9 | // set up Puppeteer 10 | const browser = await puppeteer.launch({ 11 | headless: cnf.settings.headless, 12 | args: ['--no-sandbox'] 13 | }); 14 | 15 | const page = await browser.newPage(); 16 | page.setViewport({width: 1200, height: 764}); 17 | 18 | // Load Instagram 19 | await page.goto('https://www.instagram.com'); 20 | await page.waitFor(2500); 21 | await page.click(cnf.selectors.home_to_login_button); 22 | await page.waitFor(2500); 23 | 24 | // Login 25 | await page.click(cnf.selectors.username_field); 26 | await page.keyboard.type(cnf.username); 27 | await page.click(cnf.selectors.password_field); 28 | await page.keyboard.type(cnf.password); 29 | 30 | await page.click(cnf.selectors.login_button); 31 | await page.waitForNavigation(); 32 | 33 | // Loop through shuffled hashtags 34 | let hashtags = shuffle(cnf.hashtags); 35 | 36 | for (let hl = 0; hl < hashtags.length; hl++) { 37 | 38 | // Search for hashtags 39 | await page.goto('https://www.instagram.com/explore/tags/' + hashtags[hl] + '/?hl=en'); 40 | console.log('===> hashtag search: ' + hashtags[hl]); 41 | 42 | // Loop through the latest 9 posts 43 | for (let r = 1; r < 4; r++) { 44 | for (let c = 1; c < 4; c++) { 45 | 46 | //Try to select post, wait, if successful continue 47 | let br = false; 48 | await page.click('section > main > article > div:nth-child(3) > div > div:nth-child(' + r + ') > div:nth-child(' + c +') > a').catch(() => { 49 | br = true; 50 | }); 51 | await page.waitFor(2250 + Math.floor(Math.random() * 250)); 52 | if (br) continue; 53 | 54 | // Get post info 55 | let hasEmptyHeart = await page.$(cnf.selectors.post_heart_grey); 56 | 57 | let username = await page.evaluate(x => { 58 | let element = document.querySelector(x); 59 | return Promise.resolve(element ? element.innerHTML : ''); 60 | }, cnf.selectors.post_username); 61 | 62 | let followStatus = await page.evaluate(x => { 63 | let element = document.querySelector(x); 64 | return Promise.resolve(element ? element.innerHTML : ''); 65 | }, cnf.selectors.post_follow_link); 66 | 67 | console.log('---> Evaluate post from ' + username); 68 | 69 | // Decide to like post 70 | if (hasEmptyHeart !== null && Math.random() < cnf.settings.like_ratio) { 71 | await page.click(cnf.selectors.post_like_button); 72 | console.log('---> like for ' + username); 73 | await page.waitFor(10000 + Math.floor(Math.random() * 5000)); 74 | } 75 | 76 | // Decide to follow user 77 | let isArchivedUser; 78 | await ops.inArchive(username).then(() => isArchivedUser = true).catch(() => isArchivedUser = false); 79 | 80 | if (followStatus === 'Follow' && !isArchivedUser && Math.random() < cnf.settings.follow_ratio) { 81 | await ops.addFollow(username).then(() => { 82 | return page.click(cnf.selectors.post_follow_link); 83 | }).then(() => { 84 | console.log('---> follow for ' + username); 85 | return page.waitFor(10000 + Math.floor(Math.random() * 5000)); 86 | }).catch(() => { 87 | console.log('---> Already following ' + username); 88 | }); 89 | } 90 | 91 | // Close post 92 | await page.click(cnf.selectors.post_close_button).catch(() => console.log(':::> Error closing post')); 93 | } 94 | } 95 | 96 | } 97 | 98 | // Unfollows 99 | if (cnf.settings.do_unfollows) { 100 | 101 | let cutoff = new Date().getTime() - (cnf.settings.unfollow_after_days * 86400000); 102 | let follows = await ops.getFollows(); 103 | let unfollows = []; 104 | 105 | follows.rows.forEach(user => { 106 | if (user.doc.added < cutoff) { 107 | unfollows.push(user.doc._id); 108 | } 109 | }); 110 | 111 | for (let n = 0; n < unfollows.length; n++) { 112 | 113 | let user = unfollows[n]; 114 | await page.goto('https://www.instagram.com/' + user + '/?hl=en'); 115 | await page.waitFor(1500 + Math.floor(Math.random() * 500)); 116 | 117 | let followStatus = await page.evaluate(x => { 118 | let element = document.querySelector(x); 119 | return Promise.resolve(element ? element.innerHTML : ''); 120 | }, cnf.selectors.user_unfollow_button); 121 | 122 | if (followStatus === 'Following') { 123 | console.log('---> unfollow ' + user); 124 | await page.click(cnf.selectors.user_unfollow_button); 125 | await page.waitFor(750); 126 | await page.click(cnf.selectors.user_unfollow_confirm_button); 127 | ops.unFollow(user); 128 | await page.waitFor(15000 + Math.floor(Math.random() * 5000)); 129 | } else { 130 | console.log('---> archive ' + user); 131 | ops.unFollow(user); 132 | } 133 | } 134 | 135 | } 136 | 137 | // Close browser 138 | browser.close(); 139 | 140 | }; 141 | 142 | module.exports = run; --------------------------------------------------------------------------------