summaryrefslogtreecommitdiff
path: root/src/server/api/endpoints/users/recommendation.ts
blob: f44b1c909be7145d1db939a36e779cf4e3970806 (plain)
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
88
89
90
91
const ms = require('ms');
import $ from 'cafy';
import User, { pack, ILocalUser } from '../../../../models/user';
import { getFriendIds } from '../../common/get-friends';
import Mute from '../../../../models/mute';
import * as request from 'request';
import config from '../../../../config';

export const meta = {
	desc: {
		'ja-JP': 'おすすめのユーザー一覧を取得します。'
	},

	requireCredential: true,

	kind: 'account-read'
};

export default (params: any, me: ILocalUser) => new Promise(async (res, rej) => {
	if (config.user_recommendation && config.user_recommendation.external) {
		const userName = me.username;
		const hostName = config.hostname;
		const limit = params.limit;
		const offset = params.offset;
		const timeout = config.user_recommendation.timeout;
		const engine = config.user_recommendation.engine;
		const url = engine
			.replace('{{host}}', hostName)
			.replace('{{user}}', userName)
			.replace('{{limit}}', limit)
			.replace('{{offset}}', offset);

			request(
			{
				url: url,
				timeout: timeout,
				json: true,
				followRedirect: true,
				followAllRedirects: true
			},
			(error: any, response: any, body: any) => {
				if (!error && response.statusCode == 200) {
					res(body);
				} else {
					res([]);
				}
			}
		);
	} else {
		// Get 'limit' parameter
		const [limit = 10, limitErr] = $.num.optional.range(1, 100).get(params.limit);
		if (limitErr) return rej('invalid limit param');

		// Get 'offset' parameter
		const [offset = 0, offsetErr] = $.num.optional.min(0).get(params.offset);
		if (offsetErr) return rej('invalid offset param');

		// ID list of the user itself and other users who the user follows
		const followingIds = await getFriendIds(me._id);

		// ミュートしているユーザーを取得
		const mutedUserIds = (await Mute.find({
			muterId: me._id
		})).map(m => m.muteeId);

		const users = await User
			.find({
				_id: {
					$nin: followingIds.concat(mutedUserIds)
				},
				isLocked: { $ne: true },
				$or: [{
					lastUsedAt: {
						$gte: new Date(Date.now() - ms('7days'))
					}
				}, {
					host: null
				}]
			}, {
				limit: limit,
				skip: offset,
				sort: {
					followersCount: -1
				}
			});

		// Serialize
		res(await Promise.all(users.map(async user =>
			await pack(user, me, { detail: true }))));
	}
});