Browse Source

Initial commit

Add files from pridepack.
master
TheoryOfNekomata 2 years ago
commit
76919ee3bc
11 changed files with 5954 additions and 0 deletions
  1. +9
    -0
      .eslintrc
  2. +109
    -0
      .gitignore
  3. +48
    -0
      package.json
  4. +3
    -0
      pridepack.json
  5. +20
    -0
      src/commands/pin.ts
  6. +29
    -0
      src/commands/save.ts
  7. +83
    -0
      src/index.ts
  8. +31
    -0
      src/utils/common.ts
  9. +22
    -0
      tsconfig.eslint.json
  10. +22
    -0
      tsconfig.json
  11. +5578
    -0
      yarn.lock

+ 9
- 0
.eslintrc View File

@@ -0,0 +1,9 @@
{
"root": true,
"extends": [
"lxsmnsyc/typescript"
],
"parserOptions": {
"project": "./tsconfig.eslint.json"
}
}

+ 109
- 0
.gitignore View File

@@ -0,0 +1,109 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.production
.env.development

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

.npmrc
src/messages.json
.idea/

+ 48
- 0
package.json View File

@@ -0,0 +1,48 @@
{
"version": "0.0.0",
"types": "dist/types/index.d.ts",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"exports": {
"require": "./dist/cjs/index.js",
"import": "./dist/esm/index.js"
},
"files": [
"dist",
"src"
],
"engines": {
"node": ">=16"
},
"license": "MIT",
"keywords": [
"pridepack"
],
"name": "asshurtstitution",
"dependencies": {
"discord.js": "^13.0.1",
"dotenv": "^10.0.0",
"fastify": "^3.20.1"
},
"devDependencies": {
"@types/jest": "^26.0.24",
"@types/node": "^16.4.13",
"@types/node-fetch": "^2.5.12",
"eslint": "^7.32.0",
"eslint-config-lxsmnsyc": "^0.2.3",
"pridepack": "^0.10.0",
"tslib": "^2.3.0",
"typescript": "^4.3.5"
},
"peerDependencies": {},
"scripts": {
"prepublish": "pridepack clean && pridepack build",
"build": "pridepack build",
"type-check": "pridepack check",
"lint": "pridepack lint",
"test": "pridepack test --passWithNoTests",
"clean": "pridepack clean",
"watch": "pridepack watch",
"start": "node ./dist/cjs/index.js"
}
}

+ 3
- 0
pridepack.json View File

@@ -0,0 +1,3 @@
{
"target": "es2017"
}

+ 20
- 0
src/commands/pin.ts View File

@@ -0,0 +1,20 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { Message, TextChannel } from 'discord.js';
import messages from '../messages.json';
import { transferPin } from '../utils/common';

const pin = async (
message: Message, pinTextChannel: TextChannel, silent = false,
): Promise<void> => {
const isReply = message.type === 'REPLY';
if (!isReply) {
await message.reply(messages.NOTHING_TO_PIN);
return;
}

const reply = await message.fetchReference();
await transferPin(reply, pinTextChannel, silent);
await message.reply(messages.PIN_COMPLETE);
};

export default pin;

+ 29
- 0
src/commands/save.ts View File

@@ -0,0 +1,29 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { Message, TextChannel } from 'discord.js';
import messages from '../messages.json';
import { transferPin } from '../utils/common';

const save = async (
message: Message, mainTextChannel: TextChannel, pinTextChannel: TextChannel, silent = true,
): Promise<void> => {
const pinnedMessages = await mainTextChannel.messages.fetchPinned();
const pinnedMessagesCollection = Array.from(pinnedMessages.values());
if (pinnedMessagesCollection.length <= 0) {
await message.reply(messages.NOTHING_TO_SAVE);
return;
}

const promises = pinnedMessagesCollection
.reverse()
.map((reply, i) => new Promise<void>((resolve, reject) => {
setTimeout(() => {
transferPin(reply, pinTextChannel, silent)
.then(resolve)
.catch(reject);
}, i * Number(process.env.DISCORD_MESSAGES_THROTTLE || '1000'));
}));
await Promise.all(promises);
await message.reply(messages.SAVE_COMPLETE);
};

export default save;

+ 83
- 0
src/index.ts View File

@@ -0,0 +1,83 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access, no-void */
import dotenv from 'dotenv';
import { Client, Intents, TextChannel } from 'discord.js';
import messages from './messages.json';
import { transferPin, getCommandPattern, log } from './utils/common';
import pin from './commands/pin';
import save from './commands/save';

dotenv.config();

const listen = async (channelIDMap: Map<string, string>) => {
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
client.on('ready', () => {
log(`Logged in as ${client.user?.tag || ''}!`);
});

Array.from(channelIDMap).forEach(([mainChannelID, pinChannelID]) => {
client.on('messageCreate', async (message) => {
if (message.channel.id !== mainChannelID) {
return;
}

const mainChannel = await client.channels.fetch(mainChannelID);
const pinChannel = await client.channels.fetch(pinChannelID);
if (mainChannel?.type !== 'GUILD_TEXT' || pinChannel?.type !== 'GUILD_TEXT') {
return;
}

const mainTextChannel = mainChannel as TextChannel;
const pinTextChannel = pinChannel as TextChannel;

const clientUser = client.user;
if (!clientUser) {
return;
}

if (message.type === 'CHANNEL_PINNED_MESSAGE') {
const reply = await message.fetchReference();
await transferPin(reply, pinTextChannel, false);
await reply.unpin();
await mainTextChannel.send(`${message.author.toString()} ${messages.PIN_COMPLETE as string}`);
await message.delete();
return;
}

if (message.author.id === clientUser.id) {
return;
}

const mentioned = message.mentions.users.has(clientUser.id);
if (!mentioned) {
return;
}

switch (message.content) {
case getCommandPattern(clientUser, 'pin'):
await pin(message, pinTextChannel);
return;
case getCommandPattern(clientUser, 'save'):
await save(message, mainTextChannel, pinTextChannel);
return;
default:
break;
}

await message.reply(messages.UNKNOWN_COMMAND);
});
});

await client.login(process.env.DISCORD_BOT_TOKEN as string);
return client;
};

const main = async (channelMap: Map<string, string>) => {
await listen(channelMap);
};

const channelMap = new Map<string, string>();
channelMap.set(
process.env.DISCORD_MAIN_CHANNEL as string,
process.env.DISCORD_PIN_CHANNEL as string,
);
void main(channelMap);

+ 31
- 0
src/utils/common.ts View File

@@ -0,0 +1,31 @@
import { ClientUser, Message, TextChannel } from 'discord.js';

export const transferPin = async (
reply: Message, pinTextChannel: TextChannel, silent = false,
): Promise<void> => {
await pinTextChannel.send({
content: `\`${reply.createdAt.toISOString()}\` ${silent
? reply.author.username
: reply.author.toString()}:
${reply.content}`,
embeds: Array.from(reply.attachments.values())
.map((a) => ({
image: {
height: a.height as number,
url: a.url,
width: a.width as number,
proxy_url: a.proxyURL,
},
})),
});
};

export const getCommandPattern = (clientUser: ClientUser, commandName: string): string => (
`<@!${clientUser.id}> ${commandName.toLowerCase()}`
);

export const log = (...args: unknown[]): void => {
// eslint-disable-next-line no-console
console.log(...args);
};

+ 22
- 0
tsconfig.eslint.json View File

@@ -0,0 +1,22 @@
{
"exclude": ["node_modules"],
"include": ["src", "types", "test"],
"compilerOptions": {
"module": "ESNext",
"lib": ["ESNext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"esModuleInterop": true,
"target": "ES2017",
"skipLibCheck": true,
"resolveJsonModule": true
}
}

+ 22
- 0
tsconfig.json View File

@@ -0,0 +1,22 @@
{
"exclude": ["node_modules"],
"include": ["src", "types"],
"compilerOptions": {
"module": "ESNext",
"lib": ["ESNext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./src",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"esModuleInterop": true,
"target": "ES2017",
"skipLibCheck": true,
"resolveJsonModule": true
}
}

+ 5578
- 0
yarn.lock
File diff suppressed because it is too large
View File


Loading…
Cancel
Save