-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpadletService.ts
More file actions
87 lines (81 loc) · 2.84 KB
/
Copy pathpadletService.ts
File metadata and controls
87 lines (81 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// file: Handle fetching data from Padlet API.
import type { PadletPostType, PadletPostAttachmentDataType } from "@/types";
/**
* Fetch data from a provided URL using headers.
* @param url - The URL from which data needs to be fetched.
* @param headers - Headers that need to be sent with the request.
* @returns A Promise that resolves with the JSON data from the response.
*/
async function fetchData(url: string, headers: Record<string, string>) {
const response = await fetch(url, { method: "GET", headers, mode: "cors" });
return await response.json();
}
/**
* If post has related attachments, fetch and add them to the post.
* @param post - The post for which attachments need to be fetched.
* @param headers - Headers that need to be sent with the request.
* @returns A Promise that resolves with the post and its attachments (if any).
*/
async function handleAttachment(
post: PadletPostType,
headers: Record<string, string>
): Promise<PadletPostType> {
try {
if (post.relationships.attachmentData?.links?.related == null) {
return post;
}
const jsonData = await fetchData(
post.relationships.attachmentData.links.related,
headers
);
const attachmentData: PadletPostAttachmentDataType = jsonData.data;
return { ...post, resolvedAttachmentData: attachmentData.attributes };
} catch (e) {
console.error(e);
return post;
}
}
/**
* Filter out posts from a provided array of items.
* @param items - An array of items to be filtered.
* @returns An array of filtered posts.
*/
function filterPosts(items: any[]): PadletPostType[] {
return items.filter((item: any) => item.type === "post");
}
/**
* Fetch a Padlet board by ID and return its title and posts.
* @param boardId - The ID of the Padlet board to fetch.
* @param personalAccessToken - (Optional) A personal access token.
* @returns A Promise that resolves with the board's title and posts.
*/
export async function getPadletBoard(
boardId: string,
personalAccessToken?: string
): Promise<{
title: string;
posts: PadletPostType[];
}> {
const headers: Record<string, string> = {
accept: "application/vnd.api+json",
};
if (personalAccessToken) {
headers["X-API-Key"] = personalAccessToken;
}
const jsonData = await fetchData(
`https://api.padlet.dev/v1/boards/${boardId}?include=posts`,
headers
);
let posts = filterPosts(jsonData.included);
posts = await Promise.all(
posts.map((post) => handleAttachment(post, headers))
);
return {
title: jsonData.data.attributes.title,
posts: posts as PadletPostType[],
};
}
// These are demo board IDs provided by Padlet. They can be accessed without a personal access token.
export const AFRICA_DEMO_PADLET_BOARD_ID = "qk3sab0nz9rcp0wv";
export const VIETNAMESE_DEMO_PADLET_BOARD_ID = "ripehx05bvo43tnm";
export const PILOT_DEMO_PADLET_BOARD_ID = "23h9stxv7cec89gy";