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

210 wiersze
5.6 KiB
TypeScript
Czysty Wina Historia

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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 users primary email address. */
hash: string
/** The users display name that appears on their profile. */
display_name: string
first_name?: string
last_name?: string
/** 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. */
verified_accounts: VerifiedAccount[]
/** A phonetic guide to pronouncing the users name. */
pronunciation: string
/** The pronouns the user prefers to use. */
pronouns: string
is_organization?: boolean
links?: Link[]
interests?: any[]
gallery?: GalleryImage[]
payments?: {
links?: Link[]
crypto_wallets?: CryptoWallet[]
}
/** 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
contact_info?: ContactInfo
}
export interface VerifiedAccount {
service_type: string
service_label: string
service_icon: string
url: string
is_hidden: boolean
}
export interface Link {
label: string
url: string
}
export interface GalleryImage {
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
}
}
/**
* 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.
*/
@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
}
}
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}`
}
}