Last active
February 18, 2022 02:19
-
-
Save tandevmode/4286b8db25e8a7525fd1d03e6f5f0a47 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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