Skip to content

useProxy ​

Category
Package
comuse/integrations
Last Changed
7月23日16时15分

Dynamic proxy IP management utility. Fetches proxy IP from configurable suppliers, creates proxy agents, and supports validation with automatic retry.

Built on axios.

Install ​

bash
npm i axios@^1

Usage ​

Basic ​

ts
import { useProxy } from 'comuse-integrations'
import { HttpsProxyAgent } from 'https-proxy-agent'

// Use the agent in requests
import axios from 'axios'

const { getAgent, getIp } = useProxy({
  suppliers: [
    {
      name: 'my-supplier',
      url: 'https://proxy.example.com/api/getip',
      parser: (res) => {
        if (res.code !== 200) return null
        return { ip: res.data.ip, port: res.data.port }
      },
    },
  ],
  createAgent: proxy => new HttpsProxyAgent({
    host: proxy.ip,
    port: proxy.port,
  }),
})

// Get a proxy agent (no validation)
const { proxy, agent } = await getAgent()

// Get with a custom cache key (reuses cached IP across calls)
const { proxy, agent } = await getAgent({ cacheKey: 'my-key' })
const res = await axios.get('https://example.com/api', {
  httpsAgent: agent,
})

With validation ​

ts
import axios from 'axios'
import { useProxy } from 'comuse-integrations'
import { HttpsProxyAgent } from 'https-proxy-agent'

const { getAgent } = useProxy({
  suppliers: [
    {
      name: 'proxy',
      url: 'http://api.example.com/getip',
      config: {
        params: {
          secret: 'xxx',
          num: 1,
          type: 'json',
        },
      },
      parser: (res) => {
        if (res.code !== 1000) return null
        return res.data[0]
      },
    },
  ],
  createAgent: proxy => new HttpsProxyAgent({
    host: proxy.ip,
    port: proxy.port,
  }),
  validateProxy: async (proxy, agent) => {
    const res = await axios.get('https://ipinfo.io/json', {
      httpsAgent: agent,
      timeout: 5000,
    })
    return res.data.ip === proxy.ip
  },
  maxRetries: 3,
  retryDelay: 100,
})

const { proxy, agent } = await getAgent({ needValid: true })

With custom cache key ​

Use a custom cacheKey to reuse the same proxy IP across multiple calls. The proxy is cached and reused until it expires or is explicitly deleted.

ts
const { getAgent, delIp } = useProxy({
  suppliers: [
    {
      name: 'my-supplier',
      url: 'https://proxy.example.com/api/getip',
      parser: (res) => {
        if (res.code !== 200) return null
        return { ip: res.data.ip, port: res.data.port }
      },
    },
  ],
  createAgent: proxy => new HttpsProxyAgent({ host: proxy.ip, port: proxy.port }),
})

// First call fetches a new IP, caches under 'my-task'
const { proxy, agent } = await getAgent({ cacheKey: 'my-task', needValid: true })

// Subsequent calls reuse the cached IP (no extra supplier request)
const { agent: same } = await getAgent({ cacheKey: 'my-task' })

// Delete the cache entry to force a fresh IP on next call
delIp('my-task')

Debug mode ​

Enable debug to log internal operations (cache hits/misses, IP fetching, validation, retries). Use a custom logger to redirect output.

ts
const { getAgent } = useProxy({
  suppliers: [
    {
      name: 'my-supplier',
      url: 'https://proxy.example.com/api/getip',
      parser: (res) => {
        if (res.code !== 200) return null
        return { ip: res.data.ip, port: res.data.port }
      },
    },
  ],
  createAgent: proxy => new HttpsProxyAgent({ host: proxy.ip, port: proxy.port }),
  debug: true,
  // Custom logger with prefix
  logger: (level, ...args) => {
    console.log(`[my-app] [${level}]`, ...args)
  },
})

Multiple suppliers with fallback ​

ts
const { getAgent } = useProxy({
  suppliers: [
    {
      name: 'supplier-a',
      url: 'http://api.supplier-a.com/ip',
      parser: (res) => {
        if (res.code !== 200) return null
        return res.data[0]
      },
    },
    {
      name: 'supplier-b',
      url: 'http://api.supplier-b.com/ip',
      parser: (res) => {
        if (res.code !== 200) return null
        return { ip: res.ip, port: res.port }
      },
    },
  ],
  createAgent: proxy => new HttpsProxyAgent({ host: proxy.ip, port: proxy.port }),
})

// supplier-a is tried first, if it fails, supplier-b is used
const { proxy, agent } = await getAgent()

Custom cache ​

ts
import { useProxy } from 'comuse-integrations'

const proxyCache = new Map()

const { getIp } = useProxy({
  suppliers: [
    {
      name: 'my-supplier',
      url: 'https://proxy.example.com/api/getip',
      parser: (res) => {
        if (res.code !== 200) return null
        return { ip: res.data.ip, port: res.data.port }
      },
    },
  ],
  createAgent: proxy => new HttpsProxyAgent({ host: proxy.ip, port: proxy.port }),
  cache: {
    get: key => proxyCache.get(key) ?? null,
    put: (key, value, ttl) => {
      proxyCache.set(key, value)
      if (ttl) setTimeout(() => proxyCache.delete(key), ttl)
    },
    del: (key) => {
      proxyCache.delete(key)
      return true
    },
  },
})

TTL configuration ​

The cache TTL is determined by priority: the proxy API's expire field → defaultTTL option.

ts
const { getAgent } = useProxy({
  suppliers: [
    {
      name: 'my-supplier',
      url: 'https://proxy.example.com/api/getip',
      parser: (res) => {
        if (res.code !== 200) return null
        // If the response includes an `expire` timestamp (e.g. "2026-07-23 16:00:48"),
        // it takes priority over `defaultTTL`
        return { ip: res.data[0].ip, port: res.data[0].port, expire: res.data[0].expire }
      },
    },
  ],
  createAgent: proxy => new HttpsProxyAgent({ host: proxy.ip, port: proxy.port }),
  defaultTTL: 5 * 60 * 1000, // 5 minutes, used when no `expire` field
  expireBuffer: 20000, // 20s safety margin before actual expiry
})

Error classification ​

ts
import { defaultIsProxyError, useProxy } from 'comuse-integrations'

const { getAgent, isProxyError } = useProxy({
  suppliers: [
    {
      name: 'my-supplier',
      url: 'https://proxy.example.com/api/getip',
      parser: (res) => {
        if (res.code !== 200) return null
        return { ip: res.data.ip, port: res.data.port }
      },
    },
  ],
  createAgent: proxy => new HttpsProxyAgent({ host: proxy.ip, port: proxy.port }),
})

// Use it after a failed request to decide whether to retry with a new IP
try {
  await axios.get('...', { httpsAgent: agent })
}
catch (error) {
  if (isProxyError(error)) {
    // Get a fresh agent and retry
    const { agent: newAgent } = await getAgent({ needValid: true })
  }
}
js
import { useProxy } from 'comuse-integrations'
const { getAgent, isProxyError } = useProxy({
  suppliers: [
    {
      name: 'my-supplier',
      url: 'https://proxy.example.com/api/getip',
      parser: (res) => {
        if (res.code !== 200) return null
        return { ip: res.data.ip, port: res.data.port }
      },
    },
  ],
  createAgent: (proxy) =>
    new HttpsProxyAgent({ host: proxy.ip, port: proxy.port }),
})
// Use it after a failed request to decide whether to retry with a new IP
try {
  await axios.get('...', { httpsAgent: agent })
} catch (error) {
  if (isProxyError(error)) {
    // Get a fresh agent and retry
    const { agent: newAgent } = await getAgent({ needValid: true })
  }
}

API ​

useProxy(options) ​

Returns an object with the following functions:

FunctionDescription
getAgent(options?)Get a validated proxy agent. Fetches IP, creates agent, optionally validates. Retries on failure.
getIp(key)Get proxy IP config (with caching).
delIp(key)Delete a cached IP entry.
clearCache()Clear all cached IP entries.
isProxyError(error)Check if an error is proxy-related.

UseProxyOptions ​

OptionTypeDefaultDescription
suppliersProxySupplier[]requiredProxy IP suppliers, tried in order
createAgent(proxy: ProxyConfig) => anyrequiredCreate a proxy agent instance
validateProxy(proxy: ProxyConfig, agent: any) => Promise<boolean>-Validate proxy before returning
cacheCacheLikebuilt-in memory cacheCustom cache implementation
isProxyError(error: any) => booleandefaultIsProxyErrorCustom error classifier
maxRetriesnumber3Max retry attempts
retryDelaynumber100Delay between retries (ms)
timeoutnumber3000Supplier request timeout (ms)
defaultTTLnumber3 * 60 * 1000 (3 min)Default cache TTL when no expire
expireBuffernumber20000 (20s)Expiry buffer to avoid edge cases
debugbooleanfalseEnable debug logging
logger(level: LogLevel, ...args: any[]) => voidconsole (when debug: true)Custom logger function

GetAgentOptions ​

OptionTypeDefaultDescription
cacheKeystringauto-generatedCache key for reusing the same proxy IP across calls
needValidbooleanfalseWhether to validate the proxy before returning

LogLevel ​

ts
type LogLevel = 'debug' | 'info' | 'warn' | 'error'
js

ProxySupplier ​

FieldTypeDefaultDescription
namestringrequiredSupplier name
urlstringrequiredProxy API URL
method'GET' | 'POST''GET'HTTP method
configAxiosRequestConfig-Additional axios config (params, headers, etc.)
parser(response: any) => ProxyConfig | nullrequiredParse API response, return null to trigger next supplier

Source ​

Source • Docs

Changelog ​

v4.3.4 on 7/23/2026
9f765 - feature 1 add defaultTTL, expireBuffer and proxy expire field support
v4.3.3 on 7/23/2026
fc442 - feat!: add cacheKey, debug mode and logger options
v4.3.2 on 7/22/2026
6db7a - feat(integrations): add useProxy - dynamic proxy IP management utility

Released under the MIT License.