Google pubsub进入HTTP触发的云功能吗?

时间:2018-07-29 02:00:27

标签: google-cloud-functions google-cloud-pubsub

是否可以触发pubsub消息来响应HTTP云功能?

在编辑订阅时,Google可以将消息推送到HTTPS端点,但是出于滥用的原因,人们必须能够证明您拥有域才能执行此操作,当然您不能证明您拥有Google自己的*.cloudfunctions.net域,这是它们部署所在的域。

我要订阅的特定主题是公共主题projects/pubsub-public-data/topics/taxirides-realtime。答案可能是使用后台功能,而不是使用HTTP触发的,但这由于不同的原因而无效:

gcloud functions deploy echo --trigger-resource projects/pubsub-public-data/topics/taxirides-realtime --trigger-event google.pubsub.topic.publish ERROR: gcloud crashed (ArgumentTypeError): Invalid value 'projects/pubsub-public-data/topics/taxirides-realtime': Topic must contain only Latin letters (lower- or upper-case), digits and the characters - + . _ ~ %. It must start with a letter and be from 3 to 255 characters long.

这似乎表明只允许在我拥有的主题上使用,这是一个奇怪的限制。

3 个答案:

答案 0 :(得分:0)

您收到的错误似乎是您在发出的gcloud命令中拼写错误。

ERROR: gcloud crashed (ArgumentTypeError): Invalid value 'projects/pubsub-public-data/topics/taxirides-realtime': Topic must contain only Latin letters (lower- or upper-case), digits and the characters - + . _ ~ %. It must start with a letter and be from 3 to 255 characters long

您要在命令中间放置换行符吗?

答案 1 :(得分:0)

当前,Cloud Functions不允许创建一个函数来接收其他项目中某个主题的消息。因此,指定包含“ projects / pubsub-public-data”的完整路径不起作用。用于为主题部署云功能的gcloud命令仅需要主题名称(而不是完整的资源路径)。由于完整的资源路径包含“ /”字符,因此它不是有效的规范,并会导致您看到错误。

答案 2 :(得分:0)

可以从发布/订阅主题发布到云功能。我正在寻找一种从项目A中的主题发布到项目B中的函数的方法。使用常规主题触发器无法实现,但是使用http-trigger可以实现。遵循的步骤:

  • 在项目B中创建一个基本的http触发功能。
  • 在项目A中创建一个主题。
  • 在项目A中的该主题上创建一个订阅。作为推送端点,从项目B中的函数中选择URL:

    https://YOUR_REGION-YOUR_PROJECT_ID.cloudfunctions.net/FUNCTION_NAME/?token=[randomstring] <-不要忘了最后的斜线!

    选择一个您要用来发送实际消息的服务帐户。作为受众群体,您可以选择您的域(例如example.com)。

    enter image description here

  • 现在,您可能由于错误而无法保存您的订阅,这是因为端点未通过Google验证。因此,您需要在以下网址将功能URL列入白名单:API和服务>凭据>域验证。

  • 接下来,我们需要在您的云函数中添加以下内容(python示例),以允许Google验证该函数:

    if request.method == 'GET':
        return '''
            <html>
                <head>
                    <meta name="google-site-verification" content="{token}" />
                </head>
                <body>
                </body>
            </html>
        '''.format(token=config.SITE_VERIFICATION_CODE)
    
  • 现在,我们需要保护端点。首先检查您在网址中提供的令牌:

    if (request.args.get('token', '') != '[randomstring]'):
        return 'Invalid request', 400
    
  • 检查授权标头源自提供的服务帐户和受众:

    try:
        bearer_token = request.headers.get('Authorization')
        token = bearer_token.split(' ')[1]
    
        claim = id_token.verify_oauth2_token(token, requests.Request(), audience='example.com')
        if claim['iss'] not in [
            'accounts.google.com',
            'https://accounts.google.com'
        ]:
            raise ValueError('Wrong issuer.')
    except Exception as e:
        return 'Invalid token: {}\n'.format(e), 400
    
    envelope = json.loads(request.data.decode('utf-8'))
    payload = base64.b64decode(envelope['message']['data'])
    
  • 瞧!现在应该可以使用了。

来源: https://github.com/googleapis/nodejs-pubsub/issues/118#issuecomment-379823198https://cloud.google.com/functions/docs/calling/http