Hướng dẫn phân tích Group Facebook bằng Google Script
Yeap, bài viết này sẽ giúp bạn thống kê số liệu của một group bất kỳ (ngay khi bạn không phải là admin) trong một khoảng thời gian bất kỳ (1 tuần trước, 1 tháng trước, 1 năm trước…).
Bạn có thể xem demo ở đây: Demo Group Analytics
Code này không ảnh hưởng gì đến hoạt động tài khoản của bạn, không thu thập dữ liệu cá nhân. Bạn nên chạy với tài khoản Google Suite (tài khoản Google Free chỉ chạy được 6 phút, trong khi tài khoản G Suite là 30 phút)
Các thông tin thống kê được sẽ là:
- Top 10 bài viết có nhiều reaction nhất
- Top 10 bài viết nhiều comment nhất
- Top 10 thành viên đăng bài nhiều nhất
- Top 10 thành viên comment nhiều nhất
- Tổng số lượng reactions, comments, active members, post…
Các thông tin này dùng để làm gì?
- Đọc cho vui
- Nắm được các chủ đề được quan tâm nhiều nhất, thảo luận nhiều nhất
- Tặng quà, khen thưởng thành viên tích cực trong quá khứ
- Làm công cụ đo đếm cho các event trong tương lai…
Hướng dẫn sử dụng:
- Bước 1: Truy cập: https://script.google.com/, tạo một project mới, xóa hết nội dung trong trình soạn thảo đi
- Bước 2: Kéo xuống cuối bài, copy đoạn code và paste vào trình soạn thảo của project bạn vừa tạo
- Bước 3: Điền các thông tin tương ứng vào các dòng 2, 3, 4, 5, 6, 7, gồm:
- ID của file Google Sheet: ID file Google Sheet là chuỗi ở giữa link của file, thường có dạng thế này:
10bPDOEwHHycxg47gUpAOH4jvjiVlp5VJCL_eruR-oDw
- TokenAds: vào trang quản lý tài khoản quảng cáo của bạn, viewsource, tìm chuỗi ký tự bắt đầu bằng EAA
- TokenProfile: vào trang profile của bạn, viewsource, tìm chuỗi ký tự bắt đầu bằng EAA
- Group ID: vào group bạn muốn, chọn cover của group, click chuột phải và chọn như hình, chuỗi số đầu tiên trong link chính là ID group
- ID của file Google Sheet: ID file Google Sheet là chuỗi ở giữa link của file, thường có dạng thế này:
- Bước 4: Lưu lại và chạy hàm crawlPost()
Giải thích các hàm
- configInfo(): dùng để bạn điền các thông tin cần sử dụng để quét group
- formatSheet(): tạo ra các sheet mới, định dạng và điền các công thức
- letterToNum(): chuyển một chữ cái thành vị trí của nó trong bảng chữ cái
- dateToEpoch(): chuyển ngày tháng từ định dạng ‘YYYY-MM-DD’ sang Unix
- findComments(): crawl tất cả comment của một post và trả về array chứa tên và ID người comment
- crawlPost(): quét tất cả các comment. Bạn chỉ cần chạy file này
Dưới đây là full code
function configInfo(){ var fileID = 'id-google-sheet'; //Make new Google Sheet File, then paste ID here var tokenAds = 'your-ads-account-token'; //Your Ads Account Token var tokenProfiles = 'your-profile-token'; var groupID = 'group-id'; var fromDate = '2020-08-10'; var toDate = '2020-08-17'; return [fileID, tokenAds, tokenProfiles,groupID,fromDate,toDate]; } function formatSheet(){ var configValues = configInfo(); var sheet = SpreadsheetApp.openById(configValues[0]); if(!sheet.getSheetByName("AllPost")){ sheet.renameActiveSheet('AllPost'); } if(!sheet.getSheetByName("Members")){ sheet.insertSheet('Members'); } if(!sheet.getSheetByName("DashBoard")){ sheet.insertSheet('DashBoard'); } var allPost = sheet.getSheetByName("AllPost"); allPost.getRange('A1:Z').clear(); allPost.appendRow(["Time","PostID","Post","AuthorID","Avatar","Author","Comment","Reactions"]); allPost.hideColumns(2); allPost.hideColumns(4); allPost.setColumnWidth(1, 100); allPost.setColumnWidth(3, 500); allPost.setColumnWidth(5, 50); allPost.setColumnWidth(5, 50); allPost.setColumnWidths(6, 3, 120); allPost.getRange('A1:Z').setFontFamily("Work Sans"); allPost.getRange('A1:Z').setVerticalAlignment("middle"); allPost.getRange('A1:Z1').setHorizontalAlignment("center"); allPost.setRowHeights(1, 1000, 35); allPost.setFrozenRows(1); var allMembers = sheet.getSheetByName("Members"); allMembers.getRange('A1:Z').clear(); allMembers.appendRow(["Avatar","AuthorID","AuthorName","PostID"]); allMembers.setColumnWidths(1, 5, 120); allMembers.getRange('A1:Z').setFontFamily("Work Sans"); allMembers.getRange('A1:Z').setVerticalAlignment("middle"); allMembers.getRange('A1:Z1').setHorizontalAlignment("center"); allMembers.setRowHeights(1, 1000, 35); allMembers.setFrozenRows(1); var dashBroad = sheet.getSheetByName("DashBoard"); dashBroad.setColumnWidth(letterToNum('A'), 30); dashBroad.setColumnWidth(letterToNum('P'), 30); dashBroad.setColumnWidth(letterToNum('B'), 10); dashBroad.setColumnWidth(letterToNum('H'), 10); dashBroad.setColumnWidth(letterToNum('J'), 10); dashBroad.setColumnWidth(letterToNum('O'), 10); dashBroad.setColumnWidth(letterToNum('C'), 35); dashBroad.setColumnWidth(letterToNum('K'), 35); dashBroad.setColumnWidth(letterToNum('E'), 400); dashBroad.setColumnWidth(letterToNum('L'), 400); dashBroad.setColumnWidth(letterToNum('G'), 100); dashBroad.setColumnWidth(letterToNum('N'), 100); dashBroad.setRowHeights(18, 28, 35); dashBroad.setRowHeights(33, 43, 35); dashBroad.hideColumns(letterToNum('D')); dashBroad.hideColumns(letterToNum('F')); dashBroad.hideColumns(letterToNum('M')); // #1 dashBroad.getRange('B18:H18').mergeAcross(); dashBroad.getRange('B18').setValue('TOP 10 MOST REACTION POST IN GROUP').setBackground("#1ba94c").setFontColor('white').setFontWeight("bold").setHorizontalAlignment("center"); // #2 dashBroad.getRange('J18:O18').mergeAcross(); dashBroad.getRange('J18').setValue('TOP 10 MOST COMMENT POST IN GROUP').setBackground("#1ba94c").setFontColor('white').setFontWeight("bold").setHorizontalAlignment("center"); // #3 dashBroad.getRange('B33:H33').mergeAcross(); dashBroad.getRange('B33').setValue('TOP 10 AUTHOR IN GROUP').setBackground("#1ba94c").setFontColor('white').setFontWeight("bold").setHorizontalAlignment("center"); // #4 dashBroad.getRange('J33:O33').mergeAcross(); dashBroad.getRange('J33').setValue('TOP 10 ACTIVE MEMBERS IN GROUP').setBackground("#1ba94c").setFontColor('white').setFontWeight("bold").setHorizontalAlignment("center"); dashBroad.getRange('K2:L3').merge(); dashBroad.getRange('K2').setFormula('=SPARKLINE(N3,{"charttype","bar";"max",$N$3;"color1","#02cbd3"})'); dashBroad.getRange('K5:L6').merge(); dashBroad.getRange('K5').setFormula('=SPARKLINE(N6,{"charttype","bar";"max",$N$3;"color1","#019ba0";"rtl",true})'); dashBroad.getRange('K8:L9').merge(); dashBroad.getRange('K8').setFormula('=SPARKLINE(N9,{"charttype","bar";"max",$N$3;"color1","#016a6e";"rtl",true})'); dashBroad.getRange('K11:L12').merge(); dashBroad.getRange('K11').setFormula('=SPARKLINE(N12,{"charttype","bar";"max",$N$3;"color1","#01393c";"rtl",true})'); dashBroad.getRange('N2').setValue('Reactions').setHorizontalAlignment("center"); dashBroad.getRange('N5').setValue('Comments').setHorizontalAlignment("center"); dashBroad.getRange('N8').setValue('Active members').setHorizontalAlignment("center"); dashBroad.getRange('N11').setValue('Posts').setHorizontalAlignment("center"); dashBroad.getRange('N3').setFormula('=SUM(AllPost!$H$2:H)').setHorizontalAlignment("center").setFontSize(18); dashBroad.getRange('N6').setFormula('=SUM(AllPost!$G$2:G)').setHorizontalAlignment("center").setFontSize(18); dashBroad.getRange('N9').setFormula('=COUNTUNIQUE(Members!B2:B)').setHorizontalAlignment("center").setFontSize(18); dashBroad.getRange('N12').setFormula('=COUNTA(AllPost!$C$2:C)').setHorizontalAlignment("center").setFontSize(18); dashBroad.getRange('D2:E2').mergeAcross(); dashBroad.getRange('D5:E5').mergeAcross(); dashBroad.getRange('D8:E8').mergeAcross(); dashBroad.getRange('D11:E11').mergeAcross(); dashBroad.getRange('D3:E3').mergeAcross(); dashBroad.getRange('D6:E6').mergeAcross(); dashBroad.getRange('D9:E9').mergeAcross(); dashBroad.getRange('D12:E12').mergeAcross(); dashBroad.getRange('D2').setValue('Group Name:'); dashBroad.getRange('D5').setValue('Group ID:'); dashBroad.getRange('D8').setValue('Since:'); dashBroad.getRange('D11').setValue('Until:'); var crawlPage = "https://graph.facebook.com/v7.0/"+configValues[3]+"/?access_token="+configValues[2]; var postPage = UrlFetchApp.fetch(crawlPage); var contentPage = postPage.getContentText(); var parsePage = JSON.parse(contentPage); var pageName = parsePage['name'] dashBroad.getRange('D3').setValue(pageName).setHorizontalAlignment("center").setFontSize(18); dashBroad.getRange('D6').setValue(configValues[3]).setHorizontalAlignment("center").setFontSize(18); dashBroad.getRange('D9').setValue(configValues[4]).setHorizontalAlignment("center").setFontSize(18); dashBroad.getRange('D12').setValue(configValues[5]).setHorizontalAlignment("center").setFontSize(18); dashBroad.getRange('B20:H20').setBackground("#ebebeb"); dashBroad.getRange('J20:O20').setBackground("#ebebeb"); dashBroad.getRange('B22:H22').setBackground("#ebebeb"); dashBroad.getRange('J22:O22').setBackground("#ebebeb"); dashBroad.getRange('B24:H24').setBackground("#ebebeb"); dashBroad.getRange('J24:O24').setBackground("#ebebeb"); dashBroad.getRange('B26:H26').setBackground("#ebebeb"); dashBroad.getRange('J26:O26').setBackground("#ebebeb"); dashBroad.getRange('B28:H28').setBackground("#ebebeb"); dashBroad.getRange('J28:O28').setBackground("#ebebeb"); dashBroad.getRange('B35:H35').setBackground("#ebebeb"); dashBroad.getRange('J35:O35').setBackground("#ebebeb"); dashBroad.getRange('B37:H37').setBackground("#ebebeb"); dashBroad.getRange('J37:O37').setBackground("#ebebeb"); dashBroad.getRange('B39:H39').setBackground("#ebebeb"); dashBroad.getRange('J39:O39').setBackground("#ebebeb"); dashBroad.getRange('B41:H41').setBackground("#ebebeb"); dashBroad.getRange('J41:O41').setBackground("#ebebeb"); dashBroad.getRange('B43:H43').setBackground("#ebebeb"); dashBroad.getRange('J43:O43').setBackground("#ebebeb"); dashBroad.getRange('B2:B12').setBackground("#1ba94c"); dashBroad.getRange('D19').setFormula('=QUERY(AllPost!$A$2:H,"select B,C,D,H order by H desc limit 10",-1)'); dashBroad.getRange('D34').setFormula('=QUERY(AllPost!$A$2:H,"select B,C,D,G order by G desc limit 10",-1)'); dashBroad.getRange('M19').setFormula('=QUERY(Members!A2:Z,"select B, count(B) group by B order by count(B) desc limit 10 label count(B) \'\'",-1)'); dashBroad.getRange('M34').setFormula('=QUERY(AllPost!$A$2:H,"select D, count(D) group by D order by count(D) desc limit 10 label count(D) \'\'",-1)'); for(var i = 19; i<= 28; i++){ var colC = '=IMAGE("https://graph.facebook.com/"&F'+i+'&"/picture?type=large",4,30,30)'; var colK = '=VLOOKUP(M'+i+',{Members!$B$2:B,Members!$A$2:A},2,FALSE)'; var colL = '=VLOOKUP(M'+i+',Members!$B$2:$C,2,FALSE)'; dashBroad.getRange('C'+i).setFormula(colC); dashBroad.getRange('K'+i).setFormula(colK); dashBroad.getRange('L'+i).setFormula(colL); } for(var j = 34; j<= 43; j++){ var colC = '=IMAGE("https://graph.facebook.com/"&F'+j+'&"/picture?type=large",4,30,30)'; var colK = '=VLOOKUP(M'+j+',AllPost!$D$2:F,2,FALSE)'; var colL = '=VLOOKUP(M'+j+',AllPost!$D$2:F,3,False)'; dashBroad.getRange('C'+j).setFormula(colC); dashBroad.getRange('K'+j).setFormula(colK); dashBroad.getRange('L'+j).setFormula(colL); } dashBroad.getRange('C1:C').setHorizontalAlignment("center"); dashBroad.getRange('K1:K').setHorizontalAlignment("center"); dashBroad.getRange('A1:Z').setVerticalAlignment("middle"); /* dashBroad.getRange('A1:Z').setFontFamily("Work Sans"); dashBroad.getRange('A1:Z1').setHorizontalAlignment("center"); dashBroad.setRowHeights(1, 1000, 35); dashBroad.setFrozenRows(1); */ } function letterToNum(letter){ var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(''); return alphabet.indexOf(letter) + 1; } function dateToEpoch(date){ var epoch = new Date(date).valueOf(); epoch = epoch / 1000; return epoch; } function findComments(postID){ var configValues = configInfo(); var options = { 'muteHttpExceptions' : true, }; var crawlComments = "https://graph.facebook.com/v7.0/"+postID+"/comments?fields=from%2Ccomments%7Bfrom%7D&access_token="+configValues[2]; var listCommentsAuthor = []; while(crawlComments){ var postComments = UrlFetchApp.fetch(crawlComments,options); var contentComments = postComments.getContentText(); var parseComments = JSON.parse(contentComments); crawlComments = null; if(parseComments['data']){ if(parseComments["paging"]){ crawlComments = parseComments["paging"]["next"]; } var listCm = parseComments['data']; for(var j = 0; j< listCm.length; j++){ var parentComment = listCm[j]; var commentAuthorName = parentComment['from']['name']; var commentAuthorID = parentComment['from']['id']; listCommentsAuthor.push({'cai': commentAuthorID, 'can': commentAuthorName}); if(listCm[j]['comments'] && listCm[j]['comments']['data']){ var childComment = listCm[j]['comments']['data']; for(var k = 0; k < childComment.length; k++){ var c_commentAuthorName = childComment[k]['from']['name']; var c_commentAuthorID = childComment[k]['from']['id']; listCommentsAuthor.push({'cai': c_commentAuthorID, 'can': c_commentAuthorName}); } } } } } return listCommentsAuthor; } function crawlPost() { formatSheet(); var configValues = configInfo(); var allPost = SpreadsheetApp.openById(configValues[0]).getSheetByName("AllPost"); var members = SpreadsheetApp.openById(configValues[0]).getSheetByName("Members"); allPost.getRange('A2:Z').clear(); members.getRange('A2:Z').clear(); var fromDate = dateToEpoch(configValues[4]); var toDate = dateToEpoch(configValues[5]); var crawlGroup = "https://graph.facebook.com/v7.0/"+configValues[3]+"/feed?since="+fromDate+"&until="+toDate+"&access_token="+configValues[1]; var k = 0; var options = { 'muteHttpExceptions' : true, }; while(crawlGroup){ var jsonData = UrlFetchApp.fetch(crawlGroup,options); var infoData = jsonData.getContentText(); var parseData = JSON.parse(infoData); if(parseData['data']){ var postList = parseData['data']; for(var i = 0; i < postList.length; i++){ var postID = postList[i]['id']; var crawlPost = "https://graph.facebook.com/v7.0/"+postID+"/?fields=created_time,message,from,comments.summary(true).limit(1),reactions.summary(true).limit(1)&access_token="+configValues[2]; var postData = UrlFetchApp.fetch(crawlPost,options); var contentData = postData.getContentText(); var parsePost = JSON.parse(contentData); var postTime = parsePost['created_time']; postTime = postTime.replace(/T.*$/g, ""); var postTimeEpoch = dateToEpoch(postTime); if(postTimeEpoch >= fromDate && postTimeEpoch <= toDate){ var postMess = ''; if(parsePost['message']){postMess = parsePost['message']}; var postMessFirstLine = postMess.split('\n')[0]; postMessFirstLine = postMessFirstLine.replace(/"/g, ""); var postAuthorName = parsePost['from']['name'] var postAuthorID = parsePost['from']['id']; var commentCount = parsePost['comments']['summary']['total_count']; var likeCount = parsePost['reactions']['summary']['total_count']; var postLink = 'https://facebook.com/' + postID; var colC = '=HYPERLINK("'+postLink+'";"'+postMessFirstLine+'")'; var colE = '=IMAGE("https://graph.facebook.com/'+postAuthorID+'/picture?type=large";4;30;30)'; var colF = '=HYPERLINK("https://facebook.com/'+postAuthorID+'";"'+postAuthorName+'")'; var listComments = findComments(postID); for(var x = 0; x < listComments.length; x++){ var c_avatar = '=IMAGE("https://graph.facebook.com/'+listComments[x]['cai']+'/picture?type=large";4;30;30)'; members.appendRow([c_avatar,listComments[x]['cai'],listComments[x]['can'],postID]); } allPost.appendRow([postTime,postID,colC,postAuthorID,colE,colF,listComments.length,likeCount]); } } } crawlGroup = null; if(parseData["paging"]){ crawlGroup = parseData["paging"]["next"]; } } allPost.getRange('E1:E').setHorizontalAlignment("center"); allPost.getRange('A1:Z').setFontFamily("Work Sans"); allPost.getRange('A1:Z').setVerticalAlignment("middle"); members.getRange('A1:A').setHorizontalAlignment("center"); members.getRange('A1:Z').setFontFamily("Work Sans"); members.getRange('A1:Z').setVerticalAlignment("middle"); }
Bạn nào chưa làm được thì để lại comment phía dưới nhé! Mình sẽ hỗ trợ