mirror of
https://github.com/R0m1k3/Socialflow.git
synced 2026-10-24 15:38:10 +02:00
5 files changed
+19
-12
No files matched your search
@@ -47,7 +47,7 @@ localPort = 43245
|
|||||||
externalPort = 3001
|
externalPort = 3001
|
||||||
|
|
||||||
[[ports]]
|
[[ports]]
|
||||||
localPort = 45149
|
localPort = 44509
|
||||||
externalPort = 8000
|
externalPort = 8000
|
||||||
|
|
||||||
[[ports]]
|
[[ports]]
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ export default function NewPost() {
|
|||||||
|
|
||||||
createPostMutation.mutate({
|
createPostMutation.mutate({
|
||||||
content: postText,
|
content: postText,
|
||||||
scheduledFor: scheduledDate || undefined,
|
scheduledFor: scheduledDate ? new Date(scheduledDate).toISOString() : undefined,
|
||||||
mediaIds: selectedMedia.length > 0 ? selectedMedia : undefined,
|
mediaIds: selectedMedia.length > 0 ? selectedMedia : undefined,
|
||||||
pageIds: selectedPages,
|
pageIds: selectedPages,
|
||||||
postType,
|
postType,
|
||||||
|
|||||||
@@ -24,12 +24,16 @@ The backend runs on **Node.js** with **Express.js**, fully implemented in **Type
|
|||||||
|
|
||||||
### Media Processing Pipeline
|
### Media Processing Pipeline
|
||||||
|
|
||||||
The platform leverages **Cloudinary** for cloud-based image and video storage and transformation. Original files are uploaded to Cloudinary, which then automatically generates transformation URLs for various platform-specific formats:
|
The platform leverages **Cloudinary** for cloud-based image and video storage and transformation. Original files are uploaded to Cloudinary and stored in the database.
|
||||||
- **Facebook Feed**: 1080x1080px with intelligent center crop (`crop: fill`) - square format, no borders
|
|
||||||
- **Instagram Feed**: 1080x1080px with padding (`crop: pad`) - maintains aspect ratio with auto background
|
**Publishing Strategy**: All publications to Facebook/Instagram use the **original image URL** - the platforms handle cropping and formatting automatically based on the post type (feed/story/carousel).
|
||||||
|
|
||||||
|
**Transformations for Preview Only**: Cloudinary generates transformation URLs for UI preview purposes only:
|
||||||
|
- **Facebook Landscape**: 1200x630px with intelligent center crop (`crop: fill`) - landscape format
|
||||||
|
- **Facebook Feed / Instagram Feed**: 1080x1080px with intelligent center crop (`crop: fill`) - square format
|
||||||
- **Instagram Story**: 1080x1920px with padding (`crop: pad`) - vertical format
|
- **Instagram Story**: 1080x1920px with padding (`crop: pad`) - vertical format
|
||||||
|
|
||||||
These public IDs and transformation URLs are stored in the database, allowing optimized images to be served via Cloudinary's CDN.
|
These transformation URLs are stored in the database (`facebookLandscapeUrl`, `facebookFeedUrl`, `instagramFeedUrl`, `instagramStoryUrl`) and displayed in the media library for visual preview, but are NOT used when publishing to social media platforms.
|
||||||
|
|
||||||
### Authentication & Authorization
|
### Authentication & Authorization
|
||||||
|
|
||||||
|
|||||||
@@ -88,8 +88,8 @@ export class FacebookService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async publishPhotoPost(post: Post, page: SocialPage, media: Media): Promise<string> {
|
private async publishPhotoPost(post: Post, page: SocialPage, media: Media): Promise<string> {
|
||||||
// Use the Facebook Feed optimized URL (1200x630)
|
// Use original URL - Facebook handles the cropping
|
||||||
const photoUrl = media.facebookFeedUrl || media.originalUrl;
|
const photoUrl = media.originalUrl;
|
||||||
|
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
access_token: page.accessToken!,
|
access_token: page.accessToken!,
|
||||||
@@ -128,7 +128,8 @@ export class FacebookService {
|
|||||||
const photoIds: string[] = [];
|
const photoIds: string[] = [];
|
||||||
|
|
||||||
for (const media of imageMedia) {
|
for (const media of imageMedia) {
|
||||||
const photoUrl = media.facebookFeedUrl || media.originalUrl;
|
// Use original URL - Facebook handles the cropping for carousel
|
||||||
|
const photoUrl = media.originalUrl;
|
||||||
|
|
||||||
if (!photoUrl) {
|
if (!photoUrl) {
|
||||||
console.warn(`Skipping media ${media.id} - no valid URL found`);
|
console.warn(`Skipping media ${media.id} - no valid URL found`);
|
||||||
@@ -242,7 +243,8 @@ export class FacebookService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async schedulePhotoPost(post: Post, page: SocialPage, scheduledTimestamp: number, media: Media): Promise<string> {
|
private async schedulePhotoPost(post: Post, page: SocialPage, scheduledTimestamp: number, media: Media): Promise<string> {
|
||||||
const photoUrl = media.facebookFeedUrl || media.originalUrl;
|
// Use original URL - Facebook handles the cropping
|
||||||
|
const photoUrl = media.originalUrl;
|
||||||
|
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
access_token: page.accessToken!,
|
access_token: page.accessToken!,
|
||||||
@@ -268,8 +270,8 @@ export class FacebookService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async publishStory(post: Post, page: SocialPage, media: Media): Promise<string> {
|
private async publishStory(post: Post, page: SocialPage, media: Media): Promise<string> {
|
||||||
// Use vertical format for stories (Instagram Story URL 1080x1920)
|
// Use original URL - Facebook handles the story cropping
|
||||||
const photoUrl = media.instagramStoryUrl || media.originalUrl;
|
const photoUrl = media.originalUrl;
|
||||||
|
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
access_token: page.accessToken!,
|
access_token: page.accessToken!,
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ export const media = pgTable("media", {
|
|||||||
type: mediaTypeEnum("type").notNull(),
|
type: mediaTypeEnum("type").notNull(),
|
||||||
cloudinaryPublicId: text("cloudinary_public_id"),
|
cloudinaryPublicId: text("cloudinary_public_id"),
|
||||||
originalUrl: text("original_url").notNull(),
|
originalUrl: text("original_url").notNull(),
|
||||||
|
facebookLandscapeUrl: text("facebook_landscape_url"),
|
||||||
facebookFeedUrl: text("facebook_feed_url"),
|
facebookFeedUrl: text("facebook_feed_url"),
|
||||||
instagramFeedUrl: text("instagram_feed_url"),
|
instagramFeedUrl: text("instagram_feed_url"),
|
||||||
instagramStoryUrl: text("instagram_story_url"),
|
instagramStoryUrl: text("instagram_story_url"),
|
||||||
|
|||||||
Reference in new issue
Block a user