2022-12-06 12:28:16 +00:00
2022-12-06 12:28:16 +00:00
2022-12-06 12:28:16 +00:00
2022-12-06 12:28:16 +00:00
2022-12-06 12:28:16 +00:00
2022-11-30 14:59:08 +00:00
2022-12-06 12:28:16 +00:00
2022-12-06 12:28:16 +00:00
2022-12-06 12:28:16 +00:00

trigger.dev

Problem: Tools like Pipedream are great for quickly coding up a workflow that interacts with external services, but cannot easily access internal databases or internal services without opening them up to the internet or building proxies.

Solution: With Internal Workflow, your workflows are written in your existing codebase and run in your existing infrastructure, but are coordinated through the Internal Workflow service, making it easy to trigger workflows when external events happen and make authenticated requests to APIs.

Examples

GitHub issue sync

Let's start with a simple one: syncing GitHub issues to a database

import { Workflow } from "@internal/workflows";
import { issues } from "@internal/github";

import { upsertIssue, deleteIssue } from "./db.server";

new Workflow({
  title: "Sync issues to internal database",
  version: "1.0.0",
  trigger: issues({ repo: "calcom/cal.com" }),
  run: async ({ action, data }, ctx, io) => {
    if (action === "deleted") {
      await deleteIssue(data.id);
    } else {
      await upsertIssue(data);
    }
  }
}).listen();

Send welcome email, slack message, and add user to intercom when inserted into database

This workflow is a bit more complicated. It's triggered whenever a new record is INSERTed into the users table:

import type { User } from "./db.server";
import { Workflow } from "@internal/workflow";
import { trigger } from "@internal/pg";
import { welcomeEmail } from "./emails";
import { updateUser } from "./db.server";

new Workflow({
  title: "Send Welcome Email to new users",
  version: "1.0.0",
  trigger: trigger<User>({
    table: "users",
    event: "INSERT",
  }),
  run: async (data, ctx, io) => {
    // Make sure the user is not a bot
    if (data.isBot) {
      return;
    }

    // Return if the user already received the welcome email
    if (data.emailSent) {
      return;
    }

    ctx.logger.info("Waiting for 30 minutes before sending the email", {
      user: data,
    });

    // Wait 30 minutes before sending the email
    await io.wait(30 * 60 * 1000);

    ctx.logger.info("Sending welcome email to new user", {
      user: data,
    });

    // Send the email through the email service
    await io.sendEmail({
      to: data.email,
      subject: "Welcome to our app!",
      body: welcomeEmail(data),
    });

    ctx.logger.info(`Sent welcome email to ${data.email}`);

    // Update the user to mark that the email was sent
    await updateUser(data.id, {
      emailSent: true,
    });

    await ctx.parallel([
      // Send a slack notification that the email was sent
      io.slack
        .sendMessage({
          text: `Welcome email sent to ${data.email}`,
        })
        .retry(3),
      // Save the user id on intercom
      io
        .fetch("intercom", {
          url: "https://api.intercom.io/users",
          method: "POST",
          body: JSON.stringify({
            user_id: data.id,
          }),
        })
        .retry(3),
    ]);
  },
}).listen();

Development

Warning

All the following commands should be launched from the monorepo root directory

  1. Install the dependencies.

    pnpm install
    

    You also have to copy the example .env.example:

    cp .env.example .env
    cp .env.example .env.docker
    
  2. Start the postgresql docker container

    pnpm run docker:db
    

    Note: The npm script will complete while Docker sets up the container in the background. Ensure that Docker has finished and your container is running before proceeding.

  3. Generate prisma schema

    pnpm run generate
    
  4. Run the Prisma migration to the database

    pnpm run db:migrate:deploy
    
  5. Run the first build (with dependencies via the ... option)

    pnpm run build --filter=webapp...
    

    Running simply pnpm run build will build everything, including the NextJS app.

  6. Run the Remix dev server

    pnpm run dev --filter=webapp
    

Tests, Typechecks, Lint, Install packages...

Check the turbo.json file to see the available pipelines.

  • Run the Cypress tests and Dev
    pnpm run test:e2e:dev --filter=webapp
    
  • Lint everything
    pnpm run lint
    
  • Typecheck the whole monorepo
    pnpm run typecheck
    
  • Test the whole monorepo
    pnpm run test
    or
    pnpm run test:dev 
    
  • How to install an npm package in the Remix app ?
    pnpm add dayjs --filter webapp
    
  • Tweak the tsconfigs, eslint configs in the config-package folder. Any package or app will then extend from these configs.
S
Description
Trigger.dev 支持构建和部署完全托管的 AI Agent 与工作流。|GitHub 镜像 16.1k · 🍴 1.4k
https://github.com/triggerdotdev/trigger.dev Readme Apache-2.0 189 MiB
Languages
TypeScript 99%
JavaScript 0.4%
Shell 0.2%
CSS 0.1%