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".

npx skills add https://github.com/microsoft/skills --skill azure-storage-queue-ts

@azure/storage-queue (TypeScript/JavaScript)

SDK for Azure Queue Storage operations — send, receive, peek, and manage messages in queues.

Installation

npm install @azure/storage-queue @azure/identity

Current Version: 12.x
Node.js: >= 18.0.0

Environment Variables

AZURE_STORAGE_ACCOUNT_NAME=<account-name>
AZURE_STORAGE_ACCOUNT_KEY=<account-key>
# OR connection string
AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=...
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production

Authentication

Microsoft Entra Token Credential (Recommended)

import { QueueServiceClient } from "@azure/storage-queue";
import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity";

// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
const credential = new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]});
// Or use a specific credential directly in production:
// See https://learn.microsoft.com/javascript/api/overview/azure/identity-readme?view=azure-node-latest#credential-classes
// const credential = new ManagedIdentityCredential();

const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME!;
const client = new QueueServiceClient(
  `https://${accountName}.queue.core.windows.net`,
  credential
);

Connection String

import { QueueServiceClient } from "@azure/storage-queue";

const client = QueueServiceClient.fromConnectionString(
  process.env.AZURE_STORAGE_CONNECTION_STRING!
);

StorageSharedKeyCredential (Node.js only)

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

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

const queueClient = client.getQueueClient("my-queue");
await queueClient.create();

// Or create if not exists
await queueClient.createIfNotExists();

List Queues

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

await queueClient.delete();

// Or delete if exists
await queueClient.deleteIfExists();

Get Queue Properties

const properties = await queueClient.getProperties();
console.log("Approximate message count:", properties.approximateMessagesCount);
console.log("Metadata:", properties.metadata);

Set Queue Metadata

await queueClient.setMetadata({
  department: "engineering",
  priority: "high",
});

Message Operations

Send Message

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

// 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).

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.

// 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

// After receiving
const response = await queueClient.receiveMessages();
const message = response.receivedMessageItems[0];

if (message) {
  await queueClient.deleteMessage(message.messageId, message.popReceipt);
}

Clear All Messages

await queueClient.clearMessages();

Message Processing Patterns

Basic Worker Pattern

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

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

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:

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

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

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

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

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

LimitValue
Max message size64 KB
Max visibility timeout7 days
Max time-to-live7 days (or -1 for infinite)
Max messages per receive32
Default visibility timeout30 seconds

Best Practices

  1. Use DefaultAzureCredential for local development; use ManagedIdentityCredential or WorkloadIdentityCredential for production
  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

FeatureNode.jsBrowser
StorageSharedKeyCredential
SAS generation
DefaultAzureCredential
Anonymous/SAS access
All message operations

Plus de skills de microsoft

oss-growth
microsoft
Persona de growth hacker OSS
agent-framework-azure-ai-py
microsoft
Créez des agents Azure AI Foundry à l’aide du SDK Python Microsoft Agent Framework (agent-framework-azure-ai). À utiliser lors de la création d’agents persistants avec AzureAIAgentsProvider, de l’utilisation d’outils hébergés (interpréteur de code, recherche de fichiers, recherche web), de l’intégration de serveurs MCP, de la gestion de fils de conversation ou de l’implémentation de réponses en streaming. Couvre les outils de fonction, les sorties structurées et les agents multi-outils.
development
airunway-aks-setup
microsoft
Configurez AI Runway sur AKS — du cluster nu au modèle en cours d'exécution. Couvre la vérification du cluster, l'installation du contrôleur, l'évaluation GPU, la configuration du fournisseur et le premier déploiement. QUAND : « configurer AI Runway », « intégrer un cluster AKS », « installer AI Runway », « configuration airunway », « déployer un modèle sur AKS », « inférence GPU sur AKS », « configuration KAITO sur AKS », « exécuter LLM sur AKS », « vLLM sur AKS », « configurer le service de modèles sur AKS », « contrôleur AI Runway ».
devops
appinsights-instrumentation
microsoft
Guidance for instrumenting webapps with Azure Application Insights. Provides telemetry patterns, SDK setup, and configuration references. WHEN: how to instrument app, App Insights SDK, telemetry patterns, what is App Insights, Application Insights guidance, instrumentation examples, APM best practices.
devops
applicationinsights-web-ts
microsoft
Instrumentez les applications navigateur/web avec le SDK JavaScript Application Insights (@microsoft/applicationinsights-web). Utilisez-le pour la surveillance des utilisateurs réels (RUM) — vues de page, clics, dépendances AJAX/fetch, exceptions, événements personnalisés et traces d’agents GenAI côté navigateur corrélées aux traces OpenTelemetry backend. Couvre le script de chargement du SDK et la configuration npm, les extensions de framework (React, React Native, Angular), Click Analytics, les initialiseurs de télémétrie et les conventions sémantiques OTel GenAI pour les spans d’agents/outils/modèles émises depuis le navigateur.
devops
azure-ai-anomalydetector-java
microsoft
Créez des applications de détection d'anomalies avec le SDK Azure AI Anomaly Detector pour Java. Utilisez-le lors de l'implémentation de la détection d'anomalies univariées/multivariées, de l'analyse de séries temporelles ou de la surveillance basée sur l'IA.
development
azure-ai-language-conversations-py
microsoft
Implémentez la compréhension du langage conversationnel (CLU) à l’aide du SDK Python azure-ai-language-conversations. Utilisez-le lorsque vous travaillez avec ConversationAnalysisClient pour analyser l’intention et les entités d’une conversation, créer des fonctionnalités de NLP ou intégrer la compréhension du langage dans des applications.
development
azure-ai-ml-py
microsoft
SDK v2 d’Azure Machine Learning pour Python. Utiliser pour les espaces de travail ML, les tâches, les modèles, les jeux de données, le calcul et les pipelines. Déclencheurs : « azure-ai-ml », « MLClient », « espace de travail », « registre de modèles », « tâches d’entraînement », « jeux de données ».
development