|
| 1 | +--- |
| 2 | +title: "Quickstart: Use a blocklist with JavaScript" |
| 3 | +description: In this quickstart, get started using the Azure AI Content Safety JavaScript SDK to create and use a text blocklist. |
| 4 | +author: PatrickFarley |
| 5 | +manager: nitinme |
| 6 | +ms.service: azure-ai-content-safety |
| 7 | +ms.custom: |
| 8 | +ms.topic: include |
| 9 | +ms.date: 07/16/2025 |
| 10 | +ms.author: pafarley |
| 11 | +--- |
| 12 | + |
| 13 | +[Reference documentation](https://www.npmjs.com/package/@azure-rest/ai-content-safety/v/1.0.0) | [Library source code](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/contentsafety/ai-content-safety-rest) | [Package (npm)](https://www.npmjs.com/package/@azure-rest/ai-content-safety) | [Samples](https://github.com/Azure-Samples/AzureAIContentSafety/tree/main/js/1.0.0) | |
| 14 | + |
| 15 | + |
| 16 | +## Prerequisites |
| 17 | + |
| 18 | +* An Azure subscription - [Create one for free](https://azure.microsoft.com/free/cognitive-services/) |
| 19 | +* [Node.js LTS](https://nodejs.org/) |
| 20 | +* [Visual Studio Code](https://code.visualstudio.com/) |
| 21 | +* Once you have your Azure subscription, <a href="https://aka.ms/acs-create" title="Create a Content Safety resource" target="_blank">create a Content Safety resource </a> in the Azure portal to get your key and endpoint. Enter a unique name for your resource, select your subscription, and select a resource group, supported region (see [Region availability](/azure/ai-services/content-safety/overview#region-availability)), and supported pricing tier. Then select **Create**. |
| 22 | + * The resource takes a few minutes to deploy. After it finishes, Select **go to resource**. In the left pane, under **Resource Management**, select **Subscription Key and Endpoint**. The endpoint and either of the keys are used to call APIs. |
| 23 | + |
| 24 | +## Set up local development environment |
| 25 | + |
| 26 | +1. Create a new directory for your project and navigate to it: |
| 27 | + |
| 28 | + ```console |
| 29 | + mkdir content-safety-blocklist-analysis |
| 30 | + cd content-safety-blocklist-analysis |
| 31 | + code . |
| 32 | + ``` |
| 33 | + |
| 34 | +1. Create a new package for ESM modules in your project directory: |
| 35 | + |
| 36 | + ```console |
| 37 | + npm init -y |
| 38 | + npm pkg set type=module |
| 39 | + ``` |
| 40 | + |
| 41 | +1. Install the required packages: |
| 42 | + |
| 43 | + ```console |
| 44 | + npm install @azure-rest/ai-content-safety |
| 45 | + ``` |
| 46 | + |
| 47 | +1. Create a `src` directory for your JavaScript code. |
| 48 | + |
| 49 | +[!INCLUDE [Create environment variables](../env-vars.md)] |
| 50 | + |
| 51 | +## Create and use a blocklist |
| 52 | + |
| 53 | +Create a new file in your `src` directory, `index.js` and paste in the following code. |
| 54 | + |
| 55 | + |
| 56 | +```javascript |
| 57 | +import ContentSafetyClient, { |
| 58 | + isUnexpected |
| 59 | +} from "@azure-rest/ai-content-safety"; |
| 60 | +import { AzureKeyCredential } from "@azure/core-auth"; |
| 61 | +import * as dotenv from "dotenv"; |
| 62 | + |
| 63 | +// Load the .env file |
| 64 | +dotenv.config(); |
| 65 | + |
| 66 | +// Get endpoint and key from environment variables |
| 67 | +const key = process.env.CONTENT_SAFETY_KEY; |
| 68 | +const endpoint = process.env.CONTENT_SAFETY_ENDPOINT; |
| 69 | + |
| 70 | +if (!key || !endpoint) { |
| 71 | + throw new Error("Missing required environment variables: CONTENT_SAFETY_KEY or CONTENT_SAFETY_ENDPOINT"); |
| 72 | +} |
| 73 | + |
| 74 | +// Define your blocklist information |
| 75 | +// This creates a custom blocklist for words/phrases you want to specifically block |
| 76 | +const blocklistName = "company-prohibited-terms"; |
| 77 | +const blocklistDescription = "Custom blocklist for company-specific prohibited terms and phrases"; |
| 78 | + |
| 79 | +// Define items to block - these are specific words or phrases you want to flag |
| 80 | +// Even if Azure AI doesn't naturally flag them, these will be caught |
| 81 | +const blocklistItemText1 = "confidential project alpha"; |
| 82 | +const blocklistItemText2 = "internal revenue data"; |
| 83 | + |
| 84 | +// Define sample text for analysis that contains one of our blocked terms |
| 85 | +const inputText = "Please don't share the confidential project alpha details with external teams."; |
| 86 | + |
| 87 | +/** |
| 88 | + * Step 1: Create or update a custom blocklist container |
| 89 | + */ |
| 90 | +async function createBlocklistContainer( |
| 91 | + client, |
| 92 | + name, |
| 93 | + description |
| 94 | +) { |
| 95 | + |
| 96 | + const blocklistData = { |
| 97 | + blocklistName: name, |
| 98 | + description: description |
| 99 | + }; |
| 100 | + |
| 101 | + const createBlocklistParams = { |
| 102 | + body: blocklistData, |
| 103 | + contentType: "application/merge-patch+json" |
| 104 | + }; |
| 105 | + |
| 106 | + const blocklistResult = |
| 107 | + await client.path("/text/blocklists/{blocklistName}", name).patch(createBlocklistParams); |
| 108 | + |
| 109 | + if (isUnexpected(blocklistResult)) { |
| 110 | + throw blocklistResult; |
| 111 | + } |
| 112 | + |
| 113 | + console.log("✅ Blocklist created successfully!"); |
| 114 | + console.log(` Name: ${blocklistResult.body.blocklistName}`); |
| 115 | + console.log(` Description: ${blocklistResult.body.description || "No description"}\n`); |
| 116 | +} |
| 117 | + |
| 118 | +/** |
| 119 | + * Step 2: Add specific prohibited terms to the blocklist |
| 120 | + */ |
| 121 | +async function addProhibitedTerms( |
| 122 | + client, |
| 123 | + blocklistName, |
| 124 | + terms |
| 125 | +) { |
| 126 | + |
| 127 | + const blocklistItems = terms.map(text => ({ text })); |
| 128 | + |
| 129 | + const addItemsParams = { |
| 130 | + body: { blocklistItems: blocklistItems } |
| 131 | + }; |
| 132 | + |
| 133 | + const addItemsResult = |
| 134 | + await client.path("/text/blocklists/{blocklistName}:addOrUpdateBlocklistItems", blocklistName).post(addItemsParams); |
| 135 | + |
| 136 | + if (isUnexpected(addItemsResult)) { |
| 137 | + throw addItemsResult; |
| 138 | + } |
| 139 | + |
| 140 | + console.log("✅ Terms added to blocklist successfully!"); |
| 141 | + for (const item of addItemsResult.body.blocklistItems) { |
| 142 | + console.log(` BlocklistItemId: ${item.blocklistItemId}`); |
| 143 | + console.log(` Text: "${item.text}"`); |
| 144 | + console.log(` Description: ${item.description || "No description"}\n`); |
| 145 | + } |
| 146 | +} |
| 147 | + |
| 148 | +/** |
| 149 | + * Step 3: Wait for blocklist changes to propagate through Azure's system |
| 150 | + */ |
| 151 | +async function waitForBlocklistActivation(seconds = 5) { |
| 152 | + await new Promise(resolve => setTimeout(resolve, seconds * 1000)); |
| 153 | +} |
| 154 | + |
| 155 | +/** |
| 156 | + * Step 4: Analyze text against the custom blocklist |
| 157 | + */ |
| 158 | +async function analyzeTextAgainstBlocklist( |
| 159 | + client, |
| 160 | + textToAnalyze, |
| 161 | + blocklistName |
| 162 | +) { |
| 163 | + |
| 164 | + const analyzeTextOption = { |
| 165 | + text: textToAnalyze, |
| 166 | + blocklistNames: [blocklistName], // Use our custom blocklist |
| 167 | + haltOnBlocklistHit: false // Continue analysis even if blocklist match found |
| 168 | + }; |
| 169 | + |
| 170 | + const analyzeTextParams = { body: analyzeTextOption }; |
| 171 | + |
| 172 | + const analysisResult = |
| 173 | + await client.path("/text:analyze").post(analyzeTextParams); |
| 174 | + |
| 175 | + if (isUnexpected(analysisResult)) { |
| 176 | + throw analysisResult; |
| 177 | + } |
| 178 | + |
| 179 | + return analysisResult; |
| 180 | +} |
| 181 | + |
| 182 | +/** |
| 183 | + * Step 5: Display analysis results and explain what they mean |
| 184 | + */ |
| 185 | +function displayAnalysisResults(analysisResult) { |
| 186 | + |
| 187 | + if (analysisResult.body.blocklistsMatch && analysisResult.body.blocklistsMatch.length > 0) { |
| 188 | + console.log("🚨 BLOCKED CONTENT DETECTED!"); |
| 189 | + console.log("The following prohibited terms were found:\n"); |
| 190 | + |
| 191 | + for (const match of analysisResult.body.blocklistsMatch) { |
| 192 | + console.log(` Blocklist: ${match.blocklistName}`); |
| 193 | + console.log(` Matched Term: "${match.blocklistItemText}"`); |
| 194 | + console.log(` Item ID: ${match.blocklistItemId}\n`); |
| 195 | + } |
| 196 | + |
| 197 | + } else { |
| 198 | + console.log("✅ No blocked content found."); |
| 199 | + console.log("The text does not contain any terms from your custom blocklist."); |
| 200 | + } |
| 201 | +} |
| 202 | + |
| 203 | +try { |
| 204 | + const credential = new AzureKeyCredential(key); |
| 205 | + const client = ContentSafetyClient(endpoint, credential); |
| 206 | + |
| 207 | + // Execute the five main steps |
| 208 | + await createBlocklistContainer(client, blocklistName, blocklistDescription); |
| 209 | + await addProhibitedTerms(client, blocklistName, [blocklistItemText1, blocklistItemText2]); |
| 210 | + |
| 211 | + console.log("⏳ Waiting for blocklist changes to take effect..."); |
| 212 | + await waitForBlocklistActivation(); |
| 213 | + |
| 214 | + const analysisResult = await analyzeTextAgainstBlocklist(client, inputText, blocklistName); |
| 215 | + |
| 216 | + displayAnalysisResults(analysisResult); |
| 217 | + |
| 218 | +} catch (error) { |
| 219 | + console.error("❌ An error occurred:", error.message); |
| 220 | + if (error.code) { |
| 221 | + console.error(`Error code: ${error.code}`); |
| 222 | + } |
| 223 | + if (error.details) { |
| 224 | + console.error("Error details:", error.details); |
| 225 | + } |
| 226 | +} |
| 227 | +``` |
| 228 | + |
| 229 | +This code: |
| 230 | + |
| 231 | +- Creates a custom blocklist. |
| 232 | +- Adds prohibited terms to it. |
| 233 | +- Analyzes text against the blocklist. |
| 234 | + |
| 235 | + |
| 236 | +The TypeScript implementation provides strong typing for better development experience and error checking. |
| 237 | + |
| 238 | +## Run the sample |
| 239 | + |
| 240 | +Run the application with the `node` command on your quickstart file. |
| 241 | + |
| 242 | +```console |
| 243 | +node -r dotenv/config src/index.js |
| 244 | +``` |
| 245 | + |
| 246 | +## Output |
| 247 | + |
| 248 | +When you run the application, you should see output similar to this: |
| 249 | + |
| 250 | +```console |
| 251 | +✅ Blocklist created successfully! |
| 252 | + Name: company-prohibited-terms |
| 253 | + Description: Custom blocklist for company-specific prohibited terms and phrases |
| 254 | + |
| 255 | +✅ Terms added to blocklist successfully! |
| 256 | + BlocklistItemId: 6fe21688-f65d-4d0b-9ff5-c6e5859ea83a |
| 257 | + Text: "internal revenue data" |
| 258 | + Description: No description |
| 259 | + |
| 260 | + BlocklistItemId: b48f958b-a58b-4d49-9e33-8ece75fc6c3b |
| 261 | + Text: "confidential project alpha" |
| 262 | + Description: No description |
| 263 | + |
| 264 | +🚨 BLOCKED CONTENT DETECTED! |
| 265 | +The following prohibited terms were found: |
| 266 | + |
| 267 | + Blocklist: company-prohibited-terms |
| 268 | + Matched Term: "confidential project alpha" |
| 269 | + Item ID: b48f958b-a58b-4d49-9e33-8ece75fc6c3b |
| 270 | +``` |
0 commit comments