Pub/Sub 클라우드 기능을 사용하는 Hashnode 및 Dev.to에 대한 개념
38920 단어 podcastjavascriptbeginnerswebdev
노션 데이터 검색
개념적으로 처리가 필요한 데이터를 계속 찾기 위해 가장 간단한 방법은 새 블로그가 보관될 URL의 레코드를 유지하는 것입니다. 예를 들어 추가해야 할 레코드를 찾을 때 Dev.to 추가합니다.
devto라는 열입니다. 그런 다음 Notion의 API 및 필터링된 필드를 사용하여 해당 필드가 비어 있는 기준에 맞는 레코드를 데이터베이스에서 검색할 수 있습니다.아래 예에서는
database_id의 데이터베이스에서 CodingCat.dev의 데이터베이스를 검색합니다. 우리는 또한 이 필드에 1을 전달하여 게시물이 순서대로 처리되고 순서를 벗어나지 않도록 보장할 수 있도록 이러한 항목이 순서대로 나가기를 원하기 때문에 start_cursor를 추가합니다. 또한 slug , Released , Episode 가 지정되고 start 날짜가 오늘 또는 그 이후인 팟캐스트도 찾습니다.export const queryPurrfectStreamDevTo = async (
page_size?: number,
start_cursor?: string | null
) => {
const raw = await notionClient.databases.query({
database_id: notionConfig.purrfectStreamsDb,
start_cursor: start_cursor ? start_cursor : undefined,
page_size,
filter: {
and: [
{
property: 'slug',
url: {
is_not_empty: true,
},
},
{
property: 'Status',
select: {
equals: 'Released',
},
},
{
property: 'Episode',
number: {
is_not_empty: true,
},
},
{
property: 'start',
date: {
on_or_before: new Date().toISOString(),
},
},
{
property: 'devto',
url: {
is_empty: true,
},
},
{
property: 'youtube',
url: {
is_not_empty: true,
},
},
{
property: 'spotify',
url: {
is_not_empty: true,
},
},
],
},
sorts: [
{
property: 'Season',
direction: 'ascending',
},
{
property: 'Episode',
direction: 'ascending',
},
],
});
return await formatPosts(raw, 'podcast');
};
예약된 클라우드 기능
이제 지정된 간격으로 실행할 수 있는 Google Cloud - Cloud 스케줄러 작업을 생성하는 Firebase 함수를 생성할 수 있습니다. 이것은 pubsub 기능을 사용하는 convenience method입니다. 아래에서 이 기능을 실행하고
every 5 minutes 기준과 일치하는 새 기사가 있는지 확인합니다. 이를 1시간마다 되돌릴 수도 있지만 올바른 기준이 있는 경우 비교적 빠르게 이 트리거를 볼 수 있어 좋습니다.const topicId = 'devtoCreateFromNotion';
export const scheduledNotionToDevto = functions.pubsub
.schedule('every 5 minutes')
.onRun(async () => {
// Check to see if ther are scheduled pods
console.log('Checking for scheduled pods');
const scheduledRes = await queryPurrfectStreamDevTo(1);
console.log('Scheduled Result:', JSON.stringify(scheduledRes));
if (scheduledRes?.results) {
const needCloudinaryPods = scheduledRes?.results;
console.log('Pods to add to pub/sub', JSON.stringify(needCloudinaryPods));
for (const pod of needCloudinaryPods) {
await sendTopic(topicId, pod);
}
}
console.log('Checking for devto missing');
const posts = await queryByDevto('post', 1);
console.log('Posts:', JSON.stringify(posts));
if (posts?.results) {
const needposts = posts?.results;
console.log('Posts to add to pub/sub', JSON.stringify(needposts));
for (const p of needposts) {
await sendTopic(topicId, p);
}
}
return true;
});
이제
queryPurrfectStreamDevTo 함수에서 실제로 발견된 것이 있으면 해당 항목에서 데이터를 가져와 다른 pub/sub 함수로 전달할 수 있습니다. CodingCat.dev의 경우 생성된 순서대로 항목을 게시할 수 있도록 항목 1개만 찾습니다. 이러한 API 중 일부에서 실제 플랫폼에서 원래 게시 날짜를 설정하는 쉬운 방법이 없다는 것을 알았기 때문입니다.게시물을 게시하는 Pub/Sub 기능
이 pub/sub 기능은
devtoCreateFromNotion의 주제를 보낸 다음 적절한 게시물 정보를 찾는 모든 항목을 찾습니다. 이는 플랫폼에 게시하려는 여러 항목이 있는 경우 대규모 확장이 발생하는 가장 쉬운 방법입니다.이 예에서는 게시물 유형에 따라
body_markdown를 변경합니다. 여기서 중요한 점은 검색 엔진 봇이 이것이 원본 콘텐츠라고 생각하지 않고 필요한 경우 301을 추가할 위치를 알 수 있도록 canonical_url를 전송한다는 것입니다.export const devtoToNotionPubSub = functions.pubsub
.topic(topicId)
.onPublish(async (message, context) => {
console.log('The function was triggered at ', context.timestamp);
console.log('The unique ID for the event is', context.eventId);
const page = JSON.parse(JSON.stringify(message.json));
console.log('page', page);
let data;
if (page._type === 'podcast') {
data = {
article: {
title: page.title,
published: true,
tags: ['podcast', 'webdev', 'javascript', 'beginners'],
series: `codingcatdev_podcast_${page.properties.Season.number}`,
main_image: `https://media.codingcat.dev/image/upload/b_rgb:5e1186,c_pad,w_1000,h_420/${page?.coverPhoto?.public_id}`,
canonical_url: `https://codingcat.dev/${page._type}/${page.slug}`,
description: page.excerpt,
organization_id: '1009',
body_markdown: `Original: https://codingcat.dev/${page._type}/${
page.slug
}
{% youtube ${page.properties.youtube.url} %}
{% spotify spotify:episode:${page.properties.spotify.url
.split('/')
.at(-1)
.split('?')
.at(0)} %}
`,
},
};
} else {
console.log(
`Getting ${page._type}: ${page.id} markdown, with slug ${page?.properties?.slug?.url}`
);
const post = await getNotionPageMarkdown({
_type: page._type,
slug: page?.properties?.slug?.url,
preview: false,
});
console.log('Block Result', post);
if (post && post?.content) {
data = {
article: {
title: page.title,
published: true,
tags: ['podcast', 'webdev', 'javascript', 'beginners'],
main_image: `https://media.codingcat.dev/image/upload/b_rgb:5e1186,c_pad,w_1000,h_420/${page?.coverPhoto?.public_id}`,
canonical_url: `https://codingcat.dev/${page._type}/${page.slug}`,
description: page.excerpt,
organization_id: '1009',
body_markdown: post.content,
},
};
}
}
if (data) {
try {
console.log('addArticle to devto');
const response = await addArticle(data);
console.log('addArticle result:', response);
const devto = response?.data?.url;
if (!devto) {
console.log('devto url missing');
return;
}
const update = {
page_id: page.id,
properties: {
devto: {
id: 'remote',
type: 'url',
url: devto,
},
},
};
console.log('Updating page with: ', JSON.stringify(update));
const purrfectPagePatchRes = await patchPurrfectPage(update);
console.log(
'Page update result:',
JSON.stringify(purrfectPagePatchRes)
);
return purrfectPagePatchRes;
} catch (error) {
console.error(error);
}
} else {
console.error('No Data matched for article');
}
return;
});
보너스: 로컬 테스트
이러한 기능을 자체적으로 실행하기 전에 로컬에서 테스트하는 것이 좋습니다. 이를 위해 Firebase 에뮬레이션 제품군을 사용할 수 있습니다. 그런 다음 일정 및 http 버전 모두에 대한 코드를 업데이트하여 아래와 같은 동일한 함수를 호출합니다
scheduleCheck().const scheduleCheck = async () => {
// Check to see if ther are scheduled pods
console.log('Checking for scheduled pods');
const scheduledRes = await queryPurrfectStreamDevTo(1);
console.log('Scheduled Result:', JSON.stringify(scheduledRes));
if (scheduledRes?.results) {
const needCloudinaryPods = scheduledRes?.results;
console.log('Pods to add to pub/sub', JSON.stringify(needCloudinaryPods));
for (const pod of needCloudinaryPods) {
await sendTopic(topicId, pod);
}
}
for (const _type of ['post', 'tutorial']) {
console.log('Checking for devto missing');
const posts = await queryByDevto(_type, 1);
console.log('Posts:', JSON.stringify(posts));
if (posts?.results) {
const needposts = posts?.results;
console.log('Posts to add to pub/sub', JSON.stringify(needposts));
for (const p of needposts) {
await sendTopic(topicId, p);
}
}
}
};
export const httpNotionToDevto = functions.https.onRequest(async (req, res) => {
await scheduleCheck();
res.send({ msg: 'started' });
});
export const scheduledNotionToDevto = functions.pubsub
.schedule('every 5 minutes')
.onRun(async () => {
await scheduleCheck();
return true;
});
전체 소스
전체Dev.to 예제는 다음에서 찾을 수 있습니다.
https://github.com/CodingCatDev/codingcat.dev/blob/dev/backend/firebase/functions/src/devto/scheduledNotionToDevto.ts
전체 해시노드 예시는 다음에서 찾을 수 있습니다.
https://github.com/CodingCatDev/codingcat.dev/blob/dev/backend/firebase/functions/src/hashnode/scheduledNotionToHashNode.ts
이것은 TypeScript이며 모든 함수는 배포할 파일
index.ts에 노출되어야 합니다.https://github.com/CodingCatDev/codingcat.dev/blob/dev/backend/firebase/functions/src/index.ts
Reference
이 문제에 관하여(Pub/Sub 클라우드 기능을 사용하는 Hashnode 및 Dev.to에 대한 개념), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/codingcatdev/notion-to-hashnode-and-devto-using-pubsub-cloud-functions-3ka텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)