如何在 webhook 触发的函数运行后将信息发送回前端?
Posted
技术标签:
【中文标题】如何在 webhook 触发的函数运行后将信息发送回前端?【英文标题】:How to send information back to the Front end, AFTER functions triggered by a webhook are ran? 【发布时间】:2020-05-16 16:09:19 【问题描述】:我正在使用 Plaid API 从注册用户那里收集交易数据。本质上,Plaid 需要检索对我们的 webhook 端点的更新,以让服务器知道何时准备好提取数据。当所需的代码从 Plaid 发送到该端点时,我们将知道事务数据已准备好检索,我们的后端将开始将其插入到我们的数据库中。
我们遇到的问题是如何将数据发送到前端。由于我们只在准备好从 webhook 端点上的 Plaid 拉取数据时收到警报,所以任何 res.send 都只会发送到 Plaid。如果我们有另一个端点来获取新插入的数据,用户将能够在 Webhook 操作发生之前点击那个端点。
我们有点卡住了。我们可以让 webhook 触发我们需要触发的操作,但是一旦触发就将其发送回用户是另一个问题。在将数据发送回前端之前,是否有让我们的第三个端点等待第二个端点完成?
这是 enpoint 1,它触发 Plaid 将他们的 webhook 发送到 webhook 端点。
router.post('/token_exchange', publicTokenExists, async (req, res) =>
const publicToken = req.body;
const userid = req.body;
try
const access_token = await client.exchangePublicToken(publicToken);
const Accessid = await qs.add_A_Token(access_token, userid);
const item = await client.getItem(access_token);
const Itemid = await qs.add_An_Item(item.item_id, userid);
res.status(201).json(
accessCreated: Accessid,
ItemCreated:Itemid
);
catch (err)
console.log('access', err);
);
这是端点 2,out webhook 端点。 First Plaid 发送一个带有我们忽略的对象的 post 请求,因为 webhook_code 不是我们希望操作在其上运行的那个。第二个通过了下面的条件
router.post('/webhook', async (req,res)=>
const body = req.body;
console.log("THE WEBHOOK BRUH",body)
if(body.webhook_code==="HISTORICAL TRANSACTIONS")
const A_token = await qs.GetAccessTokenThatsConnectedTo(body.item_id)
const transactions = await client.getTransactions(A_token)
const done = Promise.all(
transactions.map(async trans =>
const contents = await qs.insert_transactions(trans);
return trans;
),
);
这是端点 3,它是我们的 React 前端向我们的数据库请求事务的地方。
router.post('/transactions',checkAccessToken, async (req,res)=>
console.log("the request body", req.body)
const access = req.body.access
try
const transactions = await qs.getTransactionsDataBaseThatWeInsertedInFunctiontwo
(access,'2019-01-01','2019-01-30')
res.status(200).json(transactions)
catch(err)
console.log(err)
res.status(500).json(message:"error sending transactions")
)
所以我想我正在寻找任何一种解决方案:
方法2完成后是否可以发送插入的交易数据?
是否可以让方法 3 等到方法 2 完成,我最初考虑将其设为中间件功能,但我认为这不会消除返回到 Plaid 的响应问题而不是响应问题?
【问题讨论】:
我认为如果您在 webhook 被触发时尝试推送到客户端 - 您可以: 【参考方案1】:Plaid API documentation 指向 Plaid Pattern repo 作为处理事务 webhook 的代码示例。在示例中,他们使用 WebSockets (Socket.IO) 来通知前端。
backend emitconst handleTransactionsWebhook = async (requestBody, io) =>
const
webhook_code: webhookCode,
item_id: plaidItemId,
new_transactions: newTransactions,
...
= requestBody;
const serverLogAndEmitSocket = (additionalInfo, itemId) =>
console.log(
`WEBHOOK: TRANSACTIONS: $webhookCode: Plaid_item_id $plaidItemId: $additionalInfo`
);
// use websocket to notify the client that a webhook has been received and handled
if (webhookCode) io.emit(webhookCode, itemId );
;
switch (webhookCode)
...
case 'HISTORICAL_UPDATE':
// Fired when an Item's historical transaction pull is completed. Plaid fetches as much
// data as is available from the financial institution.
const startDate = moment().subtract(2, 'years').format('YYYY-MM-DD');
const endDate = moment().format('YYYY-MM-DD');
await handleTransactionsUpdate(plaidItemId, startDate, endDate);
const id: itemId = await retrieveItemByPlaidItemId(plaidItemId);
serverLogAndEmitSocket(`$newTransactions transactions to add.`, itemId);
break;
...
frontend handle event
useEffect(() =>
socket.current = io(`localhost:$REACT_APP_SERVER_PORT`);
...
socket.current.on('HISTORICAL_UPDATE', ( itemId = ) =>
const msg = `New Webhook Event: Item $itemId: Historical Transactions Received`;
console.log(msg);
toast(msg);
getTransactionsByItem(itemId, true);
);
【讨论】:
虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review【参考方案2】:我认为,如果您在 Webhook 被触发时尝试推送到客户端 - 您可以:
存储来自端点一的res
对象(不确定如何将 Webhook 调用映射到初始请求)。一旦 Webhook 被触发,查找 res
对象并关闭初始请求。这不太理想。如果 Webhook 在初始请求套接字关闭之前未能触发,或者如果您需要扩展应用程序 - 它不会扩展,因为您始终需要在引用打开套接字的同一应用程序中调用 Webhook。
使用 Websocket。保持对客户端开放的持久连接,并在调用 webhook 时推送通知。
【讨论】:
以上是关于如何在 webhook 触发的函数运行后将信息发送回前端?的主要内容,如果未能解决你的问题,请参考以下文章
如何确定 Webhook 未触发 Azure Function App 的原因