Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linkedin integration #71

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
76 changes: 76 additions & 0 deletions src/pages/api/linkedin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { NextApiRequest, NextApiResponse } from 'next';

export interface LinkedInAuthData {
code: string;
state: string;
}

async function getProfile(access_token: string) {
try {
const LI_PROFILE_API_ENDPOINT = 'https://api.linkedin.com/v2/me';
const response = await fetch(LI_PROFILE_API_ENDPOINT, {
headers: {
'Authorization': `Bearer ${access_token}`
}
});

if (!response.ok) {
throw new Error('Failed to fetch LinkedIn profile');
}

return await response.json();
} catch (error) {
throw new Error(`Error fetching LinkedIn profile: ${error.message}`);
}
}

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
try {
// Parse incoming data as JSON
const data: LinkedInAuthData = req.body;

// Exchange authorization code for access token
const accessTokenResponse = await fetch('https://www.linkedin.com/oauth/v2/accessToken', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: data.code,
redirect_uri: process.env.NEXT_PUBLIC_LINKEDIN_REDIRECT_URI || '', // Assuming this is your redirect URI
client_id: process.env.NEXT_PUBLIC_LINKEDIN_CLIENT_ID || '', // Your LinkedIn client ID
client_secret: process.env.NEXT_PRIVATE_LINKEDIN_SECRET || '', // Your LinkedIn client secret
}),
});

// Check if access token exchange was successful
if (!accessTokenResponse.ok) {
throw new Error('Failed to exchange authorization code for access token');
}

// Parse access token response as JSON
const accessTokenData = await accessTokenResponse.json();

// Log access token data
console.log('Access Token Data:', accessTokenData);

// Get LinkedIn profile using access token
const profile = await getProfile(accessTokenData.access_token);

// Log profile data
console.log('LinkedIn Profile:', profile);

// Respond with success message
res.status(200).json({ message: 'LinkedIn profile received successfully', profile });
} catch (error) {
// Handle errors
console.error('Error:', error);
res.status(500).json({ error: 'Internal Server Error' });
}
} else {
// Respond with method not allowed for non-POST requests
res.status(405).json({ error: 'Method Not Allowed' });
}
}
81 changes: 81 additions & 0 deletions src/pages/landing/testing-linkedin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Image from 'next/image';
import { useEffect, useState } from 'react';
import { IntroducationSecion } from '../../components/introduction-section';
import Link from 'next/link';
import { useRouter } from 'next/router';

function TestingLinkedin() {
const router = useRouter();

useEffect(() => {
const getParams = () => {
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const state = params.get('state');
if (code && state) {
fetch('/api/linkedin', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
code,
state,
}),
})
.then(response => {
if (response.ok) {
// Handle successful response
console.log('Authorization successful');
} else {
// Handle error response
console.error('Authorization failed');
}
})
.catch(error => {
// Handle network error
console.error('Error:', error);
});
}
};

// Call the function to parse parameters
getParams();
}, []); // Ensure useEffect runs only once

const generateAuthorizationUrl = () => {
const LI_AUTH_URL = 'https://www.linkedin.com/oauth/v2/authorization';
const url = new URL(LI_AUTH_URL);
url.searchParams.append('response_type', 'code');
url.searchParams.append('client_id', process.env.NEXT_PUBLIC_LINKEDIN_CLIENT_ID || '');
url.searchParams.append('redirect_uri', process.env.NEXT_PUBLIC_LINKEDIN_REDIRECT_URI || '');
url.searchParams.append('state', Math.random().toString(36).substring(7).toUpperCase());
url.searchParams.append('scope', 'profile openid');
return url.toString();
};

return (
<div className='bg-white text-black'>
<main>
<section id='work-process' className='relative lg:pt-[110px]'>
<div className='container'>
<div
className='wow fadeInUp mx-auto mb-5 max-w-[740px] text-center lg:mb-[30px]'
data-wow-delay='.2s'>
<div className='flex justify-center gap-4'>
<a
href={generateAuthorizationUrl()}
target='_self'
className='max-w-[186px] flex-1 rounded-md text-center bg-landingprimary py-[6px] px-[12px] xl:py-[10px] xl:px-[30px] text-base font-medium text-white font-bold hover:bg-opacity-60'>
Sign in with linkedIn
</a>
</div>
</div>
</div>
</section>
</main>
</div>
);
}

export default TestingLinkedin;