Skip to content

Commit 3f1b644

Browse files
committed
feature: integrate wanted api
1 parent de13c1f commit 3f1b644

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

src/graphql/ad.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { IResolvers, gql } from 'apollo-server-koa';
1+
import { ApolloError, IResolvers, gql } from 'apollo-server-koa';
22
import { ApolloContext } from '../app';
33
import adService from '../services/adService';
4+
import { isJobCategory, wantedService } from '../services/wantedService';
45

56
export const typeDef = gql`
67
type Ad {
@@ -14,8 +15,17 @@ export const typeDef = gql`
1415
is_disabled: Boolean!
1516
url: String!
1617
}
18+
type JobPosition {
19+
id: ID!
20+
name: String!
21+
companyName: String!
22+
companyLogo: String!
23+
thumbnail: String!
24+
url: String!
25+
}
1726
extend type Query {
1827
bannerAds(writer_username: String!): [Ad!]!
28+
jobPositions(category: String): [JobPosition!]!
1929
}
2030
`;
2131

@@ -24,6 +34,12 @@ export const resolvers: IResolvers<any, ApolloContext> = {
2434
bannerAds: async (_, { writer_username }: BannerAdsArgs) => {
2535
return await adService.getBannerTypeAdList(writer_username);
2636
},
37+
jobPositions: async (_, { category }: { category?: string }) => {
38+
if (isJobCategory(category)) {
39+
return wantedService.getJobPositions(category);
40+
}
41+
throw new ApolloError('Bad Request');
42+
},
2743
},
2844
};
2945

src/services/wantedService.ts

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import axios from 'axios';
2+
3+
const wantedApiId = process.env.WANTED_API_ID;
4+
const wantedApiKey = process.env.WANTED_API_SECRET;
5+
const wantedApiHost = process.env.WANTED_API_HOST;
6+
7+
const categories = {
8+
frontend: [669],
9+
backend: [872],
10+
python: [899],
11+
node: [895],
12+
mobile: [677, 678, 10111],
13+
ai: [1634],
14+
};
15+
16+
export type JobCategory = keyof typeof categories;
17+
export function isJobCategory(category: string | undefined): category is JobCategory | undefined {
18+
//check categories has key
19+
if (category === undefined) return true;
20+
return category in categories;
21+
}
22+
23+
export const wantedService = {
24+
async getJobPositions(category?: JobCategory) {
25+
const categoryParams = category
26+
? categories[category].map(c => `subcategory_tags=${c}`).join('&')
27+
: 'category_tag=518';
28+
const params = '?sort=job.popularity_order&offset=0&limit=10&'.concat(categoryParams);
29+
30+
console.log(params);
31+
32+
const response = await axios.get<WantedJobResponse>(
33+
`https://${wantedApiHost}/v2/jobs`.concat(params),
34+
{
35+
headers: {
36+
'wanted-client-id': wantedApiId,
37+
'wanted-client-secret': wantedApiKey,
38+
},
39+
}
40+
);
41+
const jobs = response.data.data.map(d => ({
42+
id: d.id,
43+
name: d.name,
44+
companyName: d.company.name,
45+
companyLogo: d.logo_img.thumb,
46+
thumbnail: d.title_img.thumb,
47+
url: d.url,
48+
}));
49+
50+
const shuffledJobs = jobs.sort(() => 0.5 - Math.random());
51+
return shuffledJobs.slice(0, 4);
52+
},
53+
};
54+
55+
type JobPosition = {
56+
id: number;
57+
status: string;
58+
due_time: string | null;
59+
name: string;
60+
company: {
61+
id: number;
62+
name: string;
63+
};
64+
reward: {
65+
total: string;
66+
recommender: string;
67+
recommendee: string;
68+
};
69+
address: {
70+
country: string;
71+
location: string;
72+
full_location: string;
73+
};
74+
title_img: {
75+
origin: string;
76+
thumb: string;
77+
};
78+
logo_img: {
79+
origin: string;
80+
thumb: string;
81+
};
82+
category_tags: {
83+
parent_tag: {
84+
id: number;
85+
title: string;
86+
};
87+
child_tags: {
88+
id: number;
89+
title: string;
90+
}[];
91+
};
92+
url: string;
93+
};
94+
95+
type WantedJobResponse = {
96+
links: any;
97+
data: JobPosition[];
98+
};

0 commit comments

Comments
 (0)