added logic for auto-publish
This commit is contained in:
parent
8412cbc572
commit
e6a8ef5f9e
@ -53,7 +53,8 @@ export const sites = pgTable("sites", {
|
|||||||
subdomain_slug: text("subdomain_slug").$defaultFn(() => {
|
subdomain_slug: text("subdomain_slug").$defaultFn(() => {
|
||||||
return makeid(10);
|
return makeid(10);
|
||||||
}),
|
}),
|
||||||
social_medias: jsonb("social_medias")
|
social_medias: jsonb("social_medias"),
|
||||||
|
auto_publish: boolean("auto_publish").default(false)
|
||||||
});
|
});
|
||||||
|
|
||||||
export const articles = pgTable("articles", {
|
export const articles = pgTable("articles", {
|
||||||
|
@ -6,6 +6,8 @@ import { articles, articles as articlesTable, signups as signupsTable, sites, us
|
|||||||
import { authMiddleware, authMiddlewareFn } from "../modules/middleware.js";
|
import { authMiddleware, authMiddlewareFn } from "../modules/middleware.js";
|
||||||
import { jsonToCsv, createBlogFromCaptions, createArticleSlug, getVideoById, env, getWhisperCaptions, getVideoWithCaptions } from "../utils/index.js";
|
import { jsonToCsv, createBlogFromCaptions, createArticleSlug, getVideoById, env, getWhisperCaptions, getVideoWithCaptions } from "../utils/index.js";
|
||||||
|
|
||||||
|
const websubVerifyToken = "FQNI4Suzih";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {FastifyInstance} fastify
|
* @param {FastifyInstance} fastify
|
||||||
@ -28,7 +30,7 @@ export const dashboardRoutes = (fastify, _, done) => {
|
|||||||
created_at: articlesTable.created_at
|
created_at: articlesTable.created_at
|
||||||
}).from(articlesTable)
|
}).from(articlesTable)
|
||||||
.where(eq(articlesTable.site_id, site_id))
|
.where(eq(articlesTable.site_id, site_id))
|
||||||
.orderBy(articlesTable.created_at).limit(5);
|
.orderBy(desc(articlesTable.created_at)).limit(5);
|
||||||
|
|
||||||
const recentSignups = await db.select({
|
const recentSignups = await db.select({
|
||||||
email: signupsTable.email,
|
email: signupsTable.email,
|
||||||
@ -338,6 +340,9 @@ export const dashboardRoutes = (fastify, _, done) => {
|
|||||||
},
|
},
|
||||||
domain: {
|
domain: {
|
||||||
type: ["string", "null"]
|
type: ["string", "null"]
|
||||||
|
},
|
||||||
|
auto_publish: {
|
||||||
|
type: "boolean"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
required: ["id"]
|
required: ["id"]
|
||||||
@ -364,6 +369,21 @@ export const dashboardRoutes = (fastify, _, done) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(site.auto_publish !== req.body.auto_publish) {
|
||||||
|
const [user] = await db.select().from(users).where(eq(users.id, req.session.user_id));
|
||||||
|
if(!user) throw new Error("Problem getting user");
|
||||||
|
let form = new FormData();
|
||||||
|
form.set("hub.callback", env.PUBLIC_API_URL + "/webhooks/youtube");
|
||||||
|
form.set("hub.topic", "https://www.youtube.com/xml/feeds/videos.xml?channel_id=" + user.channel_id);
|
||||||
|
form.set("hub.verify", "async");
|
||||||
|
form.set("hub.mode", auto_publish ? "subscribe" : "unsubscribe");
|
||||||
|
form.set("hub.verify_token", websubVerifyToken);
|
||||||
|
await fetch("https://pubsubhubbub.appspot.com/subscribe", {
|
||||||
|
method: "POST",
|
||||||
|
body: form
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const data = structuredClone(req.body);
|
const data = structuredClone(req.body);
|
||||||
|
|
||||||
delete data.id;
|
delete data.id;
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { db } from "../db/index.js";
|
import { db } from "../db/index.js";
|
||||||
import { users } from "../db/schemas.js";
|
import { articles, sites, users } from "../db/schemas.js";
|
||||||
import { authMiddleware } from "../modules/middleware.js";
|
import { getVideoWithCaptions } from "../utils/youtube.js";
|
||||||
|
import { createBlogFromCaptions } from "../utils/ai.js";
|
||||||
|
import { createArticleSlug } from "../utils/index.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -27,8 +29,10 @@ export const webhookRoutes = (fastify, _, done) => {
|
|||||||
|
|
||||||
fastify.get("/youtube", async (req, reply) => {
|
fastify.get("/youtube", async (req, reply) => {
|
||||||
// Check if the request contains the 'hub.challenge' query parameter
|
// Check if the request contains the 'hub.challenge' query parameter
|
||||||
if (req.query["hub.challenge"]) {
|
if (req.query["hub.challenge"] && req.query["hub.verify_token"] === "FQNI4Suzih") {
|
||||||
// Respond with the challenge to verify the subscription
|
// Respond with the challenge to verify the subscription
|
||||||
|
console.log(req.query)
|
||||||
|
console.log("verifying...", req.query["hub.challenge"]);
|
||||||
return reply.send(req.query["hub.challenge"]);
|
return reply.send(req.query["hub.challenge"]);
|
||||||
} else {
|
} else {
|
||||||
// Handle other cases or errors
|
// Handle other cases or errors
|
||||||
@ -39,19 +43,45 @@ export const webhookRoutes = (fastify, _, done) => {
|
|||||||
fastify.post("/youtube", async (req, reply) => {
|
fastify.post("/youtube", async (req, reply) => {
|
||||||
const { headers, body } = req;
|
const { headers, body } = req;
|
||||||
const contentType = headers['content-type'];
|
const contentType = headers['content-type'];
|
||||||
console.log(JSON.stringify(body.feed.contry))
|
|
||||||
// Check if the content type is 'application/atom+xml'
|
// Check if the content type is 'application/atom+xml'
|
||||||
if (contentType === 'application/atom+xml') {
|
if (contentType === 'application/atom+xml') {
|
||||||
// Parse the XML payload
|
try {
|
||||||
const { feed } = body;
|
// Parse the XML payload
|
||||||
// Example processing: log the video IDs of new videos
|
console.log(body)
|
||||||
feed.entry.forEach(entry => {
|
const feed = body["feed"];
|
||||||
const videoId = entry["yt:videoId"][0];
|
// Example processing: log the video IDs of new videos
|
||||||
console.log(`New video uploaded: ${videoId}`);
|
const entry = feed.entry[0];
|
||||||
});
|
const [{users: user, sites: site}] = await db.select().from(users).leftJoin(sites, eq(users.id, sites.user_id)).where(eq(users.channel_id, "UC" + feed["yt:channelId"][0]));
|
||||||
|
if (!user || !site) throw new Error("User not found");
|
||||||
|
|
||||||
// Respond with a success status
|
if (user.tokens < 3) throw new Error("Not enough tokens");
|
||||||
return reply.code(200).send();
|
const videoId = entry["yt:videoId"][0];
|
||||||
|
const videoURL = `https://youtu.be/${videoId}`;
|
||||||
|
reply.code(200).send();
|
||||||
|
|
||||||
|
const video_data = await getVideoWithCaptions(videoURL);
|
||||||
|
const blog_content_json = await createBlogFromCaptions(video_data.captions, { title: video_data.title, description: video_data.description });
|
||||||
|
|
||||||
|
await db.insert(articles).values({
|
||||||
|
site_id: site.id,
|
||||||
|
title: blog_content_json.title,
|
||||||
|
content: blog_content_json.content,
|
||||||
|
meta_title: blog_content_json.meta_title,
|
||||||
|
meta_desc: blog_content_json.meta_desc,
|
||||||
|
excerp: blog_content_json.excerp,
|
||||||
|
source_video_id: videoId,
|
||||||
|
seo_slug: createArticleSlug(blog_content_json.title),
|
||||||
|
is_public: false
|
||||||
|
}).returning({ id: articles.id });
|
||||||
|
|
||||||
|
await db.update(users).set({
|
||||||
|
tokens: user.tokens - 3
|
||||||
|
}).where(eq(users.id, user.id));
|
||||||
|
// Respond with a success status
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
return reply.code(500).send(e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Respond with an error status if the content type is not expected
|
// Respond with an error status if the content type is not expected
|
||||||
return reply.code(400).send("Bad Request");
|
return reply.code(400).send("Bad Request");
|
||||||
|
Loading…
Reference in New Issue
Block a user