require('dotenv').config();
const express = require('express');
const multer = require('multer');
const axios = require('axios');
const cloudinary = require('cloudinary').v2;
const fs = require('fs');
const app = express();
const upload = multer({ dest: 'uploads/' });
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
});
const LINEAR_API_URL = 'https://api.linear.app/graphql';
async function createLinearIssue(title, description) {
const query = `
mutation {
issueCreate(
input: {
teamId: "${process.env.LINEAR_TEAM_ID}",
title: "${title}",
description: "${description}"
}
) {
success
issue {
id
identifier
url
}
}
}
`;
const response = await axios.post(
LINEAR_API_URL,
{ query },
{
headers: {
Authorization: `Bearer ${process.env.LINEAR_API_KEY}`,
'Content-Type': 'application/json',
},
}
);
return response.data.data.issueCreate.issue.url;
}
app.post('/report', upload.single('file'), async (req, res) => {
try {
const { title, description } = req.body;
const file = req.file;
let cloudinaryUrl = 'No file uploaded';
if (file) {
const result = await cloudinary.uploader.upload(file.path, {
folder: 'linear_issues',
});
cloudinaryUrl = result.secure_url;
// Delete local file after upload
fs.unlinkSync(file.path);
}
const issueDescription = `${description}\n\nAttached file: ${cloudinaryUrl}`;
const issueUrl = await createLinearIssue(title, issueDescription);
res.status(200).json({ success: true, issueUrl });
} catch (error) {
console.error('Error:', error.message);
res.status(500).json({ success: false, error: error.message });
}
});
app.listen(process.env.PORT, () => {
console.log(`Server running at http://localhost:${process.env.PORT}`);
});