如何在 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 emit
const 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 的原因

禁用触发的 Azure WebJob

发送解析推送通知的 webhook 后

如何从 zapier 代码触发 webhook

如何让通用 Webhook 触发器插件与 Jenkins 中的多分支管道一起使用?

在发送或收到电子邮件时发送 webhook [关闭]