Line-Notify / functions / index.js
index.js
Raw
const functions = require("firebase-functions");
const clientId = functions.config().line_notify.client_id;
const clientSecret = functions.config().line_notify.client_secret;
const express = require("express");
const axios = require("axios");
const querystring = require("querystring");
const admin = require("firebase-admin");
const session = require("express-session");
const crypto = require("crypto");

const serviceAccount = require("./serviceAccountKey.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
});
const db = admin.firestore();

const app = express();
const secretKey = crypto.randomBytes(32).toString("hex");

app.use(
  session({
    secret: secretKey,
    resave: false,
    saveUninitialized: true,
  })
);

// ขั้นตอนที่ 1: Initiate OAuth flow
app.get("/auth", (req, res) => {
  const lineAuthUrl = "https://notify-bot.line.me/oauth/authorize";
  const params = {
    response_type: "code",
    client_id: clientId,
    redirect_uri: "https://lsp-line-token.firebaseapp.com/callback",
    scope: "notify",
    state: `${req.query.state}|${req.query.fullName}`,
  };
  req.session.fullName = req.query.fullName; // เก็บ fullName ใน session
  res.redirect(`${lineAuthUrl}?${querystring.stringify(params)}`);
});

// ขั้นตอนที่ 1: Callback URL หลังจากได้รับอนุญาตจาก Line Notify
app.get("/callback", async (req, res) => {
  const code = req.query.code;
  const [nickname, fullName] = req.query.state.split("|");

  if (!code) {
    console.error("Authorization code not found");
    res
      .status(400)
      .send("เชื่อมต่อ Line Notify ไม่สำเร็จ! โปรดลองใหม่อีกครั้ง");
    return;
  }

  // ขั้นตอนที่ 2: Exchange Code for Access Token
  const tokenUrl = "https://notify-bot.line.me/oauth/token";
  const params = {
    grant_type: "authorization_code",
    code,
    redirect_uri: "https://lsp-line-token.firebaseapp.com/callback",
    client_id: clientId,
    client_secret: clientSecret,
  };

  try {
    const response = await axios.post(tokenUrl, querystring.stringify(params), {
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
      },
    });
    const accessToken = response.data.access_token;
    console.log("Access Token:", accessToken);

    // สร้าง document ID โดยรวมชื่อจริงและชื่อเล่น
    const documentId = `${fullName}(${nickname})`;

    // เก็บ Access Token ไว้ใน Firestore โดยใช้ documentId เป็น document ID
    await db.collection("lineNotify").doc(documentId).set({
      fullName: fullName,
      nickname: nickname,
      line_Token: accessToken,
      authorization_Code: code,
    });

    // ขั้นตอนที่ 3: ส่งข้อความทดสอบผ่าน LINE Notify API
    const notifyUrl = "https://notify-api.line.me/api/notify";
    const message = "เชื่อมต่อระบบแจ้งเตือน LINE Notify สำเร็จ!";
    const notifyParams = querystring.stringify({ message });
    const notifyResponse = await axios.post(notifyUrl, notifyParams, {
      headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        Authorization: `Bearer ${accessToken}`,
      },
    });

    if (notifyResponse.status === 200) {
      console.log("Notification sent successfully!");

      // ส่งการตอบกลับเป็น HTML สำหรับแสดงข้อความ "เชื่อมต่อ Line Notify สำเร็จ!"
      const successHtml = `
    <!DOCTYPE html>
    <html>
      <head>
        <title>เชื่อมต่อ LINE Notify สำเร็จ</title>
        <style>
        body {
          display: flex;
          justify-content: center;
          align-items: center;
          height: 100vh;
          margin: 0;
          font-family: Arial, sans-serif;
          font-size: 50px;
          font-weight: bold;
          text-align: center;
          background-color: white;
          color: green;
        }
        </style>
      </head>
      <body>
        <div>เชื่อมต่อระบบแจ้งเตือน LINE Notify สำเร็จ!</div>
      </body>
    </html>
  `;

      res.send(successHtml);
    } else {
      console.error("Error sending notification:", notifyResponse.data);

      // ส่งการตอบกลับเป็น HTML สำหรับแสดงข้อความ "เกิดข้อผิดพลาดในการเชื่อมต่อ Line Notify"
      const errorHtml = `
    <!DOCTYPE html>
    <html>
      <head>
        <title>เกิดข้อผิดพลาดในการเชื่อมต่อ LINE Notify โปรดติดต่อครูหอพัก</title>
        <style>
        body {
          display: flex;
          justify-content: center;
          align-items: center;
          height: 100vh;
          margin: 0;
          font-family: Arial, sans-serif;
          font-size: 50px;
          font-weight: bold;
          text-align: center;
          background-color: white;
          color: darkred;
        }
        </style>
      </head>
      <body>
        <div>เกิดข้อผิดพลาดในการเชื่อมต่อ LINE Notify โปรดติดต่อครูหอพัก</div>
      </body>
    </html>
  `;

      res.status(500).send(errorHtml);
    }
  } catch (error) {
    console.error("Error:", error.message);
    res
      .status(500)
      .send("เกิดข้อผิดพลาดในการเชื่อมต่อ LINE Notify โปรดลองใหม่อีกครั้ง");
  }
});

exports.app = functions.https.onRequest(app);