Create congratulations bot (#5404)
- Created congratulations bot : <img width="939" alt="Screenshot 2024-05-14 at 12 47 13" src="https://github.com/twentyhq/twenty/assets/102751374/5138515f-fe4d-4c6d-9c7a-0240accbfca9"> - Modified OG image - Added png extension to OG image route To be noted: The bot will not work until the new API route is not deployed. Please check OG image with Cloudflare cache. --------- Co-authored-by: Ady Beraud <a.beraud96@gmail.com>
This commit is contained in:
@ -2,7 +2,7 @@ import { format } from 'date-fns';
|
||||
import { ImageResponse } from 'next/og';
|
||||
|
||||
import {
|
||||
bottomBackgroundImage,
|
||||
backgroundImage,
|
||||
container,
|
||||
contributorInfo,
|
||||
contributorInfoBox,
|
||||
@ -15,8 +15,7 @@ import {
|
||||
profileInfoContainer,
|
||||
profileUsernameHeader,
|
||||
styledContributorAvatar,
|
||||
topBackgroundImage,
|
||||
} from '@/app/api/contributors/og-image/[slug]/style';
|
||||
} from '@/app/api/contributors/[slug]/og.png/style';
|
||||
import { getContributorActivity } from '@/app/contributors/utils/get-contributor-activity';
|
||||
|
||||
const GABARITO_FONT_CDN_URL =
|
||||
@ -33,8 +32,10 @@ const getGabarito = async () => {
|
||||
export async function GET(request: Request) {
|
||||
try {
|
||||
const url = request.url;
|
||||
|
||||
const username = url.split('/')?.pop() || '';
|
||||
const splitUrl = url.split('/');
|
||||
const usernameIndex =
|
||||
splitUrl.findIndex((part) => part === 'contributors') + 1;
|
||||
const username = splitUrl[usernameIndex];
|
||||
|
||||
const contributorActivity = await getContributorActivity(username);
|
||||
if (contributorActivity) {
|
||||
@ -45,11 +46,11 @@ export async function GET(request: Request) {
|
||||
activeDays,
|
||||
contributorAvatar,
|
||||
} = contributorActivity;
|
||||
return await new ImageResponse(
|
||||
|
||||
const imageResponse = await new ImageResponse(
|
||||
(
|
||||
<div style={container}>
|
||||
<div style={topBackgroundImage}></div>
|
||||
<div style={bottomBackgroundImage}></div>
|
||||
<div style={backgroundImage}></div>
|
||||
<div style={profileContainer}>
|
||||
<img src={contributorAvatar} style={styledContributorAvatar} />
|
||||
<div style={profileInfoContainer}>
|
||||
@ -59,8 +60,8 @@ export async function GET(request: Request) {
|
||||
</h2>
|
||||
</div>
|
||||
<svg
|
||||
width="96"
|
||||
height="96"
|
||||
width="134"
|
||||
height="134"
|
||||
viewBox="0 0 136 136"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@ -122,6 +123,7 @@ export async function GET(request: Request) {
|
||||
],
|
||||
},
|
||||
);
|
||||
return imageResponse;
|
||||
}
|
||||
} catch (error) {
|
||||
return new Response(`error: ${error}`, {
|
||||
@ -14,42 +14,36 @@ export const container: CSSProperties = {
|
||||
fontFamily: 'Gabarito',
|
||||
};
|
||||
|
||||
export const topBackgroundImage: CSSProperties = {
|
||||
backgroundImage: `url(${BACKGROUND_IMAGE_URL})`,
|
||||
export const backgroundImage: CSSProperties = {
|
||||
position: 'absolute',
|
||||
zIndex: '-1',
|
||||
width: '1300px',
|
||||
height: '250px',
|
||||
transform: 'rotate(-11deg)',
|
||||
opacity: '0.2',
|
||||
top: '-100',
|
||||
left: '-25',
|
||||
};
|
||||
|
||||
export const bottomBackgroundImage: CSSProperties = {
|
||||
backgroundImage: `url(${BACKGROUND_IMAGE_URL})`,
|
||||
position: 'absolute',
|
||||
zIndex: '-1',
|
||||
width: '1300px',
|
||||
height: '250px',
|
||||
transform: 'rotate(-11deg)',
|
||||
opacity: '0.2',
|
||||
bottom: '-120',
|
||||
right: '-40',
|
||||
width: '1250px',
|
||||
height: '850px',
|
||||
transform: 'rotate(-7deg)',
|
||||
opacity: '0.8',
|
||||
backgroundImage: `
|
||||
linear-gradient(
|
||||
158.4deg,
|
||||
rgba(255, 255, 255, 0.8) 30.69%,
|
||||
#FFFFFF 35.12%,
|
||||
rgba(255, 255, 255, 0.8) 60.27%,
|
||||
rgba(255, 255, 255, 0.64) 38.88%
|
||||
),
|
||||
url(${BACKGROUND_IMAGE_URL})`,
|
||||
};
|
||||
|
||||
export const profileContainer: CSSProperties = {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
width: '780px',
|
||||
margin: '0px 0px 40px',
|
||||
width: '970px',
|
||||
height: '134px',
|
||||
margin: '0px 0px 55px',
|
||||
};
|
||||
|
||||
export const styledContributorAvatar = {
|
||||
display: 'flex',
|
||||
width: '96px',
|
||||
height: '96px',
|
||||
width: '134px',
|
||||
height: '134px',
|
||||
margin: '0px',
|
||||
border: '3px solid #141414',
|
||||
borderRadius: '16px',
|
||||
@ -65,7 +59,7 @@ export const profileInfoContainer: CSSProperties = {
|
||||
|
||||
export const profileUsernameHeader: CSSProperties = {
|
||||
margin: '0px',
|
||||
fontSize: '28px',
|
||||
fontSize: '39px',
|
||||
fontWeight: '700',
|
||||
color: '#141414',
|
||||
fontFamily: 'Gabarito',
|
||||
@ -74,7 +68,7 @@ export const profileUsernameHeader: CSSProperties = {
|
||||
export const profileContributionHeader: CSSProperties = {
|
||||
margin: '0px',
|
||||
color: '#818181',
|
||||
fontSize: '20px',
|
||||
fontSize: '27px',
|
||||
fontWeight: '400',
|
||||
};
|
||||
|
||||
@ -84,8 +78,8 @@ export const contributorInfoContainer: CSSProperties = {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-around',
|
||||
width: '780px',
|
||||
height: '149px',
|
||||
width: '970px',
|
||||
height: '209px',
|
||||
backgroundColor: '#F1F1F1',
|
||||
};
|
||||
|
||||
@ -110,14 +104,14 @@ export const contributorInfoTitle = {
|
||||
color: '#B3B3B3',
|
||||
margin: '0px',
|
||||
fontWeight: '500',
|
||||
fontSize: '24px',
|
||||
fontSize: '33px',
|
||||
};
|
||||
|
||||
export const contributorInfoStats = {
|
||||
color: '#474747',
|
||||
margin: '0px',
|
||||
fontWeight: '700',
|
||||
fontSize: '40px',
|
||||
fontSize: '55px',
|
||||
};
|
||||
|
||||
export const infoSeparator: CSSProperties = {
|
||||
@ -125,6 +119,6 @@ export const infoSeparator: CSSProperties = {
|
||||
right: 0,
|
||||
display: 'flex',
|
||||
width: '2px',
|
||||
height: '85px',
|
||||
height: '120px',
|
||||
backgroundColor: '#141414',
|
||||
};
|
||||
@ -0,0 +1,26 @@
|
||||
import { getContributorActivity } from '@/app/contributors/utils/get-contributor-activity';
|
||||
import { executePartialSync } from '@/github/execute-partial-sync';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
export async function GET(request: Request) {
|
||||
try {
|
||||
const url = request.url;
|
||||
|
||||
const username = url.split('/')?.pop() || '';
|
||||
|
||||
await executePartialSync();
|
||||
|
||||
const contributorActivity = await getContributorActivity(username);
|
||||
|
||||
if (contributorActivity) {
|
||||
const mergedPRsCount = contributorActivity.mergedPRsCount;
|
||||
const rank = contributorActivity.rank;
|
||||
return Response.json({ mergedPRsCount, rank });
|
||||
}
|
||||
} catch (error: any) {
|
||||
return new Response(`Contributor stats error: ${error?.message}`, {
|
||||
status: 500,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user