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(() => {
|
||||
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", {
|
||||
|
@ -6,6 +6,8 @@ import { articles, articles as articlesTable, signups as signupsTable, sites, us
|
||||
import { authMiddleware, authMiddlewareFn } from "../modules/middleware.js";
|
||||
import { jsonToCsv, createBlogFromCaptions, createArticleSlug, getVideoById, env, getWhisperCaptions, getVideoWithCaptions } from "../utils/index.js";
|
||||
|
||||
const websubVerifyToken = "FQNI4Suzih";
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {FastifyInstance} fastify
|
||||
@ -28,7 +30,7 @@ export const dashboardRoutes = (fastify, _, done) => {
|
||||
created_at: articlesTable.created_at
|
||||
}).from(articlesTable)
|
||||
.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({
|
||||
email: signupsTable.email,
|
||||
@ -338,6 +340,9 @@ export const dashboardRoutes = (fastify, _, done) => {
|
||||
},
|
||||
domain: {
|
||||
type: ["string", "null"]
|
||||
},
|
||||
auto_publish: {
|
||||
type: "boolean"
|
||||
}
|
||||
},
|
||||
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);
|
||||
|
||||
delete data.id;
|
||||
|
@ -2,8 +2,10 @@
|
||||
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db } from "../db/index.js";
|
||||
import { users } from "../db/schemas.js";
|
||||
import { authMiddleware } from "../modules/middleware.js";
|
||||
import { articles, sites, users } from "../db/schemas.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) => {
|
||||
// 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
|
||||
console.log(req.query)
|
||||
console.log("verifying...", req.query["hub.challenge"]);
|
||||
return reply.send(req.query["hub.challenge"]);
|
||||
} else {
|
||||
// Handle other cases or errors
|
||||
@ -39,19 +43,45 @@ export const webhookRoutes = (fastify, _, done) => {
|
||||
fastify.post("/youtube", async (req, reply) => {
|
||||
const { headers, body } = req;
|
||||
const contentType = headers['content-type'];
|
||||
console.log(JSON.stringify(body.feed.contry))
|
||||
// Check if the content type is 'application/atom+xml'
|
||||
if (contentType === 'application/atom+xml') {
|
||||
// Parse the XML payload
|
||||
const { feed } = body;
|
||||
// Example processing: log the video IDs of new videos
|
||||
feed.entry.forEach(entry => {
|
||||
const videoId = entry["yt:videoId"][0];
|
||||
console.log(`New video uploaded: ${videoId}`);
|
||||
});
|
||||
try {
|
||||
// Parse the XML payload
|
||||
console.log(body)
|
||||
const feed = body["feed"];
|
||||
// Example processing: log the video IDs of new videos
|
||||
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
|
||||
return reply.code(200).send();
|
||||
if (user.tokens < 3) throw new Error("Not enough tokens");
|
||||
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 {
|
||||
// Respond with an error status if the content type is not expected
|
||||
return reply.code(400).send("Bad Request");
|
||||
|
Loading…
Reference in New Issue
Block a user