如何将 PubSub Rest API 与 Google 服务帐户一起使用?

How to use PubSub Rest API with Google service accounts?

我们是否可以使用 Google 服务帐户调用 Google PubSub Rest API?

我有一个非常具体的要求,即使用其余部分 api 在 pub sub 上发布消息,让我知道有什么方法可以做到吗?

如果有办法获取所需的 Api 密钥或令牌以供休息 api 使用服务帐户也有帮助。

如果你想直接使用API,没有客户端库,你可以这样做

首先,获取access_token,然后将其添加到您请求的header中

    const {GoogleAuth} = require('google-auth-library');
    const auth = new GoogleAuth()
    const adc = await auth.getApplicationDefault()
    const access_token = await adc.credential.getAccessToken();
    console.log(access_token.token)

    const request = require('request');

    const topic = 'projects/gbl-imt-homerider-basguillaueb/topics/go-hello'

    const options = {
        url: ' https://pubsub.googleapis.com/v1/' + topic + ':publish',
        method: 'POST',
        headers: {
            'Authorization': 'Bearer ' + access_token.token,
            'Content-type': 'application/json'
        },
        body:'{"messages":[{"data":"' + Buffer.from("Hello World").toString('base64') + '"}]}'
    };

    request(options, function(err, res, body) {
        let json = JSON.parse(body);
        console.log(json);
    });

编辑

遗憾的是,我对 Nodejs 的理解太差了,无法为此编写干净的代码。你可以去documentation page and you can see there is constructor options for GoogleAuth class

最后像这样的东西应该可以工作(但我没有实现这个......太糟糕了......)

const auth = new GoogleAuth({
    scopes: '',
    keyFile: 'path/to/key.json'
})

因为我不好,所以我这样做了,而且有效

//Set manually the environment variables
process.env.GOOGLE_APPLICATION_CREDENTIALS='path/to/key.json'
const auth = new GoogleAuth() //Use default credentials

为了使用 pub sub,您需要创建 IAM 服务帐户并在 google 云控制台中启用 pubsub 服务。 使用以下功能发布和订阅。

发布:

const pubsub = new PubSub()  
const data = 'this is data : ' + new Date().toString();
     const dataBuffer = Buffer.from(data);
     const topicName = 'ypur-topic-name';

     pubsub
       .topic(topicName)
       .publisher()
       .publish(dataBuffer)
       .then((messageId) => {
         console.log(`Message ${messageId} published.`);
         return res.status(200).json({ success: true });
       })
       .catch((err) => {
         console.error('ERROR:', err);
       });

订阅:

const pubsub = new PubSub();

    const subscriptionName = 'your-subscription-name';
    const timeout = 6000;

    const subscription = pubsub.subscription(subscriptionName);
    let messageCount = 0;

    const messageHandler = (message) => {
      console.log(`Received message ${message.id}:`);
      console.log(`Data: ${message.data}`);
      console.log(`tAttributes: ${JSON.stringify(message.attributes)}`);
      messageCount += 1;

      // Ack the messae
      message.ack();
    };

    // Listen for new messages until timeout is hit
    subscription.on(`message`, messageHandler);
    setTimeout(() => {
      subscription.removeListener('message', messageHandler);
      console.log(`${messageCount} message(s) received.`);
    }, timeout * 1000);

完整流程可参考本教程:https://blog.cloudboost.io/google-pubsub-tutorial-74dd5b948700

这里是从 AWS Lambda 函数到 GCP pub/sub 的 restApi 调用示例。 我试图找到一种方法将 service_account.json 文件传递​​到我的 lambda 函数上的 GOOGLE_APPLICATION_CREDENTIALS 环境变量,但不幸的是找不到它,所以我决定使用 rest API 版本而不是 SDK版本。所以我从 service_account.json 中提取了客户端电子邮件和私钥(我将其添加到 AWS 机密管理器并从那里获取)

  const { JWT } = require("google-auth-library");
  const topicName = "test-topic";

  const client = new JWT({
    email: process.env.GCP_CLIENT_EMAIL,
    key: process.env.GCP_PRIVATE_KEY,
    scopes: ["https://www.googleapis.com/auth/cloud-platform"],
  });

  module.exports.publisher = async (event) => {
    console.log(event.body);
    const dataBuffer = Buffer.from(event.body).toString('base64');
    const url = `https://pubsub.googleapis.com/v1/${topicName}:publish`;
    const options = {
      url: url,
      method: 'POST',
      data: {
        messages: [
          {
            data: dataBuffer
          }
        ]
      }
    }
    const res = await client.request(options);
    console.log(res.data);
    return res.data;
  };