Bootstrap

管理节点和计算节点_使用节点1自动化办公室管理

管理节点和计算节点

File Cabinets, bookkeeping, and more are part of normal business operations. In this article we use Node.JS to explore ways to automate these tasks.

文件柜,簿记等功能是正常业务的一部分。 在本文中,我们使用Node.JS探索自动执行这些任务的方法。

Lets tackle some common items in managing an office for a small business. The first challenge we’ll examine is the typical file cabinet.

让我们解决管理小型企业办公室中的一些常见问题。 我们将研究的第一个挑战是典型的文件柜。

The purpose of the file cabinet is to store documents. Every business has their own “system” for how data is stored in the file cabinet. As long as it makes sense, most people can use it. We’ll leave this type of organisation to the experts — the administrative experts and/or bookkeepers. No, we are more interested in WHERE the data gets stored.

文件柜的目的是存储文件。 每个企业都有自己的“系统”来存储文件柜中的数据。 只要有意义,大多数人都可以使用它。 我们将把这种类型的组织留给专家-行政专家和/或簿记员。 不,我们对存储数据的位置更感兴趣。

The only thing that really needs to be physically stored are those documents that have a “wet signature” — someone has signed it with a pen. Almost every other document can be digitised by scanning it and turning it into an image or PDF file.

真正需要物理存储的唯一东西是那些带有“湿签名”的文档-有人用钢笔签名了。 几乎所有其他文档都可以通过扫描并将其转换为图像或PDF文件进行数字化处理。

We can create a virtual file cabinet then to store our documents. A simple directory structure like this may do the trick:

我们可以创建一个虚拟文件柜,然后存储我们的文档。 像这样的简单目录结构可以解决问题:

file_cabinet
- _inbox
- bookkeeping
- contracts
- ... other folders as needed ...

The actual folder names are arbitrary and up to you. The only one that needs more detail is the _inbox folder. This folder is intended as a temporary storage location for newly scanned documents. Our scanners often name the files for us automatically with incredibly descriptive filenames like Scanned_from_a_Lexmark_Multifunction_product_09-07-2020-023924.pdf. Placing these files into the _inbox folder gives us a chance to review the file, rename that file to something meaningful, and then to move that file into an appropriate folder in our virtual file cabinet.

实际的文件夹名称是任意的,由您决定。 唯一需要更多详细信息的是_inbox文件夹。 该文件夹旨在用作新扫描文档的临时存储位置。 我们的扫描仪经常使用Scanned_from_a_Lexmark_Multifunction_product_09-07-2020-023924.pdf文件名自动为我们命名文件,例如Scanned_from_a_Lexmark_Multifunction_product_09-07-2020-023924.pdf 。 将这些文件放在_inbox文件夹中,使我们有机会查看文件,将文件重命名为有意义的文件,然后将其移动到虚拟文件柜中的适当文件夹中。

If we are doing things manually we are done. Just scan into the _inbox folder or directly into the appropriate file cabinet folder.

如果我们手动做事,那就完成了。 只需扫描到_inbox文件夹或直接扫描到相应的文件柜文件夹即可。

BUT, we mentioned automating the process.

但是,我们提到了自动化过程。

If you are lucky enough to have a scanner that can send emails, you may opt to create a special mailbox to send these documents to. Then drag/drop the files from that mailbox to the _inbox folder. We can automate this with a little bit of scripting.

如果您幸运地拥有可以发送电子邮件的扫描仪,则可以选择创建一个特殊的邮箱来发送这些文档。 然后将文件从该邮箱拖放到_inbox文件夹。 我们可以用一些脚本来自动化它。

The idea here is to have some code that connects to the mailbox, extracts the attachments from the email messages, stores those attachments into our _inbox folder, and then moves the message into a “Processed” folder in the mailbox. The “Processed” mailbox folder may optionally be configured to automatically delete messages after a period of time, giving us a way to keep our mailbox clean and not requiring a good deal of mail storage.

这里的想法是让一些代码连接到邮箱,从电子邮件中提取附件,将这些附件存储到我们的_inbox文件夹中,然后将消息移动到邮箱中的“已处理”文件夹中。 可以选择将“已处理”邮箱文件夹配置为在一段时间后自动删除邮件,从而为我们提供了一种保持邮箱清洁且无需大量邮件存储的方式。

The code below will do this for us.

下面的代码将为我们做到这一点。

For this article, we will assume you are connecting to your mailbox via IMAP. If you use POP3, the code below will not work for you.

对于本文,我们假设您正在通过IMAP连接到您的邮箱。 如果您使用POP3 ,那么下面的代码将对您不起作用。

First we need to have an appropriate mailbox set up. Within this we should create a folder called “Processed” at the same level as the “Inbox”. If we do not do this we can expect errors when the code tries to move the messages.

首先,我们需要设置适当的邮箱。 在其中,我们应该在与“收件箱”相同的级别上创建一个名为“已处理 ”的文件夹。 如果我们不这样做,当代码尝试移动消息时,我们可能会期望出现错误。

Next we need our project folder setup. Run the following commands:

接下来,我们需要设置项目文件夹。 运行以下命令:

mkdir MyProject
cd MyProject
mkdir src
npm init -y

Then install the imap-simple module.

然后安装imap-simple模块。

npm install imap-simple

Now we can use it in our code. Create a src/index.js file and use this code.

现在我们可以在代码中使用它了。 创建一个src/index.js文件并使用此代码。

const fs = require('fs')
const path = require('path')
const imaps = require('imap-simple')


const _inboxFolder = '/home/myUser/Documents/file_cabinet/_inbox'
const PROCESSED_FOLDER = 'Processed'


// The mailbox connection information
// You may need to set the TLS option to TRUE, or use a different port.
var config = {
  imap: {
    user: '[email protected]',
    password: 'Super Secret',
    host: 'mymailserver.com',
    port: 143,
    tls: false,
    authTimeout: 3000,
  },
}


// ----------
// Functions
// ----------


// save the attachment in the _inbox folder
function saveAttachment(fname, content) {
  const target = path.join(_inboxFolder, fname)
  fs.writeFile(target, content, (err) => {
    if (err) {
      console.log(err)
    }
  })
}


// establish a connection to the mailbox account
async function connectToAccount(config) {
  return await imaps.connect(config)
}


// open the desired mailbox (usually this will be 'INBOX')
async function openMailbox(connection, mailbox) {
  return await connection.openBox(mailbox)
}


// retrieve a list of messages that matches our search criteria
async function searchMailbox(connection, searchCriteria, fetchOptions) {
  return await connection.search(searchCriteria, fetchOptions)
}
// ----------


// the main method
// we do this so that we can make use of async/await.
// You can use the .then() method if you'd prefer
async function main() {
  // define our search criteria and fetch options
  const searchCriteria = ['ALL']
  const fetchOptions = {
    bodies: ['HEADER.FIELDS (FROM TO SUBJECT DATE)'],
    struct: true,
  }


  // establish a connection to the account
  const connection = await connectToAccount(config)


  // open the mailbox
  await openMailbox(connection, 'INBOX')


  // retrieve a list of current messages
  const messages = await searchMailbox(connection, searchCriteria, fetchOptions)


  // for each message we retrieved, see if there are any attachments
  for (const message of messages) {


    // extract the parts of the message (think multi-part email messages)
    let parts = imaps.getParts(message.attributes.struct)


    // filter out any parts that do not have an attachment
    parts = parts.filter(
      (part) =>
        part.disposition && part.disposition.type.toUpperCase() === 'ATTACHMENT'
    )


    // for each of the parts, retrieve the attachement data
    for (const part of parts) {
      // ensure we have a valid part.
      // without this IF statement, we may process parts that are still being populated and throw errors.
      if (part && part.type) {
        // extract the attachment data
        const partData = await connection.getPartData(message, part)
        // save the attachment
        saveAttachment(part.disposition.params.filename, partData)
      }
    }


    // now move the message to the processed folder
    await connection.moveMessage(message.attributes.uid, PROCESSED_FOLDER)
  }


  // close the connection to the mailbox
  await connection.closeBox()


  // exit the application
  // - note that without this the connection remains open and the program does not stop on its own
  process.exit(0)
}


// call the main method 
main()

The code above is commented so should be fairly clear. The important parts are between lines 70 and 94. This is where we examine each email message, extract the attachment data, save the file, and then move the message to our “Processed” directory.

上面的代码已注释,因此应相当清楚。 重要部分在第70和94行之间。在这里,我们检查每封电子邮件,提取附件数据,保存文件,然后将邮件移至“已处理”目录。

If you do not have the “Processed” folder you can expect an error on line 94. To fix that you can either comment out line 94, or create the “Processed” folder.

如果没有“已处理”文件夹,则可能在第94行出现错误。要解决此问题,您可以注释掉第94行,或创建“已处理”文件夹。

Set up the config object at lines 5–17 with your specific data. This would include where your _inbox directory is (use an absolute path), the name of your “Processed” folder (in the mailbox), and your mailbox connection details.

在第5–17行使用您的特定数据设置配置对象。 这将包括_inbox目录的位置(使用绝对路径),“已处理”文件夹的名称(在邮箱中)以及邮箱连接详细信息。

Now we can run the code with node src/index.js. You should see a pause for a few moments. The more messages you have in your mailbox, and the larger the attachments, the longer that pause will be. Once completed you should be returned to your prompt and your _inbox directory should have some attachments.

现在,我们可以使用node src/index.js运行代码。 您应该会稍停片刻。 邮箱中的邮件越多,附件越大,则暂停时间越长。 完成后,应返回到提示,并且_inbox目录应包含一些附件。

Next up we just need to run this routine periodically to retrieve our documents. We could do that via a CRON job, or by manually calling this routine. For me, I’d have a CRON job run this every 30 minutes. Then I could forget about it and just focus on the scanned documents.

接下来,我们只需要定期运行此例程即可检索我们的文档。 我们可以通过CRON作业或手动调用此例程来实现。 对我来说,我每30分钟执行一次CRON作业。 然后我可能会忘记它,而只关注扫描的文档。

I won’t pretend that this is production ready code. It is a proof of concept at best, but nicely does the connection to the IMAP folder for us.

我不会假装这是生产就绪代码。 充其量只是一个概念证明,但对于我们来说,与IMAP文件夹的连接很好。

There is still lots more we can do to automate our small business office. We’ll explore that in future articles.

我们还有很多工作可以使小型企业办公室实现自动化。 我们将在以后的文章中对此进行探讨。

翻译自: https://medium.com/swlh/automating-office-management-with-node-1-84096db9974c

管理节点和计算节点

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;