Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Enterprise messaging with queues, topics, and subscriptions.
.claude/skills/azure-servicebus-ts/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | — | — |
| case-03 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✓→✓ | = Same ✓ | — | — |
| case-20 | ✗→✗ | = Same ✗ | — | — |
| case-18 | ✗→✗ | = Same ✗ | — | — |
Enterprise messaging with queues, topics, and subscriptions.
bashnpm install @azure/service-bus @azure/identity
bashSERVICEBUS_NAMESPACE=<namespace>.servicebus.windows.net SERVICEBUS_QUEUE_NAME=my-queue SERVICEBUS_TOPIC_NAME=my-topic SERVICEBUS_SUBSCRIPTION_NAME=my-subscription
typescriptimport { ServiceBusClient } from "@azure/service-bus"; import { DefaultAzureCredential } from "@azure/identity"; const fullyQualifiedNamespace = process.env.SERVICEBUS_NAMESPACE!; const client = new ServiceBusClient(fullyQualifiedNamespace, new DefaultAzureCredential());
typescriptconst sender = client.createSender("my-queue"); // Single message await sender.sendMessages({ body: { orderId: "12345", amount: 99.99 }, contentType: "application/json", }); // Batch messages const batch = await sender.createMessageBatch(); batch.tryAddMessage({ body: "Message 1" }); batch.tryAddMessage({ body: "Message 2" }); await sender.sendMessages(batch); await sender.close();
typescriptconst receiver = client.createReceiver("my-queue"); // Receive batch const messages = await receiver.receiveMessages(10, { maxWaitTimeInMs: 5000 }); for (const message of messages) { console.log(`Received: ${message.body}`); await receiver.completeMessage(message); } await receiver.close();
typescriptconst receiver = client.createReceiver("my-queue"); const subscription = receiver.subscribe({ processMessage: async (message) => { console.log(`Processing: ${message.body}`); // Message auto-completed on success }, processError: async (args) => { console.error(`Error: ${args.error}`); }, }); // Stop after some time setTimeout(async () => { await subscription.close(); await receiver.close(); }, 60000);
typescript// Send to topic const topicSender = client.createSender("my-topic"); await topicSender.sendMessages({ body: { event: "order.created", data: { orderId: "123" } }, applicationProperties: { eventType: "order.created" }, }); // Receive from subscription const subscriptionReceiver = client.createReceiver("my-topic", "my-subscription"); const messages = await subscriptionReceiver.receiveMessages(10);
typescript// Send session message const sender = client.createSender("session-queue"); await sender.sendMessages({ body: { step: 1, data: "First step" }, sessionId: "workflow-123", }); // Receive session messages const sessionReceiver = await client.acceptSession("session-queue", "workflow-123"); const messages = await sessionReceiver.receiveMessages(10); // Get/set session state const state = await sessionReceiver.getSessionState(); await sessionReceiver.setSessionState(Buffer.from(JSON.stringify({ progress: 50 }))); await sessionReceiver.close();
typescript// Move to dead-letter await receiver.deadLetterMessage(message, { deadLetterReason: "Validation failed", deadLetterErrorDescription: "Missing required field: orderId", }); // Process dead-letter queue const dlqReceiver = client.createReceiver("my-queue", { subQueueType: "deadLetter" }); const dlqMessages = await dlqReceiver.receiveMessages(10); for (const msg of dlqMessages) { console.log(`DLQ Reason: ${msg.deadLetterReason}`); // Reprocess or log await dlqReceiver.completeMessage(msg); }
typescriptconst sender = client.createSender("my-queue"); // Schedule for future delivery const scheduledTime = new Date(Date.now() + 60000); // 1 minute from now const sequenceNumber = await sender.scheduleMessages( { body: "Delayed message" }, scheduledTime ); // Cancel scheduled message await sender.cancelScheduledMessages(sequenceNumber);
typescript// Defer message for later await receiver.deferMessage(message); // Receive deferred message by sequence number const deferredMessage = await receiver.receiveDeferredMessages(message.sequenceNumber!); await receiver.completeMessage(deferredMessage[0]);
typescriptconst receiver = client.createReceiver("my-queue"); // Peek without removing const peekedMessages = await receiver.peekMessages(10); for (const msg of peekedMessages) { console.log(`Peeked: ${msg.body}`); }
typescriptimport { ServiceBusClient, ServiceBusSender, ServiceBusReceiver, ServiceBusSessionReceiver, ServiceBusMessage, ServiceBusReceivedMessage, ProcessMessageCallback, ProcessErrorCallback, } from "@azure/service-bus";
typescript// Peek-Lock (default) - message locked until completed/abandoned const receiver = client.createReceiver("my-queue", { receiveMode: "peekLock" }); await receiver.completeMessage(message); // Remove from queue await receiver.abandonMessage(message); // Return to queue await receiver.deferMessage(message); // Defer for later await receiver.deadLetterMessage(message); // Move to DLQ // Receive-and-Delete - message removed immediately const receiver = client.createReceiver("my-queue", { receiveMode: "receiveAndDelete" });
ServiceBusClient once, share across senders/receiversprocessError callback for subscription receiverscreateMessageBatch() for multiple messagesFor detailed patterns, see:
This skill is applicable to execute the workflow or actions described in the overview.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.