
Research
/Security News
Coruna Respawned: Compromised art-template npm Package Leads to iOS Browser Exploit Kit
Compromised npm package art-template delivered a Coruna-like iOS Safari exploit framework through a watering-hole attack.
discord-patreon
Advanced tools
Monitor Patreon membership events and integrate with Discord, including Discord IDs and status tracking
A Node.js package for integrating Patreon membership events with Discord, enabling automatic role management based on patron status.
npm install discord-patreon
Or with Yarn:
yarn add discord-patreon
const { PatreonEvents } = require('discord-patreon');
// Initialize with your credentials
const patreon = new PatreonEvents({
accessToken: 'your-patreon-access-token',
campaignId: 'your-campaign-id'
});
// Subscribe to events
patreon.on('ready', () => {
console.log('Patreon monitoring started!');
});
patreon.on('subscribed', (member) => {
console.log(`New patron: ${member.fullName} (${member.id})`);
console.log(`Discord ID: ${member.discordId || 'Not connected'}`);
});
// Start monitoring
patreon.initialize();
const patreon = new PatreonEvents({
// Required configuration
accessToken: 'your-patreon-access-token',
campaignId: 'your-campaign-id',
// Optional configuration
checkInterval: 60000, // How often to check for updates (ms), default: 60000 (1 minute)
cacheFile: './patreon-cache.json', // Custom cache file path
cacheSaveInterval: 300000 // How often to save cache (ms), default: 300000 (5 minutes)
});
| Event | Description | Parameter |
|---|---|---|
ready | Emitted when monitoring has started | None |
subscribed | Emitted when a new patron subscribes | Patron data object |
canceled | Emitted when a patron cancels their subscription | Patron data object |
declined | Emitted when a patron's payment is declined | Patron data object |
reactivated | Emitted when a canceled patron reactivates | Patron data object |
connected | Emitted when a patron connects their Discord account | Patron data object |
disconnected | Emitted when a patron disconnects their Discord account | Patron data object |
expired | Emitted when a membership expires | Patron data object |
error | Emitted when an error occurs | Error object |
Each patron object contains:
{
id: string; // Patreon member ID
status: string; // Status: active_patron, declined_patron, former_patron
fullName?: string; // Patron's full name (if available)
email?: string; // Patron's email (if available)
patronStatus?: string; // Detailed patron status
pledgeAmount?: number; // Amount in dollars (if available)
discordId: string | null; // Discord user ID (if connected)
joinedAt?: string; // When they became a patron
expiresAt?: string; // When their current pledge expires
relationships?: any; // Raw relationships data from Patreon API
tierId?: string; // ID of the membership tier the patron is subscribed to
}
You can access membership tier information using the tiers property of the PatreonEvents instance:
const { PatreonEvents } = require('discord-patreon');
const patreon = new PatreonEvents({
accessToken: 'your-patreon-access-token',
campaignId: 'your-campaign-id'
});
patreon.on('ready', () => {
// Get all available tiers
const allTiers = patreon.tiers.getAll();
console.log('Available membership tiers:');
allTiers.forEach(tier => {
console.log(`- ${tier.title}: $${tier.price}`);
});
// Get a specific tier's information by ID
const specificTier = patreon.tiers.get('tier-id-here');
if (specificTier) {
console.log(`Tier "${specificTier.title}" costs $${specificTier.price}/month`);
}
// Get just the price of a tier
const tierPrice = patreon.tiers.getPrice('tier-id-here');
console.log(`This tier costs $${tierPrice}`);
// Get a patron's tier price
const patron = patreon.users.get('discord-id-here');
if (patron && patron.tierId) {
const patronTierPrice = patreon.tiers.getPrice(patron.tierId);
console.log(`${patron.fullName} is on a $${patronTierPrice}/month tier`);
}
});
patreon.initialize();
Each tier object contains:
{
id: string; // Patreon tier ID
title: string; // Tier title (e.g., "Bronze", "Silver", "Gold")
price: number; // Price in dollars (e.g., 5.00)
amountCents: number; // Raw price in cents (e.g., 500)
}
const { Client, GatewayIntentBits } = require('discord.js');
const { PatreonEvents } = require('discord-patreon');
// Initialize Discord client
const client = new Client({
intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers]
});
// Initialize Patreon events
const patreon = new PatreonEvents({
accessToken: 'your-patreon-access-token',
campaignId: 'your-campaign-id',
cacheFile: './patreon-cache.json'
});
// Set up role management functions
async function addPatronRole(discordId) {
const guild = client.guilds.cache.get('your-guild-id');
if (!guild) return;
try {
const member = await guild.members.fetch(discordId);
if (member) {
await member.roles.add('patron-role-id');
console.log(`Added patron role to ${member.user.tag}`);
}
} catch (error) {
console.error(`Failed to add role: ${error.message}`);
}
}
async function removePatronRole(discordId) {
const guild = client.guilds.cache.get('your-guild-id');
if (!guild) return;
try {
const member = await guild.members.fetch(discordId);
if (member) {
await member.roles.remove('patron-role-id');
console.log(`Removed patron role from ${member.user.tag}`);
}
} catch (error) {
console.error(`Failed to remove role: ${error.message}`);
}
}
// Handle Patreon events
patreon.on('ready', () => {
console.log('Patreon monitoring started!');
});
patreon.on('subscribed', (member) => {
console.log(`New patron: ${member.fullName}`);
if (member.discordId) {
addPatronRole(member.discordId);
}
});
patreon.on('connected', (member) => {
console.log(`Patron connected Discord: ${member.discordId}`);
addPatronRole(member.discordId);
});
patreon.on('canceled', (member) => {
console.log(`Patron canceled: ${member.fullName}`);
if (member.discordId) {
removePatronRole(member.discordId);
}
});
patreon.on('declined', (member) => {
console.log(`Patron payment declined: ${member.fullName}`);
if (member.discordId) {
removePatronRole(member.discordId);
}
});
patreon.on('disconnected', (member) => {
console.log(`Patron disconnected Discord: ${member.discordId}`);
removePatronRole(member.discordId);
});
// Start both systems
client.once('ready', () => {
console.log(`Logged in as ${client.user.tag}`);
patreon.initialize();
});
client.login('your-discord-bot-token');
const { PatreonEvents } = require('discord-patreon');
const patreon = new PatreonEvents({
accessToken: 'your-patreon-access-token',
campaignId: 'your-campaign-id'
});
// Initialize and wait for ready event
patreon.on('ready', () => {
// Now you can look up patrons by Discord ID
const checkPatronStatus = (discordId) => {
const patron = patreon.users.get(discordId);
if (patron) {
console.log(`Found patron: ${patron.fullName}`);
console.log(`Status: ${patron.status}`);
console.log(`Pledge amount: $${patron.pledgeAmount || 'unknown'}`);
return true;
} else {
console.log(`No patron found with Discord ID: ${discordId}`);
return false;
}
};
// Example usage
checkPatronStatus('559253955230695426');
});
patreon.initialize();
The package includes a robust caching system that:
This ensures your application won't send duplicate welcome messages or assign roles multiple times.
// Configure with a cache file
const patreon = new PatreonEvents({
accessToken: 'your-patreon-access-token',
campaignId: 'your-campaign-id',
cacheFile: './data/patreon-cache.json' // Custom location
});
// The cache will be saved automatically and loaded on restart
To use this package, you need:
identityidentity[email]campaignscampaigns.memberscampaigns.members.addresscampaigns.members[email]Patreon has API rate limits. To avoid hitting these limits:
checkInterval (60000ms or higher recommended)To ensure the cache is saved properly before your application exits:
// Handle graceful shutdown
process.on('SIGINT', () => {
console.log('Shutting down...');
patreon.stop(); // This saves the cache and cleans up
process.exit(0);
});
initialize() after setting up event listenersidentity scopeContributions are welcome! Please feel free to submit a Pull Request.
For questions or support, please contact: devszero on Discord.
IMPORTANT: This package is currently in early development. You may encounter bugs or changes to the API in future versions. Error handling for edge cases is still being refined, and some features might not work as expected with all Patreon account configurations. Please report any issues on the GitHub repository.
FAQs
Monitor Patreon membership events and integrate with Discord, including Discord IDs and status tracking
We found that discord-patreon demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Compromised npm package art-template delivered a Coruna-like iOS Safari exploit framework through a watering-hole attack.

Company News
As AI accelerates how code is written and shipped, Socket is scaling to protect the software supply chain from the growing wave of attacks targeting open source dependencies.

Company News
Socket is scaling to defend open source against supply chain attacks as AI accelerates software development.