From 1e0d372eb58542bfcfcdd397417349611a176915 Mon Sep 17 00:00:00 2001
From: Marie <github@yuugi.dev>
Date: Wed, 2 Oct 2024 17:20:30 +0200
Subject: [PATCH] upd(backend): add support for instance oc urls

---
 .../src/server/api/endpoints/sponsors.ts      | 28 +++++++++++++++++--
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/packages/backend/src/server/api/endpoints/sponsors.ts b/packages/backend/src/server/api/endpoints/sponsors.ts
index 99414e739a..33f9d03367 100644
--- a/packages/backend/src/server/api/endpoints/sponsors.ts
+++ b/packages/backend/src/server/api/endpoints/sponsors.ts
@@ -7,10 +7,11 @@ import { Inject, Injectable } from '@nestjs/common';
 import * as Redis from 'ioredis';
 import { Endpoint } from '@/server/api/endpoint-base.js';
 import { DI } from '@/di-symbols.js';
+import { MetaService } from '@/core/MetaService.js';
 
 export const meta = {
 	tags: ['meta'],
-	description: 'Get Sharkey Sponsors',
+	description: 'Get Sharkey Sponsors or Instance Sponsors',
 
 	requireCredential: false,
 	requireCredentialPrivateMode: false,
@@ -20,6 +21,7 @@ export const paramDef = {
 	type: 'object',
 	properties: {
 		forceUpdate: { type: 'boolean', default: false },
+		instance: { type: 'boolean', default: false },
 	},
 	required: [],
 } as const;
@@ -28,14 +30,15 @@ export const paramDef = {
 export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-disable-line import/no-default-export
 	constructor(
         @Inject(DI.redis) private redisClient: Redis.Redis,
+		private metaService: MetaService,
 	) {
 		super(meta, paramDef, async (ps, me) => {
 			let totalSponsors;
 			const cachedSponsors = await this.redisClient.get('sponsors');	
 
-			if (!ps.forceUpdate && cachedSponsors) {
+			if (!ps.forceUpdate && !ps.instance && cachedSponsors) {
 				totalSponsors = JSON.parse(cachedSponsors);
-			} else {
+			} else if (!ps.instance) {
 				try {
 					const backers = await fetch('https://opencollective.com/sharkey/tiers/backer/all.json').then((response) => response.json());
 					const sponsorsOC = await fetch('https://opencollective.com/sharkey/tiers/sponsor/all.json').then((response) => response.json());
@@ -50,6 +53,25 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				} catch (error) {
 					totalSponsors = [];
 				}
+			} else {
+				try {
+					const meta = await this.metaService.fetch();
+					if (meta.donationUrl && !meta.donationUrl.includes('opencollective.com')) {
+						totalSponsors = [];
+					} else if (meta.donationUrl) {
+						const backers = await fetch(`${meta.donationUrl}/members/users.json`).then((response) => response.json());
+
+						// Merge both together into one array and make sure it only has Active subscriptions
+						const allSponsors = [...backers].filter(sponsor => sponsor.isActive === true && sponsor.role === 'BACKER');
+
+						// Remove possible duplicates
+						totalSponsors = [...new Map(allSponsors.map(v => [v.profile, v])).values()];
+					} else {
+						totalSponsors = [];
+					}
+				} catch (error) {
+					totalSponsors = [];
+				}
 			}
 			return { sponsor_data: totalSponsors };
 		});