如何建立一个自动发票生成器应用程序

661 阅读7分钟

本教程告诉你如何:

  1. 使用API生成并发送发票给你的客户
  2. 在你的配置中添加预定管道
  3. 使用项目设置定义预定触发器

作为一名软件工程师和技术内容创作者,我与很多公司签订了许多不同的合同。为了获得工作报酬,大多数公司要求我发送发票。有时他们希望每天都有一张,在周末,甚至在项目完成后。

向我的客户发送发票是至关重要的,因为它决定了我何时以及是否会按时得到付款。如果这听起来是一项重复性的工作,会深深吞噬我的生产时间,你是对的。为了让我专注于完成任务,我决定建立一个自动发票工作流程。

在本教程中,我将向你展示如何使用发票生成器API预定管道有效地生成和发送发票给你的客户。

前提条件

对于本教程,你将需要。

克隆演示程序

在本教程中,我设置了一个简单的Node.js项目,在invoice.js 文件中定义了一个现有的generateInvoice() 函数。要开始使用,请运行这个命令。

git clone https://github.com/yemiwebby/automated-invoice-starter.git automated-invoice

这将把该项目克隆到你的开发目录(或你运行该命令的任何地方)中的automated-invoice 文件夹。

接下来,进入新创建的项目并安装其依赖性。

cd automated-invoice

npm install

在本地生成一个发票

为了确认该项目按预期工作,在本地运行该应用程序。通过运行生成一张发票。

node invoice.js

输出结果应该显示,一张发票已经生成并保存在你的项目目录中。

Saved invoice to invoice.pdf

现在你可以设置将发票作为附件发送。

以附件形式发送发票

从任何部署在互联网上的应用程序发送电子邮件都需要一个SMTP服务器和其他一些配置。在本教程中,我使用了Mailtrap,它提供免费的SMTP服务,用于实验电子邮件的发送功能。如果你还没有这样做,请在这里创建一个Mailtrap账户

接下来,进入收件箱页面,查看你的SMTP和POP3凭证。

Mailtrap dashboard

创建一个环境变量

用这个命令在项目的根部创建一个.env 文件。

cp .env.sample .env

用你的mailtrap.io仪表板上的值替换占位符MAILTRAP_USERNAMEMAILTRAP_PASSWORD

发送带有发票附件的电子邮件

该应用程序使用nodemailer模块来发送带有发票附件的电子邮件。该模块已经安装。你需要做的就是打开invoice.js 文件,用这个替换它的内容。

var https = require("https");
var fs = require("fs");
require("dotenv").config();
var nodemailer = require("nodemailer");

const generateInvoice = (invoice, filename, success, error) => {
  var postData = JSON.stringify(invoice);
  var options = {
    hostname: "invoice-generator.com",
    port: 443,
    path: "/",
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Content-Length": Buffer.byteLength(postData),
    },
  };
  var file = fs.createWriteStream(filename);
  var req = https.request(options, function (res) {
    res
      .on("data", function (chunk) {
        file.write(chunk);
      })
      .on("end", function () {
        file.end();
        if (typeof success === "function") {
          success();
          sendEmail(filename);
        }
      });
  });
  req.write(postData);
  req.end();
  if (typeof error === "function") {
    req.on("error", error);
  }
};

const sendEmail = (file) => {
  var transport = nodemailer.createTransport({
    host: "smtp.mailtrap.io",
    port: 2525,
    auth: {
      user: process.env.MAILTRAP_USERNAME,
      pass: process.env.MAILTRAP_PASSWORD,
    },
  });
  var mailOptions = {
    from: "invoice@me.com",
    to: "sample@me.com",
    subject: "Invoice for weekly payments via Node.js",
    text: "Find attached the weekly invoice from me. Thanks",
    attachments: [
      {
        path: file,
      },
    ],
  };
  transport.sendMail(mailOptions, function (error, info) {
    if (error) {
      console.log(error);
    } else {
      console.log("Email sent: " + info.response);
    }
  });
};

let invoice = {
  logo: "http://invoiced.com/img/logo-invoice.png",
  from: "Invoiced\n701 Brazos St\nAustin, TX 78748",
  to: "Awesome Company / Client",
  currency: "usd",
  number: "INV-0001",
  payment_terms: "Due for payment",
  items: [
    {
      name: "Weekly technical content",
      quantity: 1,
      unit_cost: 500,
    },
    {
      name: "Employee Portal Management",
      quantity: 1,
      unit_cost: 1000,
    },
  ],
  fields: {
    tax: "%",
  },
  tax: 5,
  notes: "Thanks for being an awesome customer!",
  terms: "Looking forward to the payments",
};

generateInvoice(
  invoice,
  "invoice.pdf",
  () => console.log("Saved invoice to invoice.pdf"),
  (err) => console.log(err)
);

对这个代码块的修改通过要求nodemailer 模块来修改该文件。一个sendEmail() 函数被创建,它将生成的文件作为参数,并将其作为附件发送。该附件被发送到用mailOptions 变量定义的收件人处。*generateInvoice()* 函数调用sendEmail() 方法,并将适当的参数传递给它。

现在,再次运行该应用程序,使用。

node invoice.js

输出结果是:

Saved invoice to invoice.pdf
Email sent: 250 2.0.0 Ok: queued

这个输出显示,发票已经生成并成功发送。转到你的Mailtrap收件箱查看该邮件。

Mailtrap inbox

点击附件,打开发票。

Generate invoice

添加CircleCI配置文件

接下来,你需要为CircleCI添加管道配置,以自动创建和发送发票。

在你项目的根部,创建一个名为.circleci 的文件夹。在该文件夹中,创建一个名为config.yml 的文件。在新创建的文件中,添加这个配置。

version: 2.1
jobs:
  build:
    working_directory: ~/project
    docker:
      - image: cimg/node:17.4.0
    steps:
      - checkout
      - run:
          name: Update NPM
          command: "sudo npm install -g npm"
      - restore_cache:
          key: dependency-cache-{{ checksum "package-lock.json" }}
      - run:
          name: Install Dependencies
          command: npm install
      - save_cache:
          key: dependency-cache-{{ checksum "package-lock.json" }}
          paths:
            - ./node_modules
      - run:
          name: Run the application
          command: node invoice.js
          background: true

这个脚本拉入一个Node.js Docker镜像,并安装项目的依赖项。最后一步是运行命令,生成并发送发票。

接下来,在GitHub上建立一个仓库,将项目链接到CircleCI。

登录到您的CircleCI账户。如果您用您的GitHub账户注册,您所有的仓库将在您的项目仪表板上可用。

点击为你的automated-invoice 项目设置项目

Setup project on CircleCI

你会被提示有几个关于配置文件的选项。选择use the .circleci/config.yml in my repo 选项。输入你的代码在GitHub上存放的分支名称,然后点击Set Up Project按钮。

Select configuration

你的第一个工作流程将开始运行,但它会失败。这是因为你没有提供Mailtrap的配置细节。现在你可以解决这个问题。

点击项目设置按钮,然后点击环境变量。添加这两个新变量。

  • MAILTRAP_USERNAME
  • MAILTRAP_PASSWORD

重新运行工作流程。发票将被生成,电子邮件将被发送。

Successful Pipeline

设置一个预定的管道

通常情况下,一旦你把你的代码推送到存储库,CircleCI工作流就会自动执行。但在本教程中,我们的目标是在一个特定的时间间隔内运行该管道,最好是每周一次。使用CircleCI上的计划管道,你可以把你的管道配置成一个cron 工作,并以一定的时间间隔运行它。有两种方法可以做到这一点。

  • 使用API
  • 使用项目设置

对于本教程,我们将使用项目设置来配置管道触发器。在你的项目中,进入项目设置。从左侧边栏的菜单中点击Triggers

在触发器页面,点击添加预定的触发器。填写触发器表格来配置管道。

Schedule Trigger

下面是这些字段要输入的内容。

  • Trigger name 是唯一的计划名称。
  • Trigger Source 表示将触发管道的来源(在本教程中是 )。scheduled
  • Trigger description 是一个可选的字段,你可以用来添加更多关于触发器的信息。
  • Timetable 定义运行计划管道的时间和频率。
  • Pipeline Parameters 是在参数键内声明的变量。它们可以用来检查何时运行管道,但在本教程中你不需要它们。
  • Attribution 指定与时间表相关的用户。它可以是中立行为者的系统。或者它可以是当前的,这需要你当前用户的权限(根据你所使用的令牌)。

这些设置将管道配置为每天每5分钟运行一次。点击保存触发器来激活它。

你可以从项目触发器页面查看创建的触发器。

Project Triggers page

返回管道页面并等待至少五分钟。您的管道将被CircleCI系统触发。

Pipeline schedule results

您还可以查看您的Mailtrap收件箱,查看生成的发票。

Mailtrap multiple inbox list

总结

在本教程中,您能够即时生成发票,并将其发送给特定的收件人,而没有太多的麻烦。为了使开票过程自动化,我们使用了CircleCI的计划流水线功能。

因为你在这里实现的东西是最小的,所以它可以很容易地包含在一个现有的项目或一个新的项目中。这个工作流程的另一个优点是,你可以为你的项目保持持续集成和部署,同时CircleCI自动处理发票。这个附加功能消除了一项繁琐的手工任务,并使其自动化,这样你就可以把更多的时间用于开发和部署应用程序。