1
Fork 0
This commit is contained in:
prescientmoon 2024-05-12 04:14:45 +02:00
commit c48f34375b
Signed by: prescientmoon
SSH key fingerprint: SHA256:UUF9JT2s8Xfyv76b8ZuVL7XrmimH4o49p4b+iexbVH4
6 changed files with 523 additions and 0 deletions

2
typescript/globalbot/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.env
node_modules

View file

@ -0,0 +1,14 @@
{
"type": "module",
"name": "global-bot",
"scripts": {},
"dependencies": {
"dotenv": "^10.0.0",
"twitter-api-v2": "^1.4.1"
},
"devDependencies": {
"@types/node": "^16.7.10",
"ts-node-dev": "^1.1.8",
"typescript": "^4.4.2"
}
}

View file

@ -0,0 +1,395 @@
dependencies:
dotenv: 10.0.0
twitter-api-v2: 1.4.1
devDependencies:
'@types/node': 16.7.10
ts-node-dev: 1.1.8_typescript@4.4.2
typescript: 4.4.2
lockfileVersion: 5.1
packages:
/@types/node/16.7.10:
dev: true
resolution:
integrity: sha512-S63Dlv4zIPb8x6MMTgDq5WWRJQe56iBEY0O3SOFA9JrRienkOVDXSXBjjJw6HTNQYSE2JI6GMCR6LVbIMHJVvA==
/@types/strip-bom/3.0.0:
dev: true
resolution:
integrity: sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=
/@types/strip-json-comments/0.0.30:
dev: true
resolution:
integrity: sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==
/anymatch/3.1.2:
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.0
dev: true
engines:
node: '>= 8'
resolution:
integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
/arg/4.1.3:
dev: true
resolution:
integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
/balanced-match/1.0.2:
dev: true
resolution:
integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
/binary-extensions/2.2.0:
dev: true
engines:
node: '>=8'
resolution:
integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
/brace-expansion/1.1.11:
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
dev: true
resolution:
integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
/braces/3.0.2:
dependencies:
fill-range: 7.0.1
dev: true
engines:
node: '>=8'
resolution:
integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
/buffer-from/1.1.2:
dev: true
resolution:
integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
/chokidar/3.5.2:
dependencies:
anymatch: 3.1.2
braces: 3.0.2
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.1
normalize-path: 3.0.0
readdirp: 3.6.0
dev: true
engines:
node: '>= 8.10.0'
optionalDependencies:
fsevents: 2.3.2
resolution:
integrity: sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
/concat-map/0.0.1:
dev: true
resolution:
integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
/create-require/1.1.1:
dev: true
resolution:
integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
/diff/4.0.2:
dev: true
engines:
node: '>=0.3.1'
resolution:
integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
/dotenv/10.0.0:
dev: false
engines:
node: '>=10'
resolution:
integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
/dynamic-dedupe/0.3.0:
dependencies:
xtend: 4.0.2
dev: true
resolution:
integrity: sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE=
/fill-range/7.0.1:
dependencies:
to-regex-range: 5.0.1
dev: true
engines:
node: '>=8'
resolution:
integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
/fs.realpath/1.0.0:
dev: true
resolution:
integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
/fsevents/2.3.2:
dev: true
engines:
node: ^8.16.0 || ^10.6.0 || >=11.0.0
optional: true
os:
- darwin
resolution:
integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
/function-bind/1.1.1:
dev: true
resolution:
integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
/glob-parent/5.1.2:
dependencies:
is-glob: 4.0.1
dev: true
engines:
node: '>= 6'
resolution:
integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
/glob/7.1.7:
dependencies:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
minimatch: 3.0.4
once: 1.4.0
path-is-absolute: 1.0.1
dev: true
resolution:
integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
/has/1.0.3:
dependencies:
function-bind: 1.1.1
dev: true
engines:
node: '>= 0.4.0'
resolution:
integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
/inflight/1.0.6:
dependencies:
once: 1.4.0
wrappy: 1.0.2
dev: true
resolution:
integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
/inherits/2.0.4:
dev: true
resolution:
integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
/is-binary-path/2.1.0:
dependencies:
binary-extensions: 2.2.0
dev: true
engines:
node: '>=8'
resolution:
integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
/is-core-module/2.6.0:
dependencies:
has: 1.0.3
dev: true
resolution:
integrity: sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==
/is-extglob/2.1.1:
dev: true
engines:
node: '>=0.10.0'
resolution:
integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
/is-glob/4.0.1:
dependencies:
is-extglob: 2.1.1
dev: true
engines:
node: '>=0.10.0'
resolution:
integrity: sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
/is-number/7.0.0:
dev: true
engines:
node: '>=0.12.0'
resolution:
integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
/make-error/1.3.6:
dev: true
resolution:
integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
/minimatch/3.0.4:
dependencies:
brace-expansion: 1.1.11
dev: true
resolution:
integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
/minimist/1.2.5:
dev: true
resolution:
integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
/mkdirp/1.0.4:
dev: true
engines:
node: '>=10'
hasBin: true
resolution:
integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
/normalize-path/3.0.0:
dev: true
engines:
node: '>=0.10.0'
resolution:
integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
/once/1.4.0:
dependencies:
wrappy: 1.0.2
dev: true
resolution:
integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
/path-is-absolute/1.0.1:
dev: true
engines:
node: '>=0.10.0'
resolution:
integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
/path-parse/1.0.7:
dev: true
resolution:
integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
/picomatch/2.3.0:
dev: true
engines:
node: '>=8.6'
resolution:
integrity: sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
/readdirp/3.6.0:
dependencies:
picomatch: 2.3.0
dev: true
engines:
node: '>=8.10.0'
resolution:
integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
/resolve/1.20.0:
dependencies:
is-core-module: 2.6.0
path-parse: 1.0.7
dev: true
resolution:
integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
/rimraf/2.7.1:
dependencies:
glob: 7.1.7
dev: true
hasBin: true
resolution:
integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
/source-map-support/0.5.19:
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
dev: true
resolution:
integrity: sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
/source-map/0.6.1:
dev: true
engines:
node: '>=0.10.0'
resolution:
integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
/strip-bom/3.0.0:
dev: true
engines:
node: '>=4'
resolution:
integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=
/strip-json-comments/2.0.1:
dev: true
engines:
node: '>=0.10.0'
resolution:
integrity: sha1-PFMZQukIwml8DsNEhYwobHygpgo=
/to-regex-range/5.0.1:
dependencies:
is-number: 7.0.0
dev: true
engines:
node: '>=8.0'
resolution:
integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
/tree-kill/1.2.2:
dev: true
hasBin: true
resolution:
integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
/ts-node-dev/1.1.8_typescript@4.4.2:
dependencies:
chokidar: 3.5.2
dynamic-dedupe: 0.3.0
minimist: 1.2.5
mkdirp: 1.0.4
resolve: 1.20.0
rimraf: 2.7.1
source-map-support: 0.5.19
tree-kill: 1.2.2
ts-node: 9.1.1_typescript@4.4.2
tsconfig: 7.0.0
typescript: 4.4.2
dev: true
engines:
node: '>=0.8.0'
hasBin: true
peerDependencies:
node-notifier: '*'
typescript: '*'
peerDependenciesMeta:
node-notifier:
optional: true
resolution:
integrity: sha512-Q/m3vEwzYwLZKmV6/0VlFxcZzVV/xcgOt+Tx/VjaaRHyiBcFlV0541yrT09QjzzCxlDZ34OzKjrFAynlmtflEg==
/ts-node/9.1.1_typescript@4.4.2:
dependencies:
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
make-error: 1.3.6
source-map-support: 0.5.19
typescript: 4.4.2
yn: 3.1.1
dev: true
engines:
node: '>=10.0.0'
hasBin: true
peerDependencies:
typescript: '>=2.7'
resolution:
integrity: sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==
/tsconfig/7.0.0:
dependencies:
'@types/strip-bom': 3.0.0
'@types/strip-json-comments': 0.0.30
strip-bom: 3.0.0
strip-json-comments: 2.0.1
dev: true
resolution:
integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==
/twitter-api-v2/1.4.1:
dev: false
resolution:
integrity: sha512-jaUPQ2dpdog1iCoS7ExZbOZt+A7duHVt2I/zuaEkStyHpkppJ1Z9AJ5pY0Nxe6FjNOFqtIk4sCvYaKt0qTQHIA==
/typescript/4.4.2:
dev: true
engines:
node: '>=4.2.0'
hasBin: true
resolution:
integrity: sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==
/wrappy/1.0.2:
dev: true
resolution:
integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
/xtend/4.0.2:
dev: true
engines:
node: '>=0.4'
resolution:
integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
/yn/3.1.1:
dev: true
engines:
node: '>=6'
resolution:
integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
specifiers:
'@types/node': ^16.7.10
dotenv: ^10.0.0
ts-node-dev: ^1.1.8
twitter-api-v2: ^1.4.1
typescript: ^4.4.2

View file

@ -0,0 +1,15 @@
{
"aliases": {
"USA": "US",
"The Netherlands": "Netherlands"
},
"countries": [
"US",
"Netherlands",
"France",
"Denmark",
"Switzerland",
"Canada"
]
}

View file

@ -0,0 +1,90 @@
import TwitterApi, { TweetV2 } from "twitter-api-v2";
import { config } from "dotenv";
config();
const api = new TwitterApi(process.env.TOKEN);
const luke = "GlobeGames1";
const latest = "1433459713035935749";
const command = "!vote";
const prefixes = [command, `@${luke}`];
const client = api.readOnly;
const { aliases, countries } = require("./countries.json");
const getCoutntryName = (message: string): string | null => {
const trimmed = message.trim().toLowerCase();
for (const prefix of prefixes)
if (trimmed.startsWith(prefix.toLowerCase()))
return getCoutntryName(trimmed.substr(prefix.length));
for (const alias in aliases) {
if (trimmed.startsWith(alias.toLowerCase())) return aliases[alias];
}
for (const country of countries) {
if (trimmed.startsWith(country.toLowerCase())) return country;
}
return null;
};
const main = async () => {
const data: TweetV2[] = [];
let token: string | undefined;
let fetches = 0;
do {
const tweets = await client.v2.search(
`to:${luke} conversation_id:${latest}`,
{
"tweet.fields": ["text", "author_id", "referenced_tweets"],
next_token: token,
}
);
data.push(...tweets.data.data);
token = tweets.meta.next_token;
fetches++;
} while (token);
console.log(`Fetched the twitter api ${fetches} times`);
const votes = new Map();
for (const vote of data) {
if (
!vote.referenced_tweets.some(
(tweet) => tweet.type === "replied_to" && tweet.id === latest
)
)
continue;
const country = getCoutntryName(vote.text);
if (country === null) continue;
votes.set(vote.author_id, country);
}
const voteResults = new Map();
for (const [_author, country] of votes) {
const previousAmount = voteResults.get(country);
voteResults.set(country, (previousAmount ?? 0) + 1);
}
const sortedResults = [...voteResults.entries()];
sortedResults.sort((a, b) => b[1] - a[1]);
console.log(Object.fromEntries(sortedResults));
};
main().catch((e) => {
process.exit(1);
});

View file

@ -0,0 +1,7 @@
{
"compilerOptions": {
"module": "CommonJS",
"moduleResolution": "Node",
"target": "ES2017"
}
}