pocket newsletter lambda
1.0.0
示例 Lambda 从 Pocket 获取所有“新闻通讯”帖子。
请参阅 ./src/lambda/newsletter.js 中的 lambda 代码。
在 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 ( ',' )
: ''
} )
) ;
}
lambda 仅支持带有主体的 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 编码的表单正文请求)要么不以 Base64 编码到达。这由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 ;
} , { } ) ;
}
以下是 lambda 中的功能:
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" : ""
}
]
在我的网站上,lambda 不会从请求中读取访问令牌和消费者密钥。
相反,它是一个简单的 GET,从环境变量中读取令牌和密钥。
您应该在开始之前运行yarn
。
以下脚本可用:
yarn start
:启动 Lambda 并使用 Netlify Dev 提供静态目录。重要提示: yarn build:tw
在start
之前运行。yarn build:tw
:构建全套 Tailwind CSS 实用程序(对开发有用),请确保使用yarn build:css
检查您的网站的外观yarn build
:运行 netlify-lambda build + Tailwind CSS 生产构建(使用 PurgeCSS 删除未使用的类)yarn build:css
:Tailwind CSS 生产构建(使用 PurgeCSS 删除未使用的类)yarn lint
和yarn format
:运行 XO,“具有良好默认值的 JavaScript linter”(参见 github.com/xojs/xo),分别带或不带--fix
标志