I always get a "Success" HTTP response even though I'm issuing a custom response from my workflow

This topic was automatically generated from Slack. You can find the original thread here.

Vincent Lo : I am trying to get a custom response from a Lambda call back to a webhook/HTTP trigger but regardless of what I do, I always get the default “Success!
To customize this response, check out our docs here” message. I have tried many combinations of the code below

const AWS = require('aws-sdk')
const { accessKeyId, secretAccessKey } = auths.aws
const { region, FunctionName, eventData } = params

const lambda = new AWS.Lambda({
  accessKeyId,
  secretAccessKey,
  region
})

const lambdaParams = {
  Payload: eventData,
  FunctionName,
  InvocationType: "RequestResponse",
  LogType: "Tail",
}

this.res = await lambda.invoke(lambdaParams).promise()

this.res = await $respond({
  status: 200,
  headers: { "my-custom-header": "value" },
  body: { message: "My custom response" } // This can be any string, object, or Buffer
})

Dylan Sather (Pipedream) : just to confirm, are you using a Pipedream workflow, or an event source?

Can you remove the this.res = await portion of the $respond code?

$respond() should run synchronously the way you’re using it (so no need for the await ), and you’ll see the HTTP response that’s issued for a specific HTTP response in the observability of the trigger step (in steps.trigger.response), when you select a specific event, so you don’t need to add this.res to save the response:

Dylan Sather (Pipedream) : so if you just run:

$respond({
  status: 200,
  headers: { "my-custom-header": "value" },
  body: { message: "My custom response" },
});

it should work

Vincent Lo : yes, I am using a Pipedream workflow, through a webhook trigger to a Jotform. I then invoke a Lamda and am trying to respond with an event json eventually
thank you for your response, i shall eagerly try it now!

Dylan Sather (Pipedream) : great, if that doesn’t work, feel free to add dylan@pipedream.com as a workflow collaborator and I can take a look at your setup

Vincent Lo : hmm, still no joy. below is screenshot of entire step.

Dylan Sather (Pipedream) : ah so, are you using the Typeform event source (at Sources - Pipedream), and triggering the workflow from that?

Vincent Lo : I can see the response trying to get out…!

Vincent Lo : yes, i am using the built-in webhook creator that generates and connects the trigger to jotform

Dylan Sather (Pipedream) : got it, so currently because of how event sources trigger workflows, you can’t issue a custom response all the way from the workflow back to the client that called the event source. Do you need to issue a custom response based on the response from Lambda, or do you just need to issue a more custom, static response?

If you just want to return a custom, static response from the event source itself, visit Sources - Pipedream and select your Typeform source, click on the Configuration tab and you’ll see the code for that source. You’ll need to do two things:

First, change the line that reads http: "$.interface.http", to

http: {
  type: "$.interface.http",
  customResponse: true,
},

Then, issue the response you want using a similar API as the $respond() code you used earlier:

this.http.respond({
  status: 200,
  body: { message: "My custom response" },
  headers: { "my-custom-header": "value" },
});

Vincent Lo : i just thought i was going nuts. ok, i shall have a play.
Thank you! :thumbsup:

Dylan Sather (Pipedream) : this limitation is definitely not obvious, I’ll actually document this clearly in that section of the HTTP response docs

Vincent Lo : nearly there i think. do I need to import something?

Dylan Sather (Pipedream) : ah so that code I referenced above will actually need to go into your Typeform event source, at Sources - Pipedream

Vincent Lo : sorry, i’m a bit lost. the event source is below, after adding customresponse: true

const jotform = require('https://github.com/PipedreamHQ/pipedream/components/jotform/jotform.app.js')

module.exports = {
  name: "new-submission",
  version: "0.0.2",
  props: {
    jotform,
    formId: { propDefinition: [jotform, "formId"] },
    http: {
      type: "$.interface.http",
      customResponse: true,
    },
  },
  hooks: {
    async activate() {
      return (await this.jotform.createHook({
        endpoint: this.http.endpoint,
        formId: this.formId,
      }))
    },
    async deactivate() {
      return (await this.jotform.deleteHook({
        endpoint: this.http.endpoint,
        formId: this.formId,
      }))
    },
  },
  async run(event) {
    event.body.formData = JSON.parse(event.body.rawRequest)

    this.$emit(event.body, {
      summary: event.body.rawRequest || JSON.stringify(event.body),
      id: event.body.submissionID,
    })
  },
} 

Vincent Lo : its not clear to me where I should add

this.http.respond({
  status: 200,
  body: { message: "My custom response" },
  headers: { "my-custom-header": "value" },
});

Dylan Sather (Pipedream) : ah sorry, that should go within the run method near the bottom. Since the HTTP response happens asynchronously (technically it happens after the code runs), you can actually put it anywhere. I like to put it near the top of the run method to clarify that we’re issuing a response, so that section should read:

async run(event) {
  this.http.respond({
    status: 200,
    body: { message: "My custom response" },
    headers: { "my-custom-header": "value" },
  });

  event.body.formData = JSON.parse(event.body.rawRequest)

  this.$emit(event.body, {
    summary: event.body.rawRequest || JSON.stringify(event.body),
    id: event.body.submissionID,
  })
},

Dylan Sather (Pipedream) : We refer to Pipedream event sources generically as “components”, and you can read more about the API for those here: pipedream/COMPONENT-API.md at master · PipedreamHQ/pipedream · GitHub

Over time we’re planning to unify more about workflows and event sources / components, so there should be fewer inconsistencies with HTTP responses and other features in the future!

Vincent Lo : Omg, it worked! I can get custom headers now!

Vincent Lo : so the question is, how do i call/use/set this in the main workflow? still use $respond or something else now?

$respond({
  status: 200,
  headers: { "my-custom-header": "value" },
  body: { message: "My custom response" },
});