mirror of
https://github.com/rappleit/yeego-linkedin-prototype.git
synced 2026-01-12 15:33:54 +08:00
279 lines
7.8 KiB
TypeScript
279 lines
7.8 KiB
TypeScript
import { UNIPILE_CONFIG, unipileFetch } from '@/utils/unipile'
|
|
import { useMutation, useQuery } from '@tanstack/react-query'
|
|
|
|
export interface CreateHostedAuthLinkRequest {
|
|
type: "create" | "reconnect"
|
|
api_url?: string
|
|
expiresOn: string
|
|
providers: string | string[]
|
|
notify_url?: string
|
|
name?: string
|
|
}
|
|
|
|
export interface CreateHostedAuthLinkResponse {
|
|
url: string
|
|
id: string
|
|
expiresOn: string
|
|
}
|
|
|
|
export interface LinkedInProfile {
|
|
object: string
|
|
provider: string
|
|
provider_id: string
|
|
public_identifier: string
|
|
member_urn: string
|
|
first_name: string
|
|
last_name: string
|
|
headline?: string
|
|
primary_locale?: {
|
|
country: string
|
|
language: string
|
|
}
|
|
is_open_profile: boolean
|
|
is_premium: boolean
|
|
is_influencer: boolean
|
|
is_creator: boolean
|
|
is_relationship: boolean
|
|
network_distance?: string
|
|
is_self: boolean
|
|
websites?: any[]
|
|
follower_count?: number
|
|
connections_count?: number
|
|
location?: string
|
|
birthdate?: {
|
|
month: number
|
|
day: number
|
|
}
|
|
invitation?: {
|
|
type: string
|
|
status: string
|
|
}
|
|
profile_picture_url?: string
|
|
profile_picture_url_large?: string
|
|
// Legacy fields
|
|
id?: string
|
|
identifier?: string
|
|
display_name?: string
|
|
summary?: string
|
|
industry?: string
|
|
public_profile_url?: string
|
|
connection_count?: number
|
|
created_at?: string
|
|
updated_at?: string
|
|
}
|
|
|
|
export interface SendInvitationRequest {
|
|
provider_id: string
|
|
account_id: string
|
|
}
|
|
|
|
export interface SendInvitationResponse {
|
|
object: string
|
|
invitation_id: string
|
|
usage: number
|
|
}
|
|
|
|
export interface CancelInvitationRequest {
|
|
invitationId: string
|
|
accountId: string
|
|
}
|
|
|
|
export interface Invitation {
|
|
id: string
|
|
object: string
|
|
date: string
|
|
parsed_datetime: string
|
|
invitation_text?: string
|
|
invited_user: string
|
|
invited_user_description?: string
|
|
invited_user_id: string
|
|
invited_user_public_id: string
|
|
}
|
|
|
|
export interface InvitationsListResponse {
|
|
items: Invitation[]
|
|
has_more: boolean
|
|
total_count?: number
|
|
cursor?: string
|
|
}
|
|
|
|
export interface GetInvitationsParams {
|
|
accountId: string
|
|
cursor?: string
|
|
limit?: number
|
|
}
|
|
|
|
export const LinkedInAPI = {
|
|
// Create hosted authentication link
|
|
async createHostedAuthLink(request: CreateHostedAuthLinkRequest): Promise<CreateHostedAuthLinkResponse> {
|
|
try {
|
|
const response = await unipileFetch(`${UNIPILE_CONFIG.BASE_URL}/api/v1/hosted/accounts/link`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(request)
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const errorData = await response.json()
|
|
throw new Error(
|
|
`Failed to create hosted auth link: ${typeof errorData === 'string' ? errorData : JSON.stringify(errorData) || response.statusText}`
|
|
)
|
|
}
|
|
|
|
return await response.json()
|
|
} catch (error: any) {
|
|
throw new Error(`Failed to create hosted auth link: ${error?.message || 'Unknown error'}`);
|
|
}
|
|
},
|
|
|
|
// Retrieve LinkedIn profile by public identifier
|
|
async getProfileByIdentifier(identifier: string, accountId: string): Promise<LinkedInProfile> {
|
|
try {
|
|
const response = await unipileFetch(`${UNIPILE_CONFIG.BASE_URL}/api/v1/users/${identifier}?account_id=${accountId}`, {
|
|
method: 'GET'
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const errorData = await response.json()
|
|
throw new Error(
|
|
`Failed to retrieve profile: ${typeof errorData === 'string' ? errorData : JSON.stringify(errorData) || response.statusText}`
|
|
)
|
|
}
|
|
|
|
return await response.json()
|
|
} catch (error: any) {
|
|
throw new Error(`Failed to retrieve profile: ${error?.message || 'Unknown error'}`);
|
|
}
|
|
},
|
|
|
|
// Send LinkedIn invitation
|
|
async sendInvitation(request: SendInvitationRequest): Promise<SendInvitationResponse> {
|
|
try {
|
|
const response = await unipileFetch(`${UNIPILE_CONFIG.BASE_URL}/api/v1/users/invite`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(request)
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const errorData = await response.json()
|
|
throw new Error(
|
|
`Failed to send invitation: ${typeof errorData === 'string' ? errorData : JSON.stringify(errorData) || response.statusText}`
|
|
)
|
|
}
|
|
|
|
return await response.json()
|
|
} catch (error: any) {
|
|
throw new Error(`Failed to send invitation: ${error?.message || 'Unknown error'}`);
|
|
}
|
|
},
|
|
|
|
|
|
// Fetch all invitations by account ID
|
|
async getInvitations(accountId: string): Promise<InvitationsListResponse> {
|
|
try {
|
|
const response = await unipileFetch(`${UNIPILE_CONFIG.BASE_URL}/api/v1/users/invite/sent?account_id=${accountId}`, {
|
|
method: 'GET'
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const errorData = await response.json()
|
|
throw new Error(
|
|
`Failed to fetch invitations: ${typeof errorData === 'string' ? errorData : JSON.stringify(errorData) || response.statusText}`
|
|
)
|
|
}
|
|
|
|
return await response.json()
|
|
} catch (error: any) {
|
|
throw new Error(`Failed to fetch invitations: ${error?.message || 'Unknown error'}`);
|
|
}
|
|
},
|
|
|
|
// Fetch invitations with pagination support
|
|
async getInvitationsPaginated({ accountId, cursor, limit = 100 }: GetInvitationsParams): Promise<InvitationsListResponse> {
|
|
try {
|
|
const queryParams = new URLSearchParams({
|
|
account_id: accountId,
|
|
limit: limit.toString()
|
|
})
|
|
|
|
if (cursor) {
|
|
queryParams.append('cursor', cursor)
|
|
}
|
|
|
|
const url = `${UNIPILE_CONFIG.BASE_URL}/api/v1/users/invite/sent?${queryParams.toString()}`
|
|
|
|
const response = await unipileFetch(url, {
|
|
method: 'GET'
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const errorData = await response.json()
|
|
throw new Error(
|
|
`Failed to fetch invitations: ${typeof errorData === 'string' ? errorData : JSON.stringify(errorData) || response.statusText}`
|
|
)
|
|
}
|
|
|
|
return await response.json()
|
|
} catch (error: any) {
|
|
throw new Error(`Failed to fetch invitations: ${error?.message || 'Unknown error'}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Hook for creating hosted authentication link
|
|
export const useCreateHostedAuthLink = () => {
|
|
return useMutation({
|
|
mutationFn: (request: CreateHostedAuthLinkRequest) => LinkedInAPI.createHostedAuthLink(request),
|
|
})
|
|
}
|
|
|
|
// Hook for retrieving LinkedIn profile by identifier
|
|
export const useGetProfileByIdentifier = (identifier: string, accountId: string, enabled: boolean = true) => {
|
|
return useQuery({
|
|
queryKey: ['linkedin-profile', identifier],
|
|
queryFn: () => LinkedInAPI.getProfileByIdentifier(identifier, accountId),
|
|
enabled: enabled && !!identifier,
|
|
})
|
|
}
|
|
|
|
// Hook for sending LinkedIn invitation
|
|
export const useSendInvitation = () => {
|
|
return useMutation({
|
|
mutationFn: (request: SendInvitationRequest) => LinkedInAPI.sendInvitation(request),
|
|
})
|
|
}
|
|
|
|
// Hook for fetching all invitations by account ID
|
|
export const useGetInvitations = (accountId: string, enabled: boolean = true) => {
|
|
return useQuery({
|
|
queryKey: ['linkedin-invitations', accountId],
|
|
queryFn: () => LinkedInAPI.getInvitations(accountId),
|
|
enabled: enabled && !!accountId,
|
|
})
|
|
}
|
|
|
|
// Hook for getting LinkedIn profile and connection status
|
|
export const useLinkedInProfileAndStatus = (
|
|
linkedInProfileId: string,
|
|
accountId: string,
|
|
enabled: boolean = true
|
|
) => {
|
|
return useQuery({
|
|
queryKey: ['linkedin-profile-status', linkedInProfileId, accountId],
|
|
queryFn: async () => {
|
|
const profile = await LinkedInAPI.getProfileByIdentifier(linkedInProfileId, accountId)
|
|
const { getConnectionStatusFromProfile } = await import('@/helper/linkedinConnect')
|
|
const connectionStatus = getConnectionStatusFromProfile(profile)
|
|
|
|
return {
|
|
profile,
|
|
connectionStatus
|
|
}
|
|
},
|
|
enabled: enabled && !!linkedInProfileId && !!accountId,
|
|
refetchOnWindowFocus: true,
|
|
refetchOnMount: true,
|
|
refetchOnReconnect: true,
|
|
staleTime: 0,
|
|
gcTime: 5 * 60 * 1000,
|
|
})
|
|
}
|