-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfetchUsers.js
168 lines (148 loc) · 4.36 KB
/
fetchUsers.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
const fs = require('mz/fs');
const pako = require('pako');
const AWS = require('aws-sdk');
const fb = require('./lib/facebook');
const { getUsers } = require('./entrypoint/fbPushLegacy');
const ddb = new AWS.DynamoDB.DocumentClient({
region: 'eu-central-1',
});
const TABLE_NAME = 'tim-bot-marcus-subscriptions';
process.env.DYNAMODB_SUBSCRIPTIONS = TABLE_NAME;
const baseDir = "/Users/marcus/tmp/tim-bot-logs/e41f8376-f9ed-4797-b3e1-40eb785fc5a5";
const psid_collection = new Set();
const findUsers = async function() {
const folders = await fs.readdir(baseDir);
for(const folder of folders) {
if(folder.startsWith('.')) {
continue;
}
const packed = await fs.readFile(`${baseDir}/${folder}/000000.gz`);
const content = pako.inflate(packed, { to: 'string' });
const events = content.split("\n\n").forEach(ev => {
const parts = ev.split("\t");
const timestamp = parts[0].substr(0, 24);
console.error(`Searching at ${timestamp}...`);
const special = parts[0].substr(25).split(' ');
if(special.length > 1) {
return;
}
const msg = parts[2];
try {
const pl = JSON.parse(msg);
if(!('recipient' in pl && 'id' in pl.recipient)) {
return;
}
console.error(`Found psid: ${pl.recipient.id}`);
psid_collection.add(pl.recipient.id);
} catch(e) {
return;
}
});
}
const stream = fs.createWriteStream('psid.list');
for(psid of psid_collection) {
stream.write(`${psid}\n`);
}
stream.end();
};
const fixUserSubscriptions = async function() {
let lastUser = null;
while(true) {
const users = await getUsers('none', lastUser);
if (users.length === 0) {
break;
}
lastUser = users[users.length-1].psid;
for (const user of users) {
const chat = new fb.Chat({ sender: { id: user.psid } });
try {
await chat.getLabels();
} catch(e) {
if(e.statusCode === 400) {
console.log("Deleting user", user);
await deleteUser(user.psid);
}
}
}
}
console.log("Done");
};
const storeUser = async function(psid, item = {}) {
return new Promise((resolve, reject) => ddb.put({
TableName: TABLE_NAME,
Item: Object.assign(item, { psid }),
}, err => {
if(err) {
return reject(err);
}
resolve();
}));
};
const updateUser = async function(psid, item = none, status = 0) {
return new Promise((resolve, reject) => ddb.update({
TableName: TABLE_NAME,
Key: {
psid: psid
},
UpdateExpression: "set #item = :status",
ExpressionAttributeNames:{
"#item":item
},
ExpressionAttributeValues:{
":status":status
},
ReturnValues:"ALL_NEW",
}, (err, res) => {
if(err) {
return reject(err);
}
return res;
}));
};
const deleteUser = function(psid) {
return new Promise((resolve, reject) => ddb.delete({
TableName: TABLE_NAME,
Key: {
psid
},
}, err => {
if(err) {
return reject(err);
}
resolve();
}));
};
const persistUsers = async function() {
const psids = (await fs.readFile('psid.list', 'utf-8')).split("\n");
let i = 0;
for(psid of psids) {
i++;
const chat = new fb.Chat({ sender: { id: psid } });
let labels = [];
try {
labels = await chat.getLabels();
} catch(e) {
console.error(e.message);
continue;
}
if (labels.length === 0) {
continue;
}
const item = {
morning: (labels.indexOf('push-morning') !== -1) ? 1 : 0,
evening: (labels.indexOf('push-evening') !== -1) ? 1 : 0,
};
await storeUser(psid, item);
if (i % 10 === 0 || i === psids.length-1) {
console.error(`PROGRESS: ${i/psids.length*100}%`);
}
}
};
module.exports = {
findUsers,
fixUserSubscriptions,
storeUser,
updateUser,
deleteUser,
persistUsers,
};