ken_nogi/oldCode/express/modules/pdfToText.js
Kenichiro NOGI 06c28e8b5a oldCode: 旧LINEWORKS/Pleasanter連携コード一式を追加
express/LINEWORKS_Pleasanter/LINEWORKS_sendMessage、いずれも過去の
Express実装。Gitea移行に伴い保管。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 10:42:21 +09:00

99 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const fs = require('fs');
const path = require('path');
const { execFile } = require('child_process');
const { v4: uuidv4 } = require('uuid');
const express = require('express'); // JSON解析用にexpressをインポート
const { API_KEY } = require('../config.js'); // API_KEYをインポート
// tmpディレクトリのパス
const tmpDir = path.join(__dirname, 'tmp');
// tmpディレクトリが存在しない場合は作成
if (!fs.existsSync(tmpDir)) {
fs.mkdirSync(tmpDir);
}
// POSTエンドポイント
module.exports = (app) => {
app.post('/pdfToText', express.json({ limit: '30mb' }), async (req, res) => {
try {
// APIキーのチェック
const apiKey = req.headers['x-api-key'];
if (!apiKey || apiKey !== API_KEY) {
console.log('APIキーが不正です');
return res.status(401).json({ error: 'APIキーが不正です' });
}
// base64, fileName の3つをチェック
const { base64, fileName } = req.body;
if (!base64 || !fileName) {
return res.status(400).json({ error: 'base64とfileNameは必須です' });
}
const txtBuffer = await pdfToTextConvert(base64, fileName);
const safeFileName = encodeURIComponent(path.parse(fileName).name); // ファイル名をエスケープ
res.set({
'Content-Type': 'text/plain',
'Content-Disposition': `attachment; filename="${safeFileName}.txt"`
});
res.send(txtBuffer);
} catch (err) {
console.error('変換エラー:', err.message);
res.status(500).json({ error: err.message });
}
});
};
// PDF テキスト変換処理
async function pdfToTextConvert(base64) {
const tempId = uuidv4(); // 一意のIDを生成
const pdfPath = path.join(tmpDir, `${tempId}.pdf`);
const outputPath = path.join(tmpDir, `${tempId}.txt`);
// base64データをファイルに保存
fs.writeFileSync(pdfPath, Buffer.from(base64, 'base64'));
// pdfuniteでテキストに変換
await new Promise((resolve, reject) => {
const child = execFile(
'pdftotext',
[
'-layout',
'-nopgbrk',
pdfPath,
outputPath
],
(error, stdout, stderr) => {
if (error) {
console.error('stderr:', stderr);
reject(error);
} else {
resolve();
}
}
);
// 60秒タイムアウト
const timeout = setTimeout(() => {
child.kill('SIGTERM'); // SIGTERMを使用してプロセスを終了
reject(new Error('テキストへの変換がタイムアウトしました60秒経過'));
}, 60000);
child.on('exit', () => clearTimeout(timeout));
});
// 変換されたテキストファイルを読み込み
if (!fs.existsSync(outputPath)) {
// cleanup
fs.unlinkSync(pdfPath);;
throw new Error('テキストへの変換に失敗しました');
}
const txtBuffer = fs.readFileSync(outputPath);
// cleanup
fs.unlinkSync(pdfPath);
fs.unlinkSync(outputPath);
return txtBuffer;
}