From 0e3d1ced4668213da962231a2be77378297298dc Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Fri, 2 Dec 2022 19:10:41 +0800 Subject: [PATCH] Add recommend rest api to handler tasks --- .../elastic/{groups.ts => recommendation.ts} | 14 +++-- packages/api/src/routers/page_router.ts | 56 ++++++++++++++++++- packages/api/src/utils/createTask.ts | 6 +- 3 files changed, 64 insertions(+), 12 deletions(-) rename packages/api/src/elastic/{groups.ts => recommendation.ts} (67%) diff --git a/packages/api/src/elastic/groups.ts b/packages/api/src/elastic/recommendation.ts similarity index 67% rename from packages/api/src/elastic/groups.ts rename to packages/api/src/elastic/recommendation.ts index d87d5f086..a1b45a707 100644 --- a/packages/api/src/elastic/groups.ts +++ b/packages/api/src/elastic/recommendation.ts @@ -1,14 +1,18 @@ import { Group, Page, PageContext } from './types' -import { createPage, updatePage } from './pages' +import { createPage, getPageByParam, updatePage } from './pages' -export const recommendPage = async ( +export const addRecommendation = async ( ctx: PageContext, page: Page, - userId: string, - group: Group, - existingPage?: Page + group: Group ): Promise => { try { + const userId = ctx.uid + // check if the page is already recommended to the group + const existingPage = await getPageByParam({ + userId, + url: page.url, + }) if (existingPage) { // update recommendedBy in the existing page const recommendedBy = (existingPage.recommendedBy || []).concat(group) diff --git a/packages/api/src/routers/page_router.ts b/packages/api/src/routers/page_router.ts index 39ae6295a..5a9a6d14a 100644 --- a/packages/api/src/routers/page_router.ts +++ b/packages/api/src/routers/page_router.ts @@ -5,17 +5,14 @@ import express from 'express' import { ArticleSavingRequestStatus, - CreateArticleErrorCode, PageType, UploadFileStatus, } from '../generated/graphql' -import { isSiteBlockedForParse } from '../utils/blocked' import cors from 'cors' import { env } from '../env' import { buildLogger } from '../utils/logger' import * as jwt from 'jsonwebtoken' import { corsConfig } from '../utils/corsConfig' -import { createPageSaveRequest } from '../services/create_page_save_request' import { initModels } from '../server' import { kx } from '../datalayer/knex_config' import { @@ -32,6 +29,8 @@ import { import { Claims } from '../resolvers/types' import { createPage, getPageByParam, updatePage } from '../elastic/pages' import { createPubSubClient } from '../datalayer/pubsub' +import { Group } from '../elastic/types' +import { addRecommendation } from '../elastic/recommendation' const logger = buildLogger('app.dispatch') @@ -149,5 +148,56 @@ export function pageRouter() { return res.redirect(signedUrl) }) + // Add recommended pages to a user's library + router.options( + '/recommend', + cors({ ...corsConfig, maxAge: 600 }) + ) + router.post( + '/recommend', + cors(corsConfig), + async (req, res) => { + const token = req?.cookies?.auth || req?.headers?.authorization + if (!token || !jwt.verify(token, env.server.jwtSecret)) { + return res.status(401).send({ errorCode: 'UNAUTHORIZED' }) + } + const claims = jwt.decode(token) as Claims + + const { + userId: recommendedUserId, + pageId, + group, + } = req.body as { + userId: string + pageId: string + group: Group + } + if (!recommendedUserId || !pageId || !group) { + return res.status(400).send({ errorCode: 'BAD_DATA' }) + } + + const ctx = { + uid: recommendedUserId, + pubsub: createPubSubClient(), + } + + const page = await getPageByParam({ + userId: claims.uid, + _id: pageId, + }) + if (!page) { + return res.status(404).send({ errorCode: 'NOT_FOUND' }) + } + + const recommendedPageId = await addRecommendation(ctx, page, group) + if (!recommendedPageId) { + logger.error('Failed to add recommendation to page') + return res.sendStatus(500) + } + + return res.send({ recommendedPageId }) + } + ) + return router } diff --git a/packages/api/src/utils/createTask.ts b/packages/api/src/utils/createTask.ts index fe7d9743e..a6041668a 100644 --- a/packages/api/src/utils/createTask.ts +++ b/packages/api/src/utils/createTask.ts @@ -407,16 +407,14 @@ export const enqueueTextToSpeech = async ({ } export const enqueueRecommendation = async ( - recommendedUserId: string, - recommendedPageId: string, userId: string, + pageId: string, group: Group ): Promise => { const { GOOGLE_CLOUD_PROJECT } = process.env const payload = { userId, - recommendedUserId, - recommendedPageId, + pageId, group, }