added sqs utils

This commit is contained in:
Jun-te kim 2025-08-19 13:10:49 +00:00
parent 5b3a1afea0
commit cf0cc5e79a
3 changed files with 1370 additions and 0 deletions

1295
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,7 @@
"create_user": "tsx src/app/db/create_user.ts"
},
"dependencies": {
"@aws-sdk/client-sqs": "^3.864.0",
"@headlessui/react": "^2.2.7",
"@heroicons/react": "^2.0.18",
"@hookform/resolvers": "^3.9.1",

74
src/app/utils/sqs.ts Normal file
View file

@ -0,0 +1,74 @@
// utils/sqs.ts
import {
SQSClient,
SendMessageCommand,
GetQueueUrlCommand,
ListQueuesCommand,
SendMessageCommandOutput,
} from "@aws-sdk/client-sqs";
// If you prefer explicit creds via env, keep your current config;
// otherwise, this ctor will use the default credential chain (env vars, shared profile, role, etc.)
const sqsClient = new SQSClient({
region: process.env.AWS_REGION,
});
let cachedQueueUrl: string | null = null;
// Export if you want to reuse elsewhere
export async function getQueueUrl(queueName: string): Promise<string> {
if (cachedQueueUrl) return cachedQueueUrl;
const resp = await sqsClient.send(new GetQueueUrlCommand({ QueueName: queueName }));
if (!resp.QueueUrl) throw new Error(`Could not resolve SQS URL for queue: ${queueName}`);
cachedQueueUrl = resp.QueueUrl;
return cachedQueueUrl;
}
type SendOptions = {
queueName?: string; // defaults to env
groupId?: string; // for FIFO queues only
deduplicationId?: string; // for FIFO queues only
delaySeconds?: number; // 0-900
};
/**
* Send a message to SQS. Handles both standard and FIFO queues.
*/
export async function sendToQueue(
messageBody: unknown,
opts: SendOptions = {}
): Promise<SendMessageCommandOutput> {
const queueName = opts.queueName ?? (process.env.AWS_SQS_QUEUE_NAME as string);
if (!queueName) throw new Error("Missing AWS_SQS_QUEUE_NAME or sendToQueue opts.queueName");
const queueUrl = await getQueueUrl(queueName);
const params: any = {
QueueUrl: queueUrl,
MessageBody: JSON.stringify(messageBody),
};
// If it's a FIFO queue (ends with .fifo), include group/dedupe if provided
const isFifo = queueUrl.endsWith(".fifo");
if (isFifo) {
params.MessageGroupId = opts.groupId ?? "default-group";
if (opts.deduplicationId) params.MessageDeduplicationId = opts.deduplicationId;
}
if (typeof opts.delaySeconds === "number") {
params.DelaySeconds = opts.delaySeconds;
}
return sqsClient.send(new SendMessageCommand(params));
}
/**
* List queues in the configured region.
* Optionally filter by name prefix.
*/
export async function listQueues(prefix?: string): Promise<string[]> {
const resp = await sqsClient.send(new ListQueuesCommand(
prefix ? { QueueNamePrefix: prefix } : {}
));
return resp.QueueUrls ?? [];
}