kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
Merge pull request #689 from transitive-bullshit/feature/gravatar
commit
2df13fb94f
|
@ -23,7 +23,7 @@ jobs:
|
|||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10.4.1
|
||||
version: 10.5.2
|
||||
run_install: false
|
||||
|
||||
- name: Install Node.js
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
"tools/exa",
|
||||
"tools/firecrawl",
|
||||
"tools/hacker-news",
|
||||
"tools/gravatar",
|
||||
"tools/hunter",
|
||||
"tools/jina",
|
||||
"tools/leadmagic",
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
title: Gravatar
|
||||
description: Gravatar Profile API.
|
||||
---
|
||||
|
||||
- package: `@agentic/gravatar`
|
||||
- exports: `class GravatarClient`, `namespace gravatar`
|
||||
- env vars: `GRAVATAR_API_KEY` _(optional)_
|
||||
- [source](https://github.com/transitive-bullshit/agentic/blob/main/packages/gravatar/src/gravatar-client.ts)
|
||||
- [Gravatar API docs](https://docs.gravatar.com/api/profiles/rest-api/)
|
||||
|
||||
## Install
|
||||
|
||||
<CodeGroup>
|
||||
```bash npm
|
||||
npm install @agentic/gravatar
|
||||
```
|
||||
|
||||
```bash yarn
|
||||
yarn add @agentic/gravatar
|
||||
```
|
||||
|
||||
```bash pnpm
|
||||
pnpm add @agentic/gravatar
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { GravatarClient } from '@agentic/gravatar'
|
||||
|
||||
const gravatar = new GravatarClient()
|
||||
const profile = await gravatar.getProfileByIdentifier('my-email@example.com')
|
||||
```
|
|
@ -1,6 +1,6 @@
|
|||
import 'dotenv/config'
|
||||
|
||||
import { ZoomInfoClient } from '@agentic/stdlib'
|
||||
import * as stdlib from '@agentic/stdlib'
|
||||
import restoreCursor from 'restore-cursor'
|
||||
|
||||
/**
|
||||
|
@ -135,15 +135,17 @@ async function main() {
|
|||
// category: 'linkedin profile'
|
||||
// })
|
||||
|
||||
const zoomInfo = new ZoomInfoClient()
|
||||
const res = await zoomInfo.enrichContact({
|
||||
// emailAddress: 'travis@transitivebullsh.it'
|
||||
fullName: 'Kevin Raheja',
|
||||
companyName: 'HeyGen'
|
||||
})
|
||||
// const zoomInfo = new ZoomInfoClient()
|
||||
// const res = await zoomInfo.enrichContact({
|
||||
// // emailAddress: 'travis@transitivebullsh.it'
|
||||
// fullName: 'Kevin Raheja',
|
||||
// companyName: 'HeyGen'
|
||||
// })
|
||||
// const res = await zoomInfo.searchContacts({
|
||||
// fullName: 'Kevin Raheja'
|
||||
// })
|
||||
const gravatar = new stdlib.GravatarClient()
|
||||
const res = await gravatar.getProfileByIdentifier('email@example.com')
|
||||
|
||||
console.log(JSON.stringify(res, null, 2))
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"type": "git",
|
||||
"url": "git+https://github.com/transitive-bullshit/agentic.git"
|
||||
},
|
||||
"packageManager": "pnpm@10.4.1",
|
||||
"packageManager": "pnpm@10.5.2",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
"name": "@agentic/gravatar",
|
||||
"version": "7.4.1",
|
||||
"description": "Agentic SDK for Gravatar.",
|
||||
"author": "Travis Fischer <travis@transitivebullsh.it>",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/transitive-bullshit/agentic.git",
|
||||
"directory": "packages/gravatar"
|
||||
},
|
||||
"type": "module",
|
||||
"source": "./src/index.ts",
|
||||
"types": "./dist/index.d.ts",
|
||||
"sideEffects": false,
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "tsup --config ../../tsup.config.ts",
|
||||
"dev": "tsup --config ../../tsup.config.ts --watch",
|
||||
"clean": "del dist",
|
||||
"test": "run-s test:*",
|
||||
"test:lint": "eslint .",
|
||||
"test:typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@agentic/core": "workspace:*",
|
||||
"ky": "^1.7.5",
|
||||
"p-throttle": "^6.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"zod": "^3.24.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@agentic/tsconfig": "workspace:*"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<p align="center">
|
||||
<a href="https://agentic.so">
|
||||
<img alt="Agentic" src="https://raw.githubusercontent.com/transitive-bullshit/agentic/main/docs/media/agentic-header.jpg" width="308">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<em>AI agent stdlib that works with any LLM and TypeScript AI SDK.</em>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/transitive-bullshit/agentic/actions/workflows/main.yml"><img alt="Build Status" src="https://github.com/transitive-bullshit/agentic/actions/workflows/main.yml/badge.svg" /></a>
|
||||
<a href="https://www.npmjs.com/package/@agentic/stdlib"><img alt="NPM" src="https://img.shields.io/npm/v/@agentic/stdlib.svg" /></a>
|
||||
<a href="https://github.com/transitive-bullshit/agentic/blob/main/license"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-blue" /></a>
|
||||
<a href="https://prettier.io"><img alt="Prettier Code Formatting" src="https://img.shields.io/badge/code_style-prettier-brightgreen.svg" /></a>
|
||||
</p>
|
||||
|
||||
# Agentic
|
||||
|
||||
**See the [github repo](https://github.com/transitive-bullshit/agentic) or [docs](https://agentic.so) for more info.**
|
||||
|
||||
## License
|
||||
|
||||
MIT © [Travis Fischer](https://x.com/transitive_bs)
|
|
@ -0,0 +1,148 @@
|
|||
import crypto from 'node:crypto'
|
||||
|
||||
import {
|
||||
aiFunction,
|
||||
AIFunctionsProvider,
|
||||
getEnv,
|
||||
throttleKy
|
||||
} from '@agentic/core'
|
||||
import defaultKy, { type KyInstance } from 'ky'
|
||||
import pThrottle from 'p-throttle'
|
||||
import z from 'zod'
|
||||
|
||||
export namespace gravatar {
|
||||
export const API_BASE_URL = 'https://api.gravatar.com'
|
||||
|
||||
// Allow up to 100 unauthenticated requests per hour by default.
|
||||
export const unauthenticatedThrottle = pThrottle({
|
||||
limit: 100,
|
||||
interval: 60 * 60 * 1000
|
||||
})
|
||||
|
||||
// Allow up to 1000 authenticated requests per hour by default.
|
||||
export const authenticatedThrottle = pThrottle({
|
||||
limit: 1000,
|
||||
interval: 60 * 60 * 1000
|
||||
})
|
||||
|
||||
export type GetProfileByIdentifierOptions = {
|
||||
email: string
|
||||
}
|
||||
|
||||
export interface Profile {
|
||||
/** The SHA256 hash of the user’s primary email address. */
|
||||
hash: string
|
||||
/** The user’s display name that appears on their profile. */
|
||||
display_name: string
|
||||
/** The full URL to the user’s Gravatar profile. */
|
||||
profile_url: string
|
||||
/** The URL to the user’s avatar image, if set. */
|
||||
avatar_url: string
|
||||
/** Alternative text describing the user’s avatar. */
|
||||
avatar_alt_text: string
|
||||
/** The user’s geographical location. */
|
||||
location: string
|
||||
/** A short biography or description about the user found on their profile. */
|
||||
description: string
|
||||
/** The user’s current job title. */
|
||||
job_title: string
|
||||
/** The name of the company where the user is employed. */
|
||||
company: string
|
||||
/** An array of verified accounts the user has added to their profile. The number of verified accounts displayed is limited to a maximum of 4 in unauthenticated requests. */
|
||||
verified_accounts: any[]
|
||||
/** A phonetic guide to pronouncing the user’s name. */
|
||||
pronunciation: string
|
||||
/** The pronouns the user prefers to use. */
|
||||
pronouns: string
|
||||
|
||||
/** The total number of verified accounts the user has added to their profile, including those not displayed on their profile. This property is only provided in authenticated API requests. */
|
||||
number_verified_accounts?: number
|
||||
|
||||
/** The date and time (UTC) when the user last edited their profile. This property is only provided in authenticated API requests. Example: "2021-10-01T12:00:00Z" */
|
||||
last_profile_edit?: string
|
||||
|
||||
/** The date the user registered their account. This property is only provided in authenticated API requests. Example: "2021-10-01" */
|
||||
registration_date?: string
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A client for the Gravatar API.
|
||||
*
|
||||
* API key is optional.
|
||||
*
|
||||
* @see https://docs.gravatar.com/getting-started/
|
||||
*/
|
||||
export class GravatarClient extends AIFunctionsProvider {
|
||||
protected readonly ky: KyInstance
|
||||
protected readonly apiKey?: string
|
||||
protected readonly apiBaseUrl: string
|
||||
|
||||
constructor({
|
||||
apiKey = getEnv('GRAVATAR_API_KEY'),
|
||||
apiBaseUrl = gravatar.API_BASE_URL,
|
||||
timeoutMs = 60_000,
|
||||
throttle = true,
|
||||
ky = defaultKy
|
||||
}: {
|
||||
apiKey?: string
|
||||
apiBaseUrl?: string
|
||||
timeoutMs?: number
|
||||
throttle?: boolean
|
||||
ky?: KyInstance
|
||||
} = {}) {
|
||||
super()
|
||||
|
||||
// API key is optional
|
||||
this.apiKey = apiKey
|
||||
this.apiBaseUrl = apiBaseUrl
|
||||
|
||||
const throttledKy = throttle
|
||||
? throttleKy(
|
||||
ky,
|
||||
apiKey
|
||||
? gravatar.authenticatedThrottle
|
||||
: gravatar.unauthenticatedThrottle
|
||||
)
|
||||
: ky
|
||||
|
||||
this.ky = throttledKy.extend({
|
||||
prefixUrl: apiBaseUrl,
|
||||
timeout: timeoutMs,
|
||||
headers: Object.fromEntries(
|
||||
apiKey ? [['Authorization', `Bearer ${apiKey}`]] : []
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@aiFunction({
|
||||
name: 'gravatar_get_profile',
|
||||
description:
|
||||
'Get Gravatar profile by email. Returns a profile object or `undefined` if not found.',
|
||||
inputSchema: z.object({
|
||||
email: z.string()
|
||||
})
|
||||
})
|
||||
async getProfileByIdentifier(
|
||||
emailOrOpts: string | gravatar.GetProfileByIdentifierOptions
|
||||
): Promise<gravatar.Profile | undefined> {
|
||||
const { email } =
|
||||
typeof emailOrOpts === 'string' ? { email: emailOrOpts } : emailOrOpts
|
||||
const hashedEmail = crypto
|
||||
.createHash('SHA256')
|
||||
.update(email.trim().toLowerCase(), 'utf8')
|
||||
.digest('hex')
|
||||
|
||||
try {
|
||||
return await this.ky
|
||||
.get(`v3/profiles/${hashedEmail}`)
|
||||
.json<gravatar.Profile>()
|
||||
} catch (err: any) {
|
||||
if (err.response?.status === 404) {
|
||||
return
|
||||
}
|
||||
|
||||
throw err
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './gravatar-client'
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"extends": "@agentic/tsconfig/base.json",
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
|
@ -45,6 +45,7 @@
|
|||
"@agentic/firecrawl": "workspace:*",
|
||||
"@agentic/genkit": "workspace:*",
|
||||
"@agentic/github": "workspace:*",
|
||||
"@agentic/gravatar": "workspace:*",
|
||||
"@agentic/hacker-news": "workspace:*",
|
||||
"@agentic/hunter": "workspace:*",
|
||||
"@agentic/jina": "workspace:*",
|
||||
|
|
|
@ -8,6 +8,7 @@ export * from '@agentic/e2b'
|
|||
export * from '@agentic/exa'
|
||||
export * from '@agentic/firecrawl'
|
||||
export * from '@agentic/github'
|
||||
export * from '@agentic/gravatar'
|
||||
export * from '@agentic/hacker-news'
|
||||
export * from '@agentic/hunter'
|
||||
export * from '@agentic/jina'
|
||||
|
|
|
@ -495,6 +495,25 @@ importers:
|
|||
specifier: workspace:*
|
||||
version: link:../tsconfig
|
||||
|
||||
packages/gravatar:
|
||||
dependencies:
|
||||
'@agentic/core':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
ky:
|
||||
specifier: ^1.7.5
|
||||
version: 1.7.5
|
||||
p-throttle:
|
||||
specifier: ^6.2.0
|
||||
version: 6.2.0
|
||||
zod:
|
||||
specifier: ^3.24.2
|
||||
version: 3.24.2
|
||||
devDependencies:
|
||||
'@agentic/tsconfig':
|
||||
specifier: workspace:*
|
||||
version: link:../tsconfig
|
||||
|
||||
packages/hacker-news:
|
||||
dependencies:
|
||||
'@agentic/core':
|
||||
|
@ -883,6 +902,9 @@ importers:
|
|||
'@agentic/github':
|
||||
specifier: workspace:*
|
||||
version: link:../github
|
||||
'@agentic/gravatar':
|
||||
specifier: workspace:*
|
||||
version: link:../gravatar
|
||||
'@agentic/hacker-news':
|
||||
specifier: workspace:*
|
||||
version: link:../hacker-news
|
||||
|
|
|
@ -157,6 +157,7 @@ Full docs are available at [agentic.so](https://agentic.so).
|
|||
| [E2B](https://e2b.dev) | `@agentic/e2b` | [docs](https://agentic.so/tools/e2b) | Hosted Python code interpreter sandbox which is really useful for data analysis, flexible code execution, and advanced reasoning on-the-fly. |
|
||||
| [Exa](https://docs.exa.ai) | `@agentic/exa` | [docs](https://agentic.so/tools/exa) | Web search tailored for LLMs. |
|
||||
| [Firecrawl](https://www.firecrawl.dev) | `@agentic/firecrawl` | [docs](https://agentic.so/tools/firecrawl) | Website scraping and structured data extraction. |
|
||||
| [Gravatar](https://docs.gravatar.com/api/profiles/rest-api/) | `@agentic/gravatar` | [docs](https://agentic.so/tools/gravatar) | Gravatar profile API. |
|
||||
| [HackerNews](https://github.com/HackerNews/API) | `@agentic/hacker-news` | [docs](https://agentic.so/tools/hacker-news) | Official HackerNews API. |
|
||||
| [Hunter](https://hunter.io) | `@agentic/hunter` | [docs](https://agentic.so/tools/hunter) | Email finder, verifier, and enrichment. |
|
||||
| [Jina](https://jina.ai/reader) | `@agentic/jina` | [docs](https://agentic.so/tools/jina) | URL scraper and web search. |
|
||||
|
|
Ładowanie…
Reference in New Issue