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?