{"id":13658528,"url":"https://github.com/macbre/nodemw","last_synced_at":"2025-05-15T09:05:27.651Z","repository":{"id":3832825,"uuid":"4914019","full_name":"macbre/nodemw","owner":"macbre","description":"MediaWiki API and WikiData client written in Node.js","archived":false,"fork":false,"pushed_at":"2025-05-14T21:12:59.000Z","size":2310,"stargazers_count":240,"open_issues_count":18,"forks_count":55,"subscribers_count":8,"default_branch":"devel","last_synced_at":"2025-05-15T09:05:17.743Z","etag":null,"topics":["bot","fandom-wiki","javascript","mediawiki","mediawiki-api","nodejs","nodemw","wikia-api","wikidata"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/nodemw","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/macbre.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2012-07-05T19:45:38.000Z","updated_at":"2025-05-14T21:13:01.000Z","dependencies_parsed_at":"2023-07-06T09:33:38.241Z","dependency_job_id":"25f1f019-672d-472e-91bf-aa7004ee5843","html_url":"https://github.com/macbre/nodemw","commit_stats":{"total_commits":848,"total_committers":38,"mean_commits":22.31578947368421,"dds":0.508254716981132,"last_synced_commit":"593cc5fbf14e0b797fe4ec2f2f82de40122912ff"},"previous_names":[],"tags_count":53,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macbre%2Fnodemw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macbre%2Fnodemw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macbre%2Fnodemw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/macbre%2Fnodemw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/macbre","download_url":"https://codeload.github.com/macbre/nodemw/tar.gz/refs/heads/devel","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254310513,"owners_count":22049468,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot","fandom-wiki","javascript","mediawiki","mediawiki-api","nodejs","nodemw","wikia-api","wikidata"],"created_at":"2024-08-02T05:01:00.394Z","updated_at":"2025-05-15T09:05:27.642Z","avatar_url":"https://github.com/macbre.png","language":"JavaScript","readme":"# nodemw\n\n![Node.js CI](https://github.com/macbre/nodemw/workflows/Node.js%20CI/badge.svg)\n[![Coverage Status](https://coveralls.io/repos/github/macbre/nodemw/badge.svg?branch=devel)](https://coveralls.io/github/macbre/nodemw?branch=devel)\n![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)\n\n[MediaWiki API](https://www.mediawiki.org/wiki/API:Main_page) client written in node.js\n\n## Requirements\n\n- At minimum [Node.js at the maintenance version](https://github.com/nodejs/release#release-schedule)\n\n## Installation\n\n### Using npm\n\n```bash\nnpm install nodemw\n```\n\nOr [Download the latest stable version](https://github.com/macbre/nodemw/releases) via GitHub.\n\n### Development version\n\n```bash\ngit clone https://github.com/macbre/nodemw.git\n```\n\n## Features\n\n- HTTP requests are stored in the queue and performed in parallel with limited number of \"threads\" (i.e. there's no risk of flooding the server)\n- articles creation / edit / move / delete\n- file uploads (using given content or via provided URL)\n- Special:Log processing\n- listing articles in categories\n- and much more\n- getting claims from [WikiData](https://www.wikidata.org/wiki/Wikidata:Introduction)\n\n## Where it's used\n\n- Over 25k edits on [Poznań Wiki](http://poznan.wikia.com) as [Pyrabot](http://poznan.wikia.com/wiki/Specjalna:Wkład/Pyrabot) - [scripts repository](https://github.com/macbre/pyrabot)\n\n## First script\n\nAn example script can be found in `/examples` directory.\n\n```bash\ncd examples\nnode pagesInCategory.js\n```\n\nYou can enter **debug mode** by setting `DEBUG` enviromental variable:\n\n```bash\nDEBUG=1 node examples/pagesInCategory.js\n```\n\nYou can enter **dry-run mode** (all \"write\" operations like edits and uploads will be disabled) by setting `DRY_RUN` environmental variable (or `dryRun` entry in the config):\n\n```bash\nDRY_RUN=1 node examples/pagesInCategory.js\n```\n\n## Running unit tests\n\n```bash\nnpm test\n```\n\n## How to use it?\n\n### Creating a bot instance\n\n```js\nvar bot = require(\"nodemw\");\n\n// pass configuration object\nvar client = new bot({\n  protocol: \"https\", // Wikipedia now enforces HTTPS\n  server: \"en.wikipedia.org\", // host name of MediaWiki-powered site\n  path: \"/w\", // path to api.php script\n  debug: false, // is more verbose when set to true\n});\n\nclient.getArticle(\"foo\", function (err, data) {\n  // error handling\n  if (err) {\n    console.error(err);\n    return;\n  }\n\n  // ...\n});\n```\n\n#### Config file\n\nnodemw can use config files as well as objects directly provided to `bot` object constructor.\n\n```js\n// read config from external file\nvar client = new bot(\"config.js\");\n```\n\nConfig file is a JSON-encoded object with the following fields (see `/examples/config-DIST.js` file):\n\n```js\n{\n      \"protocol\": \"https\",  // default to 'http'\n      \"server\": \"en.wikipedia.org\",  // host name of MediaWiki-powered site\n      \"path\": \"/w\",                  // path to api.php script\n      \"debug\": false,                // is more verbose when set to true\n      \"username\": \"foo\",             // account to be used when logIn is called (optional)\n      \"password\": \"bar\",             // password to be used when logIn is called (optional)\n      \"domain\" : \"auth.bar.net\",     // domain to be used when logIn is called (optional)\n      \"userAgent\": \"Custom UA\",      // define custom bot's user agent\n      \"concurrency\": 5               // how many API requests can be run in parallel (defaults to 3)\n}\n```\n\n## Making direct API calls\n\nnodemw allows you make direct calls to MediaWiki API ([example querying Semantic MediaWiki API](https://github.com/macbre/nodemw/blob/master/examples/smw.js)):\n\n```js\nvar bot = require(\"nodemw\"),\n  client = new bot({\n    server: \"semantic-mediawiki.org\",\n    path: \"/w\",\n  }),\n  params = {\n    action: \"ask\",\n    query:\n      \"[[Modification date::+]]|?Modification date|sort=Modification date|order=desc\",\n  };\n\nclient.api.call(\n  params /* api.php parameters */,\n  function (\n    err /* Error instance or null */,\n    info /* processed query result */,\n    next /* more results? */,\n    data /* raw data */,\n  ) {\n    console.log(data \u0026\u0026 data.query \u0026\u0026 data.query.results);\n  },\n);\n```\n\n## Bot methods\n\nThe last parameter of each function in nodemw API is a callback which will be fired when the requested action is done.\n\n**Callbacks use node.js style** - `err` is always passed as the first argument.\n\n### bot.logIn(username, password, callback)\n\nLog-in using given credentials - [read more](http://www.mediawiki.org/wiki/API:Login)\n\n### bot.getCategories(prefix, callback)\n\nGets the list of all categories on a wiki\n\n### bot.getAllPages(callback)\n\nGets the list of all pages from the main namespace (excludes redirects) - [read more](https://www.mediawiki.org/wiki/API:Allpages)\n\n### bot.getPagesInCategory(category, callback)\n\nGets the list of pages in a given category - [read more](http://www.mediawiki.org/wiki/API:Properties#revisions_.2F_rv)\n\n### bot.getPagesInNamespace(namespace, callback)\n\nGets the list of pages in a given namespace - [read more](http://www.mediawiki.org/wiki/API:Allpages)\n\n### bot.getPagesByPrefix(prefix, callback)\n\nGets the list of pages by a given prefix - [read more](https://www.mediawiki.org/wiki/API:Allpages)\n\n### bot.getPagesTranscluding(page, callback)\n\nGets the list of pages that transclude the given pages - [read more](https://www.mediawiki.org/wiki/API:Transcludedin)\n\n### bot.getArticle(title, [redirect,] callback)\n\nGets article content and redirect info - [read more](https://www.mediawiki.org/wiki/API:Query#Resolving_redirects)\n\n### bot.getArticleRevisions(title, callback)\n\nGets all revisions of a given article - [read more](http://www.mediawiki.org/wiki/API:Revisions)\n\n### bot.getArticleCategories(title, callback)\n\nGets all categories a given article is in - [read more](http://www.mediawiki.org/wiki/API:Property/Categories)\n\n### bot.getArticleInfo(title, callback)\n\nGets all info of a given article - [read more](https://www.mediawiki.org/wiki/API:Info)\n\n### bot.edit(title, content, summary, minor, callback)\n\nCreates / edits an article (and mark the edit as minor if _minor_ is set to true) - [read more](http://www.mediawiki.org/wiki/API:Edit)\n\n### bot.append(title, content, summary, callback)\n\nAdds given content to the end of the page - [read more](http://www.mediawiki.org/wiki/API:Edit)\n\n### bot.prepend(title, content, summary, callback)\n\nAdds given content to the beginning of the page - [read more](http://www.mediawiki.org/wiki/API:Edit)\n\n### bot.addFlowTopic(title, topic, content, callback)\n\nAdd a Flow topic - [read more](http://www.mediawiki.org/wiki/API:Flow)\n\n### bot.delete(title, reason, callback)\n\nDeletes an article - [read more](http://www.mediawiki.org/wiki/API:Delete)\n\n### bot.purge(titles, callback)\n\nPurge a given list of articles (titles or page IDs can be provided) - [read more](https://www.mediawiki.org/wiki/API:Purge)\n\n\u003e By providing `Category:Foo` as `titles` argument you can purge all pages in a given category (available since [MW 1.21](https://github.com/wikimedia/mediawiki/commit/62216932c197f1c248ca2d95bc230f87a79ccd71))\n\n### bot.protect(title, protections, options, callback)\n\nProtect a page (A title or page ID can be provided) - [read more](https://www.mediawiki.org/wiki/API:Protect)\n\nThe `protections` value is an Array of protection information in the format:\n\n```\n{\n    action: string,\n    level?: string = 'all',\n    expiry?: string | number = 'never'\n}\n```\n\nCalls to the Protect endpoint are not additive. Each call must include a list of _all_ intended protections, including any already in place. Each call will _replace_ all existing protections.\n\n### bot.sendEmail(username, subject, text, callback)\n\nSend an email to an user - [read more](http://www.mediawiki.org/wiki/API:Email)\n\n### bot.getToken(title, action, callback)\n\nReturns token required for a number of MediaWiki API operations - [read more](\u003chttps://www.mediawiki.org/wiki/API:Tokens_(action)\u003e) / [for MW 1.24+](https://www.mediawiki.org/wiki/API:Tokens)\n\n### bot.whoami(callback)\n\nGets information about current bot's user (including rights and rate limits) - [read more](http://www.mediawiki.org/wiki/API:Meta#userinfo_.2F_ui)\n\n### bot.whois(username, callback)\n\nGets information about a specific user (including rights, current block, groups) - [read more](https://www.mediawiki.org/wiki/API:Users)\n\n### bot.whoare(usernames, callback)\n\nGets information about specific users (including rights, current block, groups) - [read more](https://www.mediawiki.org/wiki/API:Users)\n\n### bot.createAccount(username, password, callback)\n\nCreate account using given credentials - [read more](https://www.mediawiki.org/wiki/API:Account_creation)\n\n### bot.move(from, to, summary, callback)\n\nMoves (aka renames) given article - [read more](http://www.mediawiki.org/wiki/API:Move)\n\n### bot.getImages(callback)\n\nGets list of all images on a wiki\n\n### bot.getImageUsage(filename, callback)\n\nGets list of all articles using given image\n\n### bot.getImagesFromArticle(title, callback)\n\nGet list of all images that are used on a given page - [read more](http://www.mediawiki.org/wiki/API:Properties#images_.2F_im)\n\n### bot.getImageInfo(filename, callback)\n\nGets metadata (including uploader, size, dimensions and EXIF data) of given image\n\n### bot.getLog(type, start, callback)\n\nGet entries form Special:Log - [read more](http://www.mediawiki.org/wiki/API:Logevents)\n\n### bot.expandTemplates(content, title, callback)\n\nReturns XML with preprocessed wikitext - [read more](https://www.mediawiki.org/wiki/API:Parsing_wikitext#expandtemplates)\n\n### bot.parse(content, title, callback)\n\nReturns parsed wikitext - [read more](https://www.mediawiki.org/wiki/API:Parsing_wikitext#parse)\n\n### bot.fetchUrl(url, callback)\n\nMakes a GET request to provided resource and returns its content.\n\n### bot.getRecentChanges(start, callback)\n\nReturns entries from recent changes (starting from a given point)\n\n### bot.getSiteInfo(props, callback)\n\nReturns site information entries - [read more](http://www.mediawiki.org/wiki/API:Siteinfo)\n\n### bot.getSiteStats(props, callback)\n\nReturns site statistics (number of articles, edits etc) - [read more](http://www.mediawiki.org/wiki/API:Siteinfo)\n\n### bot.getMediaWikiVersion(callback)\n\nReturns the version of MediaWiki given site uses - [read more](http://www.mediawiki.org/wiki/API:Siteinfo)\n\n### client.getQueryPage(queryPage, callback)\n\nReturns entries from [QueryPage-based special pages](http://www.mediawiki.org/wiki/API:Querypage)\n\n### bot.upload(filename, content, summary _/* or extraParams */_, callback)\n\nUploads a given raw content as a File:[filename] - [read more](http://www.mediawiki.org/wiki/API:Upload)\n\n### bot.uploadByUrl(filename, url, summary _/* or extraParams */_, callback)\n\nUploads a given external resource as a File:[filename]\n\n### bot.uploadVideo(fileName, url, callback)\n\nUploads a given video as a File:[filename] (Wikia-specific API)\n\n### bot.getTemplateParamFromXml(tmplXml, paramName)\n\nGets a value of a given template parameter from article's preparsed content (see expandTemplates)\n\n### bot.getExternalLinks(title, callback)\n\nGets all external links used in article\n\n### bot.getBacklinks(title, callback)\n\nGets all articles that links to given article\n\n### bot.search(query, callback)\n\nPerforms a search\n\n## Helpers\n\n### bot.getConfig(key, def)\n\nGets config entry value (returns `def` value if not found)\n\n### bot.setConfig(key, val)\n\nSets config entry value\n\n### bot.diff(old, current)\n\nReturns a diff colored using ANSI colors (powered by [diff](https://www.npmjs.com/package/diff))\n\n## [Wikia-specific](https://community.fandom.com/api/v1) bot methods\n\n\u003e They're grouped in `bot.wikia` \"namespace\".\n\n### bot.wikia.getWikiVariables(callback)\n\nGet wiki-specific settings (like ThemeDesigner colors and hubs).\n\n### bot.wikia.getUser(userId, callback)\n\nGet information (avatar, number of edits) about a given user\n\n### bot.wikia.getUsers(userIds, callback)\n\nGet information (avatar, number of edits) about a given set of users (by their IDs)\n\n## [WikiData](https://www.wikidata.org/wiki/Wikidata:Introduction)\n\nThis API is Promise-based, use `await` keyword.\n\nExamples:\n\n```js\nconst wikidata = require(\"nodemw/lib/wikidata\");\nconst client = new wikidata();\n\n// Where is Saksun, Faroe Islands located?\nconst geo = await client.getEntityClaim(\n  \"Q928875\" /* Saksun */,\n  \"P625\" /* place location */,\n);\n\n// will give you the geolocation of the place\nexpect(geo[0].mainsnak.datavalue.value).toMatchObject({\n  latitude: 62.248888888889,\n  longitude: -7.1758333333333,\n});\n\n// When was Albert Einstein born?\nconst res = await client.getArticleClaims(\"Albert Einstein\");\n\nconst dateOfBirth = res.P569[0].mainsnak.datavalue.value;\nexpect(dateOfBirth.time).toMatch(/1879-03-14/);\n\nconst dateOfDeath = res.P570[0].mainsnak.datavalue.value;\nexpect(dateOfDeath.time).toMatch(/1955-04-18/);\n\n// interwiki links for a given artlice\nconst links = await client.getArticleSitelinks(\"Albert Einstein\");\nconsole.log(links.enwiki); // {site: \"enwiki\", title: \"Albert Einstein\", badges: [\"Q17437798\"]}\n```\n\n##\n\n##\n\n## Stargazers over time\n\n[![Stargazers over time](https://starchart.cc/macbre/nodemw.svg)](https://starchart.cc/macbre/nodemw)\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmacbre%2Fnodemw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmacbre%2Fnodemw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmacbre%2Fnodemw/lists"}