@squadai/feedback-client
v1.0.0
Published
Lightweight TypeScript library for sending feedback to Squad GPT
Readme
@squadai/feedback-client
A lightweight TypeScript/Node.js library for sending user feedback to Squad GPT using the public data ingress API.
Features
- Simple API - Just one function to submit feedback
- Lightweight - Uses native
fetch, no heavy dependencies - TypeScript Support - Fully typed for great developer experience
- Batch Support - Submit multiple feedback items with rate limiting
- Environment-based - Reads API key from
SQUAD_API_KEYenv var - Backend-focused - Designed specifically for server-side use
- Validation - Built-in source parameter validation
Installation
Install the package from npm:
npm install @squadai/feedback-clientOr with yarn:
yarn add @squadai/feedback-clientOr with pnpm:
pnpm add @squadai/feedback-clientQuick Start
1. Set Your API Key
Set the SQUAD_API_KEY environment variable:
export SQUAD_API_KEY=your-api-key-hereOr add it to your .env file:
SQUAD_API_KEY=your-api-key-here2. Submit Feedback
import { submitFeedback } from "@squadai/feedback-client";
const result = await submitFeedback("Great product! Love the new features.");
if (result.success) {
console.log("Feedback submitted successfully!");
console.log("Workspace ID:", result.data.data.workspaceId);
} else {
console.error("Failed to submit feedback:", result.error.message);
}That's it! The library automatically reads the API key from process.env.SQUAD_API_KEY.
Usage Examples
Basic Usage
import { submitFeedback } from "@squadai/feedback-client";
// The API key is automatically read from process.env.SQUAD_API_KEY
const result = await submitFeedback("The app is really easy to use!");
if (result.success) {
console.log("✓ Feedback submitted");
console.log("Workspace ID:", result.data.data.workspaceId);
} else {
console.error("✗ Error:", result.error.message);
}With Custom Source
The source parameter must contain only uppercase letters and underscores:
import { submitFeedback } from "@squadai/feedback-client";
// Valid source examples: "USER_FEEDBACK", "API_INTEGRATION", "SLACK_BOT"
const result = await submitFeedback("User feedback from integration", {
source: "USER_FEEDBACK", // Must be UPPERCASE_WITH_UNDERSCORES
});
// This will throw an error:
// source: "user-feedback" ❌ (lowercase and hyphens not allowed)
// source: "UserFeedback" ❌ (mixed case not allowed)
// source: "USER-FEEDBACK" ❌ (hyphens not allowed)Batch Submission
import { submitFeedbackBatch } from "@squadai/feedback-client";
const feedbackItems = [
"Great product!",
"Would love to see feature X",
"The UI is very intuitive",
];
const results = await submitFeedbackBatch(feedbackItems, {
source: "BATCH_IMPORT", // Must be uppercase with underscores
delayMs: 200, // Wait 200ms between submissions to avoid rate limiting
continueOnError: true, // Continue even if one fails
});
const successCount = results.filter((r) => r.success).length;
console.log(`${successCount}/${results.length} submitted successfully`);Custom Timeout
import { submitFeedback } from "@squadai/feedback-client";
const result = await submitFeedback("Test feedback", {
timeout: 5000, // 5 second timeout
});Integration with Express.js
import express from "express";
import { submitFeedback } from "@squadai/feedback-client";
const app = express();
app.use(express.json());
app.post("/api/feedback", async (req, res) => {
const { feedback } = req.body;
if (!feedback) {
return res.status(400).json({ error: "Feedback is required" });
}
const result = await submitFeedback(feedback, {
source: "WEB_FORM" // Must be uppercase with underscores
});
if (result.success) {
res.json({
message: "Thank you for your feedback!",
workspaceId: result.data.data.workspaceId,
});
} else {
res.status(500).json({
error: "Failed to submit feedback",
details: result.error.message,
});
}
});
app.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});Integration with Slack
import { submitFeedback } from "@squadai/feedback-client";
// When user posts in a feedback channel
slackApp.message(async ({ message, say }) => {
const result = await submitFeedback(message.text, {
source: "SLACK_INTEGRATION" // Must be uppercase with underscores
});
if (result.success) {
await say("Thanks for your feedback! We've recorded it.");
} else {
await say("Sorry, failed to record feedback. Please try again.");
}
});Batch Import from External Sources
import { submitFeedbackBatch } from "@squadai/feedback-client";
// Get responses from your data source
const responses = await getExternalResponses();
// Submit all responses as feedback
const results = await submitFeedbackBatch(
responses.map((r) => r.text),
{
source: "EXTERNAL_IMPORT", // Must be uppercase with underscores
delayMs: 200,
continueOnError: true,
}
);
const successCount = results.filter((r) => r.success).length;
console.log(`Imported ${successCount}/${results.length} responses`);API Reference
submitFeedback(feedback, options?)
Submit a single feedback item.
Parameters:
feedback(string, required): The feedback text to submitoptions(object, optional):source(string): The source of the feedback. Must contain only uppercase letters and underscores (e.g., "SQUAD_CLIENT", "USER_FEEDBACK"). Defaults to"SQUAD_CLIENT"baseUrl(string): The base URL for the Squad API. Defaults to"https://api.meetsquad.ai"timeout(number): Request timeout in milliseconds. Defaults to10000(10 seconds)
Returns: Promise<SubmitFeedbackResult>
The result is a discriminated union type that provides excellent type safety:
// Success case
{
success: true;
data: SquadFeedbackResponse;
statusCode: number;
}
// Failure case
{
success: false;
error: Error;
statusCode?: number;
}This means TypeScript will automatically narrow the types based on the success field:
const result = await submitFeedback("Test");
if (result.success) {
// TypeScript knows result.data exists here
console.log(result.data.data.workspaceId);
} else {
// TypeScript knows result.error exists here
console.log(result.error.message);
}submitFeedbackBatch(feedbackItems, options?)
Submit multiple feedback items with automatic rate limiting.
Parameters:
feedbackItems(string[], required): Array of feedback strings to submitoptions(object, optional):- All options from
submitFeedback delayMs(number): Delay between submissions in milliseconds to avoid rate limiting. Defaults to100continueOnError(boolean): Whether to continue submitting if one fails. Defaults totrue
- All options from
Returns: Promise<SubmitFeedbackResult[]>
An array of results for each feedback item, maintaining the same order as the input.
Environment Variables
SQUAD_API_KEY(required): Your Squad API key
Note: The API key is ALWAYS read from the environment variable SQUAD_API_KEY. This is a security best practice for backend applications.
Error Handling
The library provides detailed error information in the result object:
const result = await submitFeedback("Test feedback");
if (!result.success) {
console.error("Error:", result.error.message);
console.error("Status Code:", result.statusCode);
// Handle specific errors
if (result.error.message.includes("SQUAD_API_KEY")) {
console.error("API key not set in environment");
} else if (result.error.message.includes("Invalid source format")) {
console.error("Source must be uppercase letters and underscores only");
} else if (result.statusCode === 401) {
console.error("Invalid API key");
} else if (result.statusCode === 400) {
console.error("Bad request - check your feedback format");
} else if (result.error.message.includes("timeout")) {
console.error("Request timed out");
}
}TypeScript Support
This package is written in TypeScript and includes full type definitions. All types are exported:
import {
submitFeedback,
submitFeedbackBatch,
type SubmitFeedbackOptions,
type SubmitFeedbackBatchOptions,
type SquadFeedbackResponse,
type SubmitFeedbackResult,
type SubmitFeedbackSuccess,
type SubmitFeedbackFailure,
} from "@squadai/feedback-client";Source Parameter Validation
The source parameter is used as a path parameter in the API URL and must follow strict formatting rules:
✅ Valid formats:
"SQUAD_CLIENT""USER_FEEDBACK""API_INTEGRATION""SLACK_BOT""WEB_FORM"
❌ Invalid formats:
"squad-client"(lowercase and hyphens)"UserFeedback"(mixed case)"USER-FEEDBACK"(hyphens not allowed)"SQUAD CLIENT"(spaces not allowed)"SQUAD_123"(numbers not allowed)
If an invalid source format is provided, the library will throw an error with a descriptive message.
Development
Building from Source
If you want to contribute or build the package locally:
- Clone the repository:
git clone https://github.com/your-org/squad-feedback-client.git
cd squad-feedback-client- Install dependencies:
npm install- Build the package:
npm run buildThis will create compiled JavaScript and type definitions in the dist/ directory.
Running Tests
npm testRunning the Example
- Copy
.env.exampleto.env:
cp .env.example .env- Add your API key to
.env:
SQUAD_API_KEY=your-api-key-here- Run the example:
npm run devLicense
MIT
Support
For issues, questions, or feature requests, please:
- Contact Squad support
- Create an issue in the GitHub repository
- Check our documentation
Contributing
We welcome contributions! Please see our Contributing Guidelines for details.
Changelog
See CHANGELOG.md for a list of changes in each version.
