├── .github └── FUNDING.yml ├── .gitignore ├── .npmignore ├── .npmrc ├── README.md ├── index.js ├── package.json ├── test.js └── webpack.config.js /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [devsnek] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | custom: # Replace with a single custom sponsorship URL 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | browser.js 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | test.js 3 | webpack.config.js 4 | README.md 5 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 | Discord server 5 | NPM version 6 | NPM downloads 7 | Dependencies 8 |

9 |

10 | NPM info 11 |

12 |
13 | 14 | # Discord Rich Presence 15 | 16 | A simple wrapper around [discord-rpc](https://npmjs.org/discord-rpc) 17 | 18 | ### Example 19 | 20 | ```javascript 21 | const client = require('discord-rich-presence')('180984871685062656'); 22 | 23 | client.updatePresence({ 24 | state: 'slithering', 25 | details: '🐍', 26 | startTimestamp: Date.now(), 27 | endTimestamp: Date.now() + 1337, 28 | largeImageKey: 'snek_large', 29 | smallImageKey: 'snek_small', 30 | instance: true, 31 | }); 32 | ``` 33 | 34 | In browser you can import/require it as `discord-rich-presence/browser`. 35 | However, it should be noted that currently using rich presence in browser is 36 | a feature whitelisted by Discord, and you will most likely be unable to use it. 37 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Discord = require('discord-rpc'); 4 | const EventEmitter = require('events'); 5 | 6 | const browser = typeof window !== 'undefined'; 7 | 8 | function makeClient(clientId) { 9 | const rpc = new Discord.Client({ transport: browser ? 'websocket' : 'ipc' }); 10 | 11 | let connected = false; 12 | let activityCache = null; 13 | 14 | const instance = new class RP extends EventEmitter { 15 | updatePresence(d) { 16 | if (connected) { 17 | rpc.setActivity(d).catch((e) => this.emit('error', e)); 18 | } else { 19 | activityCache = d; 20 | } 21 | } 22 | 23 | reply(user, response) { 24 | const handle = (e) => this.emit('error', e); 25 | switch (response) { 26 | case 'YES': 27 | rpc.sendJoinInvite(user).catch(handle); 28 | break; 29 | case 'NO': 30 | case 'IGNORE': 31 | rpc.closeJoinRequest(user).catch(handle); 32 | break; 33 | default: 34 | throw new RangeError('unknown response'); 35 | } 36 | } 37 | 38 | disconnect() { 39 | rpc.destroy().catch((e) => this.emit('error', e)); 40 | } 41 | }(); 42 | 43 | rpc.on('error', (e) => instance.emit('error', e)); 44 | 45 | rpc.login({ clientId }) 46 | .then(() => { 47 | instance.emit('connected'); 48 | connected = true; 49 | 50 | rpc.subscribe('ACTIVITY_JOIN', ({ secret }) => { 51 | instance.emit('join', secret); 52 | }); 53 | rpc.subscribe('ACTIVITY_SPECTATE', ({ secret }) => { 54 | instance.emit('spectate', secret); 55 | }); 56 | rpc.subscribe('ACTIVITY_JOIN_REQUEST', (user) => { 57 | instance.emit('joinRequest', user); 58 | }); 59 | 60 | if (activityCache) { 61 | rpc.setActivity(activityCache).catch((e) => instance.emit('error', e)); 62 | activityCache = null; 63 | } 64 | }) 65 | .catch((e) => instance.emit('error', e)); 66 | 67 | return instance; 68 | } 69 | 70 | module.exports = makeClient; 71 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "discord-rich-presence", 3 | "version": "0.0.8", 4 | "description": "rich presence wrapper for discord-rpc", 5 | "main": "index.js", 6 | "unpkg": "browser.js", 7 | "jsdelivr": "browser.js", 8 | "scripts": { 9 | "build:browser": "webpack", 10 | "prepublishOnly": "env NODE_ENV=production npm run build:browser" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/devsnek/discord-rich-presence.git" 15 | }, 16 | "keywords": [ 17 | "discord", 18 | "rich", 19 | "presence", 20 | "rpc" 21 | ], 22 | "author": "snek ", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/devsnek/discord-rich-presence/issues" 26 | }, 27 | "homepage": "https://github.com/devsnek/discord-rich-presence#readme", 28 | "dependencies": { 29 | "discord-rpc": "github:discordjs/rpc" 30 | }, 31 | "devDependencies": { 32 | "uglifyjs-webpack-plugin": "^1.1.2", 33 | "webpack": "^3.10.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const client = require('.')('180984871685062656'); 4 | 5 | client.on('join', (secret) => { 6 | console.log('we should join with', secret); 7 | }); 8 | 9 | client.on('spectate', (secret) => { 10 | console.log('we should spectate with', secret); 11 | }); 12 | 13 | client.on('joinRequest', (user) => { 14 | if (user.discriminator === '1337') { 15 | client.reply(user, 'YES'); 16 | } else { 17 | client.reply(user, 'IGNORE'); 18 | } 19 | }); 20 | 21 | client.on('connected', () => { 22 | console.log('connected!'); 23 | 24 | client.updatePresence({ 25 | state: 'slithering', 26 | details: '🐍', 27 | startTimestamp: new Date(), 28 | largeImageKey: 'snek_large', 29 | smallImageKey: 'snek_small', 30 | partyId: 'snek_party', 31 | partySize: 1, 32 | partyMax: 1, 33 | matchSecret: 'slithers', 34 | joinSecret: 'boop', 35 | spectateSecret: 'sniff', 36 | }); 37 | }); 38 | 39 | process.on('unhandledRejection', console.error); 40 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); 4 | 5 | const plugins = [ 6 | new webpack.optimize.ModuleConcatenationPlugin(), 7 | ]; 8 | 9 | const prod = process.env.NODE_ENV === 'production'; 10 | 11 | if (prod) { 12 | plugins.push(new UglifyJSPlugin({ 13 | uglifyOptions: { 14 | mangle: { keep_classnames: true }, 15 | output: { comments: false }, 16 | }, 17 | })); 18 | } 19 | 20 | module.exports = { 21 | entry: './index.js', 22 | output: { 23 | path: path.resolve('.'), 24 | filename: 'browser.js', 25 | library: 'DiscordRichPresence', 26 | libraryTarget: 'umd', 27 | }, 28 | module: { 29 | rules: [ 30 | { test: /\.md$/, loader: 'ignore-loader' }, 31 | ], 32 | }, 33 | node: { 34 | fs: 'empty', 35 | dns: 'empty', 36 | tls: 'empty', 37 | child_process: 'empty', 38 | dgram: 'empty', 39 | __dirname: true, 40 | process: false, 41 | path: 'empty', 42 | Buffer: false, 43 | zlib: 'empty', 44 | }, 45 | plugins, 46 | }; 47 | --------------------------------------------------------------------------------