├/node_modules
├/modules
│├bot.js
│└sessions.js
├/routes
│├index.js
│└home.js
├/views
│└home.ejs
├/public
│└scripts
│ ├index.js
│ └home.js
├.env
├index.js
├package-lock.json
└package.json
"dependencies": {
"express": "latest",
"ejs": "latest",
"cookie-parser": "latest",
"node-telegram-bot-api" : "latest"
}
npm install
index.js
import express from 'express';
import cookieParser from 'cookie-parser';
import routes from './routes/index.js';
import sessions from './modules/sessions.js';
const ENV = process.env;
const CWD = process.cwd();
const app = express();
app.set('view engine', 'ejs');
app.set('views', `${CWD}/views`);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.use('/public', express.static(`${CWD}/public`));
app.use((req, res, next) => {
const userId = req.cookies.userId;
if (userId && sessions.has(userId)) {
res.locals.userInfo = sessions.get(userId);
}
next();
});
app.use(routes);
app.listen(ENV.SERVER_PORT, () => {
console.log('서버가 실행 중입니다.');
});
bot.js
import TelegramBot from 'node-telegram-bot-api';
const bot = new TelegramBot(process.env.TOKEN, {
polling: true,
request: {
agentOptions: {
family: 4,
keepAlive: true
}
}
});
bot.on('polling_error', (error) => {
console.error('Polling error:', error.message);
});
export default bot;
sessions.js
const sessions = new Map();
export default sessions;
index.js
import express from 'express';
const router = express.Router();
import home from './home.js';
router.use('/', home);
export default router;
home.js
import express from 'express';
import sessions from '../modules/sessions.js';
import db from '../modules/bot.js';
const router = express.Router();
router.get('/', (req, res) => {
res.render('home');
});
router.post('/', (req, res) => {
const user = req.body;
if (user) {
const userId = user.id;
const name = [user.last_name, user.first_name].filter(Boolean).join('');
res.cookie('userId', id, {
httpOnly: true, secure: true, sameSite: 'none'
});
sessions.set(String(id), { id, name });
bot.sendMessage(userId, '앱이 실행됐습니다.');
res.status(204).end();
} else {
res.status(400).end();
}
});
export default router;
home.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<script src="https://telegram.org/js/telegram-web-app.js"></script>
<script src="https://cdn.jsdelivr.net/npm/eruda"></script>
</head>
<body>
<p>Hello, World!</p>
<script>eruda.init();</script>
<script src="/public/scripts/index.js"></script>
<script src="/public/scripts/home.js"></script>
</body>
</html>
index.js
const tg = window.Telegram.WebApp;
tg.ready();
home.js
async function initializeUser() {
if (tg.initDataUnsafe && tg.initDataUnsafe.user) {
try {
const response = await fetch('/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(tg.initDataUnsafe.user)
});
if (response.status === 204) {
console.log('쿠키, 세션 등록 성공');
} else {
console.error("서버 응답 에러");
}
} catch (err) {
console.error("네트워크 에러", err);
}
}
}
initializeUser();