mjpin is a modular Node.js Discord bot designed to automate pinning Midjourney-generated images from Discord messages to your Pinterest boards. It supports multiple Pinterest accounts and includes features for workflow automation.
Note: This repository does not include prompt
.txtfiles. Create your own indata/followingdata/README.md.
- /pin: Search channel history for keyword-matching images and automatically pin up to 10 found images to Pinterest boards. Optionally specify a different board name.
- /auth: Authenticate your Pinterest account with the bot using a secure OAuth2 flow.
- /sync: Sync your Pinterest boards to make them available for pinning.
- /prompt: Generate a Midjourney prompt using OpenAI with per-guild model selection.
- /model: (Requires Manage Server) Choose the OpenAI model for the server from available chat-capable models.
- /editprompt: (Requires Administrator) Edit the system prompt files used for prompt generation. Supports modular editing of individual prompt sections.
- /settings: View and manage active Pinterest account and pin count status.
- /restart: (Requires Administrator) Restart the bot process (requires PM2 deployment).
- Pin Rate Limiting: Prevents API spam by limiting pins to 100 per 12-hour period per Pinterest account.
- Multi-Account Support: Authenticate and use multiple Pinterest accounts.
src/index.js: The main entry point for the bot with centralized command registration and interaction handling.src/commands/: Contains all the slash command handlers (pin, prompt, model, auth, sync, settings, editprompt, restart).src/services/: Houses integration logic for third-party APIs (pinterest.js, openai.js, modelSettings.js, pinterest-auth.php).src/utils/: Includes utility functions (jsonFileManager.js, pinRateLimit.js, messageSearch.js).data/: Contains user-created modular prompt.txtfiles. Any.txtfile in this directory will be automatically included in the system prompt.
- Clone the repository:
git clone <repository-url> cd mjpin
- Install dependencies:
npm install
- Set up environment variables:
- Copy the example file and fill in your values:
cp .env.example .env
- See the Environment Variables section below for details.
- Copy the example file and fill in your values:
- Prepare the data directory:
- Ensure a
data/directory exists at the project root. - Create your prompt chunk
.txtfiles. Seedata/README.mdfor how prompts are assembled and how to keep private prompts out of git while still being loaded by the bot.
- Ensure a
- Run the bot:
- Development:
npm start
- Production with pm2:
pm2 start src/index.js --name mjpin
- Development:
All secrets and API keys are managed via the .env file.
MJPIN_DISCORD_TOKEN: Your Discord bot token.MJPIN_DISCORD_CLIENT_ID: Your Discord application's client ID.MJPIN_DISCORD_GUILD_ID: The Discord server (guild) ID where you will register the slash commands.MJPIN_PINTEREST_CLIENT_ID: Your Pinterest application's client ID.MJPIN_PINTEREST_CLIENT_SECRET: Your Pinterest application's client secret.MJPIN_PINTEREST_REDIRECT_URI: The OAuth redirect URI for your Pinterest app (e.g.,https://your-domain.com/pinterest/callback). OAuth callback handled bysrc/services/pinterest-auth.php.MJPIN_OPENAI_API_KEY: Your OpenAI API key.- Optional:
MJPIN_OPENAI_SYSTEM_PROMPT(used as fallback if no.txtprompt files can be read fromdata/).
Note: OpenAI model selection is managed per-guild using the /model command. Each Discord server configures its preferred chat-capable model independently.
See data/README.md for complete details on:
- How all top-level
.txtfiles indata/are concatenated to form the system prompt - File ordering via numeric prefixes (e.g.,
00_,10_, ...) - Keeping private prompt files out of git while still loaded (e.g.,
*.private.txt,*.local.txt) - Runtime JSON files created by the bot that should not be committed
- Have both bots in the same Discord server
- Add the Midjourney bot to your server (per Midjourney's instructions).
- Add your mjpin bot to the same server, with scopes
botandapplications.commandsand permissions to read/send messages.
- Start mjpin and register commands
- Run the bot (
npm startor pm2). The bot will register its slash commands in your guild automatically on startup.
- Run the bot (
- Configure OpenAI model (Admin-only)
- Run
/modelto select the OpenAI model for your server from available chat-capable models. This is required before using/prompt.
- Run
- Connect Pinterest
- In Discord, run
/authand click the link to authorize. After approval, the OAuth callback endpoint stores your tokens.
- In Discord, run
- Sync your boards
- Run
/syncto pull your Pinterest boards into the bot.
- Run
- Generate prompts
- Run
/promptwith your idea. Copy the returned prompts.
- Run
- Create images in Midjourney
- Paste a prompt into the Midjourney bot in the same server/channel and generate images.
- Pin the images
- Run
/pinwith:keyword: The search term for finding images (also used as board name).url: The destination URL for the pins.board: (Optional) Specific board name to pin to (defaults to keyword).
- The bot automatically searches for matching images after your last
/pincommand and pins them.
- Run
- Manage accounts (optional)
- Use
/settingsto view or switch the active Pinterest account.
- Use
- Run
/authin Discord. The bot replies with an authorization URL. - Authorize the app. Pinterest redirects to your
MJPIN_PINTEREST_REDIRECT_URI. - The OAuth callback endpoint handles authorization code exchange and stores credentials in
data/pinterest_tokens.json. - Run
/syncto fetch your Pinterest boards for the authenticated account. - Use
/settingsto view/switch the active Pinterest account if you have multiple accounts.
Contributions are welcome. Please adhere to the existing code structure and principles of modularity and security.
Chris Huber — https://chubes.net