azure-storage-queue-ts
Azure Queue Storage JavaScript/TypeScript SDK (@azure/storage-queue) for message queue operations. Use for sending, receiving, peeking, and deleting messages in queues. Supports visibility timeout, message encoding, and batch operations. Triggers: "queue storage", "@azure/storage-queue", "QueueServiceClient", "QueueClient", "send message", "receive message", "dequeue", "visibility timeout".
Best use case
azure-storage-queue-ts is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Azure Queue Storage JavaScript/TypeScript SDK (@azure/storage-queue) for message queue operations. Use for sending, receiving, peeking, and deleting messages in queues. Supports visibility timeout, message encoding, and batch operations. Triggers: "queue storage", "@azure/storage-queue", "QueueServiceClient", "QueueClient", "send message", "receive message", "dequeue", "visibility timeout".
Teams using azure-storage-queue-ts should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/azure-storage-queue-ts/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How azure-storage-queue-ts Compares
| Feature / Agent | azure-storage-queue-ts | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Azure Queue Storage JavaScript/TypeScript SDK (@azure/storage-queue) for message queue operations. Use for sending, receiving, peeking, and deleting messages in queues. Supports visibility timeout, message encoding, and batch operations. Triggers: "queue storage", "@azure/storage-queue", "QueueServiceClient", "QueueClient", "send message", "receive message", "dequeue", "visibility timeout".
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# @azure/storage-queue (TypeScript/JavaScript)
SDK for Azure Queue Storage operations — send, receive, peek, and manage messages in queues.
## Installation
```bash
npm install @azure/storage-queue @azure/identity
```
**Current Version**: 12.x
**Node.js**: >= 18.0.0
## Environment Variables
```bash
AZURE_STORAGE_ACCOUNT_NAME=<account-name>
AZURE_STORAGE_ACCOUNT_KEY=<account-key>
# OR connection string
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...
```
## Authentication
### DefaultAzureCredential (Recommended)
```typescript
import { QueueServiceClient } from "@azure/storage-queue";
import { DefaultAzureCredential } from "@azure/identity";
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;
const client = new QueueServiceClient(
`https://${accountName}.queue.core.windows.net`,
new DefaultAzureCredential()
);
```
### Connection String
```typescript
import { QueueServiceClient } from "@azure/storage-queue";
const client = QueueServiceClient.fromConnectionString(
process.env.AZURE_STORAGE_CONNECTION_STRING!
);
```
### StorageSharedKeyCredential (Node.js only)
```typescript
import { QueueServiceClient, StorageSharedKeyCredential } from "@azure/storage-queue";
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;
const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY!;
const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
const client = new QueueServiceClient(
`https://${accountName}.queue.core.windows.net`,
sharedKeyCredential
);
```
### SAS Token
```typescript
import { QueueServiceClient } from "@azure/storage-queue";
const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;
const sasToken = process.env.AZURE_STORAGE_SAS_TOKEN!;
const client = new QueueServiceClient(
`https://${accountName}.queue.core.windows.net${sasToken}`
);
```
## Client Hierarchy
```
QueueServiceClient (account level)
└── QueueClient (queue level)
└── Messages (send, receive, peek, delete)
```
## Queue Operations
### Create Queue
```typescript
const queueClient = client.getQueueClient("my-queue");
await queueClient.create();
// Or create if not exists
await queueClient.createIfNotExists();
```
### List Queues
```typescript
for await (const queue of client.listQueues()) {
console.log(queue.name);
}
// With prefix filter
for await (const queue of client.listQueues({ prefix: "task-" })) {
console.log(queue.name);
}
```
### Delete Queue
```typescript
await queueClient.delete();
// Or delete if exists
await queueClient.deleteIfExists();
```
### Get Queue Properties
```typescript
const properties = await queueClient.getProperties();
console.log("Approximate message count:", properties.approximateMessagesCount);
console.log("Metadata:", properties.metadata);
```
### Set Queue Metadata
```typescript
await queueClient.setMetadata({
department: "engineering",
priority: "high",
});
```
## Message Operations
### Send Message
```typescript
const queueClient = client.getQueueClient("my-queue");
// Simple message
await queueClient.sendMessage("Hello, World!");
// With options
await queueClient.sendMessage("Delayed message", {
visibilityTimeout: 60, // Hidden for 60 seconds
messageTimeToLive: 3600, // Expires in 1 hour
});
// JSON message (must be string)
const task = { type: "process", data: { id: 123 } };
await queueClient.sendMessage(JSON.stringify(task));
```
### Receive Messages
```typescript
// Receive up to 32 messages (default: 1)
const response = await queueClient.receiveMessages({
numberOfMessages: 10,
visibilityTimeout: 30, // 30 seconds to process
});
for (const message of response.receivedMessageItems) {
console.log("Message ID:", message.messageId);
console.log("Content:", message.messageText);
console.log("Dequeue Count:", message.dequeueCount);
console.log("Pop Receipt:", message.popReceipt);
// Process the message...
// Delete after processing
await queueClient.deleteMessage(message.messageId, message.popReceipt);
}
```
### Peek Messages
Peek without removing from queue (no visibility timeout).
```typescript
const response = await queueClient.peekMessages({
numberOfMessages: 5,
});
for (const message of response.peekedMessageItems) {
console.log("Message ID:", message.messageId);
console.log("Content:", message.messageText);
// Note: No popReceipt - cannot delete peeked messages
}
```
### Update Message
Extend visibility timeout or update content.
```typescript
// Receive a message
const response = await queueClient.receiveMessages();
const message = response.receivedMessageItems[0];
if (message) {
// Update content and extend visibility
const updateResponse = await queueClient.updateMessage(
message.messageId,
message.popReceipt,
"Updated content",
60 // New visibility timeout in seconds
);
// Use new popReceipt for subsequent operations
console.log("New pop receipt:", updateResponse.popReceipt);
}
```
### Delete Message
```typescript
// After receiving
const response = await queueClient.receiveMessages();
const message = response.receivedMessageItems[0];
if (message) {
await queueClient.deleteMessage(message.messageId, message.popReceipt);
}
```
### Clear All Messages
```typescript
await queueClient.clearMessages();
```
## Message Processing Patterns
### Basic Worker Pattern
```typescript
async function processQueue(queueClient: QueueClient): Promise<void> {
while (true) {
const response = await queueClient.receiveMessages({
numberOfMessages: 10,
visibilityTimeout: 30,
});
if (response.receivedMessageItems.length === 0) {
// No messages, wait before polling again
await sleep(5000);
continue;
}
for (const message of response.receivedMessageItems) {
try {
await processMessage(message.messageText);
await queueClient.deleteMessage(message.messageId, message.popReceipt);
} catch (error) {
console.error(`Failed to process message ${message.messageId}:`, error);
// Message will become visible again after timeout
}
}
}
}
async function processMessage(content: string): Promise<void> {
const task = JSON.parse(content);
// Process task...
}
function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
```
### Poison Message Handling
```typescript
const MAX_DEQUEUE_COUNT = 5;
async function processWithPoisonHandling(
queueClient: QueueClient,
poisonQueueClient: QueueClient
): Promise<void> {
const response = await queueClient.receiveMessages({
numberOfMessages: 10,
visibilityTimeout: 30,
});
for (const message of response.receivedMessageItems) {
if (message.dequeueCount > MAX_DEQUEUE_COUNT) {
// Move to poison queue
await poisonQueueClient.sendMessage(message.messageText);
await queueClient.deleteMessage(message.messageId, message.popReceipt);
console.log(`Moved message ${message.messageId} to poison queue`);
continue;
}
try {
await processMessage(message.messageText);
await queueClient.deleteMessage(message.messageId, message.popReceipt);
} catch (error) {
console.error(`Processing failed (attempt ${message.dequeueCount}):`, error);
}
}
}
```
### Batch Processing with Visibility Extension
```typescript
async function processBatchWithExtension(queueClient: QueueClient): Promise<void> {
const response = await queueClient.receiveMessages({
numberOfMessages: 1,
visibilityTimeout: 60,
});
const message = response.receivedMessageItems[0];
if (!message) return;
let popReceipt = message.popReceipt;
// Start visibility extension timer
const extensionInterval = setInterval(async () => {
try {
const updateResponse = await queueClient.updateMessage(
message.messageId,
popReceipt,
message.messageText,
60 // Extend by another 60 seconds
);
popReceipt = updateResponse.popReceipt;
} catch (error) {
console.error("Failed to extend visibility:", error);
}
}, 45000); // Extend every 45 seconds
try {
await longRunningProcess(message.messageText);
await queueClient.deleteMessage(message.messageId, popReceipt);
} finally {
clearInterval(extensionInterval);
}
}
```
## Message Encoding
By default, messages are Base64 encoded. You can customize this:
```typescript
import { QueueClient } from "@azure/storage-queue";
// Custom encoder/decoder for plain text
const queueClient = new QueueClient(
`https://${accountName}.queue.core.windows.net/my-queue`,
credential,
{
messageEncoding: "text", // "base64" (default) or "text"
}
);
// Or with custom encoder
const customQueueClient = new QueueClient(
`https://${accountName}.queue.core.windows.net/my-queue`,
credential,
{
messageEncoding: {
encode: (message: string) => Buffer.from(message).toString("base64"),
decode: (message: string) => Buffer.from(message, "base64").toString(),
},
}
);
```
## SAS Token Generation (Node.js only)
### Generate Queue SAS
```typescript
import {
QueueSASPermissions,
generateQueueSASQueryParameters,
StorageSharedKeyCredential,
} from "@azure/storage-queue";
const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);
const sasToken = generateQueueSASQueryParameters(
{
queueName: "my-queue",
permissions: QueueSASPermissions.parse("raup"), // read, add, update, process
startsOn: new Date(),
expiresOn: new Date(Date.now() + 3600 * 1000), // 1 hour
},
sharedKeyCredential
).toString();
const sasUrl = `https://${accountName}.queue.core.windows.net/my-queue?${sasToken}`;
```
### Generate Account SAS
```typescript
import {
AccountSASPermissions,
AccountSASResourceTypes,
AccountSASServices,
generateAccountSASQueryParameters,
} from "@azure/storage-queue";
const sasToken = generateAccountSASQueryParameters(
{
services: AccountSASServices.parse("q").toString(), // queue
resourceTypes: AccountSASResourceTypes.parse("sco").toString(),
permissions: AccountSASPermissions.parse("rwdlacupi"),
expiresOn: new Date(Date.now() + 24 * 3600 * 1000),
},
sharedKeyCredential
).toString();
```
## Error Handling
```typescript
import { RestError } from "@azure/storage-queue";
try {
await queueClient.sendMessage("test");
} catch (error) {
if (error instanceof RestError) {
switch (error.statusCode) {
case 404:
console.log("Queue not found");
break;
case 400:
console.log("Bad request - message too large or invalid");
break;
case 403:
console.log("Access denied");
break;
case 409:
console.log("Queue already exists or being deleted");
break;
default:
console.error(`Storage error ${error.statusCode}: ${error.message}`);
}
}
throw error;
}
```
## TypeScript Types Reference
```typescript
import {
// Clients
QueueServiceClient,
QueueClient,
// Authentication
StorageSharedKeyCredential,
AnonymousCredential,
// SAS
QueueSASPermissions,
AccountSASPermissions,
AccountSASServices,
AccountSASResourceTypes,
generateQueueSASQueryParameters,
generateAccountSASQueryParameters,
// Messages
DequeuedMessageItem,
PeekedMessageItem,
QueueSendMessageResponse,
QueueReceiveMessageResponse,
QueueUpdateMessageResponse,
// Queue
QueueItem,
QueueGetPropertiesResponse,
// Errors
RestError,
} from "@azure/storage-queue";
```
## Message Limits
| Limit | Value |
|-------|-------|
| Max message size | 64 KB |
| Max visibility timeout | 7 days |
| Max time-to-live | 7 days (or -1 for infinite) |
| Max messages per receive | 32 |
| Default visibility timeout | 30 seconds |
## Best Practices
1. **Use DefaultAzureCredential** — Prefer AAD over connection strings/keys
2. **Always delete after processing** — Prevent duplicate processing
3. **Handle poison messages** — Move failed messages to a dead-letter queue
4. **Use appropriate visibility timeout** — Set based on expected processing time
5. **Extend visibility for long tasks** — Update message to prevent timeout
6. **Use JSON for structured data** — Serialize objects to JSON strings
7. **Check dequeueCount** — Detect repeatedly failing messages
8. **Use batch receive** — Receive multiple messages for efficiency
## Platform Differences
| Feature | Node.js | Browser |
|---------|---------|---------|
| `StorageSharedKeyCredential` | ✅ | ❌ |
| SAS generation | ✅ | ❌ |
| DefaultAzureCredential | ✅ | ❌ |
| Anonymous/SAS access | ✅ | ✅ |
| All message operations | ✅ | ✅ |Related Skills
sqs-queue-setup
Sqs Queue Setup - Auto-activating skill for AWS Skills. Triggers on: sqs queue setup, sqs queue setup Part of the AWS Skills skill category.
rabbitmq-queue-setup
Rabbitmq Queue Setup - Auto-activating skill for Backend Development. Triggers on: rabbitmq queue setup, rabbitmq queue setup Part of the Backend Development skill category.
cloud-tasks-queue-setup
Cloud Tasks Queue Setup - Auto-activating skill for GCP Skills. Triggers on: cloud tasks queue setup, cloud tasks queue setup Part of the GCP Skills skill category.
azure-ml-deployer
Azure Ml Deployer - Auto-activating skill for ML Deployment. Triggers on: azure ml deployer, azure ml deployer Part of the ML Deployment skill category.
azure-verified-modules
Azure Verified Modules (AVM) requirements and best practices for developing certified Azure Terraform modules. Use when creating or reviewing Azure modules that need AVM certification.
azure-image-builder
Build Azure managed images and Azure Compute Gallery images with Packer. Use when creating custom images for Azure VMs.
terraform-azurerm-set-diff-analyzer
Analyze Terraform plan JSON output for AzureRM Provider to distinguish between false-positive diffs (order-only changes in Set-type attributes) and actual resource changes. Use when reviewing terraform plan output for Azure resources like Application Gateway, Load Balancer, Firewall, Front Door, NSG, and other resources with Set-type attributes that cause spurious diffs due to internal ordering changes.
azure-static-web-apps
Helps create, configure, and deploy Azure Static Web Apps using the SWA CLI. Use when deploying static sites to Azure, setting up SWA local development, configuring staticwebapp.config.json, adding Azure Functions APIs to SWA, or setting up GitHub Actions CI/CD for Static Web Apps.
azure-resource-health-diagnose
Analyze Azure resource health, diagnose issues from logs and telemetry, and create a remediation plan for identified problems.
azure-pricing
Fetches real-time Azure retail pricing using the Azure Retail Prices API (prices.azure.com) and estimates Copilot Studio agent credit consumption. Use when the user asks about the cost of any Azure service, wants to compare SKU prices, needs pricing data for a cost estimate, mentions Azure pricing, Azure costs, Azure billing, or asks about Copilot Studio pricing, Copilot Credits, or agent usage estimation. Covers compute, storage, networking, databases, AI, Copilot Studio, and all other Azure service families.
azure-devops-cli
Manage Azure DevOps resources via CLI including projects, repos, pipelines, builds, pull requests, work items, artifacts, and service endpoints. Use when working with Azure DevOps, az commands, devops automation, CI/CD, or when user mentions Azure DevOps CLI.
azure-deployment-preflight
Performs comprehensive preflight validation of Bicep deployments to Azure, including template syntax validation, what-if analysis, and permission checks. Use this skill before any deployment to Azure to preview changes, identify potential issues, and ensure the deployment will succeed. Activate when users mention deploying to Azure, validating Bicep files, checking deployment permissions, previewing infrastructure changes, running what-if, or preparing for azd provision.