Skip to content

Commit

Permalink
Feature/add og img (#932)
Browse files Browse the repository at this point in the history
* Initial setup of og
* Add vercel og. Closes #926
* Fix deps
  • Loading branch information
baires authored Jun 27, 2023
1 parent b42ad36 commit 56d26c2
Show file tree
Hide file tree
Showing 12 changed files with 1,004 additions and 8,101 deletions.
20 changes: 14 additions & 6 deletions helpers/constans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ import {
REASONS_NEW_YEAR
} from './reasons'

export const HOST = 'https://shouldideploy.today'
export function getBaseUrl() {
if (typeof window !== 'undefined') return ''
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`
if (process.env.NODE_ENV === 'production')
return 'https://shouldideploy.today'
return `http://localhost:${process.env.PORT ?? 3001}`
}

export const shouldIDeploy = function (time: Time | null, date?: Date) {
if (!time) {
Expand All @@ -33,16 +39,18 @@ export const shouldIDeploy = function (time: Time | null, date?: Date) {
)
}

export const shouldIDeployAnswerImage = function (time: Time | null) {
return shouldIDeploy(time) ? `${HOST}/yes.png` : `${HOST}/no.png`
}

export const shouldIDeployColorTheme = function (time: Time | null) {
return shouldIDeploy(time) ? '#36a64f' : '#ff4136'
}

export const shouldIDeployFontTheme = function (time: Time | null) {
return shouldIDeploy(time) ? '#fff' : '#111'
}

export const shouldIDeployFavIcon = function (time: Time | null) {
return shouldIDeploy(time) ? `${HOST}/dots.png` : `${HOST}/dots-red.png`
return shouldIDeploy(time)
? `${getBaseUrl()}/dots.png`
: `${getBaseUrl()}/dots-red.png`
}

export const getRandom = function ranDay(list: string | string[]) {
Expand Down
4 changes: 3 additions & 1 deletion jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export = {
const config = {
preset: 'ts-jest',
testEnvironment: 'node',
testPathIgnorePatterns: ['/node_modules/', '/dist/']
};

export default config
8,878 changes: 812 additions & 8,066 deletions package-lock.json

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,32 @@
"repository": "https://github.com/baires/shouldideploy/",
"scripts": {
"precommit": "NODE_ENV=production lint-staged",
"dev": "next",
"dev": "next -p 3001",
"build": "next build",
"start": "next start",
"test": "jest",
"lint": "next lint --dir pages --dir component --dir helpers",
"format": "prettier-eslint --write $PWD/'**/*.js'",
"test": "jest"
"format": "prettier-eslint --write $PWD/'**/*.js'"
},
"dependencies": {
"@vercel/analytics": "^1.0.1",
"@vercel/og": "^0.5.6",
"date-fns": "^2.30.0",
"next": "^13.4.2",
"prettier-eslint-cli": "^7.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"snyk": "^1.1155.0"
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/jest": "^29.5.1",
"@types/node": "20.1.4",
"@types/react": "18.2.6",
"babel-eslint": "^10.1.0",
"eslint": "^8.40.0",
"eslint-config-next": "^13.4.2",
"eslint-config-next": "^13.4.7",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react": "^7.25.3",
"husky": "^8.0.3",
"jest": "^29.5.0",
"lint-staged": "^13.2.2",
Expand Down
143 changes: 143 additions & 0 deletions pages/api/og.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React from 'react'
import { ImageResponse } from '@vercel/og'
import {
getRandom,
dayHelper,
shouldIDeployColorTheme,
shouldIDeployFontTheme
} from '../../helpers/constans'
import Time from '../../helpers/time'

export const config = {
runtime: 'edge'
}

const font = fetch(
new URL('../../public/fonts/GeneralSans-Bold.otf', import.meta.url)
).then((res) => res.arrayBuffer())

export default async function handler() {
const fontData = await font
let timezone = Time.DEFAULT_TIMEZONE
let time = Time.validOrNull(timezone)

return new ImageResponse(
(
<div
style={{
display: 'flex',
height: '100%',
width: '100%',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: shouldIDeployColorTheme(time)
}}
>
<div
style={{
left: 42,
top: 42,
position: 'absolute',
display: 'flex',
alignItems: 'center',
fill: 'red',
fontWeight: 300
}}
>
<svg
xmlnsXlink="http://www.w3.org/1999/xlink"
width={80}
height={80}
viewBox="0 -70 670 670"
>
<path
fill={shouldIDeployFontTheme(time)}
d="M329.84 300.16c0 8.969-7.27 16.238-16.238 16.238s-16.242-7.27-16.242-16.238 7.273-16.238 16.242-16.238 16.238 7.27 16.238 16.238M399.28 300.16c0 8.969-7.273 16.238-16.242 16.238s-16.238-7.27-16.238-16.238 7.27-16.238 16.238-16.238 16.242 7.27 16.242 16.238M366.24 238c0 8.969-7.27 16.238-16.238 16.238s-16.238-7.27-16.238-16.238 7.27-16.238 16.238-16.238 16.238 7.27 16.238 16.238M324.8 183.68c0 8.969-7.273 16.242-16.242 16.242s-16.238-7.273-16.238-16.242 7.27-16.238 16.238-16.238 16.242 7.27 16.242 16.238M408.24 184.8c0 8.969-7.27 16.238-16.238 16.238s-16.238-7.27-16.238-16.238 7.27-16.242 16.238-16.242 16.238 7.273 16.238 16.242M462.56 240.24c0 8.973-7.27 16.242-16.238 16.242s-16.242-7.27-16.242-16.242c0-8.969 7.273-16.238 16.242-16.238s16.238 7.27 16.238 16.238M269.92 240.24c0 8.973-7.273 16.242-16.242 16.242s-16.238-7.27-16.238-16.242c0-8.969 7.27-16.238 16.238-16.238s16.242 7.27 16.242 16.238M462 319.76c0-8.96-7.281-16.238-16.238-15.68-8.96 0-15.68 7.281-15.68 16.238 0 8.96 7.281 15.68 16.238 15.68 8.96 0 16.238-7.281 15.68-16.238zM408.24 376.32c0 8.969-7.27 16.238-16.238 16.238s-16.238-7.27-16.238-16.238 7.27-16.242 16.238-16.242 16.238 7.273 16.238 16.242M324.8 376.32c0 8.969-7.273 16.238-16.242 16.238s-16.238-7.27-16.238-16.238 7.27-16.242 16.238-16.242 16.242 7.273 16.242 16.242M269.92 319.76c0 8.969-7.273 16.238-16.242 16.238s-16.238-7.27-16.238-16.238c0-8.973 7.27-16.242 16.238-16.242s16.242 7.27 16.242 16.242M286.72 133.84c0 8.969-7.27 16.238-16.238 16.238s-16.242-7.27-16.242-16.238 7.273-16.238 16.242-16.238 16.238 7.27 16.238 16.238M226.24 187.04c0 8.969-7.27 16.242-16.238 16.242s-16.238-7.273-16.238-16.242 7.27-16.238 16.238-16.238 16.238 7.27 16.238 16.238M199.36 260.96c0 8.969-7.27 16.238-16.238 16.238s-16.242-7.27-16.242-16.238 7.273-16.242 16.242-16.242 16.238 7.273 16.238 16.242M208.88 342.16c0 8.969-7.27 16.238-16.238 16.238s-16.242-7.27-16.242-16.238 7.273-16.238 16.242-16.238 16.238 7.27 16.238 16.238M254.24 408.8c0 8.969-7.27 16.238-16.238 16.238s-16.238-7.27-16.238-16.238 7.27-16.242 16.238-16.242 16.238 7.273 16.238 16.242M324.8 445.76c0 8.969-7.273 16.238-16.242 16.238s-16.238-7.27-16.238-16.238c0-8.973 7.27-16.242 16.238-16.242s16.242 7.27 16.242 16.242M408.24 445.76c0 8.969-7.27 16.238-16.238 16.238s-16.238-7.27-16.238-16.238c0-8.973 7.27-16.242 16.238-16.242s16.238 7.27 16.238 16.242M478.24 408.8c0 8.969-7.27 16.238-16.238 16.238s-16.238-7.27-16.238-16.238 7.27-16.242 16.238-16.242 16.238 7.273 16.238 16.242M523.04 342.16c0 8.969-7.27 16.238-16.238 16.238s-16.242-7.27-16.242-16.238 7.273-16.238 16.242-16.238 16.238 7.27 16.238 16.238M533.12 260.96c0 8.969-7.273 16.238-16.242 16.238s-16.238-7.27-16.238-16.238 7.27-16.242 16.238-16.242 16.242 7.273 16.242 16.242M504 187.04c0 8.969-7.27 16.242-16.238 16.242-8.973 0-16.242-7.273-16.242-16.242s7.27-16.238 16.242-16.238c8.969 0 16.238 7.27 16.238 16.238M444.64 133.84c0 8.969-7.273 16.238-16.242 16.238s-16.238-7.27-16.238-16.238 7.27-16.238 16.238-16.238 16.242 7.27 16.242 16.238M366.24 114.24c0 8.973-7.27 16.242-16.238 16.242s-16.238-7.27-16.238-16.242c0-8.969 7.27-16.238 16.238-16.238s16.238 7.27 16.238 16.238M248.64 76.719c0 8.969-7.273 16.242-16.242 16.242s-16.238-7.273-16.238-16.242 7.27-16.238 16.238-16.238 16.242 7.27 16.242 16.238M185.92 127.68c0 8.969-7.273 16.242-16.242 16.242s-16.238-7.273-16.238-16.242 7.27-16.238 16.238-16.238 16.242 7.27 16.242 16.238M143.36 198.24c0 8.973-7.27 16.242-16.238 16.242s-16.242-7.27-16.242-16.242c0-8.969 7.273-16.238 16.242-16.238s16.238 7.27 16.238 16.238M130.48 280c0 8.969-7.27 16.238-16.242 16.238-8.969 0-16.238-7.27-16.238-16.238s7.27-16.238 16.238-16.238c8.973 0 16.242 7.27 16.242 16.238M143.36 360.08c0 8.973-7.27 16.242-16.238 16.242s-16.242-7.27-16.242-16.242c0-8.969 7.273-16.238 16.242-16.238s16.238 7.27 16.238 16.238M185.92 432.32c0 8.969-7.273 16.238-16.242 16.238s-16.238-7.27-16.238-16.238 7.27-16.242 16.238-16.242 16.242 7.273 16.242 16.242M248.64 485.52c0 8.969-7.273 16.242-16.242 16.242s-16.238-7.273-16.238-16.242 7.27-16.238 16.238-16.238 16.242 7.27 16.242 16.238M324.8 512.4c0 8.969-7.273 16.242-16.242 16.242s-16.238-7.273-16.238-16.242 7.27-16.238 16.238-16.238 16.242 7.27 16.242 16.238M408.24 512.4c0 8.969-7.27 16.242-16.238 16.242s-16.238-7.273-16.238-16.242 7.27-16.238 16.238-16.238 16.238 7.27 16.238 16.238M484.96 483.28c0 8.969-7.273 16.238-16.242 16.238s-16.238-7.27-16.238-16.238 7.27-16.242 16.238-16.242 16.242 7.273 16.242 16.242M546.56 432.32c0 8.969-7.27 16.238-16.238 16.238s-16.242-7.27-16.242-16.238 7.273-16.242 16.242-16.242 16.238 7.273 16.238 16.242M588.56 360.08c0 8.973-7.27 16.242-16.238 16.242s-16.242-7.27-16.242-16.242c0-8.969 7.273-16.238 16.242-16.238s16.238 7.27 16.238 16.238M602 280c0 8.969-7.27 16.238-16.238 16.238-8.973 0-16.242-7.27-16.242-16.238s7.27-16.238 16.242-16.238c8.969 0 16.238 7.27 16.238 16.238M588.56 199.92c0 8.969-7.27 16.238-16.238 16.238s-16.242-7.27-16.242-16.238c0-8.973 7.273-16.242 16.242-16.242s16.238 7.27 16.238 16.242M546.56 127.68c0 8.969-7.27 16.242-16.238 16.242s-16.242-7.273-16.242-16.242 7.273-16.238 16.242-16.238 16.238 7.27 16.238 16.238M484.96 76.719c0 8.969-7.273 16.242-16.242 16.242s-16.238-7.273-16.238-16.242 7.27-16.238 16.238-16.238 16.242 7.27 16.242 16.238M408.24 47.602c0 8.969-7.27 16.238-16.238 16.238s-16.238-7.27-16.238-16.238 7.27-16.242 16.238-16.242 16.238 7.273 16.238 16.242M324.8 47.602c0 8.969-7.273 16.238-16.242 16.238s-16.238-7.27-16.238-16.238 7.27-16.242 16.238-16.242S324.8 38.633 324.8 47.602"
></path>
<use x="70" y="644" xlinkHref="#w"></use>
<use x="90.551" y="644" xlinkHref="#b"></use>
<use x="104.359" y="644" xlinkHref="#a"></use>
<use x="123.348" y="644" xlinkHref="#f"></use>
<use x="142.242" y="644" xlinkHref="#c"></use>
<use x="155.629" y="644" xlinkHref="#a"></use>
<use x="174.617" y="644" xlinkHref="#l"></use>
<use x="204.41" y="644" xlinkHref="#k"></use>
<use x="224.453" y="644" xlinkHref="#j"></use>
<use x="252.453" y="644" xlinkHref="#a"></use>
<use x="271.441" y="644" xlinkHref="#e"></use>
<use x="300.617" y="644" xlinkHref="#i"></use>
<use x="310.215" y="644" xlinkHref="#v"></use>
<use x="319.813" y="644" xlinkHref="#a"></use>
<use x="338.805" y="644" xlinkHref="#u"></use>
<use x="358.844" y="644" xlinkHref="#b"></use>
<use x="372.656" y="644" xlinkHref="#f"></use>
<use x="391.547" y="644" xlinkHref="#t"></use>
<use x="411.594" y="644" xlinkHref="#h"></use>
<use x="431.523" y="644" xlinkHref="#i"></use>
<use x="441.125" y="644" xlinkHref="#g"></use>
<use x="457.719" y="644" xlinkHref="#s"></use>
<use x="70" y="672" xlinkHref="#r"></use>
<use x="82.184" y="672" xlinkHref="#b"></use>
<use x="95.992" y="672" xlinkHref="#d"></use>
<use x="115.227" y="672" xlinkHref="#e"></use>
<use x="154.152" y="672" xlinkHref="#c"></use>
<use x="167.535" y="672" xlinkHref="#h"></use>
<use x="187.469" y="672" xlinkHref="#a"></use>
<use x="216.207" y="672" xlinkHref="#q"></use>
<use x="239.641" y="672" xlinkHref="#d"></use>
<use x="258.879" y="672" xlinkHref="#p"></use>
<use x="278.813" y="672" xlinkHref="#o"></use>
<use x="308.492" y="672" xlinkHref="#n"></use>
<use x="329.016" y="672" xlinkHref="#b"></use>
<use x="342.82" y="672" xlinkHref="#d"></use>
<use x="362.059" y="672" xlinkHref="#m"></use>
<use x="371.656" y="672" xlinkHref="#a"></use>
<use x="390.648" y="672" xlinkHref="#g"></use>
<use x="407.242" y="672" xlinkHref="#c"></use>
</svg>
<span
style={{
marginLeft: 8,
fontSize: 20,
fontWeight: 400,
color: shouldIDeployFontTheme(time)
}}
>
shouldideploy.today
</span>
</div>
<div
style={{
display: 'flex',
justifyContent: 'center',
padding: '20px 50px',
margin: '0 42px',
fontSize: 70,
fontWeight: 700,
color: shouldIDeployFontTheme(time),
width: 'auto',
maxWidth: '85%',
textAlign: 'center',
fontFamily: '"GeneralSans"',
lineHeight: 1.2,
textTransform: 'uppercase'
}}
>
{time && getRandom(dayHelper(time))}
</div>
</div>
),
{
width: 1200,
height: 630,
fonts: [
{
name: 'GeneralSans',
data: fontData,
weight: 700,
style: 'normal'
}
]
}
)
}
5 changes: 3 additions & 2 deletions pages/api/slack/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
getRandom,
dayHelper,
shouldIDeployAnswerImage,
getBaseUrl,
shouldIDeployColorTheme,
shouldIDeployFavIcon
} from '../../../helpers/constans'
Expand All @@ -28,6 +28,7 @@ export default (
) => {
let timezone = req.body.text || req.query.tz || Time.DEFAULT_TIMEZONE
let time = Time.validOrNull(timezone)
const thumb_url = `${getBaseUrl()}/api/og`

res.status(200).json({
response_type: time ? 'in_channel' : 'ephemeral',
Expand All @@ -37,7 +38,7 @@ export default (
? getRandom(dayHelper(time))
: `Invalid time zone: '${timezone}'`,
color: shouldIDeployColorTheme(time),
thumb_url: shouldIDeployAnswerImage(time),
thumb_url,
footer_icon: shouldIDeployFavIcon(time),
footer: 'Should I deploy today' + (time ? ` | ${timezone}` : '')
}
Expand Down
6 changes: 2 additions & 4 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import Head from 'next/head'
import {
shouldIDeploy,
shouldIDeployFavIcon,
shouldIDeployAnswerImage,
getRandom,
dayHelper
getBaseUrl
} from '../helpers/constans'
import Time from '../helpers/time'
import Widget from '../component/widget'
Expand Down Expand Up @@ -48,7 +46,7 @@ const Page: React.FC<IPage> = ({ tz, now: initialNow, initialReason }) => {
href={shouldIDeployFavIcon(now)}
sizes="32x32"
/>
<meta property="og:image" content={shouldIDeployAnswerImage(now)} />
<meta property="og:image" content={`${getBaseUrl()}/api/og`} />
<title>Should I Deploy Today?</title>
</Head>
<div className={`wrapper ${!shouldIDeploy(now) && 'its-friday'}`}>
Expand Down
Binary file added public/fonts/GeneralSans-Bold.otf
Binary file not shown.
Binary file removed public/no.png
Binary file not shown.
Binary file removed public/yes.png
Binary file not shown.
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "commonjs", /* Specify what module code is generated. */
"module": "es2020", /* Specify what module code is generated. */
// "rootDir": "src", /* Specify the root folder within your source files. */// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
Expand Down
32 changes: 18 additions & 14 deletions vercel.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
{
"name": "shouldideploy",
"version": 2,
"cleanUrls": true,
"trailingSlash": false,
"redirects": [
{
"source": "/api/slack/(.*)",
"destination": "/api/slack"
},
{
"source": "/api/((?!slack).*)",
"destination": "/api"
}
]
"name": "shouldideploy",
"version": 2,
"cleanUrls": true,
"trailingSlash": false,
"redirects": [
{
"source": "/api/slack/(.*)",
"destination": "/api/slack"
},
{
"source": "/api/og/(.*)",
"destination": "/api/og"
},
{
"source": "/api/((?!og|slack).*)",
"destination": "/api"
}
]
}

1 comment on commit 56d26c2

@vercel
Copy link

@vercel vercel bot commented on 56d26c2 Jun 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.