diff --git a/apps/backend/src/api/routes/webhooks.controller.ts b/apps/backend/src/api/routes/webhooks.controller.ts index 19a787301..6b341d6ab 100644 --- a/apps/backend/src/api/routes/webhooks.controller.ts +++ b/apps/backend/src/api/routes/webhooks.controller.ts @@ -1,4 +1,13 @@ -import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common'; +import { + Body, + Controller, + Delete, + Get, + Param, + Post, + Put, + Query, +} from '@nestjs/common'; import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request'; import { Organization } from '@prisma/client'; import { ApiTags } from '@nestjs/swagger'; @@ -47,4 +56,19 @@ export class WebhookController { ) { return this._webhooksService.deleteWebhook(org.id, id); } + + @Post('/send') + async sendWebhook(@Body() body: any, @Query('url') url: string) { + try { + await fetch(url, { + method: 'POST', + body: JSON.stringify(body), + headers: { 'Content-Type': 'application/json' }, + }); + } catch (err) { + /** sent **/ + } + + return { send: true }; + } } diff --git a/apps/frontend/src/components/layout/settings.component.tsx b/apps/frontend/src/components/layout/settings.component.tsx index 8a6edf980..3ae40b934 100644 --- a/apps/frontend/src/components/layout/settings.component.tsx +++ b/apps/frontend/src/components/layout/settings.component.tsx @@ -21,6 +21,7 @@ import { useVariables } from '@gitroom/react/helpers/variable.context'; import { PublicComponent } from '@gitroom/frontend/components/public-api/public.component'; import Link from 'next/link'; import { Webhooks } from '@gitroom/frontend/components/webhooks/webhooks'; +import { TopTitle } from '@gitroom/frontend/components/launches/helpers/top.title.component'; export const SettingsPopup: FC<{ getRef?: Ref }> = (props) => { const { isGeneral } = useVariables(); @@ -210,8 +211,30 @@ export const SettingsPopup: FC<{ getRef?: Ref }> = (props) => { }; export const SettingsComponent = () => { + const settings = useModals(); + const user = useUser(); + + const openModal = useCallback(() => { + if (user?.tier.current !== 'FREE') { + return; + } + + settings.openModal({ + children: ( +
+ +
+ ), + classNames: { + modal: 'bg-transparent text-textColor', + }, + withCloseButton: false, + size: '100%', + }); + }, [user]); + return ( - + { const user = useUser(); const { billingEnabled } = useVariables(); const menuItems = useMenuItems(); - return (
    diff --git a/apps/frontend/src/components/webhooks/webhooks.tsx b/apps/frontend/src/components/webhooks/webhooks.tsx index 6d964d99a..a1792854f 100644 --- a/apps/frontend/src/components/webhooks/webhooks.tsx +++ b/apps/frontend/src/components/webhooks/webhooks.tsx @@ -175,6 +175,51 @@ export const AddOrEditWebhook: FC<{ data?: any; reload: () => void }> = ( [data, integrations] ); + const sendTest = useCallback(async () => { + const url = form.getValues('url'); + toast.show('Webhook send', 'success'); + try { + await fetch(`/webhooks/send?url=${encodeURIComponent(url)}`, { + method: 'POST', + headers: { + contentType: 'application/json', + }, + body: JSON.stringify([ + { + id: 'cm6tcts4f0005qcwit25cis26', + content: 'This is the first post to instagram', + publishDate: '2025-02-06T13:09:00.000Z', + releaseURL: 'https://facebook.com/release/release', + state: 'PUBLISHED', + integration: { + id: 'cm6s4uyou0001i2r47pxix6z1', + name: 'test', + providerIdentifier: 'instagram', + picture: 'https://uploads.gitroom.com/F6LSCD8wrrQ.jpeg', + type: 'social', + }, + }, + { + id: 'cm6tcts4f0005qcwit25cis26', + content: 'This is the second post to facebook', + publishDate: '2025-02-06T13:09:00.000Z', + releaseURL: 'https://facebook.com/release2/release2', + state: 'PUBLISHED', + integration: { + id: 'cm6s4uyou0001i2r47pxix6z1', + name: 'test2', + providerIdentifier: 'facebook', + picture: 'https://uploads.gitroom.com/F6LSCD8wrrQ.jpeg', + type: 'social', + }, + }, + ]), + }); + } catch (e: any) { + /** empty **/ + } + }, []); + return (
    @@ -227,16 +272,32 @@ export const AddOrEditWebhook: FC<{ data?: any; reload: () => void }> = ( isMain={true} /> )} - +
    + + +
diff --git a/libraries/nestjs-libraries/src/database/prisma/webhooks/webhooks.service.ts b/libraries/nestjs-libraries/src/database/prisma/webhooks/webhooks.service.ts index d23bed29a..54672b5e2 100644 --- a/libraries/nestjs-libraries/src/database/prisma/webhooks/webhooks.service.ts +++ b/libraries/nestjs-libraries/src/database/prisma/webhooks/webhooks.service.ts @@ -73,10 +73,12 @@ export class WebhooksService { ); } - sendList.push({ - url: webhook.url, - data: toSend, - }); + if (toSend.length) { + sendList.push({ + url: webhook.url, + data: toSend, + }); + } } return Promise.all( diff --git a/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts b/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts index fd787a921..c548a7755 100644 --- a/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts +++ b/libraries/nestjs-libraries/src/integrations/social/instagram.provider.ts @@ -383,21 +383,47 @@ export class InstagramProvider const since = dayjs().subtract(date, 'day').unix(); const { data, ...all } = await ( - await fetch( - `https://graph.facebook.com/v20.0/${id}/insights?metric=follower_count,impressions,reach,profile_views&access_token=${accessToken}&period=day&since=${since}&until=${until}` + await this.fetch( + `https://graph.facebook.com/v20.0/${id}/insights?metric=follower_count,impressions,reach&access_token=${accessToken}&period=day&since=${since}&until=${until}` + ) + ).json(); + + const { data: data2, ...all2 } = await ( + await this.fetch( + `https://graph.facebook.com/v20.0/${id}/insights?metric_type=total_value&metric=likes,comments,shares,saves,replies&access_token=${accessToken}&period=day&since=${since}&until=${until}` ) ).json(); + const analytics = []; - return ( - data?.map((d: any) => ({ + analytics.push( + ...(data?.map((d: any) => ({ label: d.title, percentageChange: 5, data: d.values.map((v: any) => ({ total: v.value, date: dayjs(v.end_time).format('YYYY-MM-DD'), })), - })) || [] + })) || []) + ); + + analytics.push( + ...data2.map((d: any) => ({ + label: d.title, + percentageChange: 5, + data: [ + { + total: d.total_value.value, + date: dayjs().format('YYYY-MM-DD'), + }, + { + total: d.total_value.value, + date: dayjs().add(1, 'day').format('YYYY-MM-DD'), + }, + ], + })) ); + + return analytics; } music(accessToken: string, data: { q: string }) {