fisher
fisher
Explore posts from servers
CDCloudflare Developers
Created by fisher on 4/17/2025 in #workers-help
Cloudflare Rate Limiting not being in Effect
Hey there, I'm trying to get rate limiting working on my hono app, but nothing seems to be working?? I've configured it correctly and even put down temporary crazy limits and it doesn't seem to rate limit my functions from being called. (Yes, I know it doesn't stop someone from sending 20 requests or whatever but my functions are still being called 20 times, even after checking for the rate limits) jsonc config:
"unsafe": {
"bindings": [
{
"name": "RATE_LIMITER",
"type": "ratelimit",
"namespace_id": "1001",
"simple": {
"limit": 1,
"period": 60
}
}
]
}
"unsafe": {
"bindings": [
{
"name": "RATE_LIMITER",
"type": "ratelimit",
"namespace_id": "1001",
"simple": {
"limit": 1,
"period": 60
}
}
]
}
relevant sample code:
type AppType = {
Variables: {
rateLimit: boolean;
};
Bindings: {
WEBHOOK_ID: string;
WEBHOOK_TOKEN: string;
RATE_LIMITER: RateLimit;
};
};

const app = new Hono<AppType>().use(
cloudflareRateLimiter<AppType>({
rateLimitBinding: (c) => c.env.RATE_LIMITER,
keyGenerator: (c) => "sameKeyEveryTime"
}),
);

app.post("/tba", async (c) => {
return c.text("not rate limited", 200);
});
type AppType = {
Variables: {
rateLimit: boolean;
};
Bindings: {
WEBHOOK_ID: string;
WEBHOOK_TOKEN: string;
RATE_LIMITER: RateLimit;
};
};

const app = new Hono<AppType>().use(
cloudflareRateLimiter<AppType>({
rateLimitBinding: (c) => c.env.RATE_LIMITER,
keyGenerator: (c) => "sameKeyEveryTime"
}),
);

app.post("/tba", async (c) => {
return c.text("not rate limited", 200);
});
3 replies
SIASapphire - Imagine a Framework
Created by fisher on 7/15/2024 in #sapphire-support
Crosspost listener not working
I have a bot listening for message updates, and then filtering it out to be a crossposted message, but it isn't working
import { Events, Listener } from "@sapphire/framework";
import { Message, MessageFlags } from "discord.js";
import { lexer } from "marked";
import {
discordImageToGuilded,
convertToGuilded,
announceToGuilded,
} from "../resources/modules/convertToGuilded";

export class CrosspostedListener extends Listener {
public constructor(context: Listener.LoaderContext, options: Listener.Options) {
super(context, {
...options,
event: Events.MessageUpdate,
});
}

public async run(message: Message) {
if (!message.flags.has(MessageFlags.Crossposted)) return;
console.log(message);

const messageContent = message.content;
const regex = /<:[a-zA-Z0-9]+:\d+>/g;
const messageContentWithoutCustomEmojis = messageContent.replace(regex, "");
const parsed = lexer(messageContentWithoutCustomEmojis);

const image = await discordImageToGuilded(message.attachments.first());
const convertedToGuilded = convertToGuilded(parsed, image);

await announceToGuilded(convertedToGuilded);
}
}
import { Events, Listener } from "@sapphire/framework";
import { Message, MessageFlags } from "discord.js";
import { lexer } from "marked";
import {
discordImageToGuilded,
convertToGuilded,
announceToGuilded,
} from "../resources/modules/convertToGuilded";

export class CrosspostedListener extends Listener {
public constructor(context: Listener.LoaderContext, options: Listener.Options) {
super(context, {
...options,
event: Events.MessageUpdate,
});
}

public async run(message: Message) {
if (!message.flags.has(MessageFlags.Crossposted)) return;
console.log(message);

const messageContent = message.content;
const regex = /<:[a-zA-Z0-9]+:\d+>/g;
const messageContentWithoutCustomEmojis = messageContent.replace(regex, "");
const parsed = lexer(messageContentWithoutCustomEmojis);

const image = await discordImageToGuilded(message.attachments.first());
const convertedToGuilded = convertToGuilded(parsed, image);

await announceToGuilded(convertedToGuilded);
}
}
10 replies
SIASapphire - Imagine a Framework
Created by fisher on 7/13/2024 in #sapphire-support
Listeners not registering?
I'm using sapphire with TS & TSUP, but registers aren't working... listener code:
import { Events, Listener } from "@sapphire/framework";
import { ActivityType, type Client } from "discord.js";

export class ClientReadyListener extends Listener {
public constructor(
context: Listener.LoaderContext,
options: Listener.Options
) {
super(context, {
...options,
event: Events.ClientReady,
once: true,
});
}

public run(client: Client) {
client.logger.info(
`Bot Client Logged in as ${client.user!.tag} (${client.application?.id})`
);

client.user!.setActivity({
type: ActivityType.Watching,
name: "over EBC",
});
}
}
import { Events, Listener } from "@sapphire/framework";
import { ActivityType, type Client } from "discord.js";

export class ClientReadyListener extends Listener {
public constructor(
context: Listener.LoaderContext,
options: Listener.Options
) {
super(context, {
...options,
event: Events.ClientReady,
once: true,
});
}

public run(client: Client) {
client.logger.info(
`Bot Client Logged in as ${client.user!.tag} (${client.application?.id})`
);

client.user!.setActivity({
type: ActivityType.Watching,
name: "over EBC",
});
}
}
file structure: https://fisher.likes-to.party/i/AFEnbv
11 replies
TtRPC
Created by fisher on 7/2/2023 in #❓-help
Cannot read properties of undefined (reading 'trpc')
I keep getting that when trying to make an api request with my next.js page. I am using the latest Next.js version with app router enabled.
6 replies
SIASapphire - Imagine a Framework
Created by fisher on 6/16/2023 in #sapphire-support
Multiple Button Handlers, only 1 takes in a request
currently, I have 2 seperate files that both have button handlers. However, when a button is pressed, it only does parsing in 1 of the files. Both are in the interaction-handlers directory. src/interaction-handlers/operation.ts
import {
InteractionHandler,
InteractionHandlerTypes,
PieceContext,
} from "@sapphire/framework";
import type { ButtonInteraction, TextChannel } from "discord.js";

export class OperationButtonHandler extends InteractionHandler {
public constructor(ctx: PieceContext, options: InteractionHandler.Options) {
super(ctx, {
...options,
interactionHandlerType: InteractionHandlerTypes.Button,
});
}

public override parse(interaction: ButtonInteraction) {
if (interaction.customId === "host-operation.post")
return this.some<boolean>(true);
if (interaction.customId === "host-operation.cancel")
return this.some<boolean>(false);

return this.none();
}

public async run(interaction: ButtonInteraction, post: boolean) {
if (post) {
const sessionChannel = await interaction.guild?.channels.fetch(
process.env.SESSION_CHANNEL
);

const pingChoice = interaction.message.content.includes("`everyone`")
? "@everyone"
: interaction.message.content.includes("`session`")
? "<@&1119004847077859328>"
: interaction.message.content.includes("`training`")
? "<@&856317590032220200>"
: "none";

try {
(sessionChannel as TextChannel).send({
content: pingChoice,
embeds: [interaction.message.embeds[0]],
});
} catch (error) {
return interaction.update({
content: `## Cancelled
Post has been cancelled due to an error.`,
components: [],
});
}

return interaction.update({
content: `## Posted
Post has been sent in <#${process.env.SESSION_CHANNEL}>!`,
components: [],
});
} else {
return interaction.update({
content: `## Cancelled
Post has been cancelled.`,
embeds: [],
components: [],
});
}
}
}
import {
InteractionHandler,
InteractionHandlerTypes,
PieceContext,
} from "@sapphire/framework";
import type { ButtonInteraction, TextChannel } from "discord.js";

export class OperationButtonHandler extends InteractionHandler {
public constructor(ctx: PieceContext, options: InteractionHandler.Options) {
super(ctx, {
...options,
interactionHandlerType: InteractionHandlerTypes.Button,
});
}

public override parse(interaction: ButtonInteraction) {
if (interaction.customId === "host-operation.post")
return this.some<boolean>(true);
if (interaction.customId === "host-operation.cancel")
return this.some<boolean>(false);

return this.none();
}

public async run(interaction: ButtonInteraction, post: boolean) {
if (post) {
const sessionChannel = await interaction.guild?.channels.fetch(
process.env.SESSION_CHANNEL
);

const pingChoice = interaction.message.content.includes("`everyone`")
? "@everyone"
: interaction.message.content.includes("`session`")
? "<@&1119004847077859328>"
: interaction.message.content.includes("`training`")
? "<@&856317590032220200>"
: "none";

try {
(sessionChannel as TextChannel).send({
content: pingChoice,
embeds: [interaction.message.embeds[0]],
});
} catch (error) {
return interaction.update({
content: `## Cancelled
Post has been cancelled due to an error.`,
components: [],
});
}

return interaction.update({
content: `## Posted
Post has been sent in <#${process.env.SESSION_CHANNEL}>!`,
components: [],
});
} else {
return interaction.update({
content: `## Cancelled
Post has been cancelled.`,
embeds: [],
components: [],
});
}
}
}
src/interaction-handlers/profile.ts
import {
InteractionHandler,
InteractionHandlerTypes,
PieceContext,
} from "@sapphire/framework";
import {
ActionRowBuilder,
ButtonBuilder,
ButtonInteraction,
ButtonStyle,
TextChannel,
type StringSelectMenuInteraction,
StringSelectMenuBuilder,
APIStringSelectComponent,
} from "discord.js";
import embed from "../resources/templates/embed";

type ManageType = "OPERATING" | "TRAINING";
type UpdateButtonData = {
continue: boolean;
approve: boolean;
};

export class ManageProfileButtonHandler extends InteractionHandler {
public constructor(ctx: PieceContext, options: InteractionHandler.Options) {
super(ctx, {
...options,
interactionHandlerType: InteractionHandlerTypes.Button,
});
}

public override parse(interaction: ButtonInteraction) {
if (interaction.customId === "profile.edit.update.approve")
return this.some<UpdateButtonData>({
continue: true,
approve: true,
});
if (interaction.customId === "profile.edit.update.deny")
return this.some<UpdateButtonData>({
continue: true,
approve: false,
});
if (interaction.customId === "profile.edit.cancel")
return this.some<UpdateButtonData>({
continue: false,
approve: false,
});

return this.none();
}

public async run(interaction: ButtonInteraction, data: UpdateButtonData) {
if (data.continue) {
} else {
console.log(1);
interaction.update({
components: [],
});
interaction.editReply({
components: [],
});
}
}
}
import {
InteractionHandler,
InteractionHandlerTypes,
PieceContext,
} from "@sapphire/framework";
import {
ActionRowBuilder,
ButtonBuilder,
ButtonInteraction,
ButtonStyle,
TextChannel,
type StringSelectMenuInteraction,
StringSelectMenuBuilder,
APIStringSelectComponent,
} from "discord.js";
import embed from "../resources/templates/embed";

type ManageType = "OPERATING" | "TRAINING";
type UpdateButtonData = {
continue: boolean;
approve: boolean;
};

export class ManageProfileButtonHandler extends InteractionHandler {
public constructor(ctx: PieceContext, options: InteractionHandler.Options) {
super(ctx, {
...options,
interactionHandlerType: InteractionHandlerTypes.Button,
});
}

public override parse(interaction: ButtonInteraction) {
if (interaction.customId === "profile.edit.update.approve")
return this.some<UpdateButtonData>({
continue: true,
approve: true,
});
if (interaction.customId === "profile.edit.update.deny")
return this.some<UpdateButtonData>({
continue: true,
approve: false,
});
if (interaction.customId === "profile.edit.cancel")
return this.some<UpdateButtonData>({
continue: false,
approve: false,
});

return this.none();
}

public async run(interaction: ButtonInteraction, data: UpdateButtonData) {
if (data.continue) {
} else {
console.log(1);
interaction.update({
components: [],
});
interaction.editReply({
components: [],
});
}
}
}
35 replies