2

I try to develop simple app for extracting OTP code from my inboxes on next.js

To get the email data from mailboxes I use nodejs with the help of node-imap library. I use trpc on next.js to call the node code (actually I'm not sure if this is a correct way to call node in next.js).

Here is the code on src/pages/api/trpc/[trpc].ts

let OTPcodes: (string | null)[] = [];

async function run() {
    const config = {
        imap: {
            user: process.env.NEXT_PUBLIC_YMAIL_USER,
            password: process.env.NEXT_PUBLIC_YMAIL_PASSWORD,
            host: process.env.NEXT_PUBLIC_YMAIL_HOST,
            port: process.env.NEXT_PUBLIC_EMAIL_PORT,
            tls: process.env.NEXT_PUBLIC_EMAIL_TLS,
        },
        debug: logger.info.bind(logger),
    };

    const imap = new MyImap(config);
    const result = await imap.connect();
    logger.info(`result: ${result}`);
    const boxName = await imap.openBox();
    logger.info(`boxName: ${boxName}`);

    const criteria = [];
    criteria.push(['HEADER', 'SUBJECT', ' Account']);
    
    const emails = await imap.fetchEmails(criteria);
    for (let email of emails){
        let otp = null;
        mailParser.simpleParser(email.body, async (err, parsed) => {
          
          otp = matchOTP(parsed.text);
          console.log("OTP "+ otp);
          OTPcodes.push(otp);

        });
    }

    await imap.end();
}

function matchOTP(email: any){
  const regex = /\b(?![A-Z]{5}\b)[A-Z0-9]{5}\b/;
  const match = email.match(regex);
  return match && match[0];
}



async function parseEmails(){
    await run().then(() => {
      //process.exit();
    }).catch((error) => {
        logger.error(error);
        process.exit(1);
    });
}

function getOTPcodes(){
  console.log("Array of OTP "+JSON.stringify(OTPcodes));
  return OTPcodes;
}

const appRouter = router({
 
  //  Tip: Try adding a new procedure here and see if you can use it in the client!
   getOTP: publicProcedure.query(async () => {
    await parseEmails();
    let output = getOTPcodes();
    return output;
  }),
});

// export only the type definition of the API
// None of the actual implementation is exposed to the client
export type AppRouter = typeof appRouter;

// export API handler
export default trpcNext.createNextApiHandler({
  router: appRouter,
  createContext: () => ({}),
});

The problem is when I call trpc.getOtp.useQuery() from react component, I don't get all OTPCodes that supposed to be in the array (return empty array). I think I have problem in writing the asynchronous part of my codes.

Another problem is, in the parseEmails() function I call process.exit() method to stop calling the run() method repeateadly. Somehow if I don't call that method, the parseEmails function is executed several times (kind of automatic refresh every some seconds). But if I call that process.exit() method, it give me another error:

error Error: read ECONNRESET
    at TCP.onStreamRead (node:internal/stream_base_commons:217:20) {
  errno: -4077,
  code: 'ECONNRESET',
  syscall: 'read'
}

Any helps for this problem?

masu.mo
  • 783
  • 1
  • 12
  • 22

0 Answers0