Skip to content

Instantly share code, notes, and snippets.

@tandevmode
Last active February 18, 2022 02:19
Show Gist options
  • Save tandevmode/4286b8db25e8a7525fd1d03e6f5f0a47 to your computer and use it in GitHub Desktop.
Save tandevmode/4286b8db25e8a7525fd1d03e6f5f0a47 to your computer and use it in GitHub Desktop.
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const axios = require("axios");
const LINE_MESSAGING_API = "https://api.line.me/v2/bot";
const LINE_HEADER = {
"Content-Type": "application/json",
Authorization: `Bearer YOUR-ACCESS-TOKEN`
};
const msgTemplate = require("./msgTemplate");
const ONEROUND_KM = 1;
exports.LineWebhook = functions.https.onRequest(async (req, res) => {
const event = req.body.events[0];
let payload = null;
const monthAndWeek = getMonthAndWeek()
const userProfile = await getUserProfile(event.source.userId);
if (event.type === "beacon") {
const status = await admin.database().ref(monthAndWeek).child(userProfile.userId).child("status").once('value');
if (status.val() === null || status.val() === 'finish') {
// นักวิ่งเข้ามาในระยะ Beacon เพื่อเตรียมตัวกำลังจะเริ่มวิ่ง
// ส่งข้อความหานักวิ่งว่าพร้อมไหม?
payload = msgTemplate.ready();
} else if (status.val() === 'running') {
// วิ่งเข้ามาในระยะ Beacon 1 ครั้ง = 1 รอบ = 1 KM
let totalDistance = await admin.database().ref(monthAndWeek).child(userProfile.userId).child("totalDistance").once('value');
// ทำการบวกระยะเพิ่มให้นักวิ่ง
totalDistance = totalDistance.val() + ONEROUND_KM;
await admin.database().ref(monthAndWeek).child(userProfile.userId).set({
"totalDistance": totalDistance,
"pictureUrl": userProfile.pictureUrl,
"displayName": userProfile.displayName,
"status": "running"
})
// ส่งข้อความยืนยันให้นักวิ่งว่าเก็บเพิ่มอีก 1 KM
payload = msgTemplate.submitDistance(totalDistance);
}
} else if (event.type === 'postback' && event.postback.data === 'running') {
// นักวิ่งเข้ามาในระยะ Beacon เพื่อเตรียมตัวกำลังจะเริ่มวิ่ง
// นักวิ่งกดปุ่ม I'm ready, GO! เพื่อเริ่มนับ KM
await admin.database().ref(monthAndWeek).child(userProfile.userId).child("status").set("running");
payload = msgTemplate.go();
} else if (event.type === 'postback' && event.postback.data === 'finish') {
// นักวิ่งกดปุ่ม I'm done เพื่อหยุดการนับ KM
await admin.database().ref(monthAndWeek).child(userProfile.userId).child("status").set("finish");
let flexBody = await createFlexLeaderboard();
payload = msgTemplate.leaderboardHeader(flexBody, monthAndWeek);
} else if (event.type === 'message' && event.message.text === 'Leaderboard') {
// กด Richmenu เพื่อดู Ranking
let flexBody = await createFlexLeaderboard();
payload = msgTemplate.leaderboardHeader(flexBody, monthAndWeek);
}
await reply(event.replyToken, payload);
return res.end();
});
const createFlexLeaderboard = async () => {
const monthAndWeek = getMonthAndWeek()
let body = [];
let arr = [];
const snapshot = await admin.database().ref(monthAndWeek).orderByChild("totalDistance").once('value');
snapshot.forEach((childSnapshot) => {
let displayName = childSnapshot.child("displayName").val();
let totalDistance = childSnapshot.child("totalDistance").val();
let pictureUrl = childSnapshot.child("pictureUrl").val();
arr.push([totalDistance, pictureUrl, displayName]);
});
arr.sort(sortFunction);
arr.forEach(val => {
body.push(msgTemplate.leaderboardBody(
val[1], val[2], val[0].toFixed(2)));
});
return body;
}
function sortFunction(a, b) {
if (a[0] === b[0]) {
return 0;
}
else {
return (a[0] > b[0]) ? -1 : 1;
}
}
const getMonthAndWeek = () => {
var d = new Date();
var date = d.getDate();
var day = d.getDay();
var weekOfMonth = Math.ceil((date + 6 - day) / 7);
var month = new Array();
month[0] = "January";
month[1] = "February";
month[2] = "March";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "August";
month[8] = "September";
month[9] = "October";
month[10] = "November";
month[11] = "December";
var thisMonth = month[d.getMonth()];
return thisMonth + " - Week " + weekOfMonth;
}
const getUserProfile = async (userId) => {
const userProfile = await axios({
method: "get",
headers: LINE_HEADER,
url: `${LINE_MESSAGING_API}/profile/` + userId
});
return userProfile.data;
}
const reply = async (replyToken, payload) => {
await axios({
method: "post",
url: `${LINE_MESSAGING_API}/message/reply`,
headers: LINE_HEADER,
data: JSON.stringify({
replyToken: replyToken,
messages: [payload]
})
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment