diff --git a/events/interactionCreate.js b/events/interactionCreate.js
index 5b94e14..91a15ec 100644
--- a/events/interactionCreate.js
+++ b/events/interactionCreate.js
@@ -29,10 +29,6 @@ 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);
@@ -40,7 +36,9 @@ module.exports = {
// 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)
@@ -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) {
diff --git a/public/client.js b/public/client.js
index 62695df..c460c6a 100644
--- a/public/client.js
+++ b/public/client.js
@@ -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);
@@ -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
});
diff --git a/public/login.html b/public/login.html
index 5d60eb7..bdffd45 100644
--- a/public/login.html
+++ b/public/login.html
@@ -51,6 +51,14 @@
[O] OrderlyCore
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');
diff --git a/src/config/discord.js b/src/config/discord.js
index 8d8a71d..556b9b2 100644
--- a/src/config/discord.js
+++ b/src/config/discord.js
@@ -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: [
diff --git a/src/services/levelingService.js b/src/services/levelingService.js
index 44d6f81..69d18b9 100644
--- a/src/services/levelingService.js
+++ b/src/services/levelingService.js
@@ -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} が新たな境地へ到達しました!**`;
diff --git a/src/services/statusService.js b/src/services/statusService.js
index 2406e1b..04a9885 100644
--- a/src/services/statusService.js
+++ b/src/services/statusService.js
@@ -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);
diff --git a/src/services/welcomeService.js b/src/services/welcomeService.js
index 642dc9d..76926f7 100644
--- a/src/services/welcomeService.js
+++ b/src/services/welcomeService.js
@@ -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);