[nodeJS]친구를 위한 주가지수


사실 나는 nodeJS 책을 읽었고 이 책에서 크롤링 Cheerio, Nodemailer, Exceljs, Node-Cron에 대해 간략하게 배울 수 있었다.

이런 것들을 배운 후에 적용하고 싶습니다.

가장 친한 친구를 어떻게 도울 수 있습니까? 물어봤다.

.

증권업에 종사하는 친구를 위해 아침 7시에 각종 지수를 모아서 엑셀로 변환해서 메일로 보내는 nodejs 코드를 작성해 주었습니다.

cron.schedule(
  '0 7 * * *',
  async () => {
    const indexes = await getIndex();
    const excelFile = await genExcel(indexes);
    sendMail(excelFile);
  },
  {
    scheduled: true,
    timezone: 'Asia/Seoul',
  }
);

나는 매일 아침 7시에 실행되는 cron을 작성했습니다.

getIndex() 함수는 원하는 인덱스를 모두 가져오는 함수입니다.

내 친구가 필요로 하는 지수가 정확했기 때문에 매개변수 없이 싱글액션 함수로 작성했습니다.

그런 다음 방금 얻은 인덱스를 매개 변수로 전달하여 이러한 인덱스를 사용하여 Excel을 생성하는 함수인 genExcel() 함수에 전달합니다.

엑셀 파일이 생성되면 이메일 발송을 위해 sendMail() 함수로 전송됩니다.

const getIndex = async () => {
  try {
    const (
      responseKorea,
      responseUSA,
      responseTOPX,
      responseEXCHANGE,
      responseSwedenEXCHANGE,
    ) = await Promise.all((
      axios.get(urlKoreaIndex),
      axios.get(urlUSAIndex),
      axios.get(urlTOPXIndex),
      axios.get(urlEXCHANGEIndex),
      axios.get(urlSwedenExchage),
    ));

    const $korea = cheerio.load(responseKorea.data);
    const $usa = cheerio.load(responseUSA.data);
    const $topx = cheerio.load(responseTOPX.data);
    const $exchange = cheerio.load(responseEXCHANGE.data);
    const $swedenExchange = cheerio.load(responseSwedenEXCHANGE.data);

    return {
      KOSPI: $korea('#KOSPI_now').text(),
      KOSDAQ: $korea('#KOSDAQ_now').text(),
      DOW: $usa(dowSelector).text(),
      NASDAQ: $usa(nasdaqSelector).text(),
      SNP500: $usa(snpSelector).text(),
      TOPX: $topx('.spt_con strong').text(),
      USAEX: $exchange(usaExSelector).text(),
      JAPANEX: $exchange(japanExSelector).text(),
      EUROEX: $exchange(euroExSelector).text(),
      SWEDENEX: $swedenExchange(swedenExSelector).text(),
    };
  } catch (error) {
    console.error(error);
    return null;
  }
};

색인을 한번에 모아주는 사이트를 찾기가 생각보다 어려워서 여기저기 다니면서 HTML을 가지고 왔습니다.

먼저 인덱스를 받을 때마다 기다리면서 총 5번을 기다려야 하도록 코드를 작성했습니다.

HTML을 가져오는 웹사이트는 관련이 없으므로 Promise.all을 사용하여 이를 병렬로 처리했습니다.

문자열 선택자는 dowSelector와 같은 위치에 저장됩니다.

이렇게 하면 원하는 지수를 얻은 후에 반환됩니다.

const genExcel = async (data) => {
  const workbook = new ExcelJS.Workbook();
  const firstSheet = workbook.addWorksheet('지수리스트');
  firstSheet.columns = excelHeader;
  firstSheet.addRow(data);

  const excel = await workbook.xlsx.writeBuffer();
  return excel;
};

엑셀이 가능합니다.

excelHeader는 이미 매개변수로 받은 데이터와 키를 비교했기 때문에

쉽게 쓸 수 있습니다.

const send = async (data) => {
  const transporter = nodemailer.createTransport(config);
  const result = await transporter.sendMail(data);
  return result.messageId;
};

module.exports = { send };
const sendMail = async (buffer) => {
  if (!
Buffer.isBuffer(buffer)) { throw new Error('Invalid buffer object.'); } const filename = `${Date.now()}_각종지수.xlsx`; const fromEmail = process.env.MAIL_FROM; const toEmail = process.env.ENV === 'dev' ? process.env.MAIL_TO_DEV : process.env.MAIL_TO_PROD; const result = await nodemailer.send({ from: fromEmail, to: toEmail, subject: '각종지수 엑셀발송', text: '문의는 변기원에게', attachments: ( { filename, content: buffer, contentType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', }, ), }); if (!
result?.length) { throw new Error('Failed to send email.'); } return result; };

다른 모듈에서 보내기 기능의 사용을 단순화하고 오류를 처리하기 위해 result.messageId를 반환하자

메일을 받을 사람은 친구뿐이므로 환경변수에 넣고 nodemailer.send()를 실행하여 메일을 보냅니다.

그리고 버퍼를 가져와서 연결해봅시다.

생각해보면 위의 genExcel 함수를 genExcelBuffer와 같은 것으로 대체하는 것이 좋을 것입니다.

그 후로 하루에 한 번만 오전 7시에 방송되는 것이 아쉬웠다.

따라서 프론트엔드 화면을 생성하고 API를 첨부하고 (GET 요청 보내기)를 클릭하면 시간 기준으로 인덱스가 결합됩니다.

이메일을 보내는 API를 만들었습니다.

나는 일하는 동안 그녀의 기분을 좋게 하기 위해 그녀에게 꽃가루를 불어주기도 했다.

누군가에게 도움이 되기 때문에 배우기를 좋아합니다.