feat(analytics): Google Analytics・同意モード・一部機能のトラッキング実装 (MisskeyIO#784)
This commit is contained in:
parent
2f4c48bbe6
commit
fcfd004c38
53 changed files with 805 additions and 113 deletions
|
@ -69,6 +69,10 @@ export const meta = {
|
|||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
googleAnalyticsId: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
},
|
||||
swPublickey: {
|
||||
type: 'string',
|
||||
optional: false, nullable: true,
|
||||
|
@ -557,6 +561,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
recaptchaSiteKey: instance.recaptchaSiteKey,
|
||||
enableTurnstile: instance.enableTurnstile,
|
||||
turnstileSiteKey: instance.turnstileSiteKey,
|
||||
googleAnalyticsId: instance.googleAnalyticsId,
|
||||
swPublickey: instance.swPublicKey,
|
||||
themeColor: instance.themeColor,
|
||||
mascotImageUrl: instance.mascotImageUrl,
|
||||
|
|
|
@ -78,6 +78,7 @@ export const paramDef = {
|
|||
enableTurnstile: { type: 'boolean' },
|
||||
turnstileSiteKey: { type: 'string', nullable: true },
|
||||
turnstileSecretKey: { type: 'string', nullable: true },
|
||||
googleAnalyticsId: { type: 'string', nullable: true },
|
||||
sensitiveMediaDetection: { type: 'string', enum: ['none', 'all', 'local', 'remote'] },
|
||||
sensitiveMediaDetectionSensitivity: { type: 'string', enum: ['medium', 'low', 'high', 'veryLow', 'veryHigh'] },
|
||||
setSensitiveFlagAutomatically: { type: 'boolean' },
|
||||
|
@ -374,6 +375,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
set.turnstileSecretKey = ps.turnstileSecretKey;
|
||||
}
|
||||
|
||||
if (ps.googleAnalyticsId !== undefined) {
|
||||
set.googleAnalyticsId = ps.googleAnalyticsId;
|
||||
}
|
||||
|
||||
if (ps.sensitiveMediaDetection !== undefined) {
|
||||
set.sensitiveMediaDetection = ps.sensitiveMediaDetection;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { AnnouncementService } from '@/core/AnnouncementService.js';
|
||||
import { EntityNotFoundError } from "typeorm";
|
||||
import { ApiError } from "../error.js";
|
||||
import { EntityNotFoundError } from 'typeorm';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['meta'],
|
||||
|
|
|
@ -80,7 +80,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
) {
|
||||
super(meta, paramDef, async (ps, me, _token, _file, _cleanup, ip, headers) => {
|
||||
const logger = this.loggerService.getLogger('api:federation:instances');
|
||||
logger.setContext({ params: ps, user: me?.id, ip, headers });
|
||||
logger.setContext({ params: ps, userId: me?.id, ip, headers });
|
||||
logger.info('Requested to fetch federated instances.');
|
||||
|
||||
const query = this.instancesRepository.createQueryBuilder('instance');
|
||||
|
|
|
@ -8,7 +8,9 @@ import type { UserProfilesRepository } from '@/models/_.js';
|
|||
import { Endpoint } from '@/server/api/endpoint-base.js';
|
||||
import { UserEntityService } from '@/core/entities/UserEntityService.js';
|
||||
import { DI } from '@/di-symbols.js';
|
||||
import { ApiError } from '../error.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
import { LoggerService } from '@/core/LoggerService.js';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
export const meta = {
|
||||
tags: ['account'],
|
||||
|
@ -44,11 +46,16 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
@Inject(DI.userProfilesRepository)
|
||||
private userProfilesRepository: UserProfilesRepository,
|
||||
|
||||
private loggerService: LoggerService,
|
||||
private userEntityService: UserEntityService,
|
||||
) {
|
||||
super(meta, paramDef, async (ps, user, token) => {
|
||||
super(meta, paramDef, async (ps, user, token, _file, _cleanup, ip, headers) => {
|
||||
const isSecure = token == null;
|
||||
|
||||
const logger = this.loggerService.getLogger('api:account:i');
|
||||
logger.setContext({ userId: user?.id, username: user?.username, client: isSecure ? 'misskey' : 'app', ip, headers, span: (headers ? headers['x-client-transaction-id'] : undefined) ?? randomUUID() });
|
||||
logger.info('Fetching account information');
|
||||
|
||||
const now = new Date();
|
||||
const today = `${now.getFullYear()}/${now.getMonth() + 1}/${now.getDate()}`;
|
||||
|
||||
|
@ -71,11 +78,18 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
|||
userProfile.loggedInDates = [...userProfile.loggedInDates, today];
|
||||
}
|
||||
|
||||
return await this.userEntityService.pack(userProfile.user!, userProfile.user!, {
|
||||
schema: 'MeDetailed',
|
||||
includeSecrets: isSecure,
|
||||
userProfile,
|
||||
});
|
||||
try {
|
||||
const result = await this.userEntityService.pack(userProfile.user!, userProfile.user!, {
|
||||
schema: 'MeDetailed',
|
||||
includeSecrets: isSecure,
|
||||
userProfile,
|
||||
});
|
||||
logger.info('Returning account information');
|
||||
return result;
|
||||
} catch (error) {
|
||||
logger.error('Failed to pack user entity', { error });
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@ import type { Config } from '@/config.js';
|
|||
import { safeForSql } from '@/misc/safe-for-sql.js';
|
||||
import { AvatarDecorationService } from '@/core/AvatarDecorationService.js';
|
||||
import { notificationRecieveConfig } from '@/models/json-schema/user.js';
|
||||
import { ApiLoggerService } from '../../ApiLoggerService.js';
|
||||
import { ApiError } from '../../error.js';
|
||||
import { IdService } from "@/core/IdService.js";
|
||||
import { ApiLoggerService } from '@/server/api/ApiLoggerService.js';
|
||||
import { ApiError } from '@/server/api/error.js';
|
||||
import { IdService } from '@/core/IdService.js';
|
||||
|
||||
export const meta = {
|
||||
tags: ['account'],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue