Communication between a workflow execution and an external app

Hi,

I’ve been looking to make my external app (a node.js API) be able to receive events from my workflows, for example when a workflow finished its execution or is in a special state.

Right now, I made an Activity function called SendWebhook which will send a request to my Node API, then my server will be notified about the event occured in the workflow.

Here is my Node.js API (pseudocode)

// server.js
server.get("/test", async () => {
  /* Workflow gets pushed in the queue, everything works */
  await temporalClient.start(workflowOptions, "MyWorkflow", args);
});

server.post("temporal", async (req, res) => {
  const { event, data } = req.body;

  switch(event) {
    case "workflow.first_email_sent":
      firstEmailSentHelper(data);
      break;
    case "workflow.finished":
      finishedHelper(data);
      break;
  }
});

server.start();

Here is what MyWorkflow can look like (pseudocode)

// workflow.go
func MyWorkflow(ctx workflow.Context) {
  workflow.ExecuteActivity(ctx, SendEmail).Get(ctx, nil)
  workflow.Sleep(10 days)

  workflow.ExecuteActivity(ctx, SendWebhook, map[string]interface{}{
    "event": "myworkflow.first_email_sent",
    "data": map[string]string{
      "foo": "bar"
    }
  }).Get(ctx, nil)

  workflow.Sleep(1 day)
  workflow.ExecuteActivity(ctx, SendEmail).Get(ctx, nil)

  workflow.ExecuteActivity(ctx, SendWebhook, map[string]interface{}{
    "event": "myworkflow.finished",
    "data": map[string]string{
      "foo": "bar"
    }
  }).Get(ctx, nil)
}

func SendWebhook(ctx workflow.Context, data map[string]interface{}) error {
  req := http.Post("http://node_api_url/temporal", data)
  req.SetHeader("Authorization", "...")

  err := req.Do()
  if err != nil {
    return err
  }
}

I am wondering if this is the best solution or is it possible to use the Node (in my case) SDK to receive events via gRPC or even another solution.

Learning Temporal and gRPC at the same time, I’ve probably missed the ressources in the docs

Thank you in advance

You can try using the NodeJs SDK which is currently in alpha.

I am already using the Node SDK to start workflows from my expressjs app, my question was more about how to communicate from a worker to my other services.

Is it a good solution to send http requests from my Workflow activities to my API service, or does Temporal have a better solution to communicate with it?

Is it a good solution to send http requests from my Workflow activities to my API service, or does Temporal have a better solution to communicate with it?

It is a reasonable solution when you don’t have control over other services. If you do have control I would make those services implement Temporal activity and invoke that activity from the workflow.

1 Like

Thank you for your response

Does this mean that I should run a worker on my API?

Does this mean that I should run a worker on my API?

Yes. Here is a post that goes over the benefits of doing that.