
Research
GemStuffer Campaign Abuses RubyGems as Exfiltration Channel Targeting UK Local Government
GemStuffer abuses RubyGems as an exfiltration channel, packaging scraped UK council portal data into junk gems published from new accounts.
@iris-technologies/api
Advanced tools
A TypeScript client library for the Iris advertising API with automatic impression and click URL handling.
npm install @iris-technologies/api
import { IrisClient } from '@iris-technologies/api';
// Initialize the client
const client = new IrisClient('your-api-key', ['politics', 'gambling']);
// Get an advertisement with tracking URLs
const ad = await client.getAd({
messages: [
{ role: 'user', content: 'user looking for weather information' },
{ role: 'assistant', content: 'showing current weather conditions' }
],
user: { uid: 'user-123' },
device: { ip: '1.2.3.4', country: 'US', ua: 'UA' },
excludedTopics: ['politics', 'gambling']
});
if (ad) {
console.log('Ad text:', ad.adText);
console.log('Impression URL:', ad.impUrl);
console.log('Click URL:', ad.clickUrl);
console.log('Publisher payout:', ad.payout);
} else {
console.log('No ad available');
}
IrisClientnew IrisClient(apiKey: string, excludedTopics: string[])
Parameters:
apiKey: Your Iris API key for authenticationexcludedTopics: Array of topic strings to exclude from ads (e.g., ['politics', 'adult', 'gambling'])getAd(params: BidParams): Promise<BidResponse | null>Retrieves a targeted advertisement with automatic tracking URL handling.
Parameters (BidParams):
messages: Array of { role: 'user' | 'assistant', content: string } representing conversation historydevice (optional): { ip: string; country: string; ua: string; os?: string; ifa?: string }user (optional): { uid?: string; gender?: 'male' | 'female' | 'other'; age?: string; keywords?: string[] }excludedTopics (optional): string[] of topics to excludeapiKey (optional): overrides the client API key for this callReturns:
BidResponse | null: Advertisement object with tracking URLs, or null if no ad is available (e.g., 204)Example:
const ad = await client.getAd({
messages: [
{ role: 'user', content: 'How do I learn guitar?' },
{ role: 'assistant', content: 'Here are some tips for learning guitar...' }
],
user: { uid: 'user-456' }
});
updateExcludedTopics(excludedTopics: string[]): voidUpdates the list of excluded ad topics.
client.updateExcludedTopics(['politics', 'crypto', 'dating']);
getExcludedTopics(): string[]Returns a copy of the current excluded topics array.
const currentExclusions = client.getExcludedTopics();
console.log('Excluding:', currentExclusions);
BidParamstype Role = 'user' | 'assistant';
type Gender = 'male' | 'female' | 'other';
interface MessageObject { role: Role; content: string }
interface DeviceObject { ip: string; country: string; ua: string; os?: string; ifa?: string }
interface UserObject { uid?: string; gender?: Gender; age?: string; keywords?: string[] }
interface BidParams {
apiKey?: string;
messages: MessageObject[];
device?: DeviceObject;
user?: UserObject;
excludedTopics?: string[];
}
BidResponseinterface BidResponse {
adText: string; // Ad copy to display to users
impUrl?: string; // Impression tracking URL (fire when ad is shown)
clickUrl?: string; // Click tracking URL (use when ad is clicked)
payout?: number; // Publisher payout amount in USD
}
{
text: "Learn guitar online with interactive lessons!",
impUrl: "https://api.iris.tech/impression?id=abc123&price=0.15",
clickUrl: "https://api.iris.tech/click?id=abc123&redirect=https://guitarlessons.com/signup",
payout: 0.075
}
The client handles errors gracefully and logs detailed information:
// Network errors, HTTP errors, and invalid responses are handled automatically
const ad = await client.getAd({
messages: [
{ role: 'user', content: 'context' },
{ role: 'assistant', content: 'response' }
],
user: { uid: 'user' }
});
// Always check for null response
if (!ad) {
console.log('No ad available - could be network error, no inventory, or excluded topic');
}
const client = new IrisClient('api-key', ['politics']);
// Add more excluded topics based on user preferences
const userPreferences = getUserAdPreferences();
if (userPreferences.excludeGambling) {
const current = client.getExcludedTopics();
client.updateExcludedTopics([...current, 'gambling', 'casino']);
}
// Get ad with updated exclusions
const ad = await client.getAd({
messages: [
{ role: 'user', content: context },
{ role: 'assistant', content: response }
],
user: { uid: userId }
});
Perfect pairing with @iris-technologies/react:
import { IrisClient } from '@iris-technologies/api';
import { IrisAd } from '@iris-technologies/react';
const client = new IrisClient('your-api-key', ['politics']);
function AdContainer({ userInput, botResponse, userId }) {
const [ad, setAd] = useState(null);
useEffect(() => {
client.getAd(userInput, botResponse, userId)
.then(setAd);
}, [userInput, botResponse, userId]);
return ad ? <IrisAd ad={ad} /> : null;
}
The client connects to https://api.iristech.dev by default. The endpoint includes:
Common topic exclusions:
const excludedTopics = [
'politics', // Political content
'adult', // Adult/NSFW content
'gambling', // Gambling and betting
'crypto', // Cryptocurrency
'dating', // Dating and relationships
'religion', // Religious content
'health', // Medical/health claims
'financial', // Financial advice
];
const client = new IrisClient('api-key', excludedTopics);
This package includes comprehensive test coverage (21 test cases):
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
The client provides comprehensive error handling:
// Automatic retry logic and graceful degradation
const ad = await client.getAd(context, response, userId);
// Returns null on network failure, logs error details
// Handles 404, 500, timeout errors automatically
// Logs detailed error information for debugging
// Always returns null instead of throwing
// Validates response structure
// Handles missing required fields
// Graceful fallback for malformed responses
# Install dependencies
npm install
# Build the package
npm run build
# Watch mode for development
npm run dev
# Clean build artifacts
npm run clean
# Run tests
npm test
# Patch version (1.0.0 → 1.0.1) - for bug fixes
npm run version:patch
# Minor version (1.0.0 → 1.1.0) - for new features
npm run version:minor
# Major version (1.0.0 → 2.0.0) - for breaking changes
npm run version:major
# Test publish (dry run)
npm run publish:dry-run
# Publish patch version
npm run publish:patch
# Publish with beta tag
npm run publish:beta
Full TypeScript support with exported types:
import {
IrisClient,
AdResponse,
GetAdParams,
IrisClientConfig
} from '@iris-technologies/api';
// All methods and responses are fully typed
const client: IrisClient = new IrisClient('key', []);
const ad: AdResponse | null = await client.getAd('', '', '');
ISC
FAQs
Iris API client for retrieving targeted advertisements
The npm package @iris-technologies/api receives a total of 14 weekly downloads. As such, @iris-technologies/api popularity was classified as not popular.
We found that @iris-technologies/api demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
GemStuffer abuses RubyGems as an exfiltration channel, packaging scraped UK council portal data into junk gems published from new accounts.

Company News
Socket was named to the Rising in Cyber 2026 list, recognizing 30 private cybersecurity startups selected by CISOs and security executives.

Research
Socket detected 84 compromised TanStack npm package artifacts modified with suspected CI credential-stealing malware.