chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:34:48 +08:00
commit 77bb5bf71f
3762 changed files with 353249 additions and 0 deletions
+64
View File
@@ -0,0 +1,64 @@
import axios, { AxiosInstance } from 'axios'
import { LeadPayload, Lead, SearchLeadsPayload } from '../definitions/schemas'
type LeadPayloadWithOptionalEmail = Omit<LeadPayload, 'email'> & Partial<Pick<LeadPayload, 'email'>>
export class HunterClient {
private _client: AxiosInstance
public constructor(apiKey: string) {
this._client = axios.create({
baseURL: 'https://api.hunter.io/v2/',
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache',
'X-API-KEY': apiKey,
},
})
}
public async getLeads(data?: SearchLeadsPayload): Promise<Lead[]> {
const params = new URLSearchParams()
if (data) {
for (const [key, value] of Object.entries(data)) {
if (Array.isArray(value)) {
for (const v of value) {
params.append(key + '[]', String(v))
}
} else if (typeof value === 'object' && value !== null) {
for (const [k, v] of Object.entries(value)) {
params.append(`${key}[${k}]`, String(v))
}
} else if (value !== undefined) {
params.append(key, String(value))
}
}
}
const res = await this._client.get('leads?' + params.toString())
return res.data.data.leads
}
public async retrieveLead(id: number): Promise<Lead> {
const res = await this._client.get(`leads/${id}`)
return res.data.data
}
public async createLead(data: LeadPayload): Promise<Lead> {
const res = await this._client.post('leads', data)
return res.data.data
}
public async createOrUpdateLead(data: LeadPayload): Promise<Lead> {
const res = await this._client.put('leads', data)
return res.data.data
}
public async updateLead(id: number, data: LeadPayloadWithOptionalEmail): Promise<void> {
await this._client.put(`leads/${id}`, data)
}
public async deleteLead(id: number): Promise<void> {
await this._client.delete(`leads/${id}`)
}
}
+31
View File
@@ -0,0 +1,31 @@
import { isAxiosError } from 'axios'
export function parseError(error: unknown): string {
if (isAxiosError(error)) {
if (error.response) {
if (typeof error.response.data === 'string') {
return `Request failed with status ${error.response.status}: ${error.response.data}`
}
return `Request failed with status ${error.response.status}: ${error.message}`
}
if (error.request) {
return `No response received: ${error.message}`
}
return `Axios error: ${error.message}`
}
if (error instanceof Error) {
return error.message
}
if (typeof error === 'string' || typeof error === 'number' || typeof error === 'boolean') {
return String(error)
}
if (error && typeof error === 'object' && 'message' in error) {
const message = error.message
return parseError(message)
}
return 'An unexpected error occurred'
}
+102
View File
@@ -0,0 +1,102 @@
import { RuntimeError } from '@botpress/sdk'
import { HunterClient } from './client'
import { parseError } from './error-parser'
import * as bp from '.botpress'
export default new bp.Integration({
register: async ({ ctx, logger }) => {
try {
const client = new HunterClient(ctx.configuration.apiKey)
await client.getLeads()
logger.forBot().info('Hunter.io integration configured successfully')
} catch (error) {
const parsed = parseError(error)
throw new RuntimeError(`Failed to configure Hunter.io integration. Make sure the API key is valid: ${parsed}`)
}
},
unregister: async ({ logger }) => {
logger.forBot().info('Hunter.io integration unregistered')
},
actions: {
getLeads: async ({ ctx, input, logger }) => {
try {
const hunterClient = new HunterClient(ctx.configuration.apiKey)
const leads = await hunterClient.getLeads(input.search)
logger.forBot().info('Leads got successfully from Hunter.io')
return { leads }
} catch (error) {
throw new RuntimeError(parseError(error))
}
},
retrieveLead: async ({ ctx, input, logger }) => {
try {
const hunterClient = new HunterClient(ctx.configuration.apiKey)
const lead = await hunterClient.retrieveLead(input.id)
logger.forBot().info(`Lead with ID ${input.id} retrieved successfully from Hunter.io`)
return { lead }
} catch (error) {
throw new RuntimeError(parseError(error))
}
},
createLead: async ({ ctx, input, logger }) => {
try {
const hunterClient = new HunterClient(ctx.configuration.apiKey)
const lead = await hunterClient.createLead(input.lead)
logger.forBot().info('Lead created successfully in Hunter.io')
return { lead }
} catch (error) {
throw new RuntimeError(parseError(error))
}
},
createOrUpdateLead: async ({ ctx, input, logger }) => {
try {
const hunterClient = new HunterClient(ctx.configuration.apiKey)
const lead = await hunterClient.createOrUpdateLead(input.lead)
logger.forBot().info('Lead created/updated successfully in Hunter.io')
return { lead }
} catch (error) {
throw new RuntimeError(parseError(error))
}
},
updateLead: async ({ ctx, input, logger }) => {
try {
const hunterClient = new HunterClient(ctx.configuration.apiKey)
await hunterClient.updateLead(input.id, input.lead)
logger.forBot().info(`Lead with ID ${input.id} updated successfully in Hunter.io`)
return {}
} catch (error) {
throw new RuntimeError(parseError(error))
}
},
deleteLead: async ({ ctx, input, logger }) => {
try {
const hunterClient = new HunterClient(ctx.configuration.apiKey)
await hunterClient.deleteLead(input.id)
logger.forBot().info(`Lead with ID ${input.id} deleted successfully from Hunter.io`)
return {}
} catch (error) {
throw new RuntimeError(parseError(error))
}
},
},
channels: {},
handler: async () => {},
})