Skip to content

Instantly share code, notes, and snippets.

@Meshiest
Last active January 12, 2023 19:45
Show Gist options
  • Save Meshiest/2410fd3c896cc4264fec3c8f6760a6fa to your computer and use it in GitHub Desktop.
Save Meshiest/2410fd3c896cc4264fec3c8f6760a6fa to your computer and use it in GitHub Desktop.
a better discord plugin for pinging me only for specific users
/**
* @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