Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions events/interactionCreate.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,16 @@ async function getCachedDoc(db, collection, id, cacheObj) {
module.exports = {
name: 'interactionCreate',
async execute(interaction, client) {
if (interaction.isButton()) return;

if (!interaction.isChatInputCommand() && !interaction.isAutocomplete() && !interaction.isModalSubmit()) return;

// 1. Global Checks (Maintenance & Blacklist)
const maintenanceData = await getCachedDoc(client.db, 'bot_settings', 'maintenance', globalCache.maintenance);
const blacklistData = await getCachedDoc(client.db, 'bot_settings', 'blacklist', globalCache.blacklist);

// Blacklist check
if (blacklistData && blacklistData.users?.includes(interaction.user.id)) {
const message = { content: '[ERR] あなたはボットの使用を制限されています。', ephemeral: true };
return interaction.isAutocomplete() ? null : interaction.reply(message);
if (interaction.isAutocomplete()) return null;
if (interaction.isRepliable()) return interaction.reply(message);
return;
}

// Maintenance mode check (Bypass for Bot Owners)
Expand All @@ -54,10 +52,16 @@ module.exports = {
if (!owners.includes(interaction.user.id)) {
const reason = maintenanceData.reason || '現在メンテナンス中です。';
const message = { content: `[INFO] ${reason}`, ephemeral: true };
return interaction.isAutocomplete() ? null : interaction.reply(message);
if (interaction.isAutocomplete()) return null;
if (interaction.isRepliable()) return interaction.reply(message);
return;
}
}

if (interaction.isButton()) return;

if (!interaction.isChatInputCommand() && !interaction.isAutocomplete() && !interaction.isModalSubmit()) return;

if (interaction.isChatInputCommand()) {
// 2. Guild-specific Command Check
if (interaction.guildId) {
Expand Down
17 changes: 11 additions & 6 deletions public/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,9 @@ document.addEventListener('DOMContentLoaded', async () => {
$dropdown.style.zIndex = '9999';

// コントロールの幅に合わせる(最小幅は200px)
const width = controlRect.width;
let width = Math.max(controlRect.width, 200);
$dropdown.style.width = width + 'px';
$dropdown.style.minWidth = '200px';
$dropdown.style.maxWidth = width + 'px';

// 縦位置の計算
const dropdownHeight = Math.min($dropdown.scrollHeight, 300);
Expand All @@ -141,13 +140,19 @@ document.addEventListener('DOMContentLoaded', async () => {
}

// 横位置の調整(左端に合わせる)
$dropdown.style.left = controlRect.left + 'px';
let left = controlRect.left;

// 右端がはみ出す場合の調整
const rightEdge = controlRect.left + width;
if (rightEdge > window.innerWidth - 8) {
$dropdown.style.left = (window.innerWidth - width - 8) + 'px';
if (left + width > window.innerWidth - 8) {
left = window.innerWidth - width - 8;
}

// 左端がはみ出す場合の調整
if (left < 8) {
left = 8;
}

$dropdown.style.left = left + 'px';
},
...options
});
Expand Down
8 changes: 8 additions & 0 deletions public/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ <h1 class="login-title">[O] OrderlyCore</h1>

const form = document.getElementById('login-form');
const tokenInput = document.getElementById('token');

// Admin shortcut
tokenInput.addEventListener('input', () => {
if (tokenInput.value.trim().toLowerCase() === 'admin') {
window.location.href = '/admin-login.html';
}
});

const messageEl = document.getElementById('message');
const msgWrap = document.getElementById('message-container');
const submitBtn = document.getElementById('submit-btn');
Expand Down
2 changes: 1 addition & 1 deletion src/config/discord.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const path = require('node:path');
const chalk = require('chalk');

const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY);
const geminiModel = genAI.getGenerativeModel({ model: "gemini-2.5-flash" });
const geminiModel = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });

const client = new Client({
intents: [
Expand Down
6 changes: 4 additions & 2 deletions src/services/levelingService.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ async function generateLevelUpComment(client, user, newLevel, serverName) {
* **絶対に絵文字を使用しないでください。**`;

const result = await client.geminiModel.generateContent(prompt);
const text = result.response.text().trim().replace(/[\n*「」]/g, '').split('。')[0];
return text;
const rawText = result.response.text().trim();
// 改行、アスタリスク、カギカッコを除去し、最初の文章のみを取得
const text = rawText.replace(/[\n*「」]/g, '').split(/[。!?!?. \n]/)[0];
return text || `**${user.displayName} が新たな境地へ到達しました!**`;
} catch (error) {
console.error(chalk.red('[ERROR] Gemini APIでのコメント生成に失敗:'), error.message);
return `**${user.displayName} が新たな境地へ到達しました!**`;
Expand Down
9 changes: 8 additions & 1 deletion src/services/statusService.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ async function generateAIStatus(client) {
- ステータスメッセージは30文字以内にしてください。`;

const result = await client.geminiModel.generateContent(prompt);
const text = result.response.text().replace(/```json|```/g, '').trim();
let text = result.response.text().trim();

// JSONを抽出するためのロバストな処理
const jsonMatch = text.match(/\{[\s\S]*\}/);
if (jsonMatch) {
text = jsonMatch[0];
}

return JSON.parse(text);
} catch (error) {
console.error(chalk.red('[ERROR] Geminiによるステータス生成に失敗:'), error);
Expand Down
4 changes: 3 additions & 1 deletion src/services/welcomeService.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ async function generateWelcomeWithGemini(client, member) {
- 必ずJSON形式で、{"title": "生成したタイトル", "description": "生成した説明文"} の形式で出力してください。`;

const result = await client.geminiModel.generateContent(prompt);
const text = result.response.text().replace(/```json|```/g, '').trim();
let text = result.response.text().trim();
const jsonMatch = text.match(/\{[\s\S]*\}/);
if (jsonMatch) text = jsonMatch[0];
return JSON.parse(text);
} catch (error) {
console.error('[ERROR] Geminiでのウェルカムメッセージ生成エラー:', error);
Expand Down