-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add RSS feed registration and management commands (#110)
Implement commands to register and delete RSS feeds, along with an RSS parser. Update versioning and remove unnecessary development scripts.
- Loading branch information
Showing
11 changed files
with
364 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js"); | ||
const { addSubCommand, subCommandHandling } = require("../../lib/commandUtils"); | ||
const { GetLogChannel, GetErrorChannel } = require("../../lib/channelUtils"); | ||
|
||
module.exports = { | ||
guildOnly: true, | ||
adminGuildOnly: true, | ||
handlingCommands: subCommandHandling("admin/feed"), | ||
data: addSubCommand( | ||
"admin/feed", | ||
new SlashCommandBuilder() | ||
.setName("feed") | ||
.setDescription("RSS feed/atom feed Utilities") | ||
), | ||
/*data: new SlashCommandBuilder() | ||
.setName("feed") | ||
.setDescription("Regist RSS feed") | ||
.addStringOption((option) => | ||
option.setName("url").setDescription("URL of RSS feed").setRequired(true) | ||
),*/ | ||
async execute(interaction) { | ||
if (interaction.member.permissions.has("ADMINISTRATOR") === false) { | ||
interaction.reply({ | ||
content: "You don't have permission to use this command.", | ||
ephemeral: true, | ||
}); | ||
return "No permission"; | ||
} | ||
const command = this.handlingCommands.get( | ||
interaction.options.getSubcommand() | ||
); | ||
await interaction.deferReply(); | ||
if (!command) { | ||
console.log(`[-] Not Found: ${interaction.options.getSubcommand()}`); | ||
return; | ||
} | ||
try { | ||
await command.execute(interaction); | ||
console.log(`[Run] ${interaction.options.getSubcommand()}`); | ||
|
||
const logEmbed = new EmbedBuilder() | ||
.setTitle("サブコマンド実行ログ") | ||
.setDescription(`${interaction.user} がサブコマンドを実行しました。`) | ||
.setColor(interaction.client.conf.color.s) | ||
.setTimestamp() | ||
.setThumbnail(interaction.user.displayAvatarURL({ dynamic: true })) | ||
.addFields([ | ||
{ | ||
name: "サブコマンド", | ||
value: `\`\`\`\n/${interaction.options.getSubcommand()}\n\`\`\``, | ||
}, | ||
{ | ||
name: "実行サーバー", | ||
value: | ||
"```\n" + interaction.inGuild() | ||
? `${interaction.guild.name} (${interaction.guild.id})` | ||
: "DM" + "\n```", | ||
}, | ||
{ | ||
name: "実行ユーザー", | ||
value: | ||
"```\n" + | ||
`${interaction.user.tag}(${interaction.user.id})` + | ||
"\n```", | ||
}, | ||
]) | ||
.setFooter({ text: `${interaction.id}` }); | ||
const channel = await GetLogChannel(interaction); | ||
if (channel) { | ||
channel.send({ embeds: [logEmbed] }); | ||
} | ||
} catch (error) { | ||
console.error(error); | ||
const logEmbed = new EmbedBuilder() | ||
.setTitle("ERROR - cmd") | ||
.setDescription("```\n" + error.toString() + "\n```") | ||
.setColor(config.color.e) | ||
.setTimestamp(); | ||
|
||
const channel = await GetErrorChannel(interaction); | ||
if (channel) { | ||
channel.send({ embeds: [logEmbed] }); | ||
} | ||
const messageEmbed = new EmbedBuilder() | ||
.setTitle("すみません、エラーが発生しました...") | ||
.setDescription("```\n" + error + "\n```") | ||
.setColor(interaction.conf.color.e) | ||
.setTimestamp(); | ||
|
||
await interaction.editReply(messageEmbed); | ||
const logChannel = await GetLogChannel(interaction); | ||
if (logChannel) { | ||
logChannel.send({ embeds: [messageEmbed] }); | ||
} | ||
} | ||
return; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
const { | ||
SlashCommandSubcommandBuilder, | ||
StringSelectMenuBuilder, | ||
StringSelectMenuOptionBuilder, | ||
ActionRowBuilder, | ||
ComponentType, | ||
} = require("discord.js"); | ||
const logUtils = require("../../../lib/logUtils.js"); | ||
|
||
module.exports = { | ||
data: new SlashCommandSubcommandBuilder() | ||
.setName("delete") | ||
.setDescription("delete"), | ||
adminGuildOnly: true, | ||
/** | ||
* Executes the feed command. | ||
* @param {CommandInteraction} interaction - The interaction object. | ||
* @returns {Promise<string>} - A promise that resolves when the execution is complete. | ||
* @async | ||
*/ | ||
async execute(interaction) { | ||
const subscribed = await logUtils.readLog( | ||
"v1/feed/" + interaction.channel.id | ||
); | ||
if (!subscribed) { | ||
interaction.editReply({ | ||
content: "This channel is not subscribed to any feeds.", | ||
ephemeral: true, | ||
}); | ||
return "No data"; | ||
} | ||
const select = new StringSelectMenuBuilder().setCustomId("FeedSelector"); | ||
for (const feed of subscribed.data) { | ||
await select.addOptions( | ||
new StringSelectMenuOptionBuilder() | ||
.setLabel(feed.url) | ||
.setValue(feed.url) | ||
.setDescription("Last Update: " + feed.lastDate) | ||
); | ||
} | ||
|
||
const row = new ActionRowBuilder().addComponents(select); | ||
|
||
const response = await interaction.editReply({ | ||
content: "Choose your starter!", | ||
components: [row], | ||
}); | ||
|
||
const collector = response.createMessageComponentCollector({ | ||
componentType: ComponentType.StringSelect, | ||
time: 3_600_000, | ||
}); | ||
|
||
collector.on("collect", async (i) => { | ||
const selection = i.values[0]; | ||
const index = subscribed.data.findIndex((x) => x.url === selection); | ||
subscribed.data.splice(index, 1); | ||
await logUtils.loging(subscribed, `v1/feed/${interaction.channel.id}`); | ||
await i.update({ | ||
content: "Deleted: " + selection, | ||
components: [], | ||
}); | ||
}); | ||
return "No data"; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
const { SlashCommandSubcommandBuilder, EmbedBuilder } = require("discord.js"); | ||
const Discord = require("discord.js"); | ||
const { rssGet } = require("../../../lib/rss.cjs"); | ||
const logUtils = require("../../../lib/logUtils.js"); | ||
|
||
module.exports = { | ||
data: new SlashCommandSubcommandBuilder() | ||
.setName("regist") | ||
.setDescription("Regist RSS feed") | ||
.addStringOption((option) => | ||
option.setName("url").setDescription("URL of RSS feed").setRequired(true) | ||
), | ||
adminGuildOnly: true, | ||
/** | ||
* Executes the feed command. | ||
* @param {CommandInteraction} i - The interaction object. | ||
* @returns {Promise<string>} - A promise that resolves when the execution is complete. | ||
* @async | ||
*/ | ||
async execute(i) { | ||
const feed = await rssGet(i.options.getString("url")); | ||
try { | ||
let log = await logUtils.readLog("v1/feed/" + i.channel.id); | ||
console.log(log); | ||
if (log) { | ||
log.data.push({ | ||
url: i.options.getString("url"), | ||
lastDate: feed[0].pubDate, | ||
}); | ||
await logUtils.loging(log, `v1/feed/${i.channel.id}`); | ||
} else { | ||
log = { | ||
data: [ | ||
{ url: i.options.getString("url"), lastDate: feed[0].pubDate }, | ||
], | ||
}; | ||
await logUtils.loging(log, `v1/feed/${i.channel.id}`); | ||
} | ||
} catch (e) { | ||
console.error(e); | ||
} | ||
const embed = new Discord.EmbedBuilder() | ||
.setTitle("Registed RSS feed") | ||
.addFields([ | ||
{ | ||
name: "URL", | ||
value: ` ** ${i.options.getString("url")} ** `, | ||
inline: true, | ||
}, | ||
]) | ||
.setFields({ | ||
name: "Title", | ||
value: ` ** ${feed[0].title} ** `, | ||
inline: true, | ||
}) | ||
.setFields({ | ||
name: "FirstContent", | ||
value: ` ** ${feed[0].content} ** `, | ||
inline: true, | ||
}) | ||
.setColor(i.client.conf.color.s) | ||
.setTimestamp(); | ||
i.editReply({ embeds: [embed] }); | ||
return "No data"; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.