From d7764faf157cd9545363db95a428f211f23249cc Mon Sep 17 00:00:00 2001 From: Nevo David <me@nevos.io> Date: Thu, 6 Feb 2025 23:15:50 +0700 Subject: [PATCH 1/3] feat: send tests --- .../src/api/routes/webhooks.controller.ts | 26 +++++- .../src/components/webhooks/webhooks.tsx | 81 ++++++++++++++++--- .../prisma/webhooks/webhooks.service.ts | 10 ++- 3 files changed, 102 insertions(+), 15 deletions(-) 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/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 ( <FormProvider {...form}> <form onSubmit={form.handleSubmit(callBack)}> @@ -227,16 +272,32 @@ export const AddOrEditWebhook: FC<{ data?: any; reload: () => void }> = ( isMain={true} /> )} - <Button - type="submit" - className="mt-[24px]" - disabled={ - !form.formState.isValid || - (allIntegrations.value === 'specific' && !integrations?.length) - } - > - Save - </Button> + <div className="flex gap-[10px]"> + <Button + type="submit" + className="mt-[24px]" + disabled={ + !form.formState.isValid || + (allIntegrations.value === 'specific' && + !integrations?.length) + } + > + Save + </Button> + <Button + type="button" + secondary={true} + className="mt-[24px]" + onClick={sendTest} + disabled={ + !form.formState.isValid || + (allIntegrations.value === 'specific' && + !integrations?.length) + } + > + Send Test + </Button> + </div> </div> </div> </form> 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( From d51196c5364a6ba84cadcdb0a403c86fb81f9c6a Mon Sep 17 00:00:00 2001 From: Nevo David <me@nevos.io> Date: Thu, 6 Feb 2025 23:29:38 +0700 Subject: [PATCH 2/3] feat: settings --- .../components/layout/settings.component.tsx | 25 ++++++++++++++++++- .../src/components/layout/top.menu.tsx | 1 - 2 files changed, 24 insertions(+), 2 deletions(-) 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<any> }> = (props) => { const { isGeneral } = useVariables(); @@ -210,8 +211,30 @@ export const SettingsPopup: FC<{ getRef?: Ref<any> }> = (props) => { }; export const SettingsComponent = () => { + const settings = useModals(); + const user = useUser(); + + const openModal = useCallback(() => { + if (user?.tier.current !== 'FREE') { + return; + } + + settings.openModal({ + children: ( + <div className="relative flex gap-[20px] flex-col flex-1 rounded-[4px] border border-customColor6 bg-sixth p-[16px] w-[500px] mx-auto"> + <SettingsPopup /> + </div> + ), + classNames: { + modal: 'bg-transparent text-textColor', + }, + withCloseButton: false, + size: '100%', + }); + }, [user]); + return ( - <Link href="/settings"> + <Link href="/settings" onClick={openModal}> <svg width="40" height="40" diff --git a/apps/frontend/src/components/layout/top.menu.tsx b/apps/frontend/src/components/layout/top.menu.tsx index f4bc2f373..b3483eefc 100644 --- a/apps/frontend/src/components/layout/top.menu.tsx +++ b/apps/frontend/src/components/layout/top.menu.tsx @@ -77,7 +77,6 @@ export const TopMenu: FC = () => { const user = useUser(); const { billingEnabled } = useVariables(); const menuItems = useMenuItems(); - return ( <div className="flex flex-col h-full animate-normalFadeDown order-3 md:order-2 col-span-2 md:col-span-1"> <ul className="gap-0 md:gap-5 flex flex-1 items-center text-[18px]"> From 379704c997c117d68533d57043f9f78b4a234a4a Mon Sep 17 00:00:00 2001 From: Nevo David <me@nevos.io> Date: Fri, 7 Feb 2025 18:33:12 +0700 Subject: [PATCH 3/3] feat: fix --- .../integrations/social/instagram.provider.ts | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) 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 }) {