Skip to content

Commit

Permalink
Add number of users in Slack counter
Browse files Browse the repository at this point in the history
  • Loading branch information
Starefossen committed Dec 17, 2024
1 parent 24b3fe9 commit 3e8d38d
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 17 deletions.
58 changes: 58 additions & 0 deletions src/app/api/slack/userCount/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { NextRequest, NextResponse } from 'next/server';

const SLACK_BOT_TOKEN = process.env.SLACK_BOT_TOKEN;

if (!SLACK_BOT_TOKEN) {
throw new Error('SLACK_BOT_TOKEN is not defined');
}

/* eslint-disable @typescript-eslint/no-unused-vars */
export async function GET(request: NextRequest) {
try {
let userCount = 0;
let cursor = '';

do {
const fetchResponse = await fetch(`https://slack.com/api/users.list?cursor=${cursor}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${SLACK_BOT_TOKEN}`,
'Content-Type': 'application/json',
},
});

const data = await fetchResponse.json();

if (!data.ok) {
return NextResponse.json({ error: 'Failed to fetch users from Slack' }, { status: 500 });
}

interface SlackUser {
id: string;
team_id: string;
name: string;
deleted: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
}

interface SlackResponseMetadata {
next_cursor: string;
}

interface SlackUsersListResponse {
ok: boolean;
members: SlackUser[];
response_metadata?: SlackResponseMetadata;
}

userCount += (data as SlackUsersListResponse).members.filter((member: SlackUser) => !member.deleted).length;
cursor = data.response_metadata?.next_cursor || '';
} while (cursor);

return NextResponse.json({ userCount }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
}
};
38 changes: 21 additions & 17 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import { type ArticleWithSlug, getAllArticles } from '@/lib/articles'
import { formatDate } from '@/lib/formatDate'
import { metadata as globalMetadata } from './layout'
import { getUpcomingEvents } from '@/lib/events/helpers';
import { getUserCount } from '@/lib/slack/client';
import { InfoCard } from '@/components/Stats';

export const revalidate = 3600

Expand Down Expand Up @@ -70,27 +72,29 @@ function UpcomingEvents() {
)
}

function Community() {
async function Community() {
const slackUserCount = await getUserCount()
const slackUrl = `${globalMetadata.other?.joinSlackUrl || '#'}`

return (
<form
action="/thank-you"
className="rounded-2xl border border-zinc-100 p-6 dark:border-zinc-700/40"
>
<h2 className="flex text-sm font-semibold text-zinc-900 dark:text-zinc-100">
<ChatBubbleLeftRightIcon className="h-6 w-6 flex-none" />
<span className="ml-3">Bli med på diskusjonen!</span>
</h2>
<p className="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
Offentlig PaaS har Norges største nettverk av plattformentusiaster samlet i en Slack-kanal!
</p>
<>
<InfoCard title="Antall brukere på Slack" number={slackUserCount} label="kontoer" />

<div className="rounded-2xl border border-zinc-100 p-6 dark:border-zinc-700/40">
<h2 className="flex text-sm font-semibold text-zinc-900 dark:text-zinc-100">
<ChatBubbleLeftRightIcon className="h-6 w-6 flex-none" />
<span className="ml-3">Bli med på diskusjonen!</span>
</h2>
<p className="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
Offentlig PaaS har Norges største nettverk av plattformentusiaster samlet i en Slack-kanal!
</p>

<Button href={slackUrl} variant="primary" className="group mt-6 w-full">
Bli med i Slack
<SlackIcon className="h-4 w-4 fill-white" />
</Button>
</form>
<Button href={slackUrl} variant="primary" className="group mt-6 w-full">
Bli med i Slack
<SlackIcon className="h-4 w-4 fill-white" />
</Button>
</div>
</>
)
}

Expand Down
30 changes: 30 additions & 0 deletions src/lib/slack/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export async function getUserCount(): Promise<number> {
const getHost = (): string => {
if (typeof window !== 'undefined') {
return `${window.location.protocol}://${window.location.hostname}`;
}
return process.env.NEXT_PUBLIC_URL || 'http://localhost:3000';
};

const fetchUserCount = async (host: string): Promise<number> => {
try {
const response = await fetch(`${host}/api/slack/userCount`);
if (!response.ok) {
console.error('Failed to fetch user count:', response.statusText);
return 0;
}
const data = await response.json();
if (data.error) {
console.error('Error in response data:', data.error);
return 0;
}
return data.userCount;
} catch (error) {
console.error('Error fetching user count:', error);
return 0;
}
};

const host = getHost();
return fetchUserCount(host);
}

0 comments on commit 3e8d38d

Please sign in to comment.