vidspotai-shared 1.0.82-dev.0 → 1.0.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/globals/aiModels/enums.d.ts +11 -1
- package/lib/globals/aiModels/enums.d.ts.map +1 -1
- package/lib/globals/aiModels/enums.js +24 -1
- package/lib/globals/aiModels/index.d.ts.map +1 -1
- package/lib/globals/aiModels/index.js +2 -0
- package/lib/globals/aiModels/providers/anthropic.d.ts +12 -0
- package/lib/globals/aiModels/providers/anthropic.d.ts.map +1 -0
- package/lib/globals/aiModels/providers/anthropic.js +88 -0
- package/lib/globals/aiModels/providers/google.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/google.js +115 -10
- package/lib/globals/aiModels/providers/openai.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/openai.js +63 -4
- package/lib/globals/aiModels/tierHelpers.d.ts +12 -0
- package/lib/globals/aiModels/tierHelpers.d.ts.map +1 -1
- package/lib/globals/aiModels/tierHelpers.js +83 -0
- package/lib/globals/aiModels/types.d.ts +19 -0
- package/lib/globals/aiModels/types.d.ts.map +1 -1
- package/lib/globals/types.d.ts +120 -1
- package/lib/globals/types.d.ts.map +1 -1
- package/lib/globals/types.js +135 -1
- package/lib/models/agent.model.d.ts +41 -1
- package/lib/models/agent.model.d.ts.map +1 -1
- package/lib/models/index.d.ts +1 -0
- package/lib/models/index.d.ts.map +1 -1
- package/lib/models/index.js +1 -0
- package/lib/models/social.model.d.ts +180 -0
- package/lib/models/social.model.d.ts.map +1 -0
- package/lib/models/social.model.js +2 -0
- package/lib/models/user.model.d.ts +10 -0
- package/lib/models/user.model.d.ts.map +1 -1
- package/lib/models/video.model.d.ts +6 -0
- package/lib/models/video.model.d.ts.map +1 -1
- package/lib/schemas/brief.schema.d.ts +46 -0
- package/lib/schemas/brief.schema.d.ts.map +1 -1
- package/lib/schemas/brief.schema.js +72 -1
- package/lib/schemas/index.d.ts +1 -0
- package/lib/schemas/index.d.ts.map +1 -1
- package/lib/schemas/index.js +1 -0
- package/lib/schemas/project.schema.d.ts +70 -3
- package/lib/schemas/project.schema.d.ts.map +1 -1
- package/lib/schemas/project.schema.js +12 -0
- package/lib/schemas/social.schema.d.ts +91 -0
- package/lib/schemas/social.schema.d.ts.map +1 -0
- package/lib/schemas/social.schema.js +114 -0
- package/lib/schemas/videoPlan.schema.d.ts +117 -3
- package/lib/schemas/videoPlan.schema.d.ts.map +1 -1
- package/lib/schemas/videoPlan.schema.js +141 -1
- package/lib/services/agent/chatAgent.d.ts +25 -1
- package/lib/services/agent/chatAgent.d.ts.map +1 -1
- package/lib/services/agent/chatAgent.js +145 -9
- package/lib/services/agent/costPreflight.d.ts +11 -1
- package/lib/services/agent/costPreflight.d.ts.map +1 -1
- package/lib/services/agent/costPreflight.js +18 -1
- package/lib/services/agent/covers/coverPlanner.d.ts +41 -0
- package/lib/services/agent/covers/coverPlanner.d.ts.map +1 -0
- package/lib/services/agent/covers/coverPlanner.js +278 -0
- package/lib/services/agent/covers/covers.schema.d.ts +158 -0
- package/lib/services/agent/covers/covers.schema.d.ts.map +1 -0
- package/lib/services/agent/covers/covers.schema.js +166 -0
- package/lib/services/agent/covers/index.d.ts +3 -0
- package/lib/services/agent/covers/index.d.ts.map +1 -0
- package/lib/services/agent/covers/index.js +18 -0
- package/lib/services/agent/critic.d.ts +10 -0
- package/lib/services/agent/critic.d.ts.map +1 -1
- package/lib/services/agent/critic.js +37 -1
- package/lib/services/agent/editClassifier.d.ts +4 -4
- package/lib/services/agent/editClassifier.js +2 -2
- package/lib/services/agent/editExisting/editAssembler.d.ts +78 -0
- package/lib/services/agent/editExisting/editAssembler.d.ts.map +1 -0
- package/lib/services/agent/editExisting/editAssembler.js +172 -0
- package/lib/services/agent/editExisting/editExisting.schema.d.ts +119 -0
- package/lib/services/agent/editExisting/editExisting.schema.d.ts.map +1 -0
- package/lib/services/agent/editExisting/editExisting.schema.js +157 -0
- package/lib/services/agent/editExisting/highlightPicker.d.ts +48 -0
- package/lib/services/agent/editExisting/highlightPicker.d.ts.map +1 -0
- package/lib/services/agent/editExisting/highlightPicker.js +199 -0
- package/lib/services/agent/editExisting/index.d.ts +4 -0
- package/lib/services/agent/editExisting/index.d.ts.map +1 -0
- package/lib/services/agent/editExisting/index.js +19 -0
- package/lib/services/agent/eval/recorder.d.ts +13 -1
- package/lib/services/agent/eval/recorder.d.ts.map +1 -1
- package/lib/services/agent/eval/recorder.js +59 -0
- package/lib/services/agent/eval/seedBriefs.d.ts +4 -3
- package/lib/services/agent/eval/seedBriefs.d.ts.map +1 -1
- package/lib/services/agent/eval/seedBriefs.js +283 -3
- package/lib/services/agent/eval/types.d.ts +10 -0
- package/lib/services/agent/eval/types.d.ts.map +1 -1
- package/lib/services/agent/executor/core.d.ts +70 -0
- package/lib/services/agent/executor/core.d.ts.map +1 -0
- package/lib/services/agent/executor/core.js +250 -0
- package/lib/services/agent/executor/duration.d.ts +20 -0
- package/lib/services/agent/executor/duration.d.ts.map +1 -0
- package/lib/services/agent/executor/duration.js +46 -0
- package/lib/services/agent/executor/index.d.ts +15 -0
- package/lib/services/agent/executor/index.d.ts.map +1 -0
- package/lib/services/agent/executor/index.js +32 -0
- package/lib/services/agent/executor/types.d.ts +183 -0
- package/lib/services/agent/executor/types.d.ts.map +1 -0
- package/lib/services/agent/executor/types.js +29 -0
- package/lib/services/agent/executor/visual.d.ts +32 -0
- package/lib/services/agent/executor/visual.d.ts.map +1 -0
- package/lib/services/agent/executor/visual.js +400 -0
- package/lib/services/agent/executor/voice.d.ts +17 -0
- package/lib/services/agent/executor/voice.d.ts.map +1 -0
- package/lib/services/agent/executor/voice.js +119 -0
- package/lib/services/agent/extendChain.d.ts +101 -0
- package/lib/services/agent/extendChain.d.ts.map +1 -0
- package/lib/services/agent/extendChain.js +177 -0
- package/lib/services/agent/index.d.ts +11 -1
- package/lib/services/agent/index.d.ts.map +1 -1
- package/lib/services/agent/index.js +11 -1
- package/lib/services/agent/llmCaller.d.ts +7 -8
- package/lib/services/agent/llmCaller.d.ts.map +1 -1
- package/lib/services/agent/llmCallerAnthropic.d.ts +44 -31
- package/lib/services/agent/llmCallerAnthropic.d.ts.map +1 -1
- package/lib/services/agent/llmCallerAnthropic.js +135 -60
- package/lib/services/agent/llmCallerFactory.d.ts +34 -0
- package/lib/services/agent/llmCallerFactory.d.ts.map +1 -0
- package/lib/services/agent/llmCallerFactory.js +31 -0
- package/lib/services/agent/llmCallerGemini.d.ts +62 -0
- package/lib/services/agent/llmCallerGemini.d.ts.map +1 -0
- package/lib/services/agent/llmCallerGemini.js +235 -0
- package/lib/services/agent/llmCallerOpenai.d.ts +56 -0
- package/lib/services/agent/llmCallerOpenai.d.ts.map +1 -0
- package/lib/services/agent/llmCallerOpenai.js +230 -0
- package/lib/services/agent/llmCallerRegistry.d.ts.map +1 -1
- package/lib/services/agent/llmCallerRegistry.js +7 -7
- package/lib/services/agent/llmCallerRouting.d.ts +63 -0
- package/lib/services/agent/llmCallerRouting.d.ts.map +1 -0
- package/lib/services/agent/llmCallerRouting.js +124 -0
- package/lib/services/agent/llmModelRegistry.d.ts +59 -0
- package/lib/services/agent/llmModelRegistry.d.ts.map +1 -0
- package/lib/services/agent/llmModelRegistry.js +168 -0
- package/lib/services/agent/llmRetry.d.ts +57 -0
- package/lib/services/agent/llmRetry.d.ts.map +1 -0
- package/lib/services/agent/llmRetry.js +102 -0
- package/lib/services/agent/modelRouter.d.ts +3 -3
- package/lib/services/agent/modelRouter.d.ts.map +1 -1
- package/lib/services/agent/modelRouter.js +27 -13
- package/lib/services/agent/planMutations.d.ts +54 -1
- package/lib/services/agent/planMutations.d.ts.map +1 -1
- package/lib/services/agent/planMutations.js +78 -0
- package/lib/services/agent/planner/Planner.d.ts +0 -17
- package/lib/services/agent/planner/Planner.d.ts.map +1 -1
- package/lib/services/agent/planner/Planner.js +67 -303
- package/lib/services/agent/planner/overlayRegen.d.ts +38 -0
- package/lib/services/agent/planner/overlayRegen.d.ts.map +1 -0
- package/lib/services/agent/planner/overlayRegen.js +145 -0
- package/lib/services/agent/planner/plannerMessages.d.ts +34 -0
- package/lib/services/agent/planner/plannerMessages.d.ts.map +1 -0
- package/lib/services/agent/planner/plannerMessages.js +185 -0
- package/lib/services/agent/planner/promptSections.d.ts +12 -0
- package/lib/services/agent/planner/promptSections.d.ts.map +1 -1
- package/lib/services/agent/planner/promptSections.js +57 -0
- package/lib/services/agent/planner/scriptFirstPlanner.d.ts +35 -0
- package/lib/services/agent/planner/scriptFirstPlanner.d.ts.map +1 -0
- package/lib/services/agent/planner/scriptFirstPlanner.js +140 -0
- package/lib/services/agent/planner/structuralRules.d.ts +10 -0
- package/lib/services/agent/planner/structuralRules.d.ts.map +1 -1
- package/lib/services/agent/planner/structuralRules.js +92 -9
- package/lib/services/agent/planner/validators.d.ts +18 -0
- package/lib/services/agent/planner/validators.d.ts.map +1 -1
- package/lib/services/agent/planner/validators.js +97 -0
- package/lib/services/agent/planner.d.ts +2 -1
- package/lib/services/agent/planner.d.ts.map +1 -1
- package/lib/services/agent/planner.js +5 -1
- package/lib/services/agent/priorProject.d.ts +26 -0
- package/lib/services/agent/priorProject.d.ts.map +1 -0
- package/lib/services/agent/priorProject.js +51 -0
- package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
- package/lib/services/agent/providerFallback/chains.js +27 -15
- package/lib/services/agent/repurpose/index.d.ts +3 -0
- package/lib/services/agent/repurpose/index.d.ts.map +1 -0
- package/lib/services/agent/repurpose/index.js +18 -0
- package/lib/services/agent/repurpose/repurpose.schema.d.ts +132 -0
- package/lib/services/agent/repurpose/repurpose.schema.d.ts.map +1 -0
- package/lib/services/agent/repurpose/repurpose.schema.js +144 -0
- package/lib/services/agent/repurpose/shortsPicker.d.ts +25 -0
- package/lib/services/agent/repurpose/shortsPicker.d.ts.map +1 -0
- package/lib/services/agent/repurpose/shortsPicker.js +218 -0
- package/lib/services/agent/runHelpers.d.ts +21 -2
- package/lib/services/agent/runHelpers.d.ts.map +1 -1
- package/lib/services/agent/runHelpers.js +71 -2
- package/lib/services/agent/tools/animateImage.tool.d.ts +1 -0
- package/lib/services/agent/tools/animateImage.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/animateImage.tool.js +12 -0
- package/lib/services/agent/tools/chapterOutline.tool.d.ts +42 -0
- package/lib/services/agent/tools/chapterOutline.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/chapterOutline.tool.js +115 -0
- package/lib/services/agent/tools/composeScene.tool.d.ts +65 -2
- package/lib/services/agent/tools/composeScene.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/estimateCost.tool.d.ts +28 -1
- package/lib/services/agent/tools/estimateCost.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/estimateCost.tool.js +55 -7
- package/lib/services/agent/tools/extendVideo.tool.d.ts +26 -0
- package/lib/services/agent/tools/extendVideo.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/extendVideo.tool.js +149 -0
- package/lib/services/agent/tools/generateScript.tool.d.ts +184 -0
- package/lib/services/agent/tools/generateScript.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/generateScript.tool.js +123 -0
- package/lib/services/agent/tools/generateVideo.tool.d.ts +1 -0
- package/lib/services/agent/tools/generateVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/generateVideo.tool.js +20 -1
- package/lib/services/agent/tools/index.d.ts +4 -0
- package/lib/services/agent/tools/index.d.ts.map +1 -1
- package/lib/services/agent/tools/index.js +4 -0
- package/lib/services/agent/tools/matchBrollToScript.tool.d.ts +50 -0
- package/lib/services/agent/tools/matchBrollToScript.tool.d.ts.map +1 -0
- package/lib/services/agent/tools/matchBrollToScript.tool.js +139 -0
- package/lib/services/agent/tools/planVideo.tool.d.ts +57 -1
- package/lib/services/agent/tools/planVideo.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/planVideo.tool.js +3 -3
- package/lib/services/agent/tools/render.tool.d.ts +22 -1
- package/lib/services/agent/tools/render.tool.d.ts.map +1 -1
- package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
- package/lib/services/aiGen/aiGenFactory.service.js +18 -3
- package/lib/services/aiGen/helpers.d.ts +8 -0
- package/lib/services/aiGen/helpers.d.ts.map +1 -1
- package/lib/services/aiGen/helpers.js +12 -0
- package/lib/services/aiGen/providers/anthropic/anthropic.service.d.ts +26 -0
- package/lib/services/aiGen/providers/anthropic/anthropic.service.d.ts.map +1 -0
- package/lib/services/aiGen/providers/anthropic/anthropic.service.js +95 -0
- package/lib/services/aiGen/providers/google/google.service.d.ts +25 -1
- package/lib/services/aiGen/providers/google/google.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/google/google.service.js +136 -237
- package/lib/services/aiGen/providers/google/googleApiKeys.d.ts +71 -0
- package/lib/services/aiGen/providers/google/googleApiKeys.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleApiKeys.js +137 -0
- package/lib/services/aiGen/providers/google/googleErrors.d.ts +13 -0
- package/lib/services/aiGen/providers/google/googleErrors.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleErrors.js +102 -0
- package/lib/services/aiGen/providers/google/googleFetch.d.ts +8 -0
- package/lib/services/aiGen/providers/google/googleFetch.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleFetch.js +96 -0
- package/lib/services/aiGen/providers/google/googleKeyPool.d.ts +52 -0
- package/lib/services/aiGen/providers/google/googleKeyPool.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleKeyPool.js +129 -0
- package/lib/services/aiGen/providers/google/googleMusic.d.ts +15 -0
- package/lib/services/aiGen/providers/google/googleMusic.d.ts.map +1 -0
- package/lib/services/aiGen/providers/google/googleMusic.js +77 -0
- package/lib/services/aiGen/providers/kling/kling.service.d.ts +7 -3
- package/lib/services/aiGen/providers/kling/kling.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/kling/kling.service.js +23 -367
- package/lib/services/aiGen/providers/kling/klingCredits.d.ts +9 -0
- package/lib/services/aiGen/providers/kling/klingCredits.d.ts.map +1 -0
- package/lib/services/aiGen/providers/kling/klingCredits.js +63 -0
- package/lib/services/aiGen/providers/kling/klingRequests.d.ts +32 -0
- package/lib/services/aiGen/providers/kling/klingRequests.d.ts.map +1 -0
- package/lib/services/aiGen/providers/kling/klingRequests.js +194 -0
- package/lib/services/aiGen/providers/kling/klingStatus.d.ts +16 -0
- package/lib/services/aiGen/providers/kling/klingStatus.d.ts.map +1 -0
- package/lib/services/aiGen/providers/kling/klingStatus.js +173 -0
- package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/pixverse/pixverse.service.js +7 -1
- package/lib/services/bullmq.service.d.ts +61 -0
- package/lib/services/bullmq.service.d.ts.map +1 -1
- package/lib/services/bullmq.service.js +124 -2
- package/lib/services/crypto/index.d.ts +2 -0
- package/lib/services/crypto/index.d.ts.map +1 -0
- package/lib/services/crypto/index.js +17 -0
- package/lib/services/crypto/tokenVault.d.ts +47 -0
- package/lib/services/crypto/tokenVault.d.ts.map +1 -0
- package/lib/services/crypto/tokenVault.js +179 -0
- package/lib/services/editor/captionStyleHint.d.ts +3 -0
- package/lib/services/editor/captionStyleHint.d.ts.map +1 -0
- package/lib/services/editor/captionStyleHint.js +112 -0
- package/lib/services/editor/planToProject.d.ts +7 -66
- package/lib/services/editor/planToProject.d.ts.map +1 -1
- package/lib/services/editor/planToProject.helpers.d.ts +40 -0
- package/lib/services/editor/planToProject.helpers.d.ts.map +1 -0
- package/lib/services/editor/planToProject.helpers.js +177 -0
- package/lib/services/editor/planToProject.js +197 -180
- package/lib/services/editor/planToProject.types.d.ts +94 -0
- package/lib/services/editor/planToProject.types.d.ts.map +1 -0
- package/lib/services/editor/planToProject.types.js +2 -0
- package/lib/services/firestore.service.d.ts +5 -0
- package/lib/services/firestore.service.d.ts.map +1 -1
- package/lib/services/firestore.service.js +13 -0
- package/lib/services/index.d.ts +13 -0
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/index.js +13 -0
- package/lib/services/promptEnhancer/index.d.ts +18 -0
- package/lib/services/promptEnhancer/index.d.ts.map +1 -0
- package/lib/services/promptEnhancer/index.js +33 -0
- package/lib/services/promptEnhancer/models.d.ts +54 -0
- package/lib/services/promptEnhancer/models.d.ts.map +1 -0
- package/lib/services/promptEnhancer/models.js +37 -0
- package/lib/services/promptEnhancer/profiles/agent.profile.d.ts +14 -0
- package/lib/services/promptEnhancer/profiles/agent.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/agent.profile.js +40 -0
- package/lib/services/promptEnhancer/profiles/avatar.profile.d.ts +13 -0
- package/lib/services/promptEnhancer/profiles/avatar.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/avatar.profile.js +40 -0
- package/lib/services/promptEnhancer/profiles/base.d.ts +28 -0
- package/lib/services/promptEnhancer/profiles/base.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/base.js +35 -0
- package/lib/services/promptEnhancer/profiles/image.profile.d.ts +11 -0
- package/lib/services/promptEnhancer/profiles/image.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/image.profile.js +42 -0
- package/lib/services/promptEnhancer/profiles/index.d.ts +12 -0
- package/lib/services/promptEnhancer/profiles/index.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/index.js +33 -0
- package/lib/services/promptEnhancer/profiles/video.profile.d.ts +15 -0
- package/lib/services/promptEnhancer/profiles/video.profile.d.ts.map +1 -0
- package/lib/services/promptEnhancer/profiles/video.profile.js +81 -0
- package/lib/services/promptEnhancer/promptEnhancer.service.d.ts +45 -0
- package/lib/services/promptEnhancer/promptEnhancer.service.d.ts.map +1 -0
- package/lib/services/promptEnhancer/promptEnhancer.service.js +157 -0
- package/lib/services/promptEnhancer/schema.d.ts +19 -0
- package/lib/services/promptEnhancer/schema.d.ts.map +1 -0
- package/lib/services/promptEnhancer/schema.js +43 -0
- package/lib/services/promptEnhancer/types.d.ts +112 -0
- package/lib/services/promptEnhancer/types.d.ts.map +1 -0
- package/lib/services/promptEnhancer/types.js +2 -0
- package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts +60 -5
- package/lib/services/rateLimiter/distributedRateLimiter.service.d.ts.map +1 -1
- package/lib/services/rateLimiter/distributedRateLimiter.service.js +184 -16
- package/lib/services/socialAI/captionGen.d.ts +81 -0
- package/lib/services/socialAI/captionGen.d.ts.map +1 -0
- package/lib/services/socialAI/captionGen.js +206 -0
- package/lib/services/socialAI/hookScore.d.ts +85 -0
- package/lib/services/socialAI/hookScore.d.ts.map +1 -0
- package/lib/services/socialAI/hookScore.js +170 -0
- package/lib/services/socialAI/index.d.ts +3 -0
- package/lib/services/socialAI/index.d.ts.map +1 -0
- package/lib/services/socialAI/index.js +18 -0
- package/lib/services/socialAccounts/index.d.ts +2 -0
- package/lib/services/socialAccounts/index.d.ts.map +1 -0
- package/lib/services/socialAccounts/index.js +17 -0
- package/lib/services/socialAccounts/socialAccountService.d.ts +25 -0
- package/lib/services/socialAccounts/socialAccountService.d.ts.map +1 -0
- package/lib/services/socialAccounts/socialAccountService.js +105 -0
- package/lib/services/socialEngage/factory.d.ts +7 -0
- package/lib/services/socialEngage/factory.d.ts.map +1 -0
- package/lib/services/socialEngage/factory.js +25 -0
- package/lib/services/socialEngage/index.d.ts +6 -0
- package/lib/services/socialEngage/index.d.ts.map +1 -0
- package/lib/services/socialEngage/index.js +21 -0
- package/lib/services/socialEngage/meta.engage.d.ts +17 -0
- package/lib/services/socialEngage/meta.engage.d.ts.map +1 -0
- package/lib/services/socialEngage/meta.engage.js +128 -0
- package/lib/services/socialEngage/metaWebhook.d.ts +50 -0
- package/lib/services/socialEngage/metaWebhook.d.ts.map +1 -0
- package/lib/services/socialEngage/metaWebhook.js +93 -0
- package/lib/services/socialEngage/types.d.ts +72 -0
- package/lib/services/socialEngage/types.d.ts.map +1 -0
- package/lib/services/socialEngage/types.js +10 -0
- package/lib/services/socialEngage/youtube.engage.d.ts +9 -0
- package/lib/services/socialEngage/youtube.engage.d.ts.map +1 -0
- package/lib/services/socialEngage/youtube.engage.js +87 -0
- package/lib/services/socialFormat/aspectGeometry.d.ts +74 -0
- package/lib/services/socialFormat/aspectGeometry.d.ts.map +1 -0
- package/lib/services/socialFormat/aspectGeometry.js +135 -0
- package/lib/services/socialFormat/index.d.ts +2 -0
- package/lib/services/socialFormat/index.d.ts.map +1 -0
- package/lib/services/socialFormat/index.js +19 -0
- package/lib/services/socialInsights/index.d.ts +3 -0
- package/lib/services/socialInsights/index.d.ts.map +1 -0
- package/lib/services/socialInsights/index.js +18 -0
- package/lib/services/socialInsights/recommendations.d.ts +131 -0
- package/lib/services/socialInsights/recommendations.d.ts.map +1 -0
- package/lib/services/socialInsights/recommendations.js +277 -0
- package/lib/services/socialInsights/timeBuckets.d.ts +35 -0
- package/lib/services/socialInsights/timeBuckets.d.ts.map +1 -0
- package/lib/services/socialInsights/timeBuckets.js +78 -0
- package/lib/services/socialMetrics/factory.d.ts +5 -0
- package/lib/services/socialMetrics/factory.d.ts.map +1 -0
- package/lib/services/socialMetrics/factory.js +24 -0
- package/lib/services/socialMetrics/index.d.ts +6 -0
- package/lib/services/socialMetrics/index.d.ts.map +1 -0
- package/lib/services/socialMetrics/index.js +21 -0
- package/lib/services/socialMetrics/meta.metrics.d.ts +22 -0
- package/lib/services/socialMetrics/meta.metrics.d.ts.map +1 -0
- package/lib/services/socialMetrics/meta.metrics.js +137 -0
- package/lib/services/socialMetrics/tiktok.metrics.d.ts +8 -0
- package/lib/services/socialMetrics/tiktok.metrics.d.ts.map +1 -0
- package/lib/services/socialMetrics/tiktok.metrics.js +43 -0
- package/lib/services/socialMetrics/types.d.ts +54 -0
- package/lib/services/socialMetrics/types.d.ts.map +1 -0
- package/lib/services/socialMetrics/types.js +2 -0
- package/lib/services/socialMetrics/youtube.metrics.d.ts +8 -0
- package/lib/services/socialMetrics/youtube.metrics.d.ts.map +1 -0
- package/lib/services/socialMetrics/youtube.metrics.js +43 -0
- package/lib/services/socialOAuth/factory.d.ts +7 -0
- package/lib/services/socialOAuth/factory.d.ts.map +1 -0
- package/lib/services/socialOAuth/factory.js +42 -0
- package/lib/services/socialOAuth/index.d.ts +11 -0
- package/lib/services/socialOAuth/index.d.ts.map +1 -0
- package/lib/services/socialOAuth/index.js +26 -0
- package/lib/services/socialOAuth/linkedin.oauth.d.ts +14 -0
- package/lib/services/socialOAuth/linkedin.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/linkedin.oauth.js +127 -0
- package/lib/services/socialOAuth/meta.oauth.d.ts +31 -0
- package/lib/services/socialOAuth/meta.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/meta.oauth.js +214 -0
- package/lib/services/socialOAuth/oauthState.d.ts +14 -0
- package/lib/services/socialOAuth/oauthState.d.ts.map +1 -0
- package/lib/services/socialOAuth/oauthState.js +66 -0
- package/lib/services/socialOAuth/pinterest.oauth.d.ts +15 -0
- package/lib/services/socialOAuth/pinterest.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/pinterest.oauth.js +126 -0
- package/lib/services/socialOAuth/threads.oauth.d.ts +14 -0
- package/lib/services/socialOAuth/threads.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/threads.oauth.js +129 -0
- package/lib/services/socialOAuth/tiktok.oauth.d.ts +15 -0
- package/lib/services/socialOAuth/tiktok.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/tiktok.oauth.js +151 -0
- package/lib/services/socialOAuth/types.d.ts +67 -0
- package/lib/services/socialOAuth/types.d.ts.map +1 -0
- package/lib/services/socialOAuth/types.js +2 -0
- package/lib/services/socialOAuth/x.oauth.d.ts +17 -0
- package/lib/services/socialOAuth/x.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/x.oauth.js +134 -0
- package/lib/services/socialOAuth/youtube.oauth.d.ts +15 -0
- package/lib/services/socialOAuth/youtube.oauth.d.ts.map +1 -0
- package/lib/services/socialOAuth/youtube.oauth.js +156 -0
- package/lib/services/socialPublish/factory.d.ts +5 -0
- package/lib/services/socialPublish/factory.d.ts.map +1 -0
- package/lib/services/socialPublish/factory.js +32 -0
- package/lib/services/socialPublish/index.d.ts +10 -0
- package/lib/services/socialPublish/index.d.ts.map +1 -0
- package/lib/services/socialPublish/index.js +25 -0
- package/lib/services/socialPublish/linkedin.publish.d.ts +9 -0
- package/lib/services/socialPublish/linkedin.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/linkedin.publish.js +143 -0
- package/lib/services/socialPublish/meta.publish.d.ts +28 -0
- package/lib/services/socialPublish/meta.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/meta.publish.js +149 -0
- package/lib/services/socialPublish/pinterest.publish.d.ts +13 -0
- package/lib/services/socialPublish/pinterest.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/pinterest.publish.js +130 -0
- package/lib/services/socialPublish/threads.publish.d.ts +12 -0
- package/lib/services/socialPublish/threads.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/threads.publish.js +96 -0
- package/lib/services/socialPublish/tiktok.publish.d.ts +13 -0
- package/lib/services/socialPublish/tiktok.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/tiktok.publish.js +118 -0
- package/lib/services/socialPublish/types.d.ts +47 -0
- package/lib/services/socialPublish/types.d.ts.map +1 -0
- package/lib/services/socialPublish/types.js +2 -0
- package/lib/services/socialPublish/x.publish.d.ts +12 -0
- package/lib/services/socialPublish/x.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/x.publish.js +147 -0
- package/lib/services/socialPublish/youtube.publish.d.ts +9 -0
- package/lib/services/socialPublish/youtube.publish.d.ts.map +1 -0
- package/lib/services/socialPublish/youtube.publish.js +107 -0
- package/lib/services/stock/index.d.ts +2 -0
- package/lib/services/stock/index.d.ts.map +1 -0
- package/lib/services/stock/index.js +17 -0
- package/lib/services/stock/realPersonSafety.d.ts +99 -0
- package/lib/services/stock/realPersonSafety.d.ts.map +1 -0
- package/lib/services/stock/realPersonSafety.js +248 -0
- package/lib/services/translation/index.d.ts +2 -0
- package/lib/services/translation/index.d.ts.map +1 -0
- package/lib/services/translation/index.js +9 -0
- package/lib/services/translation/translation.service.d.ts +50 -0
- package/lib/services/translation/translation.service.d.ts.map +1 -0
- package/lib/services/translation/translation.service.js +211 -0
- package/lib/utils/helpers.d.ts +2 -4
- package/lib/utils/helpers.d.ts.map +1 -1
- package/lib/utils/helpers.js +9 -63
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/index.js +1 -0
- package/lib/utils/renderTier.d.ts +26 -0
- package/lib/utils/renderTier.d.ts.map +1 -0
- package/lib/utils/renderTier.js +34 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookScore.d.ts","sourceRoot":"","sources":["../../../src/services/socialAI/hookScore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGtD;;;;;;;;;;;;;;;GAeG;AAEH,iEAAiE;AACjE,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,mEAAmE;AACnE,MAAM,WAAW,mBAAmB;IAClC,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,oEAAoE;AACpE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAErD,mDAAmD;AACnD,MAAM,WAAW,UAAU;IACzB,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,OAAO,EAAE,WAAW,CAAC;IACrB,6BAA6B;IAC7B,SAAS,EAAE,mBAAmB,CAAC;IAC/B,sCAAsC;IACtC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,0DAA0D;IAC1D,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,8EAA8E;AAC9E,MAAM,MAAM,YAAY,GAAG,CACzB,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,KAC1D,OAAO,CAAC,MAAM,CAAC,CAAC;AAkBrB,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAI1D;AA+BD,qEAAqE;AACrE,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,iBAAiB,GACrB,KAAK,CAAC;IAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CA2CrD;AAYD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CA8CtD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,YAAY,EACjB,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,UAAU,CAAC,CAIrB"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.verdictForScore = verdictForScore;
|
|
4
|
+
exports.buildHookScorePrompt = buildHookScorePrompt;
|
|
5
|
+
exports.parseHookScore = parseHookScore;
|
|
6
|
+
exports.scoreHookCore = scoreHookCore;
|
|
7
|
+
const types_1 = require("../../globals/types");
|
|
8
|
+
const captionGen_1 = require("./captionGen");
|
|
9
|
+
const DRIVER_KEYS = [
|
|
10
|
+
"attention",
|
|
11
|
+
"clarity",
|
|
12
|
+
"curiosity",
|
|
13
|
+
"relevance",
|
|
14
|
+
"platformFit",
|
|
15
|
+
];
|
|
16
|
+
const MAX_HOOK_INPUT = 600;
|
|
17
|
+
const MAX_BULLET = 160;
|
|
18
|
+
const MAX_BULLETS = 4;
|
|
19
|
+
const MAX_REWRITE = 280;
|
|
20
|
+
const MAX_REWRITES = 3;
|
|
21
|
+
const VALID_PROVIDERS = new Set(Object.values(types_1.ESocialProvider));
|
|
22
|
+
/** Verdict bands: <40 weak, <70 okay, ≥70 strong. */
|
|
23
|
+
function verdictForScore(score) {
|
|
24
|
+
if (score < 40)
|
|
25
|
+
return "weak";
|
|
26
|
+
if (score < 70)
|
|
27
|
+
return "okay";
|
|
28
|
+
return "strong";
|
|
29
|
+
}
|
|
30
|
+
function clampScore(raw) {
|
|
31
|
+
const n = typeof raw === "number" ? raw : Number(raw);
|
|
32
|
+
if (!Number.isFinite(n))
|
|
33
|
+
return 0;
|
|
34
|
+
return Math.max(0, Math.min(100, Math.round(n)));
|
|
35
|
+
}
|
|
36
|
+
/** Clamp + trim a free-text bullet to one tidy line. */
|
|
37
|
+
function clampBullet(text, max) {
|
|
38
|
+
if (typeof text !== "string")
|
|
39
|
+
return "";
|
|
40
|
+
return text.replace(/\s+/g, " ").trim().slice(0, max);
|
|
41
|
+
}
|
|
42
|
+
/** Normalize a string list: trim, drop empties, dedupe, cap length + count. */
|
|
43
|
+
function normalizeList(raw, maxLen, maxCount) {
|
|
44
|
+
if (!Array.isArray(raw))
|
|
45
|
+
return [];
|
|
46
|
+
const seen = new Set();
|
|
47
|
+
const out = [];
|
|
48
|
+
for (const item of raw) {
|
|
49
|
+
const s = clampBullet(item, maxLen);
|
|
50
|
+
if (!s)
|
|
51
|
+
continue;
|
|
52
|
+
const key = s.toLowerCase();
|
|
53
|
+
if (seen.has(key))
|
|
54
|
+
continue;
|
|
55
|
+
seen.add(key);
|
|
56
|
+
out.push(s);
|
|
57
|
+
if (out.length >= maxCount)
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
/** Build the chat prompt for a hook-score request. Pure — no I/O. */
|
|
63
|
+
function buildHookScorePrompt(ctx) {
|
|
64
|
+
const lang = (ctx.language || "en").trim();
|
|
65
|
+
const provider = ctx.provider && VALID_PROVIDERS.has(ctx.provider) ? ctx.provider : undefined;
|
|
66
|
+
const platformNote = provider
|
|
67
|
+
? `Target platform: ${provider}. ${captionGen_1.PLATFORM_COPY_HINTS[provider].note}`
|
|
68
|
+
: "No specific platform — judge against general short-form video norms.";
|
|
69
|
+
const about = ctx.videoSummary
|
|
70
|
+
? `What the video is actually about (judge RELEVANCE against this — penalize bait that the video can't pay off):\n${ctx.videoSummary.slice(0, 1200)}`
|
|
71
|
+
: "The video's content is unknown — judge relevance only on internal coherence of the hook.";
|
|
72
|
+
const system = "You are a short-form video growth expert who predicts how well a hook " +
|
|
73
|
+
"will perform. You grade hooks against proven engagement drivers: " +
|
|
74
|
+
"scroll-stopping ATTENTION, instant CLARITY, a CURIOSITY gap, RELEVANCE to " +
|
|
75
|
+
"the actual content (no clickbait the video can't deliver), and native " +
|
|
76
|
+
"PLATFORM FIT. You are calibrated and honest — most hooks are mediocre; " +
|
|
77
|
+
"reserve 80+ for genuinely scroll-stopping copy. You always respond in the " +
|
|
78
|
+
`requested language (${lang}) for the prose fields and rewrites. You reply ` +
|
|
79
|
+
"with ONLY a single JSON object — no prose, no code fences.";
|
|
80
|
+
const user = `Grade this hook and propose stronger rewrites. Write prose + rewrites in language "${lang}".\n\n` +
|
|
81
|
+
`HOOK:\n"""${ctx.hook.slice(0, MAX_HOOK_INPUT)}"""\n\n` +
|
|
82
|
+
`${platformNote}\n\n${about}\n\n` +
|
|
83
|
+
"Score the hook 0-100 overall and 0-100 on each driver. Give 1-3 short " +
|
|
84
|
+
"strengths, 1-3 short actionable issues, and 2-3 rewrites that keep the " +
|
|
85
|
+
"topic but hit harder (each a complete, ready-to-use hook). Do not invent " +
|
|
86
|
+
"facts the video can't support.\n\n" +
|
|
87
|
+
"Reply with ONLY this JSON shape:\n" +
|
|
88
|
+
"{\n" +
|
|
89
|
+
' "score": 0,\n' +
|
|
90
|
+
' "breakdown": { "attention": 0, "clarity": 0, "curiosity": 0, "relevance": 0, "platformFit": 0 },\n' +
|
|
91
|
+
' "strengths": ["..."],\n' +
|
|
92
|
+
' "issues": ["..."],\n' +
|
|
93
|
+
' "rewrites": ["...", "..."]\n' +
|
|
94
|
+
"}";
|
|
95
|
+
return [
|
|
96
|
+
{ role: "system", content: system },
|
|
97
|
+
{ role: "user", content: user },
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
/** Strip a ```json … ``` fence the model may wrap the object in. */
|
|
101
|
+
function stripCodeFence(raw) {
|
|
102
|
+
const t = raw.trim();
|
|
103
|
+
if (!t.startsWith("```"))
|
|
104
|
+
return t;
|
|
105
|
+
return t
|
|
106
|
+
.replace(/^```(?:json)?\s*/i, "")
|
|
107
|
+
.replace(/\s*```$/, "")
|
|
108
|
+
.trim();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Parse + validate + clamp the model's JSON into an `IHookScore`. Defensive:
|
|
112
|
+
* malformed JSON degrades to a neutral 50 with empty coaching rather than
|
|
113
|
+
* throwing, so the composer always renders something. The verdict is ALWAYS
|
|
114
|
+
* recomputed from the clamped score (never trusted from the model) so the band
|
|
115
|
+
* and number can't disagree.
|
|
116
|
+
*/
|
|
117
|
+
function parseHookScore(raw) {
|
|
118
|
+
let obj = null;
|
|
119
|
+
try {
|
|
120
|
+
const parsed = JSON.parse(stripCodeFence(raw));
|
|
121
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
122
|
+
obj = parsed;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
obj = null;
|
|
127
|
+
}
|
|
128
|
+
if (!obj) {
|
|
129
|
+
return {
|
|
130
|
+
score: 50,
|
|
131
|
+
verdict: verdictForScore(50),
|
|
132
|
+
breakdown: {
|
|
133
|
+
attention: 50,
|
|
134
|
+
clarity: 50,
|
|
135
|
+
curiosity: 50,
|
|
136
|
+
relevance: 50,
|
|
137
|
+
platformFit: 50,
|
|
138
|
+
},
|
|
139
|
+
strengths: [],
|
|
140
|
+
issues: [],
|
|
141
|
+
rewrites: [],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const score = clampScore(obj.score);
|
|
145
|
+
const rawBreakdown = obj.breakdown && typeof obj.breakdown === "object"
|
|
146
|
+
? obj.breakdown
|
|
147
|
+
: {};
|
|
148
|
+
const breakdown = DRIVER_KEYS.reduce((acc, k) => {
|
|
149
|
+
acc[k] = clampScore(rawBreakdown[k]);
|
|
150
|
+
return acc;
|
|
151
|
+
}, {});
|
|
152
|
+
return {
|
|
153
|
+
score,
|
|
154
|
+
verdict: verdictForScore(score),
|
|
155
|
+
breakdown,
|
|
156
|
+
strengths: normalizeList(obj.strengths, MAX_BULLET, MAX_BULLETS),
|
|
157
|
+
issues: normalizeList(obj.issues, MAX_BULLET, MAX_BULLETS),
|
|
158
|
+
rewrites: normalizeList(obj.rewrites, MAX_REWRITE, MAX_REWRITES),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Score a hook with the LLM injected (testable). Builds the prompt, calls the
|
|
163
|
+
* model, parses + clamps. Never throws on a bad model response — degrades to a
|
|
164
|
+
* neutral score (see `parseHookScore`).
|
|
165
|
+
*/
|
|
166
|
+
async function scoreHookCore(llm, ctx) {
|
|
167
|
+
const messages = buildHookScorePrompt(ctx);
|
|
168
|
+
const raw = await llm(messages);
|
|
169
|
+
return parseHookScore(raw);
|
|
170
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/socialAI/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./captionGen"), exports);
|
|
18
|
+
__exportStar(require("./hookScore"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/socialAccounts/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./socialAccountService"), exports);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ESocialAccountStatus, ESocialProvider } from "../../globals/types";
|
|
2
|
+
import { ISocialTokenBundle } from "../../models/social.model";
|
|
3
|
+
import { OAuthTokens } from "../socialOAuth/types";
|
|
4
|
+
/** Encrypt cleartext OAuth tokens into the persisted bundle shape. */
|
|
5
|
+
export declare function toEncryptedTokenBundle(tokens: OAuthTokens): ISocialTokenBundle;
|
|
6
|
+
/**
|
|
7
|
+
* Return a valid CLEARTEXT access token for an account, refreshing + persisting
|
|
8
|
+
* it first if it's expired or near expiry. Throws (and flags the account as
|
|
9
|
+
* NEEDS_RECONNECT) if refresh fails — callers should surface a reconnect nudge.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getValidAccessToken(accountId: string): Promise<string>;
|
|
12
|
+
/** Persist a freshly-refreshed token bundle + mark the account healthy. */
|
|
13
|
+
export declare function persistRefreshedTokens(accountId: string, refreshed: OAuthTokens): Promise<void>;
|
|
14
|
+
/** Update only the health sub-document (status + optional error). */
|
|
15
|
+
export declare function markAccountHealth(accountId: string, status: ESocialAccountStatus, lastError?: string): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Find accounts whose access token expires within `withinMs` so the refresh
|
|
18
|
+
* daemon can proactively refresh them (Meta 60-day / YT short-lived). Scoped to
|
|
19
|
+
* ACTIVE accounts that actually have a refresh token.
|
|
20
|
+
*/
|
|
21
|
+
export declare function findAccountsNeedingRefresh(withinMs: number, limit?: number): Promise<Array<{
|
|
22
|
+
id: string;
|
|
23
|
+
provider: ESocialProvider;
|
|
24
|
+
}>>;
|
|
25
|
+
//# sourceMappingURL=socialAccountService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socialAccountService.d.ts","sourceRoot":"","sources":["../../../src/services/socialAccounts/socialAccountService.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,kBAAkB,EACnB,MAAM,2BAA2B,CAAC;AAInC,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAanD,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,WAAW,GAAG,kBAAkB,CAS9E;AAWD;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC5E;AAED,2EAA2E;AAC3E,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,WAAW,GACrB,OAAO,CAAC,IAAI,CAAC,CASf;AAED,qEAAqE;AACrE,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,oBAAoB,EAC5B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,KAAK,SAAM,GACV,OAAO,CAAC,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,CAAC,CAAC,CAQ3D"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toEncryptedTokenBundle = toEncryptedTokenBundle;
|
|
4
|
+
exports.getValidAccessToken = getValidAccessToken;
|
|
5
|
+
exports.persistRefreshedTokens = persistRefreshedTokens;
|
|
6
|
+
exports.markAccountHealth = markAccountHealth;
|
|
7
|
+
exports.findAccountsNeedingRefresh = findAccountsNeedingRefresh;
|
|
8
|
+
const firebase_1 = require("../../libs/firebase");
|
|
9
|
+
const types_1 = require("../../globals/types");
|
|
10
|
+
const logger_1 = require("../../utils/logger");
|
|
11
|
+
const firestore_service_1 = require("../firestore.service");
|
|
12
|
+
const factory_1 = require("../socialOAuth/factory");
|
|
13
|
+
const tokenVault_1 = require("../crypto/tokenVault");
|
|
14
|
+
/**
|
|
15
|
+
* X8 Social Suite — connected-account token lifecycle. Centralizes the
|
|
16
|
+
* encrypt-on-write / decrypt-on-read + refresh-if-expiring logic so the publish
|
|
17
|
+
* worker, metrics poller, and refresh daemon never touch raw ciphertext or the
|
|
18
|
+
* refresh wire directly. See notes/SOCIAL_SUITE_PLAN.md §4.
|
|
19
|
+
*/
|
|
20
|
+
/** Refresh the access token when it's within this window of expiry. */
|
|
21
|
+
const REFRESH_BUFFER_MS = 5 * 60 * 1000;
|
|
22
|
+
/** Encrypt cleartext OAuth tokens into the persisted bundle shape. */
|
|
23
|
+
function toEncryptedTokenBundle(tokens) {
|
|
24
|
+
return {
|
|
25
|
+
accessToken: (0, tokenVault_1.encryptToken)(tokens.accessToken),
|
|
26
|
+
refreshToken: tokens.refreshToken
|
|
27
|
+
? (0, tokenVault_1.encryptToken)(tokens.refreshToken)
|
|
28
|
+
: undefined,
|
|
29
|
+
expiresAt: tokens.expiresAt,
|
|
30
|
+
refreshExpiresAt: tokens.refreshExpiresAt,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async function loadAccount(accountId) {
|
|
34
|
+
const snap = await firestore_service_1.FirestoreService.socialAccountsCol.doc(accountId).get();
|
|
35
|
+
const data = snap.data();
|
|
36
|
+
if (!data)
|
|
37
|
+
throw new Error(`socialAccount ${accountId} not found`);
|
|
38
|
+
return { id: accountId, data };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Return a valid CLEARTEXT access token for an account, refreshing + persisting
|
|
42
|
+
* it first if it's expired or near expiry. Throws (and flags the account as
|
|
43
|
+
* NEEDS_RECONNECT) if refresh fails — callers should surface a reconnect nudge.
|
|
44
|
+
*/
|
|
45
|
+
async function getValidAccessToken(accountId) {
|
|
46
|
+
const { data } = await loadAccount(accountId);
|
|
47
|
+
const { tokens } = data;
|
|
48
|
+
const fresh = tokens.expiresAt - Date.now() > REFRESH_BUFFER_MS;
|
|
49
|
+
if (fresh) {
|
|
50
|
+
return (0, tokenVault_1.decryptToken)(tokens.accessToken);
|
|
51
|
+
}
|
|
52
|
+
if (!tokens.refreshToken) {
|
|
53
|
+
await markAccountHealth(accountId, types_1.ESocialAccountStatus.NEEDS_RECONNECT, "access token expired and no refresh token on file");
|
|
54
|
+
throw new Error(`socialAccount ${accountId}: expired, no refresh token`);
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const provider = (0, factory_1.getSocialOAuthProvider)(data.provider);
|
|
58
|
+
const refreshToken = (0, tokenVault_1.decryptToken)(tokens.refreshToken);
|
|
59
|
+
const refreshed = await provider.refresh(refreshToken);
|
|
60
|
+
await persistRefreshedTokens(accountId, refreshed);
|
|
61
|
+
return refreshed.accessToken;
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
65
|
+
logger_1.logger.warn("socialAccount: token refresh failed", { accountId, message });
|
|
66
|
+
await markAccountHealth(accountId, types_1.ESocialAccountStatus.NEEDS_RECONNECT, message);
|
|
67
|
+
throw new Error(`socialAccount ${accountId}: refresh failed — ${message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Persist a freshly-refreshed token bundle + mark the account healthy. */
|
|
71
|
+
async function persistRefreshedTokens(accountId, refreshed) {
|
|
72
|
+
await firestore_service_1.FirestoreService.socialAccountsCol.doc(accountId).update({
|
|
73
|
+
tokens: toEncryptedTokenBundle(refreshed),
|
|
74
|
+
health: {
|
|
75
|
+
status: types_1.ESocialAccountStatus.ACTIVE,
|
|
76
|
+
lastRefreshAt: Date.now(),
|
|
77
|
+
},
|
|
78
|
+
updatedAt: firebase_1.FieldValue.serverTimestamp(),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
/** Update only the health sub-document (status + optional error). */
|
|
82
|
+
async function markAccountHealth(accountId, status, lastError) {
|
|
83
|
+
await firestore_service_1.FirestoreService.socialAccountsCol.doc(accountId).update({
|
|
84
|
+
health: {
|
|
85
|
+
status,
|
|
86
|
+
...(lastError ? { lastError } : {}),
|
|
87
|
+
lastRefreshAt: Date.now(),
|
|
88
|
+
},
|
|
89
|
+
updatedAt: firebase_1.FieldValue.serverTimestamp(),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Find accounts whose access token expires within `withinMs` so the refresh
|
|
94
|
+
* daemon can proactively refresh them (Meta 60-day / YT short-lived). Scoped to
|
|
95
|
+
* ACTIVE accounts that actually have a refresh token.
|
|
96
|
+
*/
|
|
97
|
+
async function findAccountsNeedingRefresh(withinMs, limit = 100) {
|
|
98
|
+
const cutoff = Date.now() + withinMs;
|
|
99
|
+
const snap = await firestore_service_1.FirestoreService.socialAccountsCol
|
|
100
|
+
.where("health.status", "==", types_1.ESocialAccountStatus.ACTIVE)
|
|
101
|
+
.where("tokens.expiresAt", "<=", cutoff)
|
|
102
|
+
.limit(limit)
|
|
103
|
+
.get();
|
|
104
|
+
return snap.docs.map((d) => ({ id: d.id, provider: d.data().provider }));
|
|
105
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ESocialProvider } from "../../globals/types";
|
|
2
|
+
import { ISocialEngageClient } from "./types";
|
|
3
|
+
export declare function getSocialEngageClient(provider: ESocialProvider): ISocialEngageClient;
|
|
4
|
+
export declare function isSocialEngageSupported(provider: ESocialProvider): boolean;
|
|
5
|
+
/** Providers whose comments must be PULLED (no webhook) by the poll sweep. */
|
|
6
|
+
export declare const ENGAGE_POLL_PROVIDERS: ESocialProvider[];
|
|
7
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/services/socialEngage/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAS9C,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,eAAe,GACxB,mBAAmB,CAMrB;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAE1E;AAED,8EAA8E;AAC9E,eAAO,MAAM,qBAAqB,EAAE,eAAe,EAA8B,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ENGAGE_POLL_PROVIDERS = void 0;
|
|
4
|
+
exports.getSocialEngageClient = getSocialEngageClient;
|
|
5
|
+
exports.isSocialEngageSupported = isSocialEngageSupported;
|
|
6
|
+
const types_1 = require("../../globals/types");
|
|
7
|
+
const meta_engage_1 = require("./meta.engage");
|
|
8
|
+
const youtube_engage_1 = require("./youtube.engage");
|
|
9
|
+
const registry = {
|
|
10
|
+
[types_1.ESocialProvider.YOUTUBE]: () => new youtube_engage_1.YouTubeEngageClient(),
|
|
11
|
+
[types_1.ESocialProvider.INSTAGRAM]: () => new meta_engage_1.InstagramEngageClient(),
|
|
12
|
+
[types_1.ESocialProvider.FACEBOOK]: () => new meta_engage_1.FacebookEngageClient(),
|
|
13
|
+
};
|
|
14
|
+
function getSocialEngageClient(provider) {
|
|
15
|
+
const make = registry[provider];
|
|
16
|
+
if (!make) {
|
|
17
|
+
throw new Error(`Social engage not implemented for '${provider}'`);
|
|
18
|
+
}
|
|
19
|
+
return make();
|
|
20
|
+
}
|
|
21
|
+
function isSocialEngageSupported(provider) {
|
|
22
|
+
return Boolean(registry[provider]);
|
|
23
|
+
}
|
|
24
|
+
/** Providers whose comments must be PULLED (no webhook) by the poll sweep. */
|
|
25
|
+
exports.ENGAGE_POLL_PROVIDERS = [types_1.ESocialProvider.YOUTUBE];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/socialEngage/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./youtube.engage"), exports);
|
|
19
|
+
__exportStar(require("./meta.engage"), exports);
|
|
20
|
+
__exportStar(require("./factory"), exports);
|
|
21
|
+
__exportStar(require("./metaWebhook"), exports);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ESocialProvider } from "../../globals/types";
|
|
2
|
+
import { FetchCommentsInput, IRemoteComment, ISocialEngageClient, ModerateInput, ReplyInput, ReplyResult } from "./types";
|
|
3
|
+
/** Instagram comment engagement on a published media/Reel. */
|
|
4
|
+
export declare class InstagramEngageClient implements ISocialEngageClient {
|
|
5
|
+
readonly provider = ESocialProvider.INSTAGRAM;
|
|
6
|
+
fetchComments({ accessToken, providerPostId, since, limit, }: FetchCommentsInput): Promise<IRemoteComment[]>;
|
|
7
|
+
replyToComment({ accessToken, externalId, message, }: ReplyInput): Promise<ReplyResult>;
|
|
8
|
+
moderateComment({ accessToken, externalId, hidden, }: ModerateInput): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
/** Facebook Page post/video comment engagement. */
|
|
11
|
+
export declare class FacebookEngageClient implements ISocialEngageClient {
|
|
12
|
+
readonly provider = ESocialProvider.FACEBOOK;
|
|
13
|
+
fetchComments({ accessToken, providerPostId, since, limit, }: FetchCommentsInput): Promise<IRemoteComment[]>;
|
|
14
|
+
replyToComment({ accessToken, externalId, message, }: ReplyInput): Promise<ReplyResult>;
|
|
15
|
+
moderateComment({ accessToken, externalId, hidden, }: ModerateInput): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=meta.engage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.engage.d.ts","sourceRoot":"","sources":["../../../src/services/socialEngage/meta.engage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,UAAU,EACV,WAAW,EAEZ,MAAM,SAAS,CAAC;AA+BjB,8DAA8D;AAC9D,qBAAa,qBAAsB,YAAW,mBAAmB;IAC/D,QAAQ,CAAC,QAAQ,6BAA6B;IAExC,aAAa,CAAC,EAClB,WAAW,EACX,cAAc,EACd,KAAK,EACL,KAAU,GACX,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IA+B3C,cAAc,CAAC,EACnB,WAAW,EACX,UAAU,EACV,OAAO,GACR,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAe9B,eAAe,CAAC,EACpB,WAAW,EACX,UAAU,EACV,MAAM,GACP,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CAajC;AAWD,mDAAmD;AACnD,qBAAa,oBAAqB,YAAW,mBAAmB;IAC9D,QAAQ,CAAC,QAAQ,4BAA4B;IAEvC,aAAa,CAAC,EAClB,WAAW,EACX,cAAc,EACd,KAAK,EACL,KAAU,GACX,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IA+B3C,cAAc,CAAC,EACnB,WAAW,EACX,UAAU,EACV,OAAO,GACR,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAe9B,eAAe,CAAC,EACpB,WAAW,EACX,UAAU,EACV,MAAM,GACP,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;CAajC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FacebookEngageClient = exports.InstagramEngageClient = void 0;
|
|
4
|
+
const types_1 = require("../../globals/types");
|
|
5
|
+
const types_2 = require("./types");
|
|
6
|
+
/**
|
|
7
|
+
* Meta engagement clients (Instagram + Facebook). Comments PUSH in via webhooks
|
|
8
|
+
* (handled in the Functions webhook receiver), but we still expose fetchComments
|
|
9
|
+
* for backfill / reconciliation. Replies and hide/unhide go through the Graph
|
|
10
|
+
* API. Env: META_GRAPH_VERSION (optional, default v21.0). See plan §D.
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_GRAPH_VERSION = "v21.0";
|
|
13
|
+
function graph(path) {
|
|
14
|
+
const v = process.env.META_GRAPH_VERSION || DEFAULT_GRAPH_VERSION;
|
|
15
|
+
return `https://graph.facebook.com/${v}${path}`;
|
|
16
|
+
}
|
|
17
|
+
/** Instagram comment engagement on a published media/Reel. */
|
|
18
|
+
class InstagramEngageClient {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.provider = types_1.ESocialProvider.INSTAGRAM;
|
|
21
|
+
}
|
|
22
|
+
async fetchComments({ accessToken, providerPostId, since, limit = 50, }) {
|
|
23
|
+
const tokenQs = `access_token=${encodeURIComponent(accessToken)}`;
|
|
24
|
+
const resp = await fetch(graph(`/${providerPostId}/comments?fields=id,text,username,timestamp&limit=${Math.min(100, Math.max(1, limit))}&${tokenQs}`));
|
|
25
|
+
const json = (await resp.json());
|
|
26
|
+
if (!resp.ok || json.error) {
|
|
27
|
+
throw new Error(`InstagramEngage: comments ${resp.status} ${json.error?.message ?? ""}`.trim());
|
|
28
|
+
}
|
|
29
|
+
const out = [];
|
|
30
|
+
for (const c of json.data ?? []) {
|
|
31
|
+
if (!c.id)
|
|
32
|
+
continue;
|
|
33
|
+
const createdAt = (0, types_2.isoToMillis)(c.timestamp);
|
|
34
|
+
if (since && createdAt <= since)
|
|
35
|
+
continue;
|
|
36
|
+
out.push({
|
|
37
|
+
externalId: c.id,
|
|
38
|
+
parentProviderPostId: providerPostId,
|
|
39
|
+
authorHandle: c.username,
|
|
40
|
+
authorName: c.username,
|
|
41
|
+
text: c.text ?? "",
|
|
42
|
+
createdAt,
|
|
43
|
+
type: types_1.ESocialInboxType.COMMENT,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
async replyToComment({ accessToken, externalId, message, }) {
|
|
49
|
+
const resp = await fetch(graph(`/${externalId}/replies`), {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: { "Content-Type": "application/json" },
|
|
52
|
+
body: JSON.stringify({ message, access_token: accessToken }),
|
|
53
|
+
});
|
|
54
|
+
const json = (await resp.json());
|
|
55
|
+
if (!resp.ok || !json.id) {
|
|
56
|
+
throw new Error(`InstagramEngage: reply ${resp.status} ${json.error?.message ?? ""}`.trim());
|
|
57
|
+
}
|
|
58
|
+
return { externalId: json.id };
|
|
59
|
+
}
|
|
60
|
+
async moderateComment({ accessToken, externalId, hidden, }) {
|
|
61
|
+
const resp = await fetch(graph(`/${externalId}`), {
|
|
62
|
+
method: "POST",
|
|
63
|
+
headers: { "Content-Type": "application/json" },
|
|
64
|
+
body: JSON.stringify({ hide: hidden, access_token: accessToken }),
|
|
65
|
+
});
|
|
66
|
+
if (!resp.ok) {
|
|
67
|
+
const json = (await resp.json().catch(() => ({})));
|
|
68
|
+
throw new Error(`InstagramEngage: hide ${resp.status} ${json.error?.message ?? ""}`.trim());
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.InstagramEngageClient = InstagramEngageClient;
|
|
73
|
+
/** Facebook Page post/video comment engagement. */
|
|
74
|
+
class FacebookEngageClient {
|
|
75
|
+
constructor() {
|
|
76
|
+
this.provider = types_1.ESocialProvider.FACEBOOK;
|
|
77
|
+
}
|
|
78
|
+
async fetchComments({ accessToken, providerPostId, since, limit = 50, }) {
|
|
79
|
+
const tokenQs = `access_token=${encodeURIComponent(accessToken)}`;
|
|
80
|
+
const resp = await fetch(graph(`/${providerPostId}/comments?fields=id,message,from,created_time&limit=${Math.min(100, Math.max(1, limit))}&${tokenQs}`));
|
|
81
|
+
const json = (await resp.json());
|
|
82
|
+
if (!resp.ok || json.error) {
|
|
83
|
+
throw new Error(`FacebookEngage: comments ${resp.status} ${json.error?.message ?? ""}`.trim());
|
|
84
|
+
}
|
|
85
|
+
const out = [];
|
|
86
|
+
for (const c of json.data ?? []) {
|
|
87
|
+
if (!c.id)
|
|
88
|
+
continue;
|
|
89
|
+
const createdAt = (0, types_2.isoToMillis)(c.created_time);
|
|
90
|
+
if (since && createdAt <= since)
|
|
91
|
+
continue;
|
|
92
|
+
out.push({
|
|
93
|
+
externalId: c.id,
|
|
94
|
+
parentProviderPostId: providerPostId,
|
|
95
|
+
authorHandle: c.from?.id,
|
|
96
|
+
authorName: c.from?.name,
|
|
97
|
+
text: c.message ?? "",
|
|
98
|
+
createdAt,
|
|
99
|
+
type: types_1.ESocialInboxType.COMMENT,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
async replyToComment({ accessToken, externalId, message, }) {
|
|
105
|
+
const resp = await fetch(graph(`/${externalId}/comments`), {
|
|
106
|
+
method: "POST",
|
|
107
|
+
headers: { "Content-Type": "application/json" },
|
|
108
|
+
body: JSON.stringify({ message, access_token: accessToken }),
|
|
109
|
+
});
|
|
110
|
+
const json = (await resp.json());
|
|
111
|
+
if (!resp.ok || !json.id) {
|
|
112
|
+
throw new Error(`FacebookEngage: reply ${resp.status} ${json.error?.message ?? ""}`.trim());
|
|
113
|
+
}
|
|
114
|
+
return { externalId: json.id };
|
|
115
|
+
}
|
|
116
|
+
async moderateComment({ accessToken, externalId, hidden, }) {
|
|
117
|
+
const resp = await fetch(graph(`/${externalId}`), {
|
|
118
|
+
method: "POST",
|
|
119
|
+
headers: { "Content-Type": "application/json" },
|
|
120
|
+
body: JSON.stringify({ is_hidden: hidden, access_token: accessToken }),
|
|
121
|
+
});
|
|
122
|
+
if (!resp.ok) {
|
|
123
|
+
const json = (await resp.json().catch(() => ({})));
|
|
124
|
+
throw new Error(`FacebookEngage: hide ${resp.status} ${json.error?.message ?? ""}`.trim());
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.FacebookEngageClient = FacebookEngageClient;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { ESocialProvider } from "../../globals/types";
|
|
2
|
+
import { IRemoteComment } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Meta webhook helpers — Phase 5. Instagram + Facebook push comment/mention/DM
|
|
5
|
+
* events to our public `/v1/social/webhooks/meta` endpoint. Two concerns live
|
|
6
|
+
* here so the controller stays thin:
|
|
7
|
+
*
|
|
8
|
+
* 1. `verifyMetaSignature` — Meta signs every POST with HMAC-SHA256 of the raw
|
|
9
|
+
* body using the app secret, in the `X-Hub-Signature-256` header. We MUST
|
|
10
|
+
* verify it (the endpoint is public) before trusting anything.
|
|
11
|
+
* 2. `parseMetaWebhook` — flattens the nested `entry[].changes[]` envelope into
|
|
12
|
+
* normalized `MetaWebhookEvent`s keyed by the providerAccountId (page/IG id)
|
|
13
|
+
* so the controller can resolve the owning socialAccount and write inbox
|
|
14
|
+
* items. Unknown change types are skipped (we only ingest comments today).
|
|
15
|
+
*
|
|
16
|
+
* Env: META_APP_SECRET (signature key), META_WEBHOOK_VERIFY_TOKEN (GET verify).
|
|
17
|
+
* See notes/SOCIAL_SUITE_PLAN.md §D / §6 Phase 5.
|
|
18
|
+
*/
|
|
19
|
+
/** A normalized webhook event tied to the account that owns it. */
|
|
20
|
+
export interface MetaWebhookEvent {
|
|
21
|
+
provider: ESocialProvider;
|
|
22
|
+
/** The page id (FB) or IG user id the event belongs to — matches our account. */
|
|
23
|
+
providerAccountId: string;
|
|
24
|
+
comment: IRemoteComment;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Verify the `X-Hub-Signature-256` header against the raw request body. Returns
|
|
28
|
+
* false on any mismatch/missing-secret rather than throwing, so the caller can
|
|
29
|
+
* respond 403 uniformly. `rawBody` MUST be the exact bytes Meta sent (mount a
|
|
30
|
+
* raw-body capture on the webhook route — JSON.stringify of a parsed body will
|
|
31
|
+
* not match).
|
|
32
|
+
*/
|
|
33
|
+
export declare function verifyMetaSignature(rawBody: Buffer | string, signatureHeader: string | undefined): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Handle the GET verification handshake Meta performs when you register a
|
|
36
|
+
* webhook. Returns the challenge string to echo (200) when the verify token
|
|
37
|
+
* matches, else null (caller responds 403).
|
|
38
|
+
*/
|
|
39
|
+
export declare function verifyMetaSubscription(query: {
|
|
40
|
+
"hub.mode"?: string;
|
|
41
|
+
"hub.verify_token"?: string;
|
|
42
|
+
"hub.challenge"?: string;
|
|
43
|
+
}): string | null;
|
|
44
|
+
/**
|
|
45
|
+
* Flatten a verified Meta webhook body into normalized comment events. `object`
|
|
46
|
+
* tells us the platform: "instagram" → IG, "page" → Facebook. Only `comments`
|
|
47
|
+
* (and IG `mentions`) changes are ingested today; everything else is ignored.
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseMetaWebhook(body: unknown): MetaWebhookEvent[];
|
|
50
|
+
//# sourceMappingURL=metaWebhook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metaWebhook.d.ts","sourceRoot":"","sources":["../../../src/services/socialEngage/metaWebhook.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;;;;;;;;;;GAeG;AAEH,mEAAmE;AACnE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,eAAe,CAAC;IAC1B,iFAAiF;IACjF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,cAAc,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,eAAe,EAAE,MAAM,GAAG,SAAS,GAClC,OAAO,CAYT;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,MAAM,GAAG,IAAI,CAUhB;AAyBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,EAAE,CA8ClE"}
|