1 | # API
|
2 |
|
3 | - [Introduction](#introduction)
|
4 |
|
5 | ---
|
6 |
|
7 | - [miniplug(opts)](#mp-constructor)
|
8 | - [mp.connect({ email, password })](#mp-connect)
|
9 | - [mp.use(plugin)](#mp-use)
|
10 |
|
11 | - Room methods
|
12 | - [mp.join(room)](#mp-join)
|
13 | - [mp.room()](#mp-room)
|
14 | - [mp.getRooms(query, page, limit)](#mp-getrooms)
|
15 | - [mp.getFavorites(query, page, limit)](#mp-getfavorites)
|
16 | - [mp.getMyRooms()](#mp-getmyrooms)
|
17 | - [mp.validateRoomName(name)](#mp-validateroomname)
|
18 | - [mp.createRoom(name, isPrivate)](#mp-createroom)
|
19 | - [mp.favoriteRoom(id)](#mp-favoriteroom)
|
20 | - [mp.unfavoriteRoom(id)](#mp-unfavoriteroom)
|
21 | - [mp.getRoomState()](#mp-getroomstate)
|
22 | - User methods
|
23 | - [mp.me()](#mp-me)
|
24 | - [mp.user(id)](#mp-user)
|
25 | - [mp.userByName(name)](#mp-userbyname)
|
26 | - [mp.users()](#mp-users)
|
27 | - [mp.guests()](#mp-guests)
|
28 | - [mp.getMe()](#mp-getme)
|
29 | - [mp.getUser(id)](#mp-getuser)
|
30 | - [mp.getUsers(...ids)](#mp-getusers)
|
31 | - [mp.saveSettings(settings)](#mp-savesettings)
|
32 | - [mp.setAvatar(avatar)](#mp-setavatar)
|
33 | - [mp.setBadge(badge)](#mp-setbadge)
|
34 | - [mp.setBlurb(blurb)](#mp-setblurb)
|
35 | - [mp.setLanguage(lang)](#mp-setlanguage)
|
36 | - [mp.getTransactions()](#mp-gettransactions)
|
37 | - Booth and waitlist methods
|
38 | - [mp.score()](#mp-score)
|
39 | - [mp.vote(direction)](#mp-vote)
|
40 | - [mp.woot()](#mp-woot)
|
41 | - [mp.meh()](#mp-meh)
|
42 | - [mp.dj()](#mp-dj)
|
43 | - [mp.waitlist()](#mp-waitlist)
|
44 | - [mp.joinWaitlist()](#mp-joinwaitlist)
|
45 | - [mp.leaveWaitlist()](#mp-leavewaitlist)
|
46 | - [mp.isCycling()](#mp-iscycling)
|
47 | - [mp.setCycle(cycle)](#mp-setcycle)
|
48 | - [mp.enableCycle()](#mp-enablecycle)
|
49 | - [mp.disableCycle()](#mp-disablecycle)
|
50 | - [mp.isLocked()](#mp-islocked)
|
51 | - [mp.setLock(lock)](#mp-setlock)
|
52 | - [mp.lockWaitlist()](#mp-lockwaitlist)
|
53 | - [mp.unlockWaitlist()](#mp-unlockwaitlist)
|
54 | - [mp.addDJ(uid)](#mp-adddj)
|
55 | - [mp.moveDJ(uid, position)](#mp-movedj)
|
56 | - [mp.removeDJ(uid)](#mp-removedj)
|
57 | - [mp.getWaitlistBans()](#mp-getwaitlistbans)
|
58 | - [mp.waitlistBan(uid, duration, reason)](#mp-waitlistban)
|
59 | - [mp.waitlistUnban(uid)](#mp-waitlistunban)
|
60 | - History methods
|
61 | - [mp.historyEntry()](#mp-historyentry)
|
62 | - [mp.getRoomHistory()](#mp-getroomhistory)
|
63 | - [mp.getUserHistory(uid)](#mp-getuserhistory)
|
64 | - Chat methods
|
65 | - [mp.chat(message)](#mp-chat)
|
66 | - [mp.emote(message)](#mp-emote)
|
67 | - [mp.getChatHistory()](#mp-getchathistory)
|
68 | - [mp.deleteChat(id)](#mp-deletechat)
|
69 | - Playlist methods
|
70 | - [mp.getPlaylists()](#mp-getplaylists)
|
71 | - [mp.getActivePlaylist()](#mp-getactiveplaylist)
|
72 | - [mp.createPlaylist(name)](#mp-createplaylist)
|
73 | - [mp.deletePlaylist(id)](#mp-deleteplaylist)
|
74 | - [mp.activatePlaylist(id)](#mp-activateplaylist)
|
75 | - [mp.renamePlaylist(id, name)](#mp-renameplaylist)
|
76 | - [mp.shufflePlaylist(id)](#mp-shuffleplaylist)
|
77 | - [mp.getMedia(id)](#mp-getmedia)
|
78 | - [mp.updateMedia(pid, mid, author, title)](#mp-updatemedia)
|
79 | - [mp.moveMedia(pid, mids, before)](#mp-movemedia)
|
80 | - [mp.insertMedia(id, media, append)](#mp-insertmedia)
|
81 | - [mp.deleteMedia(pid, mids)](#mp-deletemedia)
|
82 | - Store methods
|
83 | - [mp.getProducts(type, category)](#mp-getproducts)
|
84 | - [mp.getStoreAvatars(category)](#mp-getstoreavatars)
|
85 | - [mp.getStoreBadges(category)](#mp-getstorebadges)
|
86 | - [mp.getStoreMisc(category)](#mp-getstoremisc)
|
87 | - [mp.getInventory(type)](#mp-getinventory)
|
88 | - [mp.getOwnedAvatars()](#mp-getownedavatars)
|
89 | - [mp.getOwnedBadges()](#mp-getownedbadges)
|
90 | - [mp.purchase(product)](#mp-purchase)
|
91 | - [mp.validateUsername(name)](#mp-validateusername)
|
92 | - [mp.purchaseNameChange(username)](#mp-purchasenamechange)
|
93 | - Notification methods
|
94 | - [mp.notifications()](#mp-notifications)
|
95 | - [mp.getNotifications()](#mp-notifications)
|
96 | - [mp.acknowledgeNotification(id)](#mp-notifications)
|
97 | - Classes
|
98 | - [Room](#class-room)
|
99 | - [User](#class-user)
|
100 | - [Waitlist](#class-waitlist)
|
101 | - [WaitlistBan](#class-waitlistban)
|
102 | - [ChatMessage](#class-chatmessage)
|
103 | - [Playlist](#class-playlist)
|
104 | - [Media](#class-media)
|
105 | - [HistoryEntry](#class-historyentry)
|
106 | - [StoreProduct](#class-storeproduct)
|
107 | - [InventoryProduct](#class-inventoryproduct)
|
108 | - [Notification](#class-notification)
|
109 | - [User Roles](#role)
|
110 | - [Mute Durations](#muteduration)
|
111 | - [Mute Reasons](#mutereason)
|
112 | - [Ban Durations](#banduration)
|
113 | - [Ban Reasons](#banreason)
|
114 | - [Media Sources](#mediasource)
|
115 | - [Product Categories](#productcategories)
|
116 | - [REST methods](#mp-rest)
|
117 | - [WebSocket](#mp-ws)
|
118 | - [Events](#events)
|
119 | - [Errors](#errors)
|
120 |
|
121 | ## Introduction
|
122 |
|
123 | The miniplug API is heavily Promise-based. Most methods return Promises.
|
124 |
|
125 | miniplug uses the [Bluebirdish][] library. Bluebirdish implements methods from
|
126 | the Bluebird library on top of native Promises. That means that Promises
|
127 | returned by miniplug have many of the useful methods from Bluebird, too. See its
|
128 | [API reference][Bluebird API] for documentation, and the [Bluebirdish Readme][]
|
129 | for a list of available methods.
|
130 |
|
131 | Promises work really well with JavaScript [async functions][]. Async functions
|
132 | are available in Node.js in versions 8 and up. If you are using an older
|
133 | version, you can compile async functions to generator functions, which are
|
134 | widely supported, using [async-to-gen][], or using [Babel][] with the
|
135 | [babel-plugin-transform-async-to-generator][async-to-generator] transform. If
|
136 | you do not want a build step, you can use the [Bluebird .coroutine][coroutine]
|
137 | method to write similar-looking code with generator functions.
|
138 |
|
139 | Some miniplug methods don't return Promises, but return their result
|
140 | immediately. By convention, miniplug method names that are nouns (such as
|
141 | `room()`, or `user()`) return immediately. Method names that are verbs (like
|
142 | `getRooms()`, or `getUser()`) return Promises, and usually fetch new data from
|
143 | the plug.dj API.
|
144 |
|
145 | [Bluebirdish]: https://github.com/goto-bus-stop/bluebirdish
|
146 | [Bluebirdish Readme]: https://github.com/goto-bus-stop/bluebirdish#readme
|
147 | [Bluebird API]: http://bluebirdjs.com/docs/api-reference.html
|
148 | [async functions]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
|
149 | [Babel]: https://babeljs.io
|
150 | [async-to-gen]: https://github.com/leebyron/async-to-gen
|
151 | [async-to-generator]: https://babeljs.io/docs/plugins/transform-async-to-generator/
|
152 | [coroutine]: http://bluebirdjs.com/docs/api/promise.coroutine.html
|
153 |
|
154 | <a id="mp-constructor"></a>
|
155 | ## mp = miniplug(opts={})
|
156 |
|
157 | Create a miniplug instance.
|
158 |
|
159 | - `opts.host` - The plug.dj host to use, defaults to `https://plug.dj/`.
|
160 | This can be changed for mocking or to run on a plug.dj subdomain like `stg.`.
|
161 |
|
162 | Note that a miniplug instance is not very useful until you open a
|
163 | [connection](#mp-connect) to plug.dj.
|
164 |
|
165 | ```js
|
166 | const miniplug = require('miniplug')
|
167 |
|
168 | const mp = miniplug()
|
169 | ```
|
170 |
|
171 | <a id="mp-connect"></a>
|
172 | ## mp.connect(opts): Promise<this>
|
173 |
|
174 | Connect to plug.dj. Available options:
|
175 |
|
176 | - `opts.guest` - If true, will log in as a guest user. Defaults to false.
|
177 | - `opts.email` and `opts.password` - Login credentials. Only email/password
|
178 | login is supported and support for Facebook login is not currently planned.
|
179 |
|
180 | ```js
|
181 | const mp = miniplug()
|
182 | mp.connect({ guest: true }).catch(() => {
|
183 | // failed
|
184 | })
|
185 | ```
|
186 |
|
187 | ```js
|
188 | const mp = miniplug()
|
189 | mp.connect({
|
190 | email: 'example@test.com',
|
191 | password: 'hunter2'
|
192 | }).catch(() => {
|
193 | // failed
|
194 | })
|
195 | ```
|
196 |
|
197 | This method returns `this` so you can use async/await syntax to do:
|
198 |
|
199 | ```js
|
200 | async function main () {
|
201 | const mp = await miniplug().connect({ /* ... */ })
|
202 | }
|
203 | ```
|
204 |
|
205 | <a id="mp-use"></a>
|
206 | ## mp.use(plugin)
|
207 |
|
208 | Add a plugin to enhance miniplug's functionality. Returns the miniplug instance
|
209 | for chaining.
|
210 |
|
211 | ```js
|
212 | const lotteryPlugin = require('miniplug-lottery')
|
213 |
|
214 | mp.use(lotteryPlugin())
|
215 | .use((instance) => { /* Add other custom methods to `instance` */ })
|
216 | ```
|
217 |
|
218 | <a id="mp-join"></a>
|
219 | ## mp.join(room): Promise
|
220 |
|
221 | Join a room. The parameter is the room's slug. If your room URL is
|
222 | `https://plug.dj/loves-kpop`, the slug is `loves-kpop`.
|
223 |
|
224 | ```js
|
225 | mp.join('loves-kpop').then(() => {
|
226 | mp.chat('Hello!')
|
227 | })
|
228 | ```
|
229 |
|
230 | It returns the Room object so you can do:
|
231 |
|
232 | ```js
|
233 | const room = await mp.join('my-fav-room')
|
234 | ```
|
235 |
|
236 | <a id="mp-room"></a>
|
237 | ## mp.room(): [Room](#class-room)
|
238 |
|
239 | Get the current room object.
|
240 |
|
241 | ```js
|
242 | console.log('I am in:', mp.room().name)
|
243 | ```
|
244 |
|
245 | <a id="mp-getrooms"></a>
|
246 | ## mp.getRooms(query='', page=0, limit=50): Promise<Array<[Room](#class-room)>>
|
247 |
|
248 | List open rooms, like on the plug.dj dashboard.
|
249 |
|
250 | `query` is a search query. `page` and `limit` can be used for pagination.
|
251 |
|
252 | ```js
|
253 | mp.getRooms('reggae').then((rooms) => {
|
254 | rooms.forEach((room) => {
|
255 | console.log(room.name)
|
256 | })
|
257 | })
|
258 | ```
|
259 |
|
260 | <a id="mp-getfavorites"></a>
|
261 | ## mp.getFavorites(query='', page=0, limit=50): Promise<Array<[Room](#class-room)>>
|
262 |
|
263 | List the current user's favorites.
|
264 |
|
265 | `query` is a search query. `page` and `limit` can be used for pagination.
|
266 |
|
267 | <a id="mp-getmyrooms"></a>
|
268 | ## mp.getMyRooms(): Promise<Array<[Room](#class-room)>>
|
269 |
|
270 | List the rooms created by the current user.
|
271 |
|
272 | ```js
|
273 | console.log('Your rooms:')
|
274 | mp.getMyRooms().each((room) => {
|
275 | console.log(`https://plug.dj/${room.slug}: ${room.name}`)
|
276 | })
|
277 | ```
|
278 |
|
279 | <a id="mp-validateroomname"></a>
|
280 | ## mp.validateRoomName(name): Promise<{slug: string}>
|
281 |
|
282 | Check if a room name is valid and available. Returns a Promise that resolves
|
283 | with an object containing the room's `slug` if the name is valid and available,
|
284 | and rejects if the name is invalid or unavailable.
|
285 |
|
286 | ```js
|
287 | mp.validateRoomName('Tastycat')
|
288 | .then((o) => console.log('Room is available with slug:', o.slug))
|
289 | .catch((err) => console.log(err.message))
|
290 | ```
|
291 |
|
292 | <a id="mp-createroom"></a>
|
293 | ## mp.createRoom(name, isPrivate = false): Promise<[Room](#class-room)>
|
294 |
|
295 | Create a new room. Note that plug.dj will derive an unchangeable URL slug from
|
296 | the name. This slug may collide with existing rooms.
|
297 |
|
298 | ```js
|
299 | mp.createRoom('My private test room!', true).then((room) => {
|
300 | return room.favorite()
|
301 | })
|
302 | ```
|
303 |
|
304 | <a id="mp-favoriteroom"></a>
|
305 | ## mp.favoriteRoom(id): Promise
|
306 |
|
307 | Add a room to the bot user's favorites.
|
308 |
|
309 | ```js
|
310 | mp.favoriteRoom(123456).then(() => {
|
311 | console.log('Added!')
|
312 | })
|
313 | ```
|
314 |
|
315 | <a id="mp-unfavoriteroom"></a>
|
316 | ## mp.unfavoriteRoom(id): Promise
|
317 |
|
318 | Remove a room from the bot user's favorites.
|
319 |
|
320 | ```js
|
321 | mp.unfavoriteRoom(123456).then(() => {
|
322 | console.log('Removed!')
|
323 | })
|
324 | ```
|
325 |
|
326 | <a id="mp-getroomstate"></a>
|
327 | ## mp.getRoomState(): Promise<object>
|
328 |
|
329 | Get the current room object, but fresh from the plug.dj API and not cached. It
|
330 | returns the object from plug.dj's [`/_/rooms/state`][rooms/state] endpoint.
|
331 |
|
332 | Using other API methods like [mp.room()](#mp-room) should be preferred whenever
|
333 | possible.
|
334 |
|
335 | [rooms/state]: https://github.com/plugcommunity/documentation/blob/master/api/endpoints/rooms_state.md
|
336 |
|
337 | <hr>
|
338 |
|
339 | <a id="mp-me"></a>
|
340 | ## mp.me(): [User](#class-user)
|
341 |
|
342 | Get the current logged-in user. Will be `null` when logged in as a guest user.
|
343 |
|
344 | ```js
|
345 | console.log('Logged in as', mp.me().username)
|
346 | ```
|
347 |
|
348 | <a id="mp-user"></a>
|
349 | ## mp.user(id): [User](#class-user)
|
350 |
|
351 | Synchronously get a user object from the current room. Returns `null` if the
|
352 | requested user is not in the room.
|
353 |
|
354 | ```js
|
355 | console.log('Some other user:', mp.user(123456).username)
|
356 | ```
|
357 |
|
358 | <a id="mp-userbyname"></a>
|
359 | ## mp.userByName(name): [User](#class-user)
|
360 |
|
361 | Synchronously get a user object from the current room, identified by the username.
|
362 | Returns `null` if the requested user is not in the room.
|
363 |
|
364 | Usernames are case sensitive.
|
365 |
|
366 | ```js
|
367 | // An `!id` command that shows a user's ID
|
368 | // Usage: `!id @Username`, eg `!id @Tastybot`
|
369 | mp.on('chat', (message) => {
|
370 | if (message.startsWith('!id @')) {
|
371 | const name = message.slice(5)
|
372 | const user = mp.userByName(name)
|
373 | if (user) {
|
374 | message.reply(`${user.mention()}'s ID is ${user.id}`)
|
375 | } else {
|
376 | message.reply(`I don't know the user "${name}"`)
|
377 | }
|
378 | }
|
379 | })
|
380 | ```
|
381 |
|
382 | <a id="mp-users"></a>
|
383 | ## mp.users(): Array<[User](#class-user)>
|
384 |
|
385 | Synchronously get all user objects from the current room.
|
386 |
|
387 | ```js
|
388 | console.log('Users:', mp.users().map((user) => user.username))
|
389 | ```
|
390 |
|
391 | <a id="mp-guests"></a>
|
392 | ## mp.guests(): number
|
393 |
|
394 | Get the number of guests in the current room.
|
395 |
|
396 | <a id="mp-getme"></a>
|
397 | ## mp.getMe(): Promise<[User](#class-user)>
|
398 |
|
399 | Get the current logged-in user from the plug.dj web API. [mp.me()](#mp-me)
|
400 | should be used instead whenever possible.
|
401 |
|
402 | <a id="mp-getuser"></a>
|
403 | ## mp.getUser(id): Promise<[User](#class-user)>
|
404 |
|
405 | Get a user object by ID. The user does not have to be in the same room as the
|
406 | bot.
|
407 |
|
408 | <a id="mp-getusers"></a>
|
409 | ## mp.getUsers(...ids): Promise<Array<[User](#class-user)>>
|
410 |
|
411 | Get multiple users. User IDs can be passed in an array or as separate arguments.
|
412 | Up to 50 user objects can be requested at a time.
|
413 |
|
414 | ```js
|
415 | mp.getUsers(123456, 654321).then((users) => {
|
416 | console.log('Found:', users)
|
417 | })
|
418 | ```
|
419 |
|
420 | <a id="mp-savesettings"></a>
|
421 | ## mp.saveSettings(settings): Promise
|
422 |
|
423 | Save user settings. See the [PlugCommunity documentation](https://github.com/plugcommunity/documentation/blob/master/api/endpoints/users_settings.md#parameters)
|
424 | for a list of available settings.
|
425 |
|
426 | <a id="mp-setavatar"></a>
|
427 | ## mp.setAvatar(avatar): Promise
|
428 |
|
429 | Set the bot user's avatar.
|
430 |
|
431 | <a id="mp-setbadge"></a>
|
432 | ## mp.setBadge(badge): Promise
|
433 |
|
434 | Set the bot user's badge.
|
435 |
|
436 | <a id="mp-setblurb"></a>
|
437 | ## mp.setBlurb(blurb): Promise
|
438 |
|
439 | Set the bot user's profile blurb / bio.
|
440 |
|
441 | <a id="mp-setlanguage"></a>
|
442 | ## mp.setLanguage(lang): Promise
|
443 |
|
444 | Set the bot user's language preference.
|
445 |
|
446 | <a id="mp-gettransactions"></a>
|
447 | ## mp.getTransactions(): Promise<Array>
|
448 |
|
449 | Get the bot user's transaction history.
|
450 |
|
451 | <hr>
|
452 |
|
453 | <a id="mp-score"></a>
|
454 | ## mp.score(): {positive, negative, grabs, listeners}
|
455 |
|
456 | Get the score for the currently playing media.
|
457 |
|
458 | Returns an object with properties:
|
459 |
|
460 | - `positive` - Amount of woots.
|
461 | - `negative` - Amount of mehs.
|
462 | - `grabs` - Amount of grabs.
|
463 | - `listeners` - Amount of listeners.
|
464 |
|
465 | ```js
|
466 | const score = mp.score()
|
467 | mp.chat(`Score: ${score.positive} woots - ${score.negative} mehs - ${score.grabs} grabs`)
|
468 | ```
|
469 |
|
470 | <a id="mp-vote"></a>
|
471 | ## mp.vote(direction): Promise
|
472 |
|
473 | Vote on the currently playing media.
|
474 |
|
475 | `direction` is 1 for woot, -1 for meh.
|
476 |
|
477 | ```js
|
478 | const direction = Math.random() < 0.5 ? -1 : 1
|
479 | mp.vote(direction)
|
480 | ```
|
481 |
|
482 | <a id="mp-woot"></a>
|
483 | ## mp.woot(): Promise
|
484 |
|
485 | Woot the currently playing media.
|
486 |
|
487 | ```js
|
488 | mp.woot().then(() => {
|
489 | mp.chat('Great track! Wooted!')
|
490 | })
|
491 | ```
|
492 |
|
493 | <a id="mp-meh"></a>
|
494 | ## mp.meh(): Promise
|
495 |
|
496 | Meh the currently playing media.
|
497 |
|
498 | ```js
|
499 | mp.meh().then(() => {
|
500 | mp.chat('Ew, I don\'t like this. :(')
|
501 | })
|
502 | ```
|
503 |
|
504 | <hr>
|
505 |
|
506 | <a id="mp-dj"></a>
|
507 | ## mp.dj(): [User](#class-user)
|
508 |
|
509 | Get the current DJ. Returns `null` if there is no DJ.
|
510 |
|
511 | ```js
|
512 | mp.dj().chat('Nice play!')
|
513 | // → "@Username Nice play!"
|
514 | ```
|
515 |
|
516 | <a id="mp-waitlist"></a>
|
517 | ## mp.waitlist(): [Waitlist](#class-waitlist)
|
518 |
|
519 | Get the current waitlist. A [Waitlist](#class-waitlist) object is a JavaScript
|
520 | array containing [User](#class-user) objects, so the typical JavaScript array
|
521 | methods can be used:
|
522 |
|
523 | ```js
|
524 | mp.waitlist().forEach((user, position) => {
|
525 | console.log(`#${position + 1} - ${user.username}`)
|
526 | })
|
527 | ```
|
528 |
|
529 | There are also some additional methods:
|
530 |
|
531 | ```js
|
532 | // By user ID
|
533 | mp.waitlist().contains(762534)
|
534 | // or by user object.
|
535 | mp.waitlist().contains(mp.me())
|
536 |
|
537 | mp.waitlist().positionOf(mp.me())
|
538 | ```
|
539 |
|
540 | <a id="mp-joinwaitlist"></a>
|
541 | ## mp.joinWaitlist(): Promise
|
542 |
|
543 | Join the waitlist.
|
544 |
|
545 | <a id="mp-leavewaitlist"></a>
|
546 | ## mp.leaveWaitlist(): Promise
|
547 |
|
548 | Leave the waitlist.
|
549 |
|
550 | <a id="mp-iscycling"></a>
|
551 | ## mp.isCycling(): bool
|
552 |
|
553 | Check if waitlist cycling is enabled. If enabled, users automatically rejoin the
|
554 | waitlist after their play.
|
555 |
|
556 | <a id="mp-setcycle"></a>
|
557 | ## mp.setCycle(cycle): Promise
|
558 |
|
559 | Change whether the waitlist should cycle.
|
560 |
|
561 | ```js
|
562 | // Disable waitlist cycle when there are 20 or more DJs.
|
563 | mp.on('waitlistUpdate', (waitlist) => {
|
564 | if (waitlist.length < 20) {
|
565 | mp.setCycle(true)
|
566 | } else {
|
567 | mp.setCycle(false)
|
568 | }
|
569 | })
|
570 | ```
|
571 |
|
572 | <a id="mp-enablecycle"></a>
|
573 | ## mp.enableCycle(): Promise
|
574 |
|
575 | Enable waitlist cycle. Shorthand to <code>[setCycle](#mp-setcycle)(true)</code>.
|
576 |
|
577 | <a id="mp-disablecycle"></a>
|
578 | ## mp.disableCycle(): Promise
|
579 |
|
580 | Disable waitlist cycle. Shorthand to <code>[setCycle](#mp-setcycle)(false)</code>.
|
581 |
|
582 | <a id="mp-islocked"></a>
|
583 | ## mp.isLocked(): bool
|
584 |
|
585 | Check if the waitlist is locked. If the waitlist is locked, only Resident DJs
|
586 | and up can join.
|
587 |
|
588 | <a id="mp-setlock"></a>
|
589 | ## mp.setLock(lock): Promise
|
590 |
|
591 | Change whether normal users can join the waitlist. If the waitlist is locked,
|
592 | only Resident DJs and up can join.
|
593 |
|
594 | ```js
|
595 | mp.setLock(true).then(() => {
|
596 | mp.chat('Sorry! Only staff can join the waitlist at the moment.')
|
597 | })
|
598 | ```
|
599 |
|
600 | <a id="mp-lockwaitlist"></a>
|
601 | ## mp.lockWaitlist(): Promise
|
602 |
|
603 | Lock the waitlist, preventing users from joining.
|
604 | Shorthand to <code>[setLock](#mp-setlock)(true)</code>.
|
605 |
|
606 | <a id="mp-unlockwaitlist"></a>
|
607 | ## mp.unlockWaitlist(): Promise
|
608 |
|
609 | Unlock the waitlist, allowing everyone to join.
|
610 | Shorthand to <code>[setLock](#mp-setlock)(false)</code>.
|
611 |
|
612 | <a id="mp-adddj"></a>
|
613 | ## mp.addDJ(uid): Promise
|
614 |
|
615 | Add a user to the end of the waitlist. `uid` is the user's ID.
|
616 |
|
617 | <a id="mp-movedj"></a>
|
618 | ## mp.moveDJ(uid, position): Promise
|
619 |
|
620 | Move a user in the waitlist. `uid` is the user's ID. `position` is the target
|
621 | position, starting at 0.
|
622 |
|
623 | ```js
|
624 | // Add a user to position #2 in the waitlist.
|
625 | mp.addDJ(123456).then(() => {
|
626 | return mp.moveDJ(123456, 1)
|
627 | })
|
628 | ```
|
629 |
|
630 | <a id="mp-removedj"></a>
|
631 | ## mp.removeDJ(uid): Promise
|
632 |
|
633 | Remove a user from the waitlist. `uid` is the user's ID.
|
634 |
|
635 | ```js
|
636 | const user = mp.user(123456)
|
637 | mp.removeDJ(user.id).then(() => {
|
638 | return user.chat('I removed you from the waitlist. Sorry! 🙈')
|
639 | })
|
640 | ```
|
641 |
|
642 | <a id="mp-getwaitlistbans"></a>
|
643 | ## mp.getWaitlistBans(): Promise<Array<[WaitlistBan](#class-waitlistban)>>
|
644 |
|
645 | Get a list of current Waitlist Bans.
|
646 |
|
647 | ```js
|
648 | mp.getWaitlistBans().then((list) => {
|
649 | list.forEach((ban) => {
|
650 | console.log(`${ban.user.mention()} was banned from the waitlist by ${ban.moderatorName}`)
|
651 | })
|
652 | })
|
653 | ```
|
654 |
|
655 | <a id="mp-waitlistban"></a>
|
656 | ## mp.waitlistBan(uid, duration, reason): Promise
|
657 |
|
658 | Ban a user from the waitlist.
|
659 | `uid` is the ID of the user to ban from the waitlist.
|
660 | `duration` is a [WAITLIST_BAN_DURATION](#waitlistbanduration).
|
661 | `reason` is a [WAITLIST_BAN_REASON](#waitlistbanreason).
|
662 |
|
663 | ```js
|
664 | const user = mp.userByName('AnnoyingUser')
|
665 | mp.waitlistBan(user.id, WAITLIST_BAN_DURATION.PERMA, WAITLIST_BAN_REASON.GENRE).then(() => {
|
666 | console.log('Banned', user.mention())
|
667 | })
|
668 | ```
|
669 |
|
670 | <a id="mp-waitlistunban"></a>
|
671 | ## mp.waitlistUnban(uid): Promise
|
672 |
|
673 | Unban a previously waitlist-banned user.
|
674 | `uid` is the ID of the user to unban.
|
675 |
|
676 | ```js
|
677 | mp.getWaitlistBans().each((ban) => {
|
678 | return mp.waitlistUnban(ban.user.id)
|
679 | }).then(() => {
|
680 | console.log('Unbanned _everyone_! har har')
|
681 | })
|
682 | ```
|
683 |
|
684 | <hr>
|
685 |
|
686 | <a id="mp-historyentry"></a>
|
687 | ## mp.historyEntry(): [HistoryEntry](#class-historyentry)
|
688 |
|
689 | Get the current history entry. When no song is being played, returns `null`.
|
690 |
|
691 | ```js
|
692 | const entry = mp.historyEntry()
|
693 | if (/nightcore/i.test(entry.title)) {
|
694 | entry.skip()
|
695 | }
|
696 | ```
|
697 |
|
698 | <a id="mp-getroomhistory"></a>
|
699 | ## mp.getRoomHistory(): Promise<Array<[HistoryEntry](#class-historyentry)>>
|
700 |
|
701 | Get the 25 most recent plays in the current room.
|
702 |
|
703 | ```js
|
704 | mp.on('advance', (next) => {
|
705 | // Check the room history for recent plays.
|
706 | mp.getRoomHistory().then((history) => {
|
707 | // If one of the entries is the same as the currently playing song, skip it!
|
708 | const isSameEntry = (entry) => entry.media.cid === next.media.cid
|
709 | if (history.some(isSameEntry)) {
|
710 | next.user.chat('This track was played recently.')
|
711 | next.skip()
|
712 | }
|
713 | })
|
714 | })
|
715 | ```
|
716 |
|
717 | <a id="mp-getuserhistory"></a>
|
718 | ## mp.getUserHistory(uid): Promise<Array<[HistoryEntry](#class-historyentry)>>
|
719 |
|
720 | Get the 25 most recent plays by a user. `uid` is the user's ID.
|
721 |
|
722 | ```js
|
723 | mp.on('userJoin', (user) => {
|
724 | mp.getUserHistory(user).then((history) => {
|
725 | if (history.some((entry) => /The Koxx/i.test(entry.media.artist))) {
|
726 | user.chat('Welcome! You played excellent music recently!')
|
727 | }
|
728 | })
|
729 | })
|
730 | ```
|
731 |
|
732 | <hr>
|
733 |
|
734 | <a id="mp-chat"></a>
|
735 | ## mp.chat(message): Promise<[ChatMessage](#class-chatmessage)>
|
736 |
|
737 | Send a chat message. Returns a Promise that will resolve with the message once
|
738 | it is sent.
|
739 |
|
740 | ```js
|
741 | const delay = require('delay')
|
742 |
|
743 | // Send a temporary greeting that is deleted after 5 seconds.
|
744 | // Note that the bot user needs to have the appropriate staff permissions to be
|
745 | // able to delete its own messages.
|
746 | mp.chat('Hello!')
|
747 | .then(delay(5000)) // Using the `delay` module from npm
|
748 | .then((message) => message.delete())
|
749 | ```
|
750 |
|
751 | <a id="mp-emote"></a>
|
752 | ## mp.emote(message): Promise<[ChatMessage](#class-chatmessage)>
|
753 |
|
754 | Send an emote chat message, like `/me` or `/em` on the plug.dj web client.
|
755 |
|
756 | ```js
|
757 | mp.emote('does a little dance')
|
758 | .then((message) => { /* Resolves to the message, just like mp.chat(). */ })
|
759 | ```
|
760 |
|
761 | <a id="mp-getchathistory"></a>
|
762 | ## mp.getChatHistory(): Promise<Array<[ChatMessage](#class-ChatMessage)>>
|
763 |
|
764 | Get the 30 most recent chat messages, including messages that were sent before
|
765 | the bot user joined the room.
|
766 |
|
767 | ```js
|
768 | mp.getChatHistory().then((messages) => {
|
769 | messages.forEach((message) => {
|
770 | console.log(`<${message.un}> ${message.message}`)
|
771 | })
|
772 | })
|
773 | ```
|
774 |
|
775 | <a id="mp-deletechat"></a>
|
776 | ## mp.deleteChat(id): Promise
|
777 |
|
778 | Delete a chat message by ID.
|
779 |
|
780 | ```js
|
781 | // Delete all incoming chat:
|
782 | mp.on('chat', (message) => {
|
783 | mp.deleteChat(message.cid)
|
784 | })
|
785 | ```
|
786 |
|
787 | <hr>
|
788 |
|
789 | <a id="mp-getplaylists"></a>
|
790 | ## mp.getPlaylists(): Promise<Array<[Playlist](#class-playlist)>>
|
791 |
|
792 | Get all the user's playlists.
|
793 |
|
794 | ```js
|
795 | const each = require('p-each-series')
|
796 |
|
797 | each(mp.getPlaylists(), (playlist) => {
|
798 | console.log(`${playlist.name} (${playlist.count})`)
|
799 | })
|
800 | ```
|
801 |
|
802 | <a id="mp-getactiveplaylist"></a>
|
803 | ## mp.getActivePlaylist(): Promise<[Playlist](#class-playlist)>
|
804 |
|
805 | Get the user's active playlist.
|
806 |
|
807 | ```js
|
808 | mp.getActivePlaylist().then((playlist) => {
|
809 | return playlist.insert({
|
810 | format: mp.MEDIA_SOURCE.YOUTUBE,
|
811 | cid: 'UT4zZzAtWm4',
|
812 | author: 'Ovcoco',
|
813 | title: 'Your Ghost',
|
814 | duration: 209,
|
815 | image: 'https://i.ytimg.com/vi/UT4zZzAtWm4/default.jpg'
|
816 | })
|
817 | })
|
818 | ```
|
819 |
|
820 | <a id="mp-createplaylist"></a>
|
821 | ## mp.createPlaylist(name): Promise<[Playlist](#class-playlist)>
|
822 |
|
823 | Create a new playlist.
|
824 |
|
825 | ```js
|
826 | mp.createPlaylist('Test playlist').then((playlist) => {
|
827 | return Promise.all([
|
828 | playlist.insert([
|
829 | // your favourite songs
|
830 | ]),
|
831 | playlist.activate()
|
832 | ])
|
833 | })
|
834 | ```
|
835 |
|
836 | <a id="mp-deleteplaylist"></a>
|
837 | ## mp.deletePlaylist(id): Promise
|
838 |
|
839 | Permanently delete a playlist by ID.
|
840 |
|
841 | Alias: [`playlist.delete()`](#playlist-delete)
|
842 |
|
843 | <a id="mp-activateplaylist"></a>
|
844 | ## mp.activatePlaylist(id): Promise
|
845 |
|
846 | Set a playlist to active by ID.
|
847 |
|
848 | Alias: [`playlist.activate()`](#playlist-activate)
|
849 |
|
850 | <a id="mp-renameplaylist"></a>
|
851 | ## mp.renamePlaylist(id, name): Promise
|
852 |
|
853 | Rename a playlist.
|
854 |
|
855 | Alias: [`playlist.rename(name)`](#playlist-rename)
|
856 |
|
857 | <a id="mp-shuffleplaylist"></a>
|
858 | ## mp.shufflePlaylist(id): Promise<Array<[Media](#class-media)>
|
859 |
|
860 | Shuffle a playlist. Returns a Promise that resolves with the shuffled media
|
861 | items.
|
862 |
|
863 | Alias: [`playlist.shuffle()`](#playlist-shuffle)
|
864 |
|
865 | <a id="mp-getmedia"></a>
|
866 | ## mp.getMedia(id): Promise<Array<[Media](#class-media)>
|
867 |
|
868 | Get the media items in a playlist.
|
869 |
|
870 | Alias: [`playlist.getMedia()`](#playlist-getmedia)
|
871 |
|
872 | <a id="mp-updatemedia"></a>
|
873 | ## mp.updateMedia(pid, mid, author, title): Promise<{author, title}>
|
874 |
|
875 | Update the author and title tags of a media item. Returns a Promise that
|
876 | resolves with the new actual author and title as used by plug.dj, with HTML
|
877 | escapes.
|
878 |
|
879 | ```js
|
880 | mp.updateMedia(playlist.id, media.id, 'Test Author', '& Test Title').then(({ author, title }) => {
|
881 | // author == "Test Author"
|
882 | // title == "& Test Title"
|
883 | })
|
884 | ```
|
885 |
|
886 | Alias: [`media.update(author, title)`](#media-update)
|
887 |
|
888 | <a id="mp-movemedia"></a>
|
889 | ## mp.moveMedia(pid, mids, before): Promise
|
890 |
|
891 | Move existing media items to a different position in the playlist.
|
892 |
|
893 | Alias: [`playlist.move()`](#playlist-move)
|
894 |
|
895 | <a id="mp-insertmedia"></a>
|
896 | ## mp.insertMedia(id, media, append=true): Promise
|
897 |
|
898 | Insert new media items into a playlist.
|
899 |
|
900 | Alias: [`playlist.insert()`](#playlist-insert)
|
901 |
|
902 | <a id="mp-deletemedia"></a>
|
903 | ## mp.deleteMedia(pid, mids): Promise<Array<[Media](#class-media)>
|
904 |
|
905 | Alias: [`media.delete()`](#media-delete)
|
906 |
|
907 | <hr>
|
908 |
|
909 | <a id="mp-getproducts"></a>
|
910 | ## mp.getProducts(type, category='all'): Promise<[StoreProduct](#class-storeproduct)>
|
911 |
|
912 | Get the product listing from a store category. `type` is one of 'avatars',
|
913 | 'badges' or 'misc'. `category` selects a specific category, like a page in the
|
914 | store. See [Product Categories](#productcategories) for an overview of available
|
915 | categories for each product type.
|
916 |
|
917 | ```js
|
918 | const randomItem = require('random-item')
|
919 | mp.getProducts('avatars', 'island').then((products) => {
|
920 | return randomItem(products).purchase()
|
921 | })
|
922 | ```
|
923 |
|
924 | <a id="mp-getstoreavatars"></a>
|
925 | ## mp.getStoreAvatars(category='all'): Promise<[StoreProduct](#class-storeproduct)>
|
926 |
|
927 | Get the avatars store listing. Shorthand to `getProducts('avatars', category)`.
|
928 |
|
929 | <a id="mp-getstorebadges"></a>
|
930 | ## mp.getStoreBadges(category='all'): Promise<[StoreProduct](#class-storeproduct)>
|
931 |
|
932 | Get the badges store listing. Shorthand to `getProducts('badges', category)`.
|
933 |
|
934 | <a id="mp-getstoremisc"></a>
|
935 | ## mp.getStoreMisc(category='all'): Promise<[StoreProduct](#class-storeproduct)>
|
936 |
|
937 | Get the miscellaneous store listing. Shorthand to `getProducts('misc', category)`.
|
938 |
|
939 | <a id="mp-getinventory"></a>
|
940 | ## mp.getInventory(type): Promise<[InventoryProduct](#class-inventoryproduct)>
|
941 |
|
942 | Get the products purchased by the user.
|
943 |
|
944 | <a id="mp-getownedavatars"></a>
|
945 | ## mp.getOwnedAvatars(): Promise<[InventoryProduct](#class-inventoryproduct)>
|
946 |
|
947 | Get the avatars purchased by the user.
|
948 |
|
949 | <a id="mp-getownedbadges"></a>
|
950 | ## mp.getOwnedBadges(): Promise<[InventoryProduct](#class-inventoryproduct)>
|
951 |
|
952 | Get the badges purchased by the user.
|
953 |
|
954 | <a id="mp-purchase"></a>
|
955 | ## mp.purchase(product): Promise
|
956 |
|
957 | Purchase an avatar or a badge. `product` is a product ID, or a
|
958 | [StoreProduct](#class-storeproduct).
|
959 |
|
960 | <a id="mp-validateusername"></a>
|
961 | ## mp.validateUsername(name): Promise<{slug: string}>
|
962 |
|
963 | Check if a user name is valid and available. Returns a Promise that resolves
|
964 | with an object containing the new profile `slug` if the name is valid and
|
965 | available, and rejects if the name is invalid or unavailable.
|
966 |
|
967 | ```js
|
968 | mp.validateUsername('Burkes')
|
969 | .then((o) => console.log('Username is available with slug:', o.slug))
|
970 | .catch((err) => console.log(err.message))
|
971 | ```
|
972 |
|
973 | <a id="mp-purchasenamechange"></a>
|
974 | ## mp.purchaseNameChange(username): Promise
|
975 |
|
976 | Purchase a name change.
|
977 |
|
978 | <hr>
|
979 |
|
980 | <a id="mp-notifications"></a>
|
981 | ## mp.notifications(): Array<[Notification](#class-notification)>
|
982 |
|
983 | Get a list of current notifications.
|
984 |
|
985 | ```js
|
986 | // Acknowledge all notifications.
|
987 | const promises = mp.notifications().map((notif) => {
|
988 | return notif.acknowledge()
|
989 | })
|
990 |
|
991 | // Wait for all acknowledgements to go through.
|
992 | Promise.all(promises).then(() => {
|
993 | console.log('All clear!')
|
994 | })
|
995 | ```
|
996 |
|
997 | <a id="mp-notifications"></a>
|
998 | ## mp.getNotifications(): Promise<Array<[Notification](#class-notification)>>
|
999 |
|
1000 | Get current notifications from the plug.dj Web API. Normally
|
1001 | [mp.notifications()](#mp-notifications) should be preferred instead, because
|
1002 | it's instant.
|
1003 |
|
1004 | <a id="mp-notifications"></a>
|
1005 | ## mp.acknowledgeNotification(id): Promise
|
1006 |
|
1007 | Acknowledge and remove a notification. `id` is the numeric unique ID of the
|
1008 | notification.
|
1009 |
|
1010 | <hr>
|
1011 |
|
1012 | <a id="class-room"></a>
|
1013 | ## Room
|
1014 |
|
1015 | ### Properties
|
1016 |
|
1017 | - [room.id](#room-id)
|
1018 | - [room.name](#room-name)
|
1019 | - [room.slug](#room-slug)
|
1020 | - [room.join()](#room-join)
|
1021 | - [room.getHost()](#room-gethost)
|
1022 | - [room.favorite()](#room-favorite)
|
1023 | - [room.unfavorite()](#room-unfavorite)
|
1024 |
|
1025 | <a id="room-id"></a>
|
1026 | ### room.id: number
|
1027 |
|
1028 | The room's unique ID.
|
1029 |
|
1030 | <a id="room-name"></a>
|
1031 | ### room.name: string
|
1032 |
|
1033 | The room's name.
|
1034 |
|
1035 | <a id="room-slug"></a>
|
1036 | ### room.slug: string
|
1037 |
|
1038 | The room's unique URL slug.
|
1039 |
|
1040 | ```js
|
1041 | mp.chat('Visit us at https://plug.dj/' + mp.room().slug + '!')
|
1042 | ```
|
1043 |
|
1044 | <a id="room-join"></a>
|
1045 | ### room.join(): Promise
|
1046 |
|
1047 | Join this room. See [mp.join(room)](#mp-join).
|
1048 |
|
1049 | ```js
|
1050 | // Join the most populous room.
|
1051 | mp.getRooms().then((rooms) => {
|
1052 | const room = rooms[0]
|
1053 | return room.join()
|
1054 | })
|
1055 | ```
|
1056 |
|
1057 | <a id="room-gethost"></a>
|
1058 | ### room.getHost(): Promise<[User](#class-user)>
|
1059 |
|
1060 | Get this room's host.
|
1061 |
|
1062 | ```js
|
1063 | // Attempt to befriend the host of the most populated room.
|
1064 | mp.getRooms().get(0).then((room) => {
|
1065 | return room.getHost()
|
1066 | }).then((host) => {
|
1067 | return host.befriend()
|
1068 | })
|
1069 |
|
1070 | // To get the host from the current room, use:
|
1071 | mp.room().getHost().then((host) => {
|
1072 | // Do whatever
|
1073 | })
|
1074 | ```
|
1075 |
|
1076 | <a id="room-favorite"></a>
|
1077 | ### room.favorite(): Promise
|
1078 |
|
1079 | Add this room to the bot user's favorites.
|
1080 |
|
1081 | ```js
|
1082 | // Add the top 50 most populous rooms to favorites.
|
1083 | mp.getRooms()
|
1084 | .map((room) => room.favorite())
|
1085 | .then(() => {
|
1086 | console.log('Added lots of favorites')
|
1087 | })
|
1088 | ```
|
1089 |
|
1090 | <a id="room-unfavorite"></a>
|
1091 | ### room.unfavorite(): Promise
|
1092 |
|
1093 | Remove this room from the bot user's favorites.
|
1094 |
|
1095 | ```js
|
1096 | // Remove the current room from favorites.
|
1097 | mp.room().unfavorite().then(() => {
|
1098 | console.log('Removed!')
|
1099 | })
|
1100 | ```
|
1101 |
|
1102 | <a id="class-user"></a>
|
1103 | ## User
|
1104 |
|
1105 | ### Properties
|
1106 |
|
1107 | - [user.id](#user-id)
|
1108 | - [user.username](#user-username)
|
1109 | - [user.role](#user-role)
|
1110 | - [user.gRole](#user-grole)
|
1111 | - [user.hasPermission(role)](#user-haspermission)
|
1112 | - [user.hasGlobalPermission(role)](#user-hasglobalpermission)
|
1113 | - [user.chat(text)](#user-chat)
|
1114 | - [user.emote(text)](#user-emote)
|
1115 | - [user.mention()](#user-mention)
|
1116 | - [user.add()](#user-add)
|
1117 | - [user.move(position)](#user-move)
|
1118 | - [user.remove()](#user-remove)
|
1119 | - [user.skip(historyId)](#user-skip)
|
1120 | - [user.befriend()](#user-befriend)
|
1121 | - [user.rejectRequest()](#user-rejectrequest)
|
1122 | - [user.ignore()](#user-ignore)
|
1123 | - [user.unignore()](#user-unignore)
|
1124 | - [user.mute(duration, reason)](#user-mute)
|
1125 | - [user.unmute()](#user-unmute)
|
1126 | - [user.ban(duration, reason)](#user-ban)
|
1127 | - [user.unban()](#user-unban)
|
1128 | - [user.waitlistBan(duration, reason)](#user-waitlistban)
|
1129 | - [user.waitlistUnban()](#user-waitlistunban)
|
1130 | - [user.getHistory()](#user-gethistory)
|
1131 |
|
1132 | <a id="user-id"></a>
|
1133 | ### user.id: number
|
1134 |
|
1135 | User ID.
|
1136 |
|
1137 | <a id="user-username"></a>
|
1138 | ### user.username: string
|
1139 |
|
1140 | Username.
|
1141 |
|
1142 | <a id="user-role"></a>
|
1143 | ### user.role: [ROLE](#role)
|
1144 |
|
1145 | The user's role in the current room. One of
|
1146 |
|
1147 | - `ROLE.NONE`,
|
1148 | - `ROLE.DJ`,
|
1149 | - `ROLE.BOUNCER`,
|
1150 | - `ROLE.MANAGER`,
|
1151 | - `ROLE.COHOST`,
|
1152 | - `ROLE.HOST`.
|
1153 |
|
1154 | <a id="user-grole"></a>
|
1155 | ### user.gRole: [ROLE](#role)
|
1156 |
|
1157 | The user's global role. One of
|
1158 |
|
1159 | - `ROLE.NONE`,
|
1160 | - `ROLE.PROMOTER`,
|
1161 | - `ROLE.PLOT`,
|
1162 | - `ROLE.SITEMOD`,
|
1163 | - `ROLE.AMBASSADOR`,
|
1164 | - `ROLE.ADMIN`.
|
1165 |
|
1166 | <a id="user-haspermission"></a>
|
1167 | ### user.hasPermission(role: [ROLE](#role)): bool
|
1168 |
|
1169 | Check if the user has a role in the current room.
|
1170 |
|
1171 | This function checks if either one of the role in the current room, or the
|
1172 | global role is equal to or higher than the given role.
|
1173 |
|
1174 | **Parameters**
|
1175 |
|
1176 | - `role` - The permission to check for.
|
1177 |
|
1178 | ```js
|
1179 | const { ROLE } = require('miniplug')
|
1180 | mp.me().hasPermission(ROLE.NONE) // → true
|
1181 | mp.me().hasPermission(ROLE.BOUNCER) // depends on your role in the current room
|
1182 | ```
|
1183 |
|
1184 | <a id="user-hasglobalpermission"></a>
|
1185 | ### user.hasGlobalPermission(role: [ROLE](#role)): bool
|
1186 |
|
1187 | Check if the user has the given global role. Returns `true` if the user's global
|
1188 | role is equal to or higher than the given role.
|
1189 |
|
1190 | **Parameters**
|
1191 |
|
1192 | - `role` - The role to check for.
|
1193 |
|
1194 | ```js
|
1195 | const { ROLE } = require('miniplug')
|
1196 | mp.me().hasGlobalPermission(ROLE.NONE) // → true
|
1197 | mp.me().hasGlobalPermission(ROLE.AMBASSADOR)
|
1198 | ```
|
1199 |
|
1200 | <a id="user-chat"></a>
|
1201 | ### user.chat(text): Promise<[ChatMessage](#class-chatmessage)>
|
1202 |
|
1203 | Send a chat message directed at this user. Prepends `@Username` to the provided
|
1204 | text.
|
1205 |
|
1206 | ```js
|
1207 | mp.user(123456).chat('Hello!')
|
1208 | // → "@Username Hello!"
|
1209 | ```
|
1210 |
|
1211 | <a id="user-emote"></a>
|
1212 | ### user.emote(text): Promise<[ChatMessage](#class-chatmessage)>
|
1213 |
|
1214 | Send an emote chat message directed at this user.
|
1215 |
|
1216 | ```js
|
1217 | mp.user(123456).emote('Hello!')
|
1218 | // → "/me @Username Hello!"
|
1219 | ```
|
1220 |
|
1221 | <a id="user-mention"></a>
|
1222 | ### user.mention(): string
|
1223 |
|
1224 | Get a string to mention the user in the chat.
|
1225 |
|
1226 | ```js
|
1227 | const mentionStr = mp.user(123456).mention()
|
1228 | // → "@Username"
|
1229 | ```
|
1230 |
|
1231 | This function is also used when stringifying a user object, for example when
|
1232 | embedding it in a template string:
|
1233 |
|
1234 | ```js
|
1235 | const message = `Hello ${mp.user(123456)}!`
|
1236 | // → "Hello @Username!"
|
1237 | ```
|
1238 |
|
1239 | <a id="user-add"></a>
|
1240 | ### user.add(): Promise
|
1241 |
|
1242 | Add the user to the waitlist.
|
1243 |
|
1244 | <a id="user-move"></a>
|
1245 | ### user.move(position): Promise
|
1246 |
|
1247 | Move the user to a different position in the waitlist.
|
1248 |
|
1249 | <a id="user-remove"></a>
|
1250 | ### user.remove(): Promise
|
1251 |
|
1252 | Remove the user from the waitlist or the DJ Booth.
|
1253 |
|
1254 | <a id="user-skip"></a>
|
1255 | ### user.skip(historyId): Promise
|
1256 |
|
1257 | > Please use the [historyEntry.skip](#historyentry-skip) method instead.
|
1258 |
|
1259 | Skip the user. `historyId` is the ID of the currently playing track, i.e.
|
1260 | `mp.historyEntry().id`.
|
1261 |
|
1262 | <a id="user-befriend"></a>
|
1263 | ### user.befriend(): Promise
|
1264 |
|
1265 | Send or accept a friend request to/from this user.
|
1266 |
|
1267 | <a id="user-rejectrequest"></a>
|
1268 | ### user.rejectRequest(): Promise
|
1269 |
|
1270 | Reject a friend request from this user.
|
1271 |
|
1272 | <a id="user-ignore"></a>
|
1273 | ### user.ignore(): Promise
|
1274 |
|
1275 | Ignore the user in chat.
|
1276 |
|
1277 | <a id="user-unignore"></a>
|
1278 | ### user.unignore(): Promise
|
1279 |
|
1280 | Stop ignoring the user in chat.
|
1281 |
|
1282 | <a id="user-mute"></a>
|
1283 | ### user.mute(duration, reason): Promise
|
1284 |
|
1285 | Mute the user in chat. `duration` is a [MUTE_DURATION](#muteduration). `reason`
|
1286 | is a [MUTE_REASON](#mutereason).
|
1287 |
|
1288 | <a id="user-unmute"></a>
|
1289 | ### user.unmute(): Promise
|
1290 |
|
1291 | Unmute the user in chat.
|
1292 |
|
1293 | <a id="user-ban"></a>
|
1294 | ### user.ban(duration, reason): Promise
|
1295 |
|
1296 | Ban the user from the room. `duration` is a [BAN_DURATION](#banduration).
|
1297 | `reason` is a [BAN_REASON](#banreason).
|
1298 |
|
1299 | <a id="user-unban"></a>
|
1300 | ### user.unban(): Promise
|
1301 |
|
1302 | Unban the user from the room.
|
1303 |
|
1304 | <a id="user-waitlistban"></a>
|
1305 | ### user.waitlistBan(duration, reason): Promise
|
1306 |
|
1307 | Ban the user from the waitlist.
|
1308 | `duration` is a [WAITLIST_BAN_DURATION](#waitlistbanduration).
|
1309 | `reason` is a [WAITLIST_BAN_REASON](#waitlistbanreason).
|
1310 |
|
1311 | <a id="user-waitlistunban"></a>
|
1312 | ### user.waitlistUnban(): Promise
|
1313 |
|
1314 | Unban the user from the waitlist.
|
1315 |
|
1316 | <a id="user-gethistory"></a>
|
1317 | ### user.getHistory(): Promise<Array<[HistoryEntry](#class-historyentry)>>
|
1318 |
|
1319 | Get the 25 most recent plays by this user. See also [mp.getUserHistory(uid)](#mp-getuserhistory).
|
1320 |
|
1321 | <a id="class-waitlist"></a>
|
1322 | ## Waitlist
|
1323 |
|
1324 | Waitlist objects are JavaScript arrays of [User](#class-user) objects. Like
|
1325 | JavaScript arrays, Waitlist objects are zero-indexed, so the user on top of the
|
1326 | waitlist (#1 on plug.dj) is `waitlist[0]`.
|
1327 |
|
1328 | ```js
|
1329 | // Notify users when they're about to play.
|
1330 | mp.on('advance', () => {
|
1331 | const waitlist = mp.waitlist()
|
1332 | if (waitlist.length >= 1) {
|
1333 | waitlist[0].chat('You\'re up next!')
|
1334 | }
|
1335 | })
|
1336 | ```
|
1337 |
|
1338 | Because Waitlist objects are JavaScript arrays, all the usual JavaScript array
|
1339 | methods can be used. Note that most native JavaScript array methods return plain
|
1340 | JavaScript arrays, and _not_ Waitlist objects.
|
1341 |
|
1342 | ```js
|
1343 | const firstTen = mp.waitlist().slice(0, 10)
|
1344 | // firstTen is NOT a Waitlist object--just an array of the first ten users.
|
1345 | ```
|
1346 |
|
1347 | ### Properties
|
1348 |
|
1349 | - [waitlist.contains(user)](#waitlist-contains)
|
1350 | - [waitlist.positionOf(user)](#waitlist-positionof)
|
1351 |
|
1352 | <a id="waitlist-contains"></a>
|
1353 | ### waitlist.contains(user): bool
|
1354 |
|
1355 | Check if a user is in the waitlist. `user` is a [User](#class-user) object or a
|
1356 | user ID.
|
1357 |
|
1358 | ```js
|
1359 | if (mp.waitlist().contains(123456)) {
|
1360 | mp.user(123456).chat('You\'re in the waitlist, Hermione!')
|
1361 | }
|
1362 | ```
|
1363 |
|
1364 | This is similar to the `Array#includes` method of JavaScript arrays. However,
|
1365 | `includes` only checks that exactly the given object is in the array, whereas
|
1366 | `contains` checks whether an object representing the same user as the given
|
1367 | object or ID is in the array.
|
1368 |
|
1369 | <a id="waitlist-positionof"></a>
|
1370 | ### waitlist.positionOf(user): number
|
1371 |
|
1372 | Returns the position of a user in the waitlist. `user` is a [User](#class-user)
|
1373 | object or a user ID. Returns -1 if the given user is not in the waitlist.
|
1374 |
|
1375 | This is similar to the `Array#indexOf` method of JavaScript arrays. The same
|
1376 | differences apply as with <code>[waitlist.contains](#waitlist-contains)</code>.
|
1377 |
|
1378 | <a id="class-waitlistban"></a>
|
1379 | ## WaitlistBan
|
1380 |
|
1381 | ### Properties
|
1382 |
|
1383 | - [wlban.user](#waitlistban-user)
|
1384 | - [wlban.moderator](#waitlistban-moderator)
|
1385 | - [wlban.moderatorName](#waitlistban-moderatorname)
|
1386 | - [wlban.duration](#waitlistban-duration)
|
1387 | - [wlban.reason](#waitlistban-reason)
|
1388 | - [wlban.timestamp](#waitlistban-timestamp)
|
1389 | - [wlban.getUser()](#waitlistban-getuser)
|
1390 | - [wlban.remove()](#waitlistban-remove)
|
1391 |
|
1392 | <a id="waitlistban-user"></a>
|
1393 | ### wlban.user: [User](#class-user)
|
1394 |
|
1395 | The user who was banned from the waitlist.
|
1396 | This object is only guaranteed to have the `id` and `username` properties.
|
1397 | Most user methods will work, but if more properties are required, the [`wlban.getUser()`](#waitlistban-getuser) method should be used.
|
1398 |
|
1399 | <a id="waitlistban-moderator"></a>
|
1400 | ### wlban.moderator: [User](#class-user)
|
1401 |
|
1402 | The moderator who installed the waitlist ban.
|
1403 | **This property is only guaranteed to exist on WaitlistBan objects from the ['modWaitlistBan'](#event-modwaitlistban) event.**
|
1404 |
|
1405 | <a id="waitlistban-moderatorname"></a>
|
1406 | ### wlban.moderatorName: string
|
1407 |
|
1408 | The username of the moderator who installed the waitlist ban.
|
1409 |
|
1410 | <a id="waitlistban-duration"></a>
|
1411 | ### wlban.duration: [WAITLIST_BAN_DURATION](#waitlistbanduration)
|
1412 |
|
1413 | The duration of the waitlist ban.
|
1414 |
|
1415 | <a id="waitlistban-reason"></a>
|
1416 | ### wlban.reason: [WAITLIST_BAN_REASON](#waitlistbanreason)
|
1417 |
|
1418 | The reason for the waitlist ban.
|
1419 | This property is always `null` on WaitlistBan objects from the ['modWaitlistBan'](#event-modwaitlistban) event.
|
1420 |
|
1421 | <a id="waitlistban-timestamp"></a>
|
1422 | ### wlban.timestamp: Date
|
1423 |
|
1424 | When the waitlist ban was installed.
|
1425 |
|
1426 | <a id="waitlistban-getuser"></a>
|
1427 | ### wlban.getUser(): Promise<[User](#class-user)>
|
1428 |
|
1429 | Get the banned user object.
|
1430 |
|
1431 | <a id="waitlistban-remove"></a>
|
1432 | ### wlban.remove(): Promise
|
1433 |
|
1434 | Remove the waitlist ban.
|
1435 |
|
1436 | <a id="class-chatmessage"></a>
|
1437 | ## ChatMessage
|
1438 |
|
1439 | ### Properties
|
1440 |
|
1441 | - [message.id](#chatmessage-id)
|
1442 | - [message.message](#chatmessage-message)
|
1443 | - [message.uid](#chatmessage-uid)
|
1444 | - [message.un](#chatmessage-un)
|
1445 | - [message.user](#chatmessage-user)
|
1446 | - [message.getUser()](#chatmessage-getuser)
|
1447 | - [message.own()](#chatmessage-own)
|
1448 | - [message.reply(text)](#chatmessage-reply)
|
1449 | - [message.emote(text)](#chatmessage-emote)
|
1450 | - [message.delete()](#chatmessage-delete)
|
1451 |
|
1452 | <a id="chatmessage-id"></a>
|
1453 | ### message.id: string
|
1454 |
|
1455 | Message ID.
|
1456 |
|
1457 | <a id="chatmessage-message"></a>
|
1458 | ### message.message: string
|
1459 |
|
1460 | Message text contents.
|
1461 |
|
1462 | <a id="chatmessage-uid"></a>
|
1463 | ### message.uid: number
|
1464 |
|
1465 | User ID of the sender of the message.
|
1466 |
|
1467 | <a id="chatmessage-un"></a>
|
1468 | ### message.un: string
|
1469 |
|
1470 | Username of the sender of the message.
|
1471 |
|
1472 | <a id="chatmessage-user"></a>
|
1473 | ### message.user: [User](#class-user)
|
1474 |
|
1475 | The user that sent the message.
|
1476 |
|
1477 | In some cases, plug.dj might send chat messages from users who aren't reported as being in the room.
|
1478 | In those cases, the `user` property will only have the user's username and ID, which is good enough to use for most purposes.
|
1479 | If you require the full user object, use [`message.getUser()`](#chatmessage-getuser).
|
1480 | Notably, if you need to use the user's `role` for a chat command permissions check, it's best to call `getUser()`.
|
1481 |
|
1482 | <a id="chatmessage-getuser"></a>
|
1483 | ### message.getUser(): Promise<[User](#class-user)>
|
1484 |
|
1485 | Get the sender of the message.
|
1486 | This uses the local user object (from [`mp.user()`](#mp-user)) if available, and falls back to a network request (through [`mp.getUser()`](#mp-getuser)) if not.
|
1487 |
|
1488 | <a id="chatmessage-own"></a>
|
1489 | ### message.own(): bool
|
1490 |
|
1491 | Returns true if the message was sent by the logged-in user, or false if it was
|
1492 | sent by someone else.
|
1493 |
|
1494 | ```js
|
1495 | mp.chat('My own message').then((message) => {
|
1496 | assert.ok(message.own() === true)
|
1497 | })
|
1498 |
|
1499 | mp.on('chat', (message) => {
|
1500 | // True if it was sent using mp.chat() or mp.emote().
|
1501 | // False if it was sent by some other user.
|
1502 | message.own()
|
1503 | })
|
1504 | ```
|
1505 |
|
1506 | <a id="chatmessage-reply"></a>
|
1507 | ### message.reply(text): Promise<[ChatMessage](#class-chatmessage)>
|
1508 |
|
1509 | Reply to the sender of the message using an @-mention.
|
1510 |
|
1511 | ```js
|
1512 | mp.on('chat', (message) => {
|
1513 | if (message.message === '!myid') {
|
1514 | // Sends "@Username Your user ID is 123456"
|
1515 | message.reply('Your user ID is ' + message.uid)
|
1516 | }
|
1517 | })
|
1518 | ```
|
1519 |
|
1520 | <a id="chatmessage-emote"></a>
|
1521 | ### message.emote(text): Promise<[ChatMessage](#class-chatmessage)>
|
1522 |
|
1523 | Reply to the sender of the message using an @-mention in an [emote](#mp-emote)
|
1524 | message.
|
1525 |
|
1526 | <a id="chatmessage-delete"></a>
|
1527 | ### message.delete(): Promise
|
1528 |
|
1529 | Delete the message.
|
1530 |
|
1531 | ```js
|
1532 | mp.on('chat', (message) => {
|
1533 | message.delete().then(() => {
|
1534 | console.log('Deleted message from ' + message.un)
|
1535 | })
|
1536 | })
|
1537 | ```
|
1538 |
|
1539 | <a id="class-playlist"></a>
|
1540 | ## Playlist
|
1541 |
|
1542 | ### Properties
|
1543 |
|
1544 | - [playlist.id](#playlist-id)
|
1545 | - [playlist.name](#playlist-name)
|
1546 | - [playlist.count](#playlist-count)
|
1547 | - [playlist.active](#playlist-active)
|
1548 | - [playlist.delete()](#playlist-delete)
|
1549 | - [playlist.activate()](#playlist-activate)
|
1550 | - [playlist.rename(name)](#playlist-rename)
|
1551 | - [playlist.shuffle()](#playlist-shuffle)
|
1552 | - [playlist.getMedia()](#playlist-getmedia)
|
1553 | - [playlist.insert(media, append)](#playlist-insert)
|
1554 | - [playlist.move(media, before)](#playlist-move)
|
1555 |
|
1556 | <a id="playlist-id"></a>
|
1557 | ### playlist.id: number
|
1558 |
|
1559 | The playlist ID.
|
1560 |
|
1561 | <a id="playlist-name"></a>
|
1562 | ### playlist.name: string
|
1563 |
|
1564 | Playlist name.
|
1565 |
|
1566 | <a id="playlist-count"></a>
|
1567 | ### playlist.count: number
|
1568 |
|
1569 | The amount of media items in the playlist.
|
1570 |
|
1571 | <a id="playlist-active"></a>
|
1572 | ### playlist.active: bool
|
1573 |
|
1574 | True if this is the active playlist.
|
1575 |
|
1576 | <a id="playlist-delete"></a>
|
1577 | ### playlist.delete(): Promise
|
1578 |
|
1579 | Permanently delete the playlist.
|
1580 |
|
1581 | <a id="playlist-activate"></a>
|
1582 | ### playlist.activate(): Promise
|
1583 |
|
1584 | Set this playlist to active.
|
1585 |
|
1586 | <a id="playlist-rename"></a>
|
1587 | ### playlist.rename(name): Promise
|
1588 |
|
1589 | Rename the playlist.
|
1590 |
|
1591 | <a id="playlist-shuffle"></a>
|
1592 | ### playlist.shuffle(): Promise<Array<[Media](#class-media)>>
|
1593 |
|
1594 | Shuffle the items in the playlist. Returns a Promise that resolves to the
|
1595 | shuffled media items in the playlist.
|
1596 |
|
1597 | <a id="playlist-getmedia"></a>
|
1598 | ### playlist.getMedia(): Promise<Array<[Media](#class-media)>>
|
1599 |
|
1600 | Get the items in the playlist.
|
1601 |
|
1602 | <a id="playlist-insert"></a>
|
1603 | ### playlist.insert(media, append=true): Promise<{id, count}>
|
1604 |
|
1605 | Add media items to the playlist. `media` can be a [Media](#class-media) object
|
1606 | or ID, or an array of [Media](#class-media) objects or IDs. When `append` is
|
1607 | true, the medias are added to the end of the playlist. When `append` is false,
|
1608 | they are added to the front.
|
1609 |
|
1610 | Returns a Promise that resolves to an object containing the playlist `id`, and
|
1611 | the new total `count` of items in the playlist.
|
1612 |
|
1613 | <a id="playlist-move"></a>
|
1614 | ### playlist.move(media, before): Promise<Array<[Media](#class-media)>>
|
1615 |
|
1616 | Move media items in the playlist. `media` can be a [Media](#class-media) object
|
1617 | or ID, or an array of [Media](#class-media) objects or IDs. The items will be
|
1618 | moved in front of the [Media](#class-media) objects or ID given in `before`.
|
1619 | If `before` is -1, the items will be moved to the end of the playlist.
|
1620 |
|
1621 | Returns a Promise that resolves with the Media items in the playlist after the
|
1622 | move was finished.
|
1623 |
|
1624 | <a id="class-media"></a>
|
1625 | ## Media
|
1626 |
|
1627 | ### Properties
|
1628 |
|
1629 | - [media.id](#media-id)
|
1630 | - [media.format](#media-format)
|
1631 | - [media.cid](#media-cid)
|
1632 | - [media.author](#media-author)
|
1633 | - [media.title](#media-title)
|
1634 | - [media.duration](#media-duration)
|
1635 | - [media.image](#media-image)
|
1636 | - [media.update(author, title)](#media-update)
|
1637 | - [media.delete()](#media-delete)
|
1638 |
|
1639 | <a id="media-id"></a>
|
1640 | ### media.id: number
|
1641 |
|
1642 | The media ID on plug.dj.
|
1643 |
|
1644 | <a id="media-format"></a>
|
1645 | ### media.format: [MEDIA_SOURCE](#mediasource)
|
1646 |
|
1647 | The media source. Can be `MEDIA_SOURCE.YOUTUBE` or `MEDIA_SOURCE.SOUNDCLOUD`.
|
1648 |
|
1649 | <a id="media-cid"></a>
|
1650 | ### media.cid: string
|
1651 |
|
1652 | The media ID on the relevant source.
|
1653 |
|
1654 | <a id="media-author"></a>
|
1655 | ### media.author: string
|
1656 |
|
1657 | The author / artist tag of the media.
|
1658 |
|
1659 | <a id="media-title"></a>
|
1660 | ### media.title: string
|
1661 |
|
1662 | The title tag of the media.
|
1663 |
|
1664 | <a id="media-duration"></a>
|
1665 | ### media.duration: number
|
1666 |
|
1667 | Duration in seconds of the media.
|
1668 |
|
1669 | <a id="media-image"></a>
|
1670 | ### media.image: string
|
1671 |
|
1672 | A URL pointing to a thumbnail image.
|
1673 |
|
1674 | <a id="media-update"></a>
|
1675 | ### media.update(author, title): Promise<{author, title}>
|
1676 |
|
1677 | Update the author and title tags of a media item. Returns a Promise that
|
1678 | resolves with the new actual author and title as used by plug.dj, with HTML
|
1679 | escapes.
|
1680 |
|
1681 | <a id="media-delete"></a>
|
1682 | ### media.delete(): Promise
|
1683 |
|
1684 | Delete the media from the playlist it belongs to.
|
1685 |
|
1686 | <a id="class-historyentry"></a>
|
1687 | ## HistoryEntry
|
1688 |
|
1689 | ### Properties
|
1690 |
|
1691 | - [entry.id](#historyentry-id)
|
1692 | - [entry.media](#historyentry-media)
|
1693 | - [entry.room](#historyentry-room)
|
1694 | - [entry.user](#historyentry-user)
|
1695 | - [entry.timestamp](#historyentry-timestamp)
|
1696 | - [entry.score](#historyentry-score)
|
1697 | - [entry.getUser()](#historyentry-getuser)
|
1698 | - [entry.skip()](#historyentry-skip)
|
1699 |
|
1700 | <a id="historyentry-id"></a>
|
1701 | ### entry.id: string
|
1702 |
|
1703 | The unique ID of the history entry.
|
1704 |
|
1705 | <a id="historyentry-media"></a>
|
1706 | ### entry.media: [Media](#class-media)
|
1707 |
|
1708 | The media that was played.
|
1709 |
|
1710 | <a id="historyentry-room"></a>
|
1711 | ### entry.room: [Room](#class-room)
|
1712 |
|
1713 | The room where the history entry was played. Note that this `.room` object only
|
1714 | contains three of the Room class properties:
|
1715 |
|
1716 | - `entry.room.name` - The name of the room;
|
1717 | - `entry.room.slug` - The URL slug of the room;
|
1718 | - `entry.room.private` - Whether the room is private.
|
1719 |
|
1720 | There is not currently a way to load a full Room object if you need more
|
1721 | information. This will hopefully be added in a future update.
|
1722 |
|
1723 | <a id="historyentry-user"></a>
|
1724 | ### entry.user: [User](#class-user)
|
1725 |
|
1726 | The user that played this song. Note that this `.user` object only contains two
|
1727 | of the User class properties:
|
1728 |
|
1729 | - `entry.user.id` - The user's ID. This allows you to use most User class
|
1730 | methods.
|
1731 | - `entry.user.username` - The user's name.
|
1732 |
|
1733 | If you need anything else, use the [entry.getUser()](#historyentry-getuser)
|
1734 | method to load a full User object.
|
1735 |
|
1736 | <a id="historyentry-time"></a>
|
1737 | <a id="historyentry-timestamp"></a>
|
1738 | ### entry.timestamp: Date
|
1739 |
|
1740 | Timestamp at which the history entry was played.
|
1741 |
|
1742 | <a id="historyentry-score"></a>
|
1743 | ### entry.score: {positive, negative, grabs, listeners}
|
1744 |
|
1745 | An object describing audience response to the song. Contains four properties,
|
1746 | all numbers:
|
1747 |
|
1748 | - `entry.score.positive` - The amount of woots.
|
1749 | - `entry.score.negative` - The amount of mehs.
|
1750 | - `entry.score.grabs` - The amount of grabs.
|
1751 | - `entry.score.listeners` - The amount of people in the room at the time the
|
1752 | song was played.
|
1753 | - `entry.score.skipped` - Contains the number 0 if this song was played through
|
1754 | to the end, and nonzero if it was skipped.
|
1755 | (Not available on the current Booth entry.)
|
1756 |
|
1757 | <a id="historyentry-getuser"></a>
|
1758 | ### entry.getUser(): Promise<[User](#class-user)>
|
1759 |
|
1760 | Get the full user object of the user who played this song.
|
1761 |
|
1762 | <a id="historyentry-skip"></a>
|
1763 | ### entry.skip(): Promise
|
1764 |
|
1765 | Skip this play.
|
1766 |
|
1767 | ```js
|
1768 | mp.historyEntry().skip()
|
1769 | ```
|
1770 |
|
1771 | <a id="class-storeproduct"></a>
|
1772 | ## StoreProduct
|
1773 |
|
1774 | ### Properties
|
1775 |
|
1776 | - [product.type](#storeproduct-type)
|
1777 | - [product.category](#storeproduct-category)
|
1778 | - [product.id](#storeproduct-id)
|
1779 | - [product.name](#storeproduct-name)
|
1780 | - [product.level](#storeproduct-level)
|
1781 | - [product.pp](#storeproduct-pp)
|
1782 | - [product.sub](#storeproduct-sub)
|
1783 | - [product.cash](#storeproduct-cash)
|
1784 | - [product.purchase()](#storeproduct-purchase)
|
1785 |
|
1786 | <a id="storeproduct-type"></a>
|
1787 | ### product.type: string
|
1788 |
|
1789 | The product type: 'avatars', 'badges', or 'misc'.
|
1790 |
|
1791 | <a id="storeproduct-category"></a>
|
1792 | ### product.category: string
|
1793 |
|
1794 | The product category, i.e. the page on which it appears in the store. See
|
1795 | [Product Categories](#productcategories).
|
1796 |
|
1797 | <a id="storeproduct-id"></a>
|
1798 | ### product.id: number
|
1799 |
|
1800 | The product ID.
|
1801 |
|
1802 | <a id="storeproduct-name"></a>
|
1803 | ### product.name: string
|
1804 |
|
1805 | The product name. This is _not_ a human-readable name. Examples include
|
1806 | "classic01" and "admin-o01".
|
1807 |
|
1808 | <a id="storeproduct-level"></a>
|
1809 | ### product.level: number
|
1810 |
|
1811 | The minimum level the user has to have to unlock the product.
|
1812 |
|
1813 | <a id="storeproduct-pp"></a>
|
1814 | ### product.pp: number?
|
1815 |
|
1816 | The price of the product in plug points. If the product cannot be purchased with
|
1817 | points, this property will not exist (i.e. be `undefined`).
|
1818 |
|
1819 | <a id="storeproduct-sub"></a>
|
1820 | ### product.sub: number?
|
1821 |
|
1822 | `1` if the product is for Subscribers only. Subscriber-only products are
|
1823 | automatically added to the inventories of subscribed users. If the product is
|
1824 | not automatically available to subscribers, this property will not exist
|
1825 | (i.e. be `undefined`).
|
1826 |
|
1827 | Note that `1` is a "truthy" value and `undefined` is falsy, so a simple `if`
|
1828 | statement can be used to check if a product is subscriber-only:
|
1829 |
|
1830 | ```js
|
1831 | mp.getStoreAvatars().each((avatar) => {
|
1832 | let description = `Avatar: ${avatar.name}`
|
1833 | if ('pp' in avatar) {
|
1834 | description += ` - Points: ${avatar.pp}`
|
1835 | }
|
1836 | if ('cash' in avatar) {
|
1837 | description += ` - $${avatar.cash}`
|
1838 | }
|
1839 | if (avatar.sub) {
|
1840 | description += ' - Free for Subscribers'
|
1841 | }
|
1842 | console.log(description)
|
1843 | })
|
1844 | ```
|
1845 |
|
1846 | <a id="storeproduct-cash"></a>
|
1847 | ### product.cash: number?
|
1848 |
|
1849 | The price of the product in US dollars. If the product cannot be purchased with
|
1850 | real money, this property will not exist (i.e. be `undefined`).
|
1851 |
|
1852 | <a id="storeproduct-purchase"></a>
|
1853 | ### product.purchase(): Promise
|
1854 |
|
1855 | Purchase the product. Only works for products that can be purchased with points.
|
1856 |
|
1857 | <a id="class-inventoryproduct"></a>
|
1858 | ## InventoryProduct
|
1859 |
|
1860 | ### Properties
|
1861 |
|
1862 | - [product.type](#inventoryproduct-type)
|
1863 | - [product.category](#inventoryproduct-category)
|
1864 | - [product.id](#inventoryproduct-id)
|
1865 |
|
1866 | <a id="inventoryproduct-type"></a>
|
1867 | ### product.type: string
|
1868 |
|
1869 | The product type: 'avatars', 'badges', or 'misc'.
|
1870 |
|
1871 | <a id="inventoryproduct-category"></a>
|
1872 | ### product.category: string
|
1873 |
|
1874 | The product category, i.e. the page on which it appears in the user's inventory.
|
1875 | See [Product Categories](#productcategories).
|
1876 |
|
1877 | <a id="inventoryproduct-id"></a>
|
1878 | ### product.name: string
|
1879 |
|
1880 | The internal product name.
|
1881 |
|
1882 | <hr>
|
1883 |
|
1884 | <a id="class-notification"></a>
|
1885 | ## Notification
|
1886 |
|
1887 | A plug.dj service notification. These are the notifications listed on your user
|
1888 | profile under My Profile » Notifications.
|
1889 |
|
1890 | ### Properties
|
1891 |
|
1892 | - [notification.id](#notification-id)
|
1893 | - [notification.action](#notification-action)
|
1894 | - [notification.timestamp](#notification-timestamp)
|
1895 | - [notification.value](#notification-value)
|
1896 | - [notification.level](#notification-level)
|
1897 | - [notification.message](#notification-message)
|
1898 | - [notification.from](#notification-from)
|
1899 | - [notification.amount](#notification-amount)
|
1900 | - [notification.acknowledge()](#notification-acknowledge)
|
1901 |
|
1902 | <a id="notification-id"></a>
|
1903 | ### notification.id: number
|
1904 |
|
1905 | Unique ID of the notification.
|
1906 |
|
1907 | <a id="notification-action"></a>
|
1908 | ### notification.action: string
|
1909 |
|
1910 | Type of notification.
|
1911 | This determines what the [Notification](#class-notification)'s
|
1912 | [`value`](#notification-value) stands for. Miniplug parses the `value` for some
|
1913 | notification types.
|
1914 |
|
1915 | - `levelUp` - The user leveled up. `level` is the new level.
|
1916 | - `custom` - A custom notification sent by plug.dj. `message` contains the
|
1917 | notification message. Note that the message can contain HTML.
|
1918 | - `gift` - The user received a gift. `from` contains the username of the
|
1919 | sender, and `amount` contains the amount of PP that was gifted.
|
1920 | - `boostExpired` - An XP boost purchased by the user has expired. Obsolete,
|
1921 | since plug.dj doesn't sell XP boosts anymore.
|
1922 |
|
1923 | <a id="notification-timestamp"></a>
|
1924 | ### notification.timestamp: Date
|
1925 |
|
1926 | Date and time when the notification came in.
|
1927 |
|
1928 | <a id="notification-value"></a>
|
1929 | ### notification.value: string
|
1930 |
|
1931 | Raw value of the notification. This can mean different things for different
|
1932 | actions. It's best to use one of the other properties documented below if you
|
1933 | can.
|
1934 |
|
1935 | See [`notification.action`](#notification-action).
|
1936 |
|
1937 | <a id="notification-level"></a>
|
1938 | ### notification.level: number
|
1939 |
|
1940 | The user's new level after leveling up. Only present when the notification
|
1941 | `action` is `levelUp`.
|
1942 |
|
1943 | <a id="notification-message"></a>
|
1944 | ### notification.message: string
|
1945 |
|
1946 | HTML message contents of a plug.dj announcement notification. Only present when
|
1947 | the notification `action` is `custom`.
|
1948 |
|
1949 | <a id="notification-from"></a>
|
1950 | ### notification.from: string
|
1951 |
|
1952 | Nickname of the sender of a gift. Only present when the notification `action` is
|
1953 | `gift`.
|
1954 |
|
1955 | <a id="notification-amount"></a>
|
1956 | ### notification.amount: number
|
1957 |
|
1958 | Amount of PP in a gift. Only present when the notification `action` is `gift`.
|
1959 |
|
1960 | <a id="notification-acknowledge"></a>
|
1961 | ### notification.acknowledge(): Promise
|
1962 |
|
1963 | Acknowledge and remove the notification.
|
1964 |
|
1965 | <hr>
|
1966 |
|
1967 | <a id="role"></a>
|
1968 | ## User Roles
|
1969 |
|
1970 | ```js
|
1971 | const { ROLE } = require('miniplug')
|
1972 | ```
|
1973 |
|
1974 | ### ROLE.NONE
|
1975 |
|
1976 | A normal user.
|
1977 |
|
1978 | ### ROLE.DJ
|
1979 |
|
1980 | A Resident DJ in the current room.
|
1981 |
|
1982 | ### ROLE.BOUNCER
|
1983 |
|
1984 | A Bouncer in the current room.
|
1985 |
|
1986 | ### ROLE.MANAGER
|
1987 |
|
1988 | A Manager in the current room.
|
1989 |
|
1990 | ### ROLE.COHOST
|
1991 |
|
1992 | A Cohost in the current room.
|
1993 |
|
1994 | ### ROLE.HOST
|
1995 |
|
1996 | The current room's host.
|
1997 |
|
1998 | ### ROLE.PROMOTER
|
1999 |
|
2000 | A plug.dj Promoter.
|
2001 |
|
2002 | ### ROLE.PLOT
|
2003 |
|
2004 | A PLoT (Plug.dj League of Translators) member, who works on plug.dj localization.
|
2005 |
|
2006 | ### ROLE.SITEMOD
|
2007 |
|
2008 | A site-wide moderator.
|
2009 |
|
2010 | ### ROLE.AMBASSADOR
|
2011 |
|
2012 | A plug.dj Brand Ambassador.
|
2013 |
|
2014 | ### ROLE.ADMIN
|
2015 |
|
2016 | A plug.dj site admin.
|
2017 |
|
2018 | <a id="muteduration"></a>
|
2019 | ## Mute Durations
|
2020 |
|
2021 | ```js
|
2022 | const { MUTE_DURATION } = require('miniplug')
|
2023 | ```
|
2024 |
|
2025 | ### MUTE_DURATION.SHORT
|
2026 |
|
2027 | 15 minutes.
|
2028 |
|
2029 | ### MUTE_DURATION.MEDIUM
|
2030 |
|
2031 | 30 minutes.
|
2032 |
|
2033 | ### MUTE_DURATION.LONG
|
2034 |
|
2035 | 45 minutes.
|
2036 |
|
2037 | <a id="mutereason"></a>
|
2038 | ## Mute Reasons
|
2039 |
|
2040 | ```js
|
2041 | const { MUTE_REASON } = require('miniplug')
|
2042 | ```
|
2043 |
|
2044 | ### MUTE_REASON.VIOLATING_RULES
|
2045 |
|
2046 | Violating community rules.
|
2047 |
|
2048 | ### MUTE_REASON.VERBAL_ABUSE
|
2049 |
|
2050 | Verbal abuse or harassment.
|
2051 |
|
2052 | ### MUTE_REASON.SPAMMING
|
2053 |
|
2054 | Spamming or trolling.
|
2055 |
|
2056 | ### MUTE_REASON.LANGUAGE
|
2057 |
|
2058 | Offensive language.
|
2059 |
|
2060 | ### MUTE_REASON.ATTITUDE
|
2061 |
|
2062 | Negative attitude
|
2063 |
|
2064 | <a id="banduration"></a>
|
2065 | ## Ban Durations
|
2066 |
|
2067 | ```js
|
2068 | const { BAN_DURATION } = require('miniplug')
|
2069 | ```
|
2070 |
|
2071 | ### BAN_DURATION.HOUR
|
2072 |
|
2073 | A 1 hour ban.
|
2074 |
|
2075 | ### BAN_DURATION.DAY
|
2076 |
|
2077 | A 1 day ban.
|
2078 |
|
2079 | ### BAN_DURATION.PERMA
|
2080 |
|
2081 | A permanent ban.
|
2082 |
|
2083 | <a id="banreason"></a>
|
2084 | ## Ban Reasons
|
2085 |
|
2086 | ```js
|
2087 | const { BAN_REASON } = require('miniplug')
|
2088 | ```
|
2089 |
|
2090 | ### BAN_REASON.SPAMMING
|
2091 |
|
2092 | Spamming or trolling.
|
2093 |
|
2094 | ### BAN_REASON.VERBAL_ABUSE
|
2095 |
|
2096 | Verbal abuse or offensive language.
|
2097 |
|
2098 | ### BAN_REASON.OFFENSIVE_PLAYS
|
2099 |
|
2100 | Playing offensive videos/songs.
|
2101 |
|
2102 | ### BAN_REASON.GENRE
|
2103 |
|
2104 | Repeatedly playing inappropriate genre(s).
|
2105 |
|
2106 | ### BAN_REASON.ATTITUDE
|
2107 |
|
2108 | Negative attitude.
|
2109 |
|
2110 | <a id="waitlistbanduration"></a>
|
2111 | ## Waitlist Ban Durations
|
2112 |
|
2113 | ```js
|
2114 | const { WAITLIST_BAN_DURATION } = require('miniplug')
|
2115 | ```
|
2116 |
|
2117 | ### WAITLIST_BAN_DURATION.SHORT
|
2118 |
|
2119 | A 15 minute waitlist ban.
|
2120 |
|
2121 | ### WAITLIST_BAN_DURATION.MEDIUM
|
2122 |
|
2123 | A 1 hour waitlist ban.
|
2124 |
|
2125 | ### WAITLIST_BAN_DURATION.LONG
|
2126 |
|
2127 | A 1 day waitlist ban.
|
2128 |
|
2129 | ### WAITLIST_BAN_DURATION.PERMA
|
2130 |
|
2131 | A permanent waitlist ban.
|
2132 |
|
2133 | <a id="waitlistbanreason"></a>
|
2134 | ## Waitlist Ban Reasons
|
2135 |
|
2136 | ```js
|
2137 | const { WAITLIST_BAN_REASON } = require('miniplug')
|
2138 | ```
|
2139 |
|
2140 | ### WAITLIST_BAN_REASON.SPAMMING
|
2141 |
|
2142 | Spamming or trolling.
|
2143 |
|
2144 | ### WAITLIST_BAN_REASON.VERBAL_ABUSE
|
2145 |
|
2146 | Verbal abuse or offensive language.
|
2147 |
|
2148 | ### WAITLIST_BAN_REASON.OFFENSIVE_PLAYS
|
2149 |
|
2150 | Playing offensive videos/songs.
|
2151 |
|
2152 | ### WAITLIST_BAN_REASON.GENRE
|
2153 |
|
2154 | Repeatedly playing inappropriate genre(s).
|
2155 |
|
2156 | ### WAITLIST_BAN_REASON.ATTITUDE
|
2157 |
|
2158 | Negative attitude.
|
2159 |
|
2160 | <a id="mediasource"></a>
|
2161 | ## Media Sources
|
2162 |
|
2163 | ```js
|
2164 | const { MEDIA_SOURCE } = require('miniplug')
|
2165 | ```
|
2166 |
|
2167 | ### MEDIA_SOURCE.YOUTUBE
|
2168 |
|
2169 | Identifies a YouTube video.
|
2170 |
|
2171 | ### MEDIA_SOURCE.SOUNDCLOUD
|
2172 |
|
2173 | Identifies a SoundCloud track.
|
2174 |
|
2175 | <a id="productcategories"></a>
|
2176 | ## Product Categories
|
2177 |
|
2178 | Note: These listings were last updated on 03 December 2016. It's not guaranteed
|
2179 | to be 100% correct. If you spot a mistake or a missing category, please send a
|
2180 | PR!
|
2181 |
|
2182 | ### Avatars
|
2183 |
|
2184 | - 'classic'
|
2185 | - 'hiphop'
|
2186 | - 'rave'
|
2187 | - 'base'
|
2188 | - 'country'
|
2189 | - '80s'
|
2190 | - 'rock'
|
2191 | - '2014hw'
|
2192 | - 'robot'
|
2193 | - 'zoo'
|
2194 | - 'warrior'
|
2195 | - 'dragon'
|
2196 | - '2014winter'
|
2197 | - 'sea'
|
2198 | - 'island'
|
2199 | - 'diner'
|
2200 | - 'beach'
|
2201 | - 'nyc'
|
2202 |
|
2203 | ### Badges
|
2204 |
|
2205 | - 'b-original'
|
2206 | - 'b-sea'
|
2207 | - 'b-island'
|
2208 | - 'b-rave'
|
2209 | - 'b-base'
|
2210 | - 'b-food'
|
2211 | - 'b-diner'
|
2212 | - 'b-country'
|
2213 | - 'b-robot'
|
2214 | - 'b-zoo'
|
2215 | - 'b-hiphop'
|
2216 | - 'b-80s'
|
2217 | - 'b-warrior'
|
2218 | - 'b-beach'
|
2219 | - 'b-nyc'
|
2220 |
|
2221 | ### Misc
|
2222 |
|
2223 | - 'username'
|
2224 | - 'boost' is obsolete, but used to contain XP boost items in the past.
|
2225 |
|
2226 | <a id="mp-rest"></a>
|
2227 | ## mp.get/post/put/del(url: string, data: object): Promise
|
2228 |
|
2229 | > These are low-level REST methods. You most likely do not need to use them
|
2230 | > directly. Instead, use one of the methods described in the rest of this
|
2231 | > document.
|
2232 |
|
2233 | Send an HTTP request to the given plug.dj API endpoint. The `url` is relative
|
2234 | to the plug.dj API base URL. `data` is used for the request body for POST, PUT
|
2235 | and DELETE requests, and as the query string for GET requests.
|
2236 |
|
2237 | ```js
|
2238 | mp.get('rooms', { q: 'k-pop' }).then(console.log)
|
2239 | // sends `GET https://plug.dj/_/rooms?q=k-pop`
|
2240 |
|
2241 | mp.post('booth/skip', { userID: 123456, historyID: mp.historyEntry().id })
|
2242 | // sends `POST https://plug.dj/_/booth/skip` with a request body like:
|
2243 | // { "userID": 123456, "historyID": "ab0c47eb-6c92-45f8-8711-75e27977db06" }
|
2244 | ```
|
2245 |
|
2246 | <a id="mp-ws"></a>
|
2247 | # WebSocket
|
2248 |
|
2249 | ## mp.ws: WebSocket
|
2250 |
|
2251 | The [plug-socket](https://github.com/miniplug/plug-socket) WebSocket
|
2252 | instance. This is also an instance of the [ws](https://github.com/websockets/ws)
|
2253 | module.
|
2254 |
|
2255 | It has a few methods, but miniplug has better wrappers around all of them.
|
2256 | The [mp.ws](#mp-ws) property is useful if you need to attach native WebSocket
|
2257 | events (eg. `'close'`), but otherwise there are better options.
|
2258 |
|
2259 | <a id="events"></a>
|
2260 | # Events
|
2261 |
|
2262 | - [advance](#event-advance)
|
2263 | - [ban](#event-ban)
|
2264 | - [chat](#event-chat)
|
2265 | - [chatDelete](#event-chatdelete)
|
2266 | - [disconnected](#event-disconnected)
|
2267 | - [earn](#event-earn)
|
2268 | - [friendAccept](#event-friendaccept)
|
2269 | - [friendRequest](#event-friendrequest)
|
2270 | - [gifted](#event-gifted)
|
2271 | - [grab](#event-grab)
|
2272 | - [guestJoin](#event-guestjoin)
|
2273 | - [guestLeave](#event-guestleave)
|
2274 | - [modAddDj](#event-modadddj)
|
2275 | - [modBan](#event-modban)
|
2276 | - [modMoveDj](#event-modmovedj)
|
2277 | - [modMute](#event-modmute)
|
2278 | - [modRemoveDj](#event-modremovedj)
|
2279 | - [modSkip](#event-modskip)
|
2280 | - [modStaff](#event-modstaff)
|
2281 | - [modWaitlistBan](#event-modwaitlistban)
|
2282 | - [roomUpdate](#event-roomupdate)
|
2283 | - [roomNameUpdate](#event-roomnameupdate)
|
2284 | - [roomDescriptionUpdate](#event-roomdescriptionupdate)
|
2285 | - [roomWelcomeUpdate](#event-roomwelcomeupdate)
|
2286 | - [roomMinChatLevelUpdate](#event-roomminchatlevelupdate)
|
2287 | - [skip](#event-skip)
|
2288 | - [sub](#event-sub)
|
2289 | - [userJoin](#event-userjoin)
|
2290 | - [userLeave](#event-userleave)
|
2291 | - [userUpdate](#event-userupdate)
|
2292 | - [vote](#event-vote)
|
2293 | - [waitlistClear](#event-waitlistclear)
|
2294 | - [waitlistCycle](#event-waitlistcycle)
|
2295 | - [waitlistLock](#event-waitlistlock)
|
2296 | - [waitlistUpdate](#event-waitlistupdate)
|
2297 |
|
2298 | <a id="event-advance"></a>
|
2299 | ## 'advance'
|
2300 |
|
2301 | Fired when the DJ booth advances, and the next song starts playing.
|
2302 |
|
2303 | **Parameters**
|
2304 |
|
2305 | - `next` - The new [HistoryEntry](#class-historyentry), or `null` if there is
|
2306 | no new DJ.
|
2307 | - `previous` - The previous [HistoryEntry](#class-historyentry), or `null` if
|
2308 | there was no DJ earlier.
|
2309 |
|
2310 | ```js
|
2311 | mp.on('advance', (next, previous) => {
|
2312 | if (previous) {
|
2313 | console.log('Last song:', previous.media.author, '-', previous.media.title)
|
2314 | }
|
2315 | if (next) {
|
2316 | console.log('Next song:', next.media.author, '-', next.media.title)
|
2317 | }
|
2318 | })
|
2319 | ```
|
2320 |
|
2321 | <a id="event-ban"></a>
|
2322 | ## 'ban'
|
2323 |
|
2324 | Fired when a moderator bans you.
|
2325 |
|
2326 | **Parameters**
|
2327 |
|
2328 | - `duration` - The duration of how long the ban lasts.
|
2329 | - `reason` - The reason why the ban was issued.
|
2330 |
|
2331 | ```js
|
2332 | mp.on('ban', (data) => {
|
2333 | var duration = '', reason = ''
|
2334 |
|
2335 | switch (data.duration) {
|
2336 | case 'h': duration = 'for one hour'; break;
|
2337 | case 'd': duration = 'for a day'; break;
|
2338 | case 'f': duration = 'forever'; break;
|
2339 | }
|
2340 |
|
2341 | switch (data.reason) {
|
2342 | case 1: reason = 'spamming or trolling'; break;
|
2343 | case 2: reason = 'verbal abuse or harassment'; break;
|
2344 | case 3: reason = 'playing offensive videos/songs'; break;
|
2345 | case 4: reason = 'repeatedly playing inappropriate genre(s)'; break;
|
2346 | case 5: reason = 'negative attitude'; break;
|
2347 | }
|
2348 |
|
2349 | console.log(`I have been banned ${duration} (reason: ${reason})`)
|
2350 | })
|
2351 | ```
|
2352 |
|
2353 | <a id="event-chat"></a>
|
2354 | ## 'chat'
|
2355 |
|
2356 | Fired when a chat message is received.
|
2357 |
|
2358 | **Parameters**
|
2359 |
|
2360 | - `message` - The incoming [ChatMessage](#class-chatmessage).
|
2361 |
|
2362 | ```js
|
2363 | mp.on('chat', (message) => {
|
2364 | if (/^!whoami/.test(message.message)) {
|
2365 | message.reply(`You are ${message.un}, #${message.uid}.`)
|
2366 | }
|
2367 | })
|
2368 | ```
|
2369 |
|
2370 | <a id="event-chatdelete"></a>
|
2371 | ## 'chatDelete'
|
2372 |
|
2373 | Fired when a chat message is deleted.
|
2374 |
|
2375 | **Parameters**
|
2376 |
|
2377 | - `del` - An object with two properties:
|
2378 | - `cid` - The ID of the chat message that is being deleted.
|
2379 | - `user` - The [User](#class-user) that deleted the message.
|
2380 |
|
2381 | ```js
|
2382 | mp.on('chatDelete', (del) => {
|
2383 | console.info(`${del.user.username} deleted message #${del.cid}.`)
|
2384 | })
|
2385 | ```
|
2386 |
|
2387 | <a id="event-disconnected"></a>
|
2388 | ## 'disconnected'
|
2389 |
|
2390 | Fired when the connection to the plug.dj WebSocket server has ended.
|
2391 | With this event you can implement an auto-reconnect system.
|
2392 |
|
2393 | ```js
|
2394 | let timeout = 0
|
2395 | function reconnect () {
|
2396 | console.info('Trying to reconnect...')
|
2397 | mp.connect({ email: 'xyz@hoi.com', password: 'whatever' })
|
2398 | .then(() => {
|
2399 | console.info('Reconnected!')
|
2400 | })
|
2401 | .catch(() => {
|
2402 | console.warn('Failed to reconnect, trying again in', timeout, 'ms')
|
2403 | setTimeout(reconnect, timeout)
|
2404 | })
|
2405 | timeout += 1000 // 1 second
|
2406 | }
|
2407 |
|
2408 | mp.on('disconnected', () => {
|
2409 | console.warn('!! Connection lost.')
|
2410 | reconnect()
|
2411 | })
|
2412 | ```
|
2413 |
|
2414 | <a id="event-earn"></a>
|
2415 | ## 'earn'
|
2416 |
|
2417 | Fired when xp/pp is added to your account.
|
2418 |
|
2419 | **Parameters**
|
2420 |
|
2421 | - `xp` - The new xp amount.
|
2422 | - `pp` - The new pp amount.
|
2423 | - `level` - The current level, or new level on level up.
|
2424 |
|
2425 | ```js
|
2426 | mp.on('earn', (data) => {
|
2427 | console.info(`I now have ${data.xp} xp, ${data.pp} pp, and am level ${data.level}.`)
|
2428 | })
|
2429 | ```
|
2430 |
|
2431 | <a id="event-friendaccept"></a>
|
2432 | ## 'friendAccept'
|
2433 |
|
2434 | Fired when a user accepts a friend request.
|
2435 |
|
2436 | **Parameters**
|
2437 |
|
2438 | - `user` - The [User](#class-user) that accepted the request.
|
2439 |
|
2440 | ```js
|
2441 | mp.on('friendAccept', (user) => {
|
2442 | mp.chat(`Thanks ${user}, for accepting my friend request!`)
|
2443 | })
|
2444 | ```
|
2445 |
|
2446 | <a id="event-friendrequest"></a>
|
2447 | ## 'friendRequest'
|
2448 |
|
2449 | Fired when a user sends you a friend request. The [User](#class-user) methods
|
2450 | [.befriend](#user-befriend) and [.rejectRequest](#user-rejectrequest) can be
|
2451 | used to respond to the request.
|
2452 |
|
2453 | **Parameters**
|
2454 |
|
2455 | - `user` - The [User](#class-user) that sent the request.
|
2456 |
|
2457 | ```js
|
2458 | mp.on('friendRequest', (user) => {
|
2459 | if (user.level < 5) {
|
2460 | user.befriend()
|
2461 | } else {
|
2462 | user.chat('I only befriend users whose level is below 5, sorry.')
|
2463 | user.rejectRequest()
|
2464 | }
|
2465 | })
|
2466 | ```
|
2467 |
|
2468 | <a id="event-gifted"></a>
|
2469 | ## 'gifted'
|
2470 |
|
2471 | Fired when a user sends another user a gift.
|
2472 |
|
2473 | **Parameters**
|
2474 |
|
2475 | - `sender` - The name of the user who sent the gift.
|
2476 | - `recipient` - The name of the user who received the gift.
|
2477 |
|
2478 | ```js
|
2479 | mp.on('gifted', (data) => {
|
2480 | console.log(`${data.sender} sent ${data.recipient} a gift!`)
|
2481 | })
|
2482 | ```
|
2483 |
|
2484 | <a id="event-grab"></a>
|
2485 | ## 'grab'
|
2486 |
|
2487 | Fired when a user grabs the current song.
|
2488 |
|
2489 | **Parameters**
|
2490 |
|
2491 | - `user` - The [User](#class-user) who grabbed the song.
|
2492 |
|
2493 | ```js
|
2494 | mp.on('grab', (user) => {
|
2495 | const media = mp.media()
|
2496 | console.log(user.mention(), 'grabbed', media.author, '-', media.title)
|
2497 | })
|
2498 | ```
|
2499 |
|
2500 | <a id="event-guestjoin"></a>
|
2501 | ## 'guestJoin'
|
2502 |
|
2503 | Fired when a guest joins the room. Does not receive any parameters.
|
2504 |
|
2505 | ```js
|
2506 | mp.on('guestJoin', () => {
|
2507 | console.log('A wild guest appeared!')
|
2508 | })
|
2509 | ```
|
2510 |
|
2511 | <a id="event-guestleave"></a>
|
2512 | ## 'guestLeave'
|
2513 |
|
2514 | Fired when a guest leaves the room. Does not receive any parameters.
|
2515 |
|
2516 | ```js
|
2517 | mp.on('guestLeave', () => {
|
2518 | console.log('A guest left the room.')
|
2519 | })
|
2520 | ```
|
2521 |
|
2522 | <a id="#event-modadddj"></a>
|
2523 | ## 'modAddDj'
|
2524 |
|
2525 | Fired when a moderator adds a user to the waitlist.
|
2526 |
|
2527 | **Parameters**
|
2528 |
|
2529 | - `moderator` - The staff [User](#class-user) who added the user to the waitlist.
|
2530 | - `username` - The name of the user that was added.
|
2531 | - `cycle` - Weather the waitlist should cycle (true/false)
|
2532 |
|
2533 | ```js
|
2534 | mp.on('modAddDj', (data) => {
|
2535 | console.log(`Moderator ${data.moderator.username} has added ${data.username} to the waitlist.`)
|
2536 | })
|
2537 | ```
|
2538 |
|
2539 | <a id="#event-modban"></a>
|
2540 | ## 'modBan'
|
2541 |
|
2542 | Fired when a moderator bans a user.
|
2543 |
|
2544 | **Parameters**
|
2545 |
|
2546 | - `moderator` - The staff [User](#class-user) who banned the user.
|
2547 | - `username` - The name of the user that was banned.
|
2548 | - `duration` - The duration of time the ban lasts for
|
2549 |
|
2550 | ```js
|
2551 | mp.on('modBan', (data) => {
|
2552 | var duration = '';
|
2553 |
|
2554 | switch (data.duration) {
|
2555 | case 'h': duration = 'for an hour'; break;
|
2556 | case 'd': duration = 'for a day'; break;
|
2557 | case 'f': duration = 'forever'; break;
|
2558 | }
|
2559 |
|
2560 | console.log(`Moderator ${data.moderator.username} has banned ${data.username} ${duration}.`)
|
2561 | })
|
2562 | ```
|
2563 |
|
2564 | <a id="#event-modmovedj"></a>
|
2565 | ## 'modMoveDj'
|
2566 |
|
2567 | Fired when a moderator moves the position of a user in the waitlist.
|
2568 |
|
2569 | **Parameters**
|
2570 |
|
2571 | - `moderator` - The staff [User](#class-user) who moved the user in the waitlist.
|
2572 | - `username` - The name of the user that was moved.
|
2573 | - `movedFrom` - The position the user was at.
|
2574 | - `movedTo` - The position the user was moved to.
|
2575 |
|
2576 | ```js
|
2577 | mp.on('modMoveDj', (data) => {
|
2578 | // movedFrom and movedTo are both 0 indexed
|
2579 | console.log(`${data.moderator.username} has moved ${data.username} from position ${data.movedFrom + 1} to position ${data.movedTo + 1}`)
|
2580 | })
|
2581 | ```
|
2582 |
|
2583 | <a id="#event-modmute"></a>
|
2584 | ## 'modMute'
|
2585 |
|
2586 | Fired when a moderator mutes a user.
|
2587 |
|
2588 | **Parameters**
|
2589 |
|
2590 | - `moderator` - The staff [User](#class-user) who muted the user.
|
2591 | - `username` - The [User](#class-user) object of the user who was muted.
|
2592 | - `reason` - The reason for the mute.
|
2593 | - `duration` - The length of time the mute lasts for.
|
2594 |
|
2595 | ```js
|
2596 | mp.on('modMute', (data) => {
|
2597 | var length = '', reason = '', msg = `${data.moderator.username} `;
|
2598 |
|
2599 | switch (data.duration) {
|
2600 | case 'o': length = 'unmuted'; break;
|
2601 | case 's': length = '15'; break;
|
2602 | case 'm': length = '30'; break;
|
2603 | case 'l': length = '45'; break;
|
2604 | }
|
2605 |
|
2606 | switch (data.reason) {
|
2607 | case 1: reason = 'violating community rules'; break;
|
2608 | case 2: reason = 'verbal abuse or harassment'; break;
|
2609 | case 3: reason = 'spamming or trolling'; break;
|
2610 | case 4: reason = 'offensive language'; break;
|
2611 | case 5: reason = 'negative attitude'; break;
|
2612 | }
|
2613 |
|
2614 | if (data.duration == 'o')
|
2615 | msg += `unmuted ${data.user.username}`
|
2616 | else
|
2617 | msg += `muted ${data.user.username} (${length} mins) for ${reason}`
|
2618 |
|
2619 | console.log(msg)
|
2620 | })
|
2621 | ```
|
2622 |
|
2623 | <a id="#event-modremovedj"></a>
|
2624 | ## 'modRemoveDj'
|
2625 |
|
2626 | Fired when a moderator removes a user from the waitlist.
|
2627 |
|
2628 | **Parameters**
|
2629 |
|
2630 | - `moderator` - The staff [User](#class-user) who removed the user from the waitlist.
|
2631 | - `username` - The name of the user that was removed.
|
2632 | - `inBooth` - Weather the user was in the booth/djing (true/false)
|
2633 |
|
2634 | ```js
|
2635 | mp.on('modRemoveDj', (data) => {
|
2636 | console.log(`${data.moderator.username} has removed ${data.username} from the ${data.inBooth ? 'booth' : 'waitlist'}`)
|
2637 | })
|
2638 | ```
|
2639 |
|
2640 | <a id="#event-modskip"></a>
|
2641 | ## 'modSkip'
|
2642 |
|
2643 | Fired when a moderator skips the current song playing.
|
2644 |
|
2645 | **Parameters**
|
2646 |
|
2647 | - `moderator` - The staff [User](#class-user) who skipped the song.
|
2648 |
|
2649 | ```js
|
2650 | mp.on('modSkip', (moderator) => {
|
2651 | console.log(`${moderator.username} has skipped the current DJ`)
|
2652 | })
|
2653 | ```
|
2654 |
|
2655 | <a id="#event-modstaff"></a>
|
2656 | ## 'modStaff'
|
2657 |
|
2658 | Fired when a user is promoted or demoted.
|
2659 |
|
2660 | **Parameters**
|
2661 |
|
2662 | - `moderator` - The staff [User](#class-user) who promoted/demoted the user.
|
2663 | - `user` - The [User](#class-user) who was promoted/demoted.
|
2664 | - `role` - The role of the user who was promoted/demoted.
|
2665 |
|
2666 | ```js
|
2667 | mp.on('modStaff', (data) => {
|
2668 | var role = ''
|
2669 |
|
2670 | if (data.role === 1)
|
2671 | role = 'Resident DJ'
|
2672 | else if (data.role === 2)
|
2673 | role = 'Bouncer'
|
2674 | else if (data.role === 3)
|
2675 | role = 'Manager'
|
2676 | else if (data.role === 4)
|
2677 | role = 'Co-Host'
|
2678 | else if (data.role === 5)
|
2679 | role = 'Host'
|
2680 |
|
2681 | if (data.role == 0)
|
2682 | console.log(`${data.moderator.username} removed ${data.user.username} from the staff.`)
|
2683 | else
|
2684 | console.log(`${data.moderator.username} set ${data.user.username} as a ${role}.`)
|
2685 | })
|
2686 | ```
|
2687 |
|
2688 | <a id="event-waitlistban"></a>
|
2689 | <a id="event-modwaitlistban"></a>
|
2690 | ## 'modWaitlistBan'
|
2691 |
|
2692 | Fired when a user is banned from the waitlist.
|
2693 |
|
2694 | **Parameters**
|
2695 |
|
2696 | - `ban` - A [WaitlistBan](#class-waitlistban) object representing the new ban.
|
2697 |
|
2698 | ```js
|
2699 | mp.on('modWaitlistBan', (ban) => {
|
2700 | ban.user.chat('Ha! Sucker!')
|
2701 | })
|
2702 | ```
|
2703 |
|
2704 | <a id="event-roomupdate"></a>
|
2705 | ## 'roomUpdate'
|
2706 |
|
2707 | Fired when an attribute of the current room updates.
|
2708 |
|
2709 | **Parameters**
|
2710 |
|
2711 | - `change` - Object containing the new attribute/value pair. For example, if
|
2712 | the welcome message was changed, the object may contain
|
2713 | `{ welcome: 'Hello!' }`.
|
2714 | - `user` - The staff [User](#class-user) who made the change.
|
2715 |
|
2716 | ```js
|
2717 | const roomProperties = mp.room().toJSON()
|
2718 |
|
2719 | mp.on('roomUpdate', (change) => {
|
2720 | Object.assign(roomProperties, change)
|
2721 | })
|
2722 | ```
|
2723 |
|
2724 | <a id="event-roomnameupdate"></a>
|
2725 | ## 'roomNameUpdate'
|
2726 |
|
2727 | Fired when the room name was changed.
|
2728 |
|
2729 | **Parameters**
|
2730 |
|
2731 | - `name` - The new room name.
|
2732 | - `user` - The staff [User](#class-user) who made the change.
|
2733 |
|
2734 | ```js
|
2735 | mp.on('roomNameUpdate', (name, user) => {
|
2736 | console.log(user.mention(), 'changed the room name to', name)
|
2737 | })
|
2738 | ```
|
2739 |
|
2740 | <a id="event-roomdescriptionupdate"></a>
|
2741 | ## 'roomDescriptionUpdate'
|
2742 |
|
2743 | Fired when the room description was changed.
|
2744 |
|
2745 | **Parameters**
|
2746 |
|
2747 | - `description` - The new room description.
|
2748 | - `user` - The staff [User](#class-user) who made the change.
|
2749 |
|
2750 | ```js
|
2751 | mp.on('roomDescriptionUpdate', (description, user) => {
|
2752 | console.log(user.mention(), 'changed the room description to:')
|
2753 | console.log(description)
|
2754 | })
|
2755 | ```
|
2756 |
|
2757 | <a id="event-roomwelcomeupdate"></a>
|
2758 | ## 'roomWelcomeUpdate'
|
2759 |
|
2760 | Fired when the room welcome message was changed.
|
2761 |
|
2762 | **Parameters**
|
2763 |
|
2764 | - `welcome` - The new welcome message.
|
2765 | - `user` - The staff [User](#class-user) who made the change.
|
2766 |
|
2767 | ```js
|
2768 | mp.on('roomWelcomeUpdate', (welcome, user) => {
|
2769 | console.log(user.mention(), 'changed the welcome message.')
|
2770 | console.log('New users will now see', welcome)
|
2771 | })
|
2772 | ```
|
2773 |
|
2774 | <a id="event-roomminchatlevelupdate"></a>
|
2775 | ## 'roomMinChatLevelUpdate'
|
2776 |
|
2777 | Fired when the room's minimum chat level changes.
|
2778 |
|
2779 | **Parameters**
|
2780 |
|
2781 | - `minChatLevel` - The new minimum chat level.
|
2782 | - `user` - The staff [User](#class-user) who made the change.
|
2783 |
|
2784 | ```js
|
2785 | mp.on('roomMinChatLevelUpdate', (level, user) => {
|
2786 | console.log(user.mention(), 'changed the minimum chat level to', level)
|
2787 | })
|
2788 | ```
|
2789 |
|
2790 | <a id="event-skip"></a>
|
2791 | ## 'skip'
|
2792 |
|
2793 | Fired when a user skips their own play.
|
2794 |
|
2795 | **Parameters**
|
2796 |
|
2797 | - `user` - The [User](#class-user) object of the user who skipped.
|
2798 |
|
2799 | ```js
|
2800 | mp.on('skip', (user) => {
|
2801 | console.log(`${user.username} has decided to skip.`)
|
2802 | })
|
2803 | ```
|
2804 |
|
2805 | <a id="event-sub"></a>
|
2806 | ## 'sub'
|
2807 |
|
2808 | Fired when the current user gets a gold subscription membership.
|
2809 |
|
2810 | **Parameters**
|
2811 |
|
2812 | - `value` - The subscription value. 0 for no subscription, 1 for a gold subscription.
|
2813 |
|
2814 | ```js
|
2815 | mp.on('sub', (value) => {
|
2816 | if (value) mp.emote('is now a gold subscriber :tada:')
|
2817 | })
|
2818 | ```
|
2819 |
|
2820 | <a id="event-userjoin"></a>
|
2821 | ## 'userJoin'
|
2822 |
|
2823 | Fired when a user joins the room.
|
2824 |
|
2825 | **Parameters**
|
2826 |
|
2827 | - `user` - The [User](#class-user) object of the new user.
|
2828 |
|
2829 | ```js
|
2830 | mp.on('userJoin', (user) => {
|
2831 | user.send('Welcome!')
|
2832 | })
|
2833 | ```
|
2834 |
|
2835 | <a id="event-userleave"></a>
|
2836 | ## 'userLeave'
|
2837 |
|
2838 | Fired when a user leaves the room.
|
2839 |
|
2840 | **Parameters**
|
2841 |
|
2842 | - `user` - The [User](#class-user) object of the leaving user.
|
2843 |
|
2844 | ```js
|
2845 | const { BAN_DURATION, BAN_REASON } = require('miniplug')
|
2846 | mp.on('userLeave', (user) => {
|
2847 | // Alright then. GOOD BYE AND NEVER COME BACK!! 😠💢
|
2848 | user.ban(BAN_DURATION.PERMANENT, BAN_REASON.ATTITUDE)
|
2849 | })
|
2850 | ```
|
2851 |
|
2852 | <a id="event-userupdate"></a>
|
2853 | ## 'userUpdate'
|
2854 |
|
2855 | Fired when a user object was updated.
|
2856 |
|
2857 | **Parameters**
|
2858 |
|
2859 | - `user` - The [User](#class-user) object that is being updated.
|
2860 | - `prevProps` - An object containing the old values of the properties that have
|
2861 | changed.
|
2862 |
|
2863 | ```js
|
2864 | const { BAN_DURATION, BAN_REASON } = require('miniplug')
|
2865 | const { pick, keys } = require('lodash')
|
2866 |
|
2867 | mp.on('userUpdate', (user, prevProps) => {
|
2868 | const updatedPropsOnly = pick(user, keys(prevProps))
|
2869 |
|
2870 | console.log(`Updated ${user.mention()}:`)
|
2871 | console.log(prevProps, '→', updatedPropsOnly)
|
2872 | })
|
2873 | ```
|
2874 |
|
2875 | <a id="event-vote"></a>
|
2876 | ## 'vote'
|
2877 |
|
2878 | Fired when a user woots or mehs a song.
|
2879 |
|
2880 | **Parameters**
|
2881 |
|
2882 | - `data` - An object with two properties:
|
2883 | - `user` - The [User](#class-user) who voted.
|
2884 | - `vote` - The direction of the vote: `1` for a woot, `-1` for a meh.
|
2885 |
|
2886 | ```js
|
2887 | mp.on('vote', (data) => {
|
2888 | if (data.vote === 1) {
|
2889 | console.log(data.user.mention(), 'wooted this track!')
|
2890 | } else if (data.vote === -1) {
|
2891 | console.log(data.user.mention(), 'meh\'d this track…')
|
2892 | }
|
2893 | })
|
2894 | ```
|
2895 |
|
2896 | <a id="event-waitlistclear"></a>
|
2897 | ## 'waitlistClear'
|
2898 |
|
2899 | Fired when the waitlist is cleared.
|
2900 |
|
2901 | **Parameters**
|
2902 |
|
2903 | - `update` - An object with the following properties:
|
2904 | - `user` - The [User](#class-user) that cleared the waitlist.
|
2905 |
|
2906 | ```js
|
2907 | mp.on('waitlistClear', (update) => {
|
2908 | console.info(`${update.user.mention()} cleared the waitlist!`)
|
2909 | })
|
2910 | ```
|
2911 |
|
2912 | <a id="event-waitlistcycle"></a>
|
2913 | ## 'waitlistCycle'
|
2914 |
|
2915 | Fired when the waitlist cycle status changes.
|
2916 |
|
2917 | **Parameters**
|
2918 |
|
2919 | - `update` - An object with two properties:
|
2920 | - `shouldCycle` - Whether the waitlist should cycle.
|
2921 | - `user` - The [User](#class-user) that changed this setting.
|
2922 |
|
2923 | ```js
|
2924 | mp.on('waitlistCycle', (update) => {
|
2925 | console.info(`Waitlist cycling is now ${update.shouldCycle ? 'enabled' : 'disabled'}!`)
|
2926 | })
|
2927 | ```
|
2928 |
|
2929 | <a id="event-waitlistlock"></a>
|
2930 | ## 'waitlistLock'
|
2931 |
|
2932 | Fired when the waitlist lock status changes.
|
2933 |
|
2934 | **Parameters**
|
2935 |
|
2936 | - `update` - An object with the following properties:
|
2937 | - `locked` - A boolean indicating the new waitlist locked status.
|
2938 | - `cleared` - True if the waitlist was also cleared.
|
2939 | - `user` - The [User](#class-user) that changed this setting.
|
2940 |
|
2941 | ```js
|
2942 | mp.on('waitlistLock', (update) => {
|
2943 | let verb = 'unlocked'
|
2944 | if (update.cleared) verb = 'cleared'
|
2945 | else if (update.locked) verb = 'locked'
|
2946 |
|
2947 | console.info(`${update.user.mention()} ${verb} the waitlist.`)
|
2948 | })
|
2949 | ```
|
2950 |
|
2951 | <a id="event-waitlistupdate"></a>
|
2952 | ## 'waitlistUpdate'
|
2953 |
|
2954 | Fired when the waitlist changes.
|
2955 |
|
2956 | **Parameters**
|
2957 |
|
2958 | - `next` - The new [Waitlist](#class-waitlist).
|
2959 | - `previous` - The previous [Waitlist](#class-waitlist).
|
2960 |
|
2961 | ```js
|
2962 | mp.on('waitlistUpdate', (next, previous) => {
|
2963 | const me = mp.me()
|
2964 |
|
2965 | // Notify the next DJ that it is almost their turn.
|
2966 | if (next.length > 0) {
|
2967 | next[0].send('You are next!')
|
2968 | }
|
2969 |
|
2970 | // Both parameters are full Waitlist objects.
|
2971 | console.log('I moved from', previous.positionOf(me), 'to', next.positionOf(me))
|
2972 | })
|
2973 | ```
|
2974 |
|
2975 | <a id="errors"></a>
|
2976 | # Errors
|
2977 |
|
2978 | Miniplug wraps errors from the plug.dj API in custom error classes.
|
2979 | Specific types of errors can be caught using Bluebird's `catch` function:
|
2980 |
|
2981 | ```js
|
2982 | const miniplug = require('miniplug')
|
2983 |
|
2984 | const mp = miniplug({ /* credentials */ })
|
2985 | mp.purchaseNameChange('Test Name')
|
2986 | .catch(miniplug.NotEnoughPPError, (err) => {
|
2987 | console.error('You do not have enough Plug Points to change your name.')
|
2988 | })
|
2989 | ```
|
2990 |
|
2991 | All error objects have the following properties:
|
2992 |
|
2993 | - `message` - A human-readable string describing the reason for the error.
|
2994 | - `status` - A status code from plug.dj.
|
2995 | - `response` - The HTTP response object from [got](https://github.com/sindresorhus/got#goturl-options).
|
2996 | - `cause` - The error that was wrapped, usually one from [got](https://github.com/sindresorhus/got#errors).
|
2997 |
|
2998 | <a id="error-requesterror"></a>
|
2999 | ## RequestError
|
3000 |
|
3001 | A generic error that indicates that you have tried to do something impossible.
|
3002 |
|
3003 | <a id="error-badloginerror"></a>
|
3004 | ## BadLoginError
|
3005 |
|
3006 | The username/password combination was incorrect.
|
3007 |
|
3008 | <a id="error-notauthorizederror"></a>
|
3009 | ## NotAuthorizedError
|
3010 |
|
3011 | The bot account does not have permission to do this thing. Perhaps because the
|
3012 | thing requires you to be logged in, or to be a certain rank in the room.
|
3013 |
|
3014 | <a id="error-notfounderror"></a>
|
3015 | ## NotFoundError
|
3016 |
|
3017 | The thing you are looking for does not exist.
|
3018 |
|
3019 | <a id="error-novalidplaylisterror"></a>
|
3020 | ## NoValidPlaylistError
|
3021 |
|
3022 | The user to be added to the waitlist does not have a valid playlist.
|
3023 |
|
3024 | <a id="error-notenoughpperror"></a>
|
3025 | ## NotEnoughPPError
|
3026 |
|
3027 | The bot account does not have enough Plug Points to purchase this thing.
|