@gp_jcisneros/aws-utils
Version:
AWS SDK utilities for GreenPay microservices
194 lines (170 loc) • 6.55 kB
JavaScript
const { SQSClient, SendMessageCommand, ReceiveMessageCommand, DeleteMessageCommand } = require('@aws-sdk/client-sqs');
const { AWSError, IntegrationError } = require('@gp_jcisneros/errors');
/**
* Utilities for AWS SQS operations
*/
class SQSUtils {
constructor(region = process.env.AWS_REGION || 'us-east-1') {
this.client = new SQSClient({ region });
}
/**
* Send a message to SQS queue
* @param {string} queueUrl - URL of the SQS queue
* @param {Object|string} messageBody - Message to send
* @param {Object} options - Additional options (delaySeconds, messageAttributes, etc.)
* @returns {Promise<Object>} - Send result
*/
async sendMessage(queueUrl, messageBody, options = {}) {
try {
const command = new SendMessageCommand({
QueueUrl: queueUrl,
MessageBody: typeof messageBody === 'string' ? messageBody : JSON.stringify(messageBody),
DelaySeconds: options.delaySeconds || 0,
MessageAttributes: options.messageAttributes || {},
MessageGroupId: options.messageGroupId,
MessageDeduplicationId: options.messageDeduplicationId
});
const result = await this.client.send(command);
return {
success: true,
messageId: result.MessageId,
sequenceNumber: result.SequenceNumber,
md5OfMessageBody: result.MD5OfMessageBody
};
} catch (error) {
// Si ya es un error personalizado, lo relanzamos
if (error instanceof AWSError || error instanceof IntegrationError) {
throw error;
}
throw new IntegrationError(`SQS send failed for ${queueUrl}: ${error.message}`, 'SQS_SEND_ERROR', 'sqs', {
queueUrl,
messageBody: typeof messageBody === 'string' ? messageBody : JSON.stringify(messageBody)
});
}
}
/**
* Receive messages from SQS queue
* @param {string} queueUrl - URL of the SQS queue
* @param {Object} options - Receive options (maxNumberOfMessages, waitTimeSeconds, etc.)
* @returns {Promise<Array>} - Array of received messages
*/
async receiveMessages(queueUrl, options = {}) {
try {
const command = new ReceiveMessageCommand({
QueueUrl: queueUrl,
MaxNumberOfMessages: options.maxNumberOfMessages || 10,
WaitTimeSeconds: options.waitTimeSeconds || 20,
VisibilityTimeout: options.visibilityTimeout || 30,
MessageAttributeNames: options.messageAttributeNames || ['All'],
AttributeNames: options.attributeNames || ['All']
});
const result = await this.client.send(command);
return result.Messages || [];
} catch (error) {
// Si ya es un error personalizado, lo relanzamos
if (error instanceof AWSError || error instanceof IntegrationError) {
throw error;
}
throw new IntegrationError(`SQS receive failed for ${queueUrl}: ${error.message}`, 'SQS_RECEIVE_ERROR', 'sqs', {
queueUrl,
options
});
}
}
/**
* Delete a message from SQS queue
* @param {string} queueUrl - URL of the SQS queue
* @param {string} receiptHandle - Receipt handle of the message to delete
* @returns {Promise<Object>} - Delete result
*/
async deleteMessage(queueUrl, receiptHandle) {
try {
const command = new DeleteMessageCommand({
QueueUrl: queueUrl,
ReceiptHandle: receiptHandle
});
await this.client.send(command);
return {
success: true
};
} catch (error) {
// Si ya es un error personalizado, lo relanzamos
if (error instanceof AWSError || error instanceof IntegrationError) {
throw error;
}
throw new IntegrationError(`SQS delete failed for ${queueUrl}: ${error.message}`, 'SQS_DELETE_ERROR', 'sqs', {
queueUrl,
receiptHandle
});
}
}
/**
* Send JSON message to SQS queue
* @param {string} queueUrl - URL of the SQS queue
* @param {Object} jsonData - JSON data to send
* @param {Object} options - Additional options
* @returns {Promise<Object>} - Send result
*/
async sendJsonMessage(queueUrl, jsonData, options = {}) {
return this.sendMessage(queueUrl, jsonData, options);
}
/**
* Process messages from SQS queue with a handler function
* @param {string} queueUrl - URL of the SQS queue
* @param {Function} messageHandler - Function to handle each message
* @param {Object} options - Processing options
* @returns {Promise<Object>} - Processing result
*/
async processMessages(queueUrl, messageHandler, options = {}) {
try {
const messages = await this.receiveMessages(queueUrl, options);
const results = [];
for (const message of messages) {
try {
const result = await messageHandler(message);
await this.deleteMessage(queueUrl, message.ReceiptHandle);
results.push({ success: true, messageId: message.MessageId, result });
} catch (error) {
results.push({ success: false, messageId: message.MessageId, error: error.message });
}
}
return {
processed: results.length,
successful: results.filter(r => r.success).length,
failed: results.filter(r => !r.success).length,
results
};
} catch (error) {
// Si ya es un error personalizado, lo relanzamos
if (error instanceof AWSError || error instanceof IntegrationError) {
throw error;
}
throw new IntegrationError(`SQS message processing failed for ${queueUrl}: ${error.message}`, 'SQS_PROCESS_ERROR', 'sqs', {
queueUrl,
options
});
}
}
// Static methods for convenience
static async sendMessage(queueUrl, messageBody, options = {}) {
const utils = new SQSUtils();
return utils.sendMessage(queueUrl, messageBody, options);
}
static async receiveMessages(queueUrl, options = {}) {
const utils = new SQSUtils();
return utils.receiveMessages(queueUrl, options);
}
static async deleteMessage(queueUrl, receiptHandle) {
const utils = new SQSUtils();
return utils.deleteMessage(queueUrl, receiptHandle);
}
static async sendJsonMessage(queueUrl, jsonData, options = {}) {
const utils = new SQSUtils();
return utils.sendJsonMessage(queueUrl, jsonData, options);
}
static async processMessages(queueUrl, messageHandler, options = {}) {
const utils = new SQSUtils();
return utils.processMessages(queueUrl, messageHandler, options);
}
}
module.exports = { SQSUtils };