Skip to content

Mapped the other urls #7

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
20 changes: 12 additions & 8 deletions src/lib/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
GRAPHQL_ENDPOINT,
} from './consts';
import { IS_DEBUG } from './env';
import { ThreadsUserProfileResponse } from '../types/threads-api';
import { mapUserProfile } from './map';
import { ThreadsRepliesResponse, ThreadsUserProfileResponse, UserThreadsResponse } from '../types/threads-api';
import { mapThreadsReplies, mapUserProfile, mapUserThreads } from './map';

const fetchBase = ({ documentId, variables }) => {
return fetch(GRAPHQL_ENDPOINT, {
Expand Down Expand Up @@ -67,10 +67,12 @@ export const fetchUserProfileThreads = async ({
}

const variables = { userID: userId };
return fetchBase({
const data = (await fetchBase({
variables,
documentId: ENDPOINTS_DOCUMENT_ID.USER_PROFILE_THREADS,
});
})) as UserThreadsResponse;

return mapUserThreads(data);
};

export const fetchUserReplies = async ({
Expand All @@ -91,15 +93,17 @@ export const fetchUserReplies = async ({
});
};

export const fetchThreadReplies = ({ threadId }) => {
export const fetchThreadReplies = async ({ threadId }) => {
const variables = { postID: threadId };
return fetchBase({
const data = (await fetchBase({
variables,
documentId: ENDPOINTS_DOCUMENT_ID.USER_PROFILE_THREADS_REPLIES,
});
})) as ThreadsRepliesResponse;

return mapThreadsReplies(data);
};

export const fetchPostReplies = ({ threadId }) => {
export const fetchPostReplies = async ({ threadId }) => {
const variables = { postID: threadId };
return fetchBase({
variables,
Expand Down
28 changes: 27 additions & 1 deletion src/lib/map.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ThreadsUserProfileResponse} from '../types/threads-api'
import { ThreadsRepliesResponse, ThreadsUserProfileResponse, UserThreadsResponse } from '../types/threads-api'

/*
{"data":{"userData":{"user":{"is_private":false,"profile_pic_url":"https://scontent.cdninstagram.com/v/t51.2885-19/358174537_954616899107816_8099109910283809308_n.jpg?stp=dst-jpg_s150x150&_nc_ht=scontent.cdninstagram.com&_nc_cat=108&_nc_ohc=s5qTOIc_KREAX8qfpDD&edm=APs17CUBAAAA&ccb=7-5&oh=00_AfDaktW3vHUeFvaE14qoy7LmddGuAqWUh2uirC7ulm_TsQ&oe=64B34341&_nc_sid=10d13b","username":"midu.dev","hd_profile_pic_versions":[{"height":320,"url":"https://scontent.cdninstagram.com/v/t51.2885-19/358174537_954616899107816_8099109910283809308_n.jpg?stp=dst-jpg_s320x320&_nc_ht=scontent.cdninstagram.com&_nc_cat=108&_nc_ohc=s5qTOIc_KREAX8qfpDD&edm=APs17CUBAAAA&ccb=7-5&oh=00_AfBUgVik0k-VaqXmyuuJUp6bEmAyDHIkkB3ssbnHYwGg_A&oe=64B34341&_nc_sid=10d13b","width":320},{"height":640,"url":"https://scontent.cdninstagram.com/v/t51.2885-19/358174537_954616899107816_8099109910283809308_n.jpg?stp=dst-jpg_s640x640&_nc_ht=scontent.cdninstagram.com&_nc_cat=108&_nc_ohc=s5qTOIc_KREAX8qfpDD&edm=APs17CUBAAAA&ccb=7-5&oh=00_AfCG0VVjm58zezRMrUgG_HlTuOL0MlMMsUpGRDgn4CrMiA&oe=64B34341&_nc_sid=10d13b","width":640}],"is_verified":false,"biography":"👨‍💻 Ingeniero de Software + JavaScript\n⌨️ Aprende Programación conmigo\n🏆 Google Expert + GitHub Star\n🙌 Comparto recursos y tutoriales","biography_with_entities":null,"follower_count":34756,"profile_context_facepile_users":null,"bio_links":[{"url":"https://twitch.tv/midudev"}],"pk":"8242141302","full_name":"midudev • Programación y Desarrollo JavaScript","id":null}}},"extensions":{"is_final":true}}
*/

// Organises the original response of the user profile
export const mapUserProfile = (rawResponse: ThreadsUserProfileResponse) => {
const userApiResponse = rawResponse?.data?.userData?.user
if (!userApiResponse) return null
Expand All @@ -26,4 +27,29 @@ export const mapUserProfile = (rawResponse: ThreadsUserProfileResponse) => {
full_name,
profile_pics
}
}

// Organises the original response of the user threads
export const mapUserThreads = (rawResponse: UserThreadsResponse) => {
if (!rawResponse.data) return null

return rawResponse.data.mediaData.threads.map(({ id, thread_items }) => {
return { id, items: thread_items }
})
}

// Organises the original response of the thread replies
export const mapThreadsReplies = (rawResponse: ThreadsRepliesResponse) => {
if (!rawResponse.data) return null

const containing_thread = {
id: rawResponse.data.data.containing_thread.id,
items: rawResponse.data.data.containing_thread.thread_items
}

const reply_threads = rawResponse.data.data.reply_threads.map(({ id, thread_items }) => {
return { id, thread_items }
})

return { containing_thread, reply_threads }
}
135 changes: 135 additions & 0 deletions src/types/threads-api.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// User profile types

export type ThreadsUserProfileResponse = {
data: Data;
extensions: Extensions;
Expand Down Expand Up @@ -40,3 +42,136 @@ export type HDProfilePicVersion = {
export type Extensions = {
is_final: boolean;
}

// User threads types

export type UserThreadsResponse = {
data: { mediaData: { threads: Thread[] } };
extensions: Extensions;
}

export type Thread = {
thread_items: ThreadItem[];
id: string;
}

export type ThreadItem = {
post: Post;
line_type: LineType;
view_replies_cta_string: null | string;
reply_facepile_users: ReplyFacepileUser[];
should_show_replies_cta: boolean;
__typename: ThreadItemTypename;
}

export enum ThreadItemTypename {
XDTThreadItem = "XDTThreadItem",
}

export enum LineType {
Line = "line",
None = "none",
}

export type Post = {
user: User;
image_versions2: PostImageVersions2;
original_width: number;
original_height: number;
video_versions: VideoVersion[];
carousel_media: CarouselMedia[] | null;
carousel_media_count: number | null;
pk: string;
has_audio: boolean | null;
text_post_app_info: TextPostAppInfo;
caption: Caption;
taken_at: number;
like_count: number;
code: string;
media_overlay_info: null;
id: string;
}

export type Caption = {
text: string;
}

export type CarouselMedia = {
image_versions2: CarouselMediaImageVersions2;
video_versions: any[];
has_audio: boolean | null;
original_height: number;
original_width: number;
pk: string;
id: string;
}

export type CarouselMediaImageVersions2 = {
candidates: PurpleCandidate[];
}

export type PurpleCandidate = {
url: string;
}

export type PostImageVersions2 = {
candidates: FluffyCandidate[];
}

export type FluffyCandidate = {
height: number;
url: string;
width: number;
__typename: CandidateTypename;
}

export enum CandidateTypename {
XDTImageCandidate = "XDTImageCandidate",
}

export type TextPostAppInfo = {
link_preview_attachment: string | null;
share_info: ShareInfo;
reply_to_author: string | null;
is_post_unavailable: boolean;
}

export type ShareInfo = {
quoted_post: any;
reposted_post: any;
}

export type UserShort = {
profile_pic_url: string;
username: string;
id: string | null;
is_verified: boolean;
pk: string;
}

export type VideoVersion = {
type: number;
url: string;
__typename: VideoVersionTypename;
}

export enum VideoVersionTypename {
XDTVideoVersion = "XDTVideoVersion",
}

export type ReplyFacepileUser = {
__typename: ReplyFacepileUserTypename;
id: null;
profile_pic_url: string;
}

export enum ReplyFacepileUserTypename {
XDTUserDict = "XDTUserDict",
}

// Threads replies types

export type ThreadsRepliesResponse = {
data: { data: { containing_thread: Thread; reply_threads: Thread[] } };
extensions: Extensions;
}