Last active
January 31, 2025 17:40
-
-
Save Meshiest/2410fd3c896cc4264fec3c8f6760a6fa to your computer and use it in GitHub Desktop.
a better discord plugin for pinging me only for specific users
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @name PingMePlease | |
* @source https://gist.github.com/Meshiest/2410fd3c896cc4264fec3c8f6760a6fa | |
* @updateUrl https://gist.githubusercontent.com/Meshiest/2410fd3c896cc4264fec3c8f6760a6fa/raw/PingMePlease.plugin.js | |
* @website https://gist.github.com/Meshiest/2410fd3c896cc4264fec3c8f6760a6fa | |
* @version 0.0.4 | |
*/ | |
const request = require('request'); | |
const fs = require('fs'); | |
const path = require('path'); | |
const config = { | |
info: { | |
name: 'PingMePlease', | |
authors: [ | |
{ | |
name: 'cake', | |
discord_id: '122931452319891456', | |
github_username: 'Meshiest', | |
}, | |
], | |
github_raw: | |
'https://gist.githubusercontent.com/Meshiest/2410fd3c896cc4264fec3c8f6760a6fa/raw/PingMePlease.plugin.js', | |
version: '0.0.4', | |
description: 'Sends message notifications for specific users', | |
}, | |
defaultConfig: [ | |
{ | |
type: 'textbox', | |
name: 'User IDs (Split with `,`)', | |
note: 'Only send notification sounds for users with this id.', | |
id: 'userIds', | |
value: '', | |
}, | |
{ | |
type: 'slider', | |
name: 'Volume', | |
note: 'Notification volume', | |
min: 0, | |
max: 1, | |
id: 'volume', | |
value: 0.5, | |
stickToMarkers: false, | |
}, | |
], | |
}; | |
module.exports = !global.ZeresPluginLibrary | |
? class { | |
constructor() { } | |
load() { | |
BdApi.showConfirmationModal( | |
'Library plugin is needed', | |
`A Library plugin for PingMePlease is missing. Please click "Download" to install it.`, | |
{ | |
confirmText: 'Download', | |
cancelText: 'Cancel', | |
onConfirm: () => { | |
request.get( | |
'https://rauenzi.github.io/BDPluginLibrary/release/0PluginLibrary.plugin.js', | |
(error, response, body) => { | |
if (error) | |
return electron.shell.openExternal( | |
'https://betterdiscord.net/ghdl?url=https://raw.githubusercontent.com/rauenzi/BDPluginLibrary/master/release/0PluginLibrary.plugin.js' | |
); | |
fs.writeFileSync( | |
path.join(BdApi.Plugins.folder, '0PluginLibrary.plugin.js'), | |
body | |
); | |
BdApi.showToast('Finished downloading 0PluginLibrary', { | |
type: 'success', | |
}); | |
} | |
); | |
}, | |
} | |
); | |
} | |
start() { } | |
stop() { } | |
} | |
: !window.BDFDB_Global || | |
(!window.BDFDB_Global.loaded && !window.BDFDB_Global.started) | |
? class { | |
constructor() { } | |
load() { | |
BdApi.showConfirmationModal( | |
'Library plugin is needed', | |
`A Library plugin for PingMePlease is missing. Please click "Download" to install it.`, | |
{ | |
confirmText: 'Download', | |
cancelText: 'Cancel', | |
onConfirm: () => { | |
request.get( | |
'https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js', | |
(error, response, body) => { | |
if (error) | |
return electron.shell.openExternal( | |
'https://betterdiscord.net/ghdl?url=https://mwittrien.github.io/BetterDiscordAddons/Library/0BDFDB.plugin.js' | |
); | |
fs.writeFileSync( | |
path.join(BdApi.Plugins.folder, '0BDFDB.plugin.js'), | |
body | |
); | |
BdApi.showToast('Finished downloading BDFDB', { | |
type: 'success', | |
}); | |
} | |
); | |
}, | |
} | |
); | |
} | |
start() { } | |
stop() { } | |
} | |
: (([Plugin, { DiscordModules, Patcher }]) => { | |
const { | |
Dispatcher, | |
ChannelStore, | |
MediaInfo, | |
UserStore, | |
UserStatusStore, | |
WindowInfo, | |
SelectedChannelStore, | |
} = DiscordModules; | |
let BDFDB; | |
const soundParser = (src) => { | |
if (!BDFDB?.LibraryModules?.SoundParser) | |
BDFDB = BDFDB_Global.PluginUtils.buildPlugin()[1]; | |
return BDFDB?.LibraryModules?.SoundParser?.(src) ?? src; | |
}; | |
let audioDevice; | |
let lastPing = Date.now(); | |
const defaultAudioDevice = 'default'; | |
const change = () => { | |
if ( | |
window.navigator.mediaDevices && | |
window.navigator.mediaDevices.enumerateDevices | |
) { | |
window.navigator.mediaDevices | |
.enumerateDevices() | |
.then(enumeratedDevices => { | |
const id = MediaInfo.getOutputDeviceId(); | |
const allDevices = MediaInfo.getOutputDevices(); | |
const filteredDevices = enumeratedDevices.filter( | |
d => d.kind == 'audiooutput' && d.deviceId != 'communications' | |
); | |
const deviceIndex = | |
Object.values(allDevices) | |
.sort((a, b) => a.index - b.index) | |
.findIndex(d => d.id == id) - 1; | |
const deviceViaId = allDevices[id]; | |
let deviceViaIndex = filteredDevices[deviceIndex]; | |
if ( | |
deviceViaId && | |
deviceViaIndex && | |
deviceViaIndex.label != deviceViaId.name | |
) | |
deviceViaIndex = filteredDevices.find( | |
d => d.label == deviceViaId.name | |
); | |
audioDevice = deviceViaIndex | |
? deviceViaIndex.deviceId | |
: defaultAudioDevice; | |
}) | |
.catch(err => { | |
console.error('error getting audio device', err); | |
audioDevice = defaultAudioDevice; | |
}); | |
} | |
}; | |
const WebAudioSound = class WebAudioSound { | |
constructor(src, volume) { | |
this._src = soundParser(src); | |
this._volume = volume; | |
} | |
loop() { | |
this._ensureAudio().then(audio => { | |
audio.loop = true; | |
audio.play(); | |
}); | |
} | |
play() { | |
this._ensureAudio().then(audio => { | |
audio.loop = false; | |
audio.play(); | |
}); | |
} | |
pause() { | |
this._audio.then(audio => { | |
audio.pause(); | |
}); | |
} | |
stop() { | |
this._destroyAudio(); | |
} | |
setTime(time) { | |
this._audio.then(audio => { | |
audio.currentTime = time; | |
}); | |
} | |
setLoop(loop) { | |
this._audio.then(audio => { | |
audio.loop = loop; | |
}); | |
} | |
_destroyAudio() { | |
if (this._audio) { | |
this._audio.then(audio => { | |
audio.pause(); | |
audio.src = ''; | |
}); | |
this._audio = null; | |
} | |
} | |
_ensureAudio() { | |
return ( | |
(this._audio = | |
this._audio || | |
new Promise((callback, errorCallback) => { | |
let audio = new Audio(); | |
audio.src = | |
this._src && this._src.startsWith('data') | |
? this._src.replace(/ /g, '') | |
: this._src; | |
audio.onloadeddata = _ => { | |
audio.volume = Math.min( | |
(MediaInfo.getOutputVolume() / 100) * this._volume, | |
1 | |
); | |
audio.setSinkId(audioDevice || defaultAudioDevice); | |
callback(audio); | |
}; | |
audio.onerror = err => { | |
errorCallback(new Error('could not play audio')); | |
console.error('Error playing audio', err); | |
}; | |
audio.onended = _ => this._destroyAudio(); | |
audio.load(); | |
})), | |
this._audio | |
); | |
} | |
}; | |
let sound; | |
return class plugin extends Plugin { | |
constructor() { | |
super(); | |
this.getSettingsPanel = () => { | |
return this.buildSettingsPanel().getElement(); | |
}; | |
const om = this.onMessage.bind(this); | |
this.onMessage = e => { | |
try { | |
om(e); | |
} catch (e) { | |
console.error(e); | |
} | |
}; | |
} | |
onStart() { | |
MediaInfo.addChangeListener(change); | |
change(); | |
Dispatcher.subscribe('MESSAGE_CREATE', this.onMessage); | |
} | |
onStop() { | |
Dispatcher.unsubscribe('MESSAGE_CREATE', this.onMessage); | |
MediaInfo.removeChangeListener(change); | |
Patcher.unpatchAll(); | |
} | |
getStatus() { | |
const { id } = UserStore.getCurrentUser(); | |
return UserStatusStore.getStatus(id); | |
} | |
playSound() { | |
if (sound) sound.stop(); | |
sound = new WebAudioSound('./message3.mp3', this.settings.volume); | |
sound.play(); | |
} | |
onMessage({ message }) { | |
// one ping every 5 seconds | |
if (Date.now() < lastPing + 5000) return; | |
// online or invisible only | |
const status = this.getStatus(); | |
if (status !== 'online' && status !== 'invisible') return; | |
// not in config | |
const userIds = this.settings.userIds | |
.trim() | |
.split(',') | |
.filter(Boolean); | |
if (!userIds.includes(message.author.id)) return; | |
// channel isn't dm or group chat | |
const channel = ChannelStore.getChannel(message.channel_id); | |
const isGroupDM = channel.type === 3; // guild dm | |
const isDM = channel.type === 1; // dm; | |
if (!isGroupDM && !isDM) return; | |
// only when window isn't focused and that channel is open | |
if (WindowInfo.isFocused() && SelectedChannelStore.getChannelId() === channel.id) return; | |
// play the sound and update the last ping time | |
lastPing = Date.now(); | |
this.playSound(); | |
} | |
}; | |
})(global.ZeresPluginLibrary.buildPlugin(config)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment