Pocket에서 모든 "뉴스레터" 게시물을 가져오는 Lambda 예제
./src/lambda/newsletter.js에서 람다 코드를 참조하세요.
https://pocket-newsletter-lambda.netlify.com/에서 실행하세요.
목차:
Pocket 관련 논리의 대부분은 fetchBookmarks
함수이며 다음을 수행합니다.
state: 'all'
전달합니다.tag: 'newsletter'
사용하여 newsletter
태그가 붙은 게시물을 가져옵니다.detailType: 'complete'
API가 더 완전한 데이터를 반환함을 의미합니다.{ title, url, excerpts, authors }
의 단순 목록으로 변환합니다(해당 필드는 모두 문자열입니다).코드 보기
async function fetchBookmarks ( consumerKey , accessToken ) {
const res = await axios . post ( 'https://getpocket.com/v3/get' , {
consumer_key : consumerKey ,
access_token : accessToken ,
tag : 'newsletter' ,
state : 'all' ,
detailType : 'complete'
} ) ;
const { list } = res . data ;
// List is a key-value timestamp->entry map
const entries = Object . values ( list ) ;
return entries . map (
( {
given_title ,
given_url ,
resolved_url ,
resolved_title ,
excerpt ,
authors ,
rest
} ) => ( {
... rest ,
title : given_title || resolved_title ,
url : given_url || resolved_url ,
excerpt ,
authors : authors
? Object . values ( authors )
. map ( ( { name } ) => name )
. filter ( Boolean )
. join ( ',' )
: ''
} )
) ;
}
람다는 본문이 있는 POST만 지원하므로 다음과 같습니다.
if ( event . httpMethod !== 'POST' ) {
return {
statusCode : 404 ,
body : 'Not Found'
} ;
}
if ( ! event . body ) {
return {
statusCode : 400 ,
body : 'Bad Request'
} ;
}
우리는 URL 인코딩된 양식 POST 요청(예: 데모 페이지에서 JS가 비활성화된 경우 수행됨)과 JSON 요청을 모두 지원합니다.
본문은 base64로 인코딩되어 도착하거나(URL 인코딩된 양식 본문 요청을 사용하는 경우) 도착하지 않습니다. 이는 event
의 isBase64Encoded
플래그로 표시됩니다.
Node에서 base64로 인코딩된 문자열을 구문 분석하는 것은 Buffer.from(event.body, 'base64').toString('utf-8)
사용하여 수행됩니다.
URL 인코딩 형식의 본문을 객체로 변환하려면 간단한 필드가 있는 POST에 대해 작동하는 다음 함수가 사용됩니다.
function parseUrlEncoded ( urlEncodedString ) {
const keyValuePairs = urlEncodedString . split ( '&' ) ;
return keyValuePairs . reduce ( ( acc , kvPairString ) => {
const [ k , v ] = kvPairString . split ( '=' ) ;
acc [ k ] = v ;
return acc ;
} , { } ) ;
}
람다의 기능은 다음과 같습니다.
const {
pocket_consumer_key : pocketConsumerKey ,
pocket_access_token : pocketAccessToken
} = event . isBase64Encoded
? parseUrlEncoded ( Buffer . from ( event . body , 'base64' ) . toString ( 'utf-8' ) )
: JSON . parse ( event . body ) ;
소비자 키나 액세스 토큰이 누락된 경우 400을 보냅니다.
if ( ! pocketConsumerKey || ! pocketAccessToken ) {
return {
statusCode : 400 ,
body : 'Bad Request'
} ;
}
마지막으로 우리는 fetchBookmarks
가져오려고 시도합니다(해당 함수의 기능은 위에서 자세히 설명되어 있습니다).
요청 오류로 인해 실패하면(axios가 실패하면 오류에 대한 response
속성이 있음) 해당 응답의 정보를 클라이언트에 다시 보내고 싶습니다. 그렇지 않으면 오류 시 500, 성공 시 200입니다.
try {
const bookmarks = await fetchBookmarks ( pocketConsumerKey , pocketAccessToken ) ;
return {
statusCode : 200 ,
body : JSON . stringify ( bookmarks )
} ;
} catch ( e ) {
if ( e . response ) {
return {
statusCode : e . response . statusCode ,
body : `Error while connecting to Pocket API: ${ e . response . statusText } `
}
}
return {
statusCode : 500 ,
body : e . message
}
}
[
{
"title" : "TechnicalDebt" ,
"url" : "https://martinfowler.com/bliki/TechnicalDebt.html" ,
"excerpt" : "Software systems are prone to the build up of cruft - deficiencies in internal quality that make it harder than it would ideally be to modify and extend the system further." ,
"authors" : ""
} ,
{
"title" : "CannotMeasureProductivity" ,
"url" : "https://martinfowler.com/bliki/CannotMeasureProductivity.html" ,
"excerpt" : "We see so much emotional discussion about software process, design practices and the like. Many of these arguments are impossible to resolve because the software industry lacks the ability to measure some of the basic elements of the effectiveness of software development." ,
"authors" : ""
} ,
{
"title" : "How SQLite Is Tested" ,
"url" : "https://www.sqlite.org/testing.html" ,
"excerpt" : "The reliability and robustness of SQLite is achieved in part by thorough and careful testing. As of version 3.23.0 (2018-04-02), the SQLite library consists of approximately 128.9 KSLOC of C code." ,
"authors" : ""
} ,
{
"title" : "How FriendFeed uses MySQL to store schema-less data" ,
"url" : "https://backchannel.org/blog/friendfeed-schemaless-mysql" ,
"excerpt" : "We use MySQL for storing all of the data in FriendFeed. Our database has grown a lot as our user base has grown. We now store over 250 million entries and a bunch of other data, from comments and "likes" to friend lists." ,
"authors" : ""
} ,
{
"title" : "jlevy/the-art-of-command-line: Master the command line, in one page" ,
"url" : "https://github.com/jlevy/the-art-of-command-line" ,
"excerpt" : "Note: I'm looking for a new (and potentially paid) lead author to help expand this to a more comprehensive Guide. While it's very popoular, it could be both deeper and more helpful." ,
"authors" : ""
} ,
{
"title" : "Project Mezzanine: The Great Migration | Uber Engineering Blog" ,
"url" : "https://eng.uber.com/mezzanine-migration/" ,
"excerpt" : "What happens when you have to migrate hundreds of millions of rows of data and more than 100 services over several weeks while simultaneously keeping Uber running for millions of riders? This is the story of how dozens of engineers helped Uber move to Mezzanine in 2014." ,
"authors" : "Rene Schmidt"
} ,
{
"title" : "8 Protips to Start Killing It When Dockerizing Node.js - NodeSource" ,
"url" : "https://nodesource.com/blog/8-protips-to-start-killing-it-when-dockerizing-node-js/" ,
"excerpt" : "Containers are the best way to deploy Node.js applications to production. Containers provide a wide variety of benefits, from having the same environment in production and development to streamlining deploys for speed and size. Dockerizing your Node." ,
"authors" : "Tierney Cyren"
} ,
{
"title" : "How and Why We Switched from Erlang to Python – Mixpanel Engineering" ,
"url" : "https://engineering.mixpanel.com/2011/08/05/how-and-why-we-switched-from-erlang-to-python/" ,
"excerpt" : "A core component of Mixpanel is the server that sits at http://api.mixpanel.com. This server is the entry point for all data that comes into the system – it’s hit every time an event is sent from a browser, phone, or backend server." ,
"authors" : "mxpnl"
} ,
{
"title" : "Some Were Meant for C - kell17some-preprint.pdf" ,
"url" : "https://www.cs.kent.ac.uk/people/staff/srk21//research/papers/kell17some-preprint.pdf" ,
"excerpt" : "" ,
"authors" : ""
} ,
{
"title" : "API Gateways Are Going Through an Identity Crisis" ,
"url" : "http://blog.christianposta.com/microservices/api-gateways-are-going-through-an-identity-crisis/" ,
"excerpt" : "API Gateways are going through a bit of an identity crisis these days. Are they centralized, shared resources that facilitate the exposure and governance of APIs to external entities?" ,
"authors" : ""
} ,
{
"title" : "Understanding Database Sharding" ,
"url" : "https://www.digitalocean.com/community/tutorials/understanding-database-sharding" ,
"excerpt" : "Any application or website that sees significant growth will eventually need to scale in order to accommodate increases in traffic. For data-driven applications and websites, it's critical that scaling is done in a way that ensures the security and integrity of their data." ,
"authors" : "Justin Ellingwood"
} ,
{
"title" : "Moving from Ruby to Rust" ,
"url" : "http://deliveroo.engineering/2019/02/14/moving-from-ruby-to-rust.html" ,
"excerpt" : "In the Logistics Algorithms team, we have a service, called Dispatcher, the main purpose of which is to offer an order to the rider, optimally." ,
"authors" : "Andrii Dmytrenko"
} ,
{
"title" : "Getting to Know Python 3.7: Data Classes, async/await and More! | Heroku" ,
"url" : "https://blog.heroku.com/python37-dataclasses-async-await" ,
"excerpt" : "If you're like me, or like many other Python developers, you've probably lived (and maybe migrated) through a few version releases. Python 3.7(." ,
"authors" : "Casey Faist"
} ,
{
"title" : "? What does Unsplash cost in 2019?" ,
"url" : "https://medium.com/p/f499620a14d0" ,
"excerpt" : "Since then, Unsplash has continued to grow tremendously, now powering more image use than the major image media incumbents, Shutterstock, Getty, and Adobe, combined." ,
"authors" : "Luke Chesser"
} ,
{
"title" : "PHP in 2019 - stitcher.io" ,
"url" : "https://stitcher.io/blog/php-in-2019" ,
"excerpt" : "Do you remember the popular "PHP: a fractal of bad design" blog post? The first time I read it, I was working in a crappy place with lots of legacy PHP projects. This article got me wondering whether I should just quit and go do something entirely different than programming." ,
"authors" : ""
}
]
내 사이트에서 람다는 요청에서 액세스 토큰과 소비자 키를 읽지 않습니다.
대신 환경 변수에서 토큰과 키를 읽는 간단한 GET입니다.
시작하기 전에 yarn
실행해야 합니다.
다음 스크립트를 사용할 수 있습니다.
yarn start
: Netlify Dev를 사용하여 Lambda를 시작하고 정적 디렉터리를 제공합니다. 중요: yarn build:tw
start
전에 실행됩니다.yarn build:tw
: Tailwind CSS 유틸리티 전체 세트(개발에 유용함)를 빌드하고, yarn build:css
사용하여 사이트가 실시간으로 어떻게 보일지 확인하세요.yarn build
: netlify-lambda 빌드 + Tailwind CSS 프로덕션 빌드 실행(PurgeCSS를 사용하여 사용하지 않는 클래스 제거)yarn build:css
: Tailwind CSS 프로덕션 빌드(PurgeCSS를 사용하여 사용하지 않는 클래스 제거)yarn lint
및 yarn format
: 각각 --fix
플래그를 사용하거나 사용하지 않고 "훌륭한 기본값을 사용하는 JavaScript linter"(github.com/xojs/xo 참조)인 XO를 실행합니다.