chatgpt-api/legacy/packages/gravatar/src/gravatar-client.ts

210 wiersze
5.6 KiB
TypeScript
Czysty Zwykły widok Historia

2025-02-27 22:33:25 +00:00
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'
2025-02-27 22:33:25 +00:00
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 users primary email address. */
hash: string
/** The users display name that appears on their profile. */
display_name: string
2025-02-27 23:16:35 +00:00
first_name?: string
last_name?: string
2025-02-27 22:33:25 +00:00
/** The full URL to the users Gravatar profile. */
profile_url: string
/** The URL to the users avatar image, if set. */
avatar_url: string
/** Alternative text describing the users avatar. */
avatar_alt_text: string
/** The users geographical location. */
location: string
/** A short biography or description about the user found on their profile. */
description: string
/** The users 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. */
2025-02-28 05:30:16 +00:00
verified_accounts: VerifiedAccount[]
2025-02-27 22:33:25 +00:00
/** A phonetic guide to pronouncing the users name. */
pronunciation: string
/** The pronouns the user prefers to use. */
pronouns: string
2025-02-27 23:16:35 +00:00
is_organization?: boolean
links?: Link[]
interests?: any[]
2025-02-28 05:30:16 +00:00
gallery?: GalleryImage[]
2025-02-27 23:16:35 +00:00
payments?: {
2025-02-28 05:30:16 +00:00
links?: Link[]
2025-02-27 23:16:35 +00:00
crypto_wallets?: CryptoWallet[]
}
2025-02-27 22:33:25 +00:00
/** 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
2025-02-27 23:16:35 +00:00
contact_info?: ContactInfo
}
2025-02-28 05:30:16 +00:00
export interface VerifiedAccount {
2025-02-27 23:16:35 +00:00
service_type: string
service_label: string
service_icon: string
url: string
is_hidden: boolean
}
export interface Link {
label: string
url: string
}
2025-02-28 05:30:16 +00:00
export interface GalleryImage {
2025-02-27 23:16:35 +00:00
url: string
alt_text: string
}
export interface CryptoWallet {
label: string
address: string
}
export interface ContactInfo {
home_phone: string
work_phone: string
cell_phone: string
email: string
contact_form: string
calendar: string
2025-02-27 22:33:25 +00:00
}
}
/**
* 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}`]] : []
)
})
}
/**
* Get Gravatar profile by email. Returns a profile object or `undefined` if not found.
*/
2025-02-27 22:33:25 +00:00
@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
}
}
2025-02-27 23:16:35 +00:00
async getAvatarForIdentifier(
emailOrOpts: string | gravatar.GetProfileByIdentifierOptions
): Promise<string> {
const { email } =
typeof emailOrOpts === 'string' ? { email: emailOrOpts } : emailOrOpts
const hashedEmail = crypto
.createHash('SHA256')
.update(email.trim().toLowerCase(), 'utf8')
.digest('hex')
return `https://gravatar.com/avatar/${hashedEmail}`
}
2025-02-27 22:33:25 +00:00
}