Node background timing browser screenshot and sent to the nail group

Background: There is a data kanban page in our department, which requires regular screenshots to be taken in the group to synchronize information with members in the group. Previously, we used to take screenshots manually, but sometimes I forget this method and the time is not controllable. Therefore, I consider whether I can realize automatic screenshots and send them to the pin group through node background.

The realization function is mainly the following parts

1. Set up the Node background

Please refer to my previous article on how a front-end developer develops Node from scratch to release

2. Enable puppeteer to load web pages and take screenshots

The first step is to install puttteer, a headless browser

import puppeteer from 'puppeteer'
Copy the code

Step 2 Open the web page

const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox']}) try {let token = await login() if (! token) { return } let url = `${baseUrl}/dashboard/index.html? token=${token}` const page = await browser.newPage() page.setViewport({ width: 1920, height: 1080 }) await page.goto(url, { timeout: 50000 }) await page.waitFor(4000) // await waitTime(4000) await page.screenshot({ type: 'png', path: ImgPath fullPage: true})} Catch (error) {console.log(error)} finally {await browser.close()}Copy the code

Matters needing attention:

1. Parameters such as sandbox are reported in centos. You need to add parameters during browser initialization
2. SetViewport Set the width and height of the page as required
3. The page.goto parameter timeout is the timeout period for opening web pages. I set this parameter to 50s and set it as required
4. Page.waitfor (4000) specifies the wait time for the page. For example, if the page is separated from the front and back, we need to waitFor the ajax request data to complete before taking a screenshot. There is, of course, another way to do this, which is to use the waitUntil parameter in the goto method

The third way is to implement a waitTime method yourself through a promise that waits for the corresponding time.

5. Page. Screenshot is a screenshot method.
6. Finally, the most important thing is to always put the screenshot ina try catch and finally close the browser, otherwise if the browser is not closed, the server memory will be very impressive.

3. Upload pictures to Jinshanyun

Ks3, AK,SK, ks3, AK,SK

let KS3 = require('ks3' // AK = AccessKey; SK = SecretKey let ks3 = new ks3 (ACCESS_KEY_ID, ACCESS_KEY_SECRET) ks3.object.put() // Use this method to upload a local imageCopy the code

After uploading the image, you will get an online address of Jinshanyin. Note that you need to set the permission of the image to ACL: ‘public-read’ when uploading the image.

4. Create a scheduled task

“Node-schedule” is used for scheduled tasks. I define that the scheduled tasks are sent at 10 o ‘clock every day. Please refer to the Github document for specific rules

Import schedule from 'node-schedule' // define a rule let rule = new schedule.recurrencerule () rule-hour = 10 // rule. Minute = 0 // minute rule-second = 0 // second schedule.scheduleJob(rule, () => {action() // execute a series of methods, including screenshot, upload, send nail})Copy the code

5. Send messages to the spike group

Tacks has API documentation, but I’m using a library packaged by my brotherdingtalk-robot-sender, very useful

1. Add a custom robot to the nail group, and a Webhook will be generated after the addition. Please copy this address, which we need when sending the nail message.

2. When adding a robot, you need to add customized keywords. When sending a message, you need to contain one or more of these keywords to send the message successfully.

3. You can directly call the encapsulated markdown, text, link, and text methods to send messages.

This library is very simple to use and recommended.

Import ChatBot from 'dingtalk-robotsender' const robot = new ChatBot({webhook: ` `} {webShotToken} https://oapi.dingtalk.com/robot/send?access_token=$const title = 'keyword' const text = ` # # # # ${format (' yyyy - MM - dd hh: MM)} board data (${} XXX) \ n ` + ` # # # # # XXXXX: ${data} \ n \ n ` + ` # # # # #! [](${data.img})\n\n` const at = { isAtAll: false, atMobiles: [''] } robot.markdown(title, text, at)Copy the code

6. Release of the use of the pit encountered

1. I am using PM2 to manage node distribution, which will start 4 sub-processes. In the code, I started the scheduled task during initialization, which will cause a problem.

The solution is to identify the process by its ID and initialize the scheduled task only when the process ID is 0.

This can be determined by the INSTANCE_ID field in process.env. This field was actually configured in the pM2 configuration file because of a conflict between pm2 and the config library, so I needed to define a variable name. If not, you can use the ‘NODE_APP_INSTANCE’ variable to get the process ID.

"instance_var": "INSTANCE_ID",
process.env.INSTANCE_ID === '1
Copy the code

2. Just as the so-called wave is not smooth, another wave arises. Just as the V problem of PM2 is solved, a new problem arises. An enemy will stop a thief from coming. This time, the solution is to determine the IP address of the server. Both servers have their own IP addresses. As long as the IP address of one server is locked, only the scheduled task on this server is good.

The procedure for obtaining an IP address is as follows

export function getIPAdress() { let interfaces = require('os').networkInterfaces() for (let devName in interfaces) { let  iface = interfaces[devName] for (let i = 0; i < iface.length; i++) { let alias = iface[i] if ( alias.family === 'IPv4' && alias.address ! = = '127.0.0.1 &&! alias.internal ) { return alias.address } } } }Copy the code

Finally finally, after the service online found that the page Chinese font a lot of display square… Collapse…

We use centos 7.5. There are a lot of solutions on the web to copy Windows font files to centos. I find this a bit troublesome… So I kept looking. I finally found a way. Just execute this method.

yum groupinstall Fonts
Copy the code

All set ~ see you every day at 10:00. What problem please leave a message to correct ha ~