{
  "schema": "https://ai-atoms.com/schemas/skill-v1.json",
  "type": "skill",
  "id": "skill/azure-storage-queue-ts",
  "version": "1.0.1",
  "name": "Azure Storage Queue Ts",
  "description": "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\".",
  "system_prompt_fragment": "# @azure/storage-queue (TypeScript/JavaScript)\n\nSDK for Azure Queue Storage operations — send, receive, peek, and manage messages in queues.\n\n## Installation\n\n```bash\nnpm install @azure/storage-queue @azure/identity\n```\n\n**Current Version**: 12.x  \n**Node.js**: >= 18.0.0\n\n## Environment Variables\n\n```bash\nAZURE_STORAGE_ACCOUNT_NAME=<account-name>\nAZURE_STORAGE_ACCOUNT_KEY=<account-key>\n# OR connection string\nAZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...\n```\n\n## Authentication\n\n### DefaultAzureCredential (Recommended)\n\n```typescript\nimport { QueueServiceClient } from \"@azure/storage-queue\";\nimport { DefaultAzureCredential } from \"@azure/identity\";\n\nconst accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;\nconst client = new QueueServiceClient(\n  `https://${accountName}.queue.core.windows.net`,\n  new DefaultAzureCredential()\n);\n```\n\n### Connection String\n\n```typescript\nimport { QueueServiceClient } from \"@azure/storage-queue\";\n\nconst client = QueueServiceClient.fromConnectionString(\n  process.env.AZURE_STORAGE_CONNECTION_STRING!\n);\n```\n\n### StorageSharedKeyCredential (Node.js only)\n\n```typescript\nimport { QueueServiceClient, StorageSharedKeyCredential } from \"@azure/storage-queue\";\n\nconst accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;\nconst accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY!;\n\nconst sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);\nconst client = new QueueServiceClient(\n  `https://${accountName}.queue.core.windows.net`,\n  sharedKeyCredential\n);\n```\n\n### SAS Token\n\n```typescript\nimport { QueueServiceClient } from \"@azure/storage-queue\";\n\nconst accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;\nconst sasToken = process.env.AZURE_STORAGE_SAS_TOKEN!;\n\nconst client = new QueueServiceClient(\n  `https://${accountName}.queue.core.windows.net${sasToken}`\n);\n```\n\n## Client Hierarchy\n\n```\nQueueServiceClient (account level)\n└── QueueClient (queue level)\n    └── Messages (send, receive, peek, delete)\n```\n\n## Queue Operations\n\n### Create Queue\n\n```typescript\nconst queueClient = client.getQueueClient(\"my-queue\");\nawait queueClient.create();\n\n// Or create if not exists\nawait queueClient.createIfNotExists();\n```\n\n### List Queues\n\n```typescript\nfor await (const queue of client.listQueues()) {\n  console.log(queue.name);\n}\n\n// With prefix filter\nfor await (const queue of client.listQueues({ prefix: \"task-\" })) {\n  console.log(queue.name);\n}\n```\n\n### Delete Queue\n\n```typescript\nawait queueClient.delete();\n\n// Or delete if exists\nawait queueClient.deleteIfExists();\n```\n\n### Get Queue Properties\n\n```typescript\nconst properties = await queueClient.getProperties();\nconsole.log(\"Approximate message count:\", properties.approximateMessagesCount);\nconsole.log(\"Metadata:\", properties.metadata);\n```\n\n### Set Queue Metadata\n\n```typescript\nawait queueClient.setMetadata({\n  department: \"engineering\",\n  priority: \"high\",\n});\n```\n\n## Message Operations\n\n### Send Message\n\n```typescript\nconst queueClient = client.getQueueClient(\"my-queue\");\n\n// Simple message\nawait queueClient.sendMessage(\"Hello, World!\");\n\n// With options\nawait queueClient.sendMessage(\"Delayed message\", {\n  visibilityTimeout: 60, // Hidden for 60 seconds\n  messageTimeToLive: 3600, // Expires in 1 hour\n});\n\n// JSON message (must be string)\nconst task = { type: \"process\", data: { id: 123 } };\nawait queueClient.sendMessage(JSON.stringify(task));\n```\n\n### Receive Messages\n\n```typescript\n// Receive up to 32 messages (default: 1)\nconst response = await queueClient.receiveMessages({\n  numberOfMessages: 10,\n  visibilityTimeout: 30, // 30 seconds to process\n});\n\nfor (const message of response.receivedMessageItems) {\n  console.log(\"Message ID:\", message.messageId);\n  console.log(\"Content:\", message.messageText);\n  console.log(\"Dequeue Count:\", message.dequeueCount);\n  console.log(\"Pop Receipt:\", message.popReceipt);\n  \n  // Process the message...\n  \n  // Delete after processing\n  await queueClient.deleteMessage(message.messageId, message.popReceipt);\n}\n```\n\n### Peek Messages\n\nPeek without removing from queue (no visibility timeout).\n\n```typescript\nconst response = await queueClient.peekMessages({\n  numberOfMessages: 5,\n});\n\nfor (const message of response.peekedMessageItems) {\n  console.log(\"Message ID:\", message.messageId);\n  console.log(\"Content:\", message.messageText);\n  // Note: No popReceipt - cannot delete peeked messages\n}\n```\n\n### Update Message\n\nExtend visibility timeout or update content.\n\n```typescript\n// Receive a message\nconst response = await queueClient.receiveMessages();\nconst message = response.receivedMessageItems[0];\n\nif (message) {\n  // Update content and extend visibility\n  const updateResponse = await queueClient.updateMessage(\n    message.messageId,\n    message.popReceipt,\n    \"Updated content\",\n    60 // New visibility timeout in seconds\n  );\n  \n  // Use new popReceipt for subsequent operations\n  console.log(\"New pop receipt:\", updateResponse.popReceipt);\n}\n```\n\n### Delete Message\n\n```typescript\n// After receiving\nconst response = await queueClient.receiveMessages();\nconst message = response.receivedMessageItems[0];\n\nif (message) {\n  await queueClient.deleteMessage(message.messageId, message.popReceipt);\n}\n```\n\n### Clear All Messages\n\n```typescript\nawait queueClient.clearMessages();\n```\n\n## Message Processing Patterns\n\n### Basic Worker Pattern\n\n```typescript\nasync function processQueue(queueClient: QueueClient): Promise<void> {\n  while (true) {\n    const response = await queueClient.receiveMessages({\n      numberOfMessages: 10,\n      visibilityTimeout: 30,\n    });\n\n    if (response.receivedMessageItems.length === 0) {\n      // No messages, wait before polling again\n      await sleep(5000);\n      continue;\n    }\n\n    for (const message of response.receivedMessageItems) {\n      try {\n        await processMessage(message.messageText);\n        await queueClient.deleteMessage(message.messageId, message.popReceipt);\n      } catch (error) {\n        console.error(`Failed to process message ${message.messageId}:`, error);\n        // Message will become visible again after timeout\n      }\n    }\n  }\n}\n\nasync function processMessage(content: string): Promise<void> {\n  const task = JSON.parse(content);\n  // Process task...\n}\n\nfunction sleep(ms: number): Promise<void> {\n  return new Promise((resolve) => setTimeout(resolve, ms));\n}\n```\n\n### Poison Message Handling\n\n```typescript\nconst MAX_DEQUEUE_COUNT = 5;\n\nasync function processWithPoisonHandling(\n  queueClient: QueueClient,\n  poisonQueueClient: QueueClient\n): Promise<void> {\n  const response = await queueClient.receiveMessages({\n    numberOfMessages: 10,\n    visibilityTimeout: 30,\n  });\n\n  for (const message of response.receivedMessageItems) {\n    if (message.dequeueCount > MAX_DEQUEUE_COUNT) {\n      // Move to poison queue\n      await poisonQueueClient.sendMessage(message.messageText);\n      await queueClient.deleteMessage(message.messageId, message.popReceipt);\n      console.log(`Moved message ${message.messageId} to poison queue`);\n      continue;\n    }\n\n    try {\n      await processMessage(message.messageText);\n      await queueClient.deleteMessage(message.messageId, message.popReceipt);\n    } catch (error) {\n      console.error(`Processing failed (attempt ${message.dequeueCount}):`, error);\n    }\n  }\n}\n```\n\n### Batch Processing with Visibility Extension\n\n```typescript\nasync function processBatchWithExtension(queueClient: QueueClient): Promise<void> {\n  const response = await queueClient.receiveMessages({\n    numberOfMessages: 1,\n    visibilityTimeout: 60,\n  });\n\n  const message = response.receivedMessageItems[0];\n  if (!message) return;\n\n  let popReceipt = message.popReceipt;\n\n  // Start visibility extension timer\n  const extensionInterval = setInterval(async () => {\n    try {\n      const updateResponse = await queueClient.updateMessage(\n        message.messageId,\n        popReceipt,\n        message.messageText,\n        60 // Extend by another 60 seconds\n      );\n      popReceipt = updateResponse.popReceipt;\n    } catch (error) {\n      console.error(\"Failed to extend visibility:\", error);\n    }\n  }, 45000); // Extend every 45 seconds\n\n  try {\n    await longRunningProcess(message.messageText);\n    await queueClient.deleteMessage(message.messageId, popReceipt);\n  } finally {\n    clearInterval(extensionInterval);\n  }\n}\n```\n\n## Message Encoding\n\nBy default, messages are Base64 encoded. You can customize this:\n\n```typescript\nimport { QueueClient } from \"@azure/storage-queue\";\n\n// Custom encoder/decoder for plain text\nconst queueClient = new QueueClient(\n  `https://${accountName}.queue.core.windows.net/my-queue`,\n  credential,\n  {\n    messageEncoding: \"text\", // \"base64\" (default) or \"text\"\n  }\n);\n\n// Or with custom encoder\nconst customQueueClient = new QueueClient(\n  `https://${accountName}.queue.core.windows.net/my-queue`,\n  credential,\n  {\n    messageEncoding: {\n      encode: (message: string) => Buffer.from(message).toString(\"base64\"),\n      decode: (message: string) => Buffer.from(message, \"base64\").toString(),\n    },\n  }\n);\n```\n\n## SAS Token Generation (Node.js only)\n\n### Generate Queue SAS\n\n```typescript\nimport {\n  QueueSASPermissions,\n  generateQueueSASQueryParameters,\n  StorageSharedKeyCredential,\n} from \"@azure/storage-queue\";\n\nconst sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey);\n\nconst sasToken = generateQueueSASQueryParameters(\n  {\n    queueName: \"my-queue\",\n    permissions: QueueSASPermissions.parse(\"raup\"), // read, add, update, process\n    startsOn: new Date(),\n    expiresOn: new Date(Date.now() + 3600 * 1000), // 1 hour\n  },\n  sharedKeyCredential\n).toString();\n\nconst sasUrl = `https://${accountName}.queue.core.windows.net/my-queue?${sasToken}`;\n```\n\n### Generate Account SAS\n\n```typescript\nimport {\n  AccountSASPermissions,\n  AccountSASResourceTypes,\n  AccountSASServices,\n  generateAccountSASQueryParameters,\n} from \"@azure/storage-queue\";\n\nconst sasToken = generateAccountSASQueryParameters(\n  {\n    services: AccountSASServices.parse(\"q\").toString(), // queue\n    resourceTypes: AccountSASResourceTypes.parse(\"sco\").toString(),\n    permissions: AccountSASPermissions.parse(\"rwdlacupi\"),\n    expiresOn: new Date(Date.now() + 24 * 3600 * 1000),\n  },\n  sharedKeyCredential\n).toString();\n```\n\n## Error Handling\n\n```typescript\nimport { RestError } from \"@azure/storage-queue\";\n\ntry {\n  await queueClient.sendMessage(\"test\");\n} catch (error) {\n  if (error instanceof RestError) {\n    switch (error.statusCode) {\n      case 404:\n        console.log(\"Queue not found\");\n        break;\n      case 400:\n        console.log(\"Bad request - message too large or invalid\");\n        break;\n      case 403:\n        console.log(\"Access denied\");\n        break;\n      case 409:\n        console.log(\"Queue already exists or being deleted\");\n        break;\n      default:\n        console.error(`Storage error ${error.statusCode}: ${error.message}`);\n    }\n  }\n  throw error;\n}\n```\n\n## TypeScript Types Reference\n\n```typescript\nimport {\n  // Clients\n  QueueServiceClient,\n  QueueClient,\n\n  // Authentication\n  StorageSharedKeyCredential,\n  AnonymousCredential,\n\n  // SAS\n  QueueSASPermissions,\n  AccountSASPermissions,\n  AccountSASServices,\n  AccountSASResourceTypes,\n  generateQueueSASQueryParameters,\n  generateAccountSASQueryParameters,\n\n  // Messages\n  DequeuedMessageItem,\n  PeekedMessageItem,\n  QueueSendMessageResponse,\n  QueueReceiveMessageResponse,\n  QueueUpdateMessageResponse,\n\n  // Queue\n  QueueItem,\n  QueueGetPropertiesResponse,\n\n  // Errors\n  RestError,\n} from \"@azure/storage-queue\";\n```\n\n## Message Limits\n\n| Limit | Value |\n|-------|-------|\n| Max message size | 64 KB |\n| Max visibility timeout | 7 days |\n| Max time-to-live | 7 days (or -1 for infinite) |\n| Max messages per receive | 32 |\n| Default visibility timeout | 30 seconds |\n\n## Best Practices\n\n1. **Use DefaultAzureCredential** — Prefer AAD over connection strings/keys\n2. **Always delete after processing** — Prevent duplicate processing\n3. **Handle poison messages** — Move failed messages to a dead-letter queue\n4. **Use appropriate visibility timeout** — Set based on expected processing time\n5. **Extend visibility for long tasks** — Update message to prevent timeout\n6. **Use JSON for structured data** — Serialize objects to JSON strings\n7. **Check dequeueCount** — Detect repeatedly failing messages\n8. **Use batch receive** — Receive multiple messages for efficiency\n\n## Platform Differences\n\n| Feature | Node.js | Browser |\n|---------|---------|---------|\n| `StorageSharedKeyCredential` | ✅ | ❌ |\n| SAS generation | ✅ | ❌ |\n| DefaultAzureCredential | ✅ | ❌ |\n| Anonymous/SAS access | ✅ | ✅ |\n| All message operations | ✅ | ✅ |\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.",
  "applicable_domains": [
    "devops"
  ],
  "category": "devops",
  "invocation": [
    "/azure-storage-queue-ts"
  ],
  "authored_by": "claudeskills.in community",
  "source_url": "https://claudeskills.in/skill/azure-storage-queue-ts",
  "provenance": {
    "source": "claudeskills.in",
    "source_url": "https://claudeskills.in/skill/azure-storage-queue-ts",
    "license": "unknown",
    "imported_at": "2026-09-03",
    "notes": "Aggregated by claudeskills.in from community GitHub lists."
  },
  "tags": [
    "claudeskills",
    "devops"
  ],
  "lifecycle": "draft"
}