Skip to content

Astro + Temporal try

This code demonstrates how to initiate a workflow in Astro using the Temporal client

This code demonstrates how to initiate a workflow in Astro using the Temporal client without defining the workflow code in TypeScript. Instead, it calls a worker that is written in Python just by specifying the workflow’s name.

Temporal Status
npm create astro@latest
create src/actions/index.ts
// src/actions/index.ts
import { defineAction } from "astro:actions";
import { z } from "astro:schema";
import { nanoid } from "nanoid";

import { Client } from "@temporalio/client";

export const server = {
  // action declarations
  getGreeting: defineAction({
    input: z.object({
      name: z.string(),
    }),
    handler: async (input) => {
      console.log(input);
      return `Hello, ${input.name}!`;
    },
  }),

  startTemporal: defineAction({
    handler: async (input) => {
      const client = new Client();
      const handle = await client.workflow.start("YourWorkflow", {
        taskQueue: "your-task-queue",
        args: ["Astro"],
        workflowId: "my-workflow-id" + nanoid(),
      });
      return { workflowId: handle.workflowId };
    },
  }),

// get status of the workflow (workflowId gets from previous action - startTemporal )
  temporalStatus: defineAction({
    input: z.object({
      workflowId: z.string(),
    }),
    handler: async (input) => {
      const client = new Client();
      const testHandle = client.workflow.getHandle(input.workflowId);
      const workflowStatus = await testHandle.query("get_workflow_status");
      return workflowStatus;
    },
  }),
};
// Welcome.astro

<button>Start the flow</button>
<p id="statusUpdate"></p>

...
<script>
	import { actions } from 'astro:actions';

	const button = document.querySelector('button');
	const statusUpdate = document.querySelector('#statusUpdate');

	button?.addEventListener('click', async () => {
		const { data, error } = await actions.startTemporal({ name: "Houston" });
		if (data && data.workflowId) {
			const checkStatus = async () => {
				const { data: statusData, error: statusError } = await actions.temporalStatus({ workflowId: data.workflowId });
				console.log('Workflow status:', statusData);
				const currentTime = new Date();
				const formattedTime = currentTime.getHours().toString().padStart(2, '0') + ':' + currentTime.getMinutes().toString().padStart(2, '0') + ':' + currentTime.getSeconds().toString().padStart(2, '0');
				statusUpdate.innerHTML += `<br/>${formattedTime} - Workflow status: ${statusData}`;

				if (statusError) {
					console.error('Error fetching workflow status:', statusError);
				} else {
					console.log('Workflow status:', statusData);
					if (statusData === 'wisdom') {
						clearInterval(statusInterval);
						console.log('Workflow has reached the wisdom status.');
					}
				}
			};

			// Call checkStatus every 5 seconds until status is 'wisdom'
			const statusInterval = setInterval(checkStatus, 5000);
		} else {
			console.error('Error starting workflow:', error);
		}
	});
</script>