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.)