├── .editorconfig ├── .eslintrc.json ├── Components └── tag.jsx ├── LICENSE ├── README.md ├── index.js ├── jsconfig.json ├── manifest.json └── style.css /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | root=true 3 | 4 | [*] 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | 9 | [*.{js,ts}] 10 | charset = utf-8 11 | indent_style = tab 12 | indent_size = 4 13 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], 3 | "env": { 4 | "node": true, 5 | "es6": true 6 | }, 7 | "parser": "@typescript-eslint/parser", 8 | "parserOptions": { "ecmaVersion": 2018, "sourceType": "module" }, 9 | "rules": { 10 | "no-extra-parens": ["warn", "all", { 11 | "nestedBinaryExpressions": false 12 | }], 13 | "valid-jsdoc": ["warn", { 14 | "requireReturn": false, 15 | "requireReturnDescription": false, 16 | "prefer": { 17 | "arg": "param", 18 | "argument": "param", 19 | "prop": "property", 20 | "constructor": "class", 21 | "augments": "extends", 22 | "fires": "emits", 23 | "var": "member", 24 | "yield": "yields", 25 | "return": "returns", 26 | "exception": "throws", 27 | "virtual": "abstract" 28 | }, 29 | "preferType": { 30 | "String": "string", 31 | "Number": "number", 32 | "Boolean": "boolean", 33 | "Symbol": "symbol", 34 | "function": "Function", 35 | "object": "Object", 36 | "date": "Date", 37 | "error": "Error" 38 | } 39 | }], 40 | "@typescript-eslint/indent": ["error", "tab"], 41 | "accessor-pairs": "warn", 42 | "array-callback-return": "error", 43 | "complexity": "warn", 44 | "curly": ["error", "multi-line", "consistent"], 45 | "dot-location": ["error", "property"], 46 | "dot-notation": "error", 47 | "eqeqeq": "error", 48 | "no-console": ["error", { "allow": ["log", "warn", "error"] }], 49 | "no-empty-function": "error", 50 | "no-floating-decimal": "error", 51 | "no-implied-eval": "error", 52 | "no-lone-blocks": "error", 53 | "no-multi-spaces": "error", 54 | "no-new-func": "error", 55 | "no-new-wrappers": "error", 56 | "no-new": "error", 57 | "no-octal-escape": "error", 58 | "no-return-assign": "error", 59 | "no-self-compare": "error", 60 | "no-sequences": "error", 61 | "no-unmodified-loop-condition": "error", 62 | "no-unused-expressions": "error", 63 | "no-useless-call": "error", 64 | "no-useless-concat": "error", 65 | "no-useless-escape": "error", 66 | "no-void": "error", 67 | "no-warning-comments": "warn", 68 | "wrap-iife": "error", 69 | "yoda": "error", 70 | 71 | "no-label-var": "error", 72 | "no-shadow": "error", 73 | "no-undef-init": "error", 74 | 75 | "callback-return": "error", 76 | "handle-callback-err": "error", 77 | "no-mixed-requires": "error", 78 | "no-new-require": "error", 79 | "no-path-concat": "error", 80 | 81 | "array-bracket-spacing": "error", 82 | "block-spacing": "error", 83 | "brace-style": ["error", "1tbs", { "allowSingleLine": true }], 84 | "camelcase": "error", 85 | "comma-dangle": "error", 86 | "comma-spacing": "error", 87 | "comma-style": "error", 88 | "computed-property-spacing": "error", 89 | "consistent-this": "error", 90 | "eol-last": "error", 91 | "func-names": "error", 92 | "func-style": ["error", "declaration", { "allowArrowFunctions": true }], 93 | "id-length": ["error", { "exceptions": ["i", "j", "a", "b", "e", "r", "m", "c"] }], 94 | "indent": [0, 4, { "SwitchCase": 1 }], 95 | "key-spacing": "error", 96 | "keyword-spacing": ["error", { 97 | "overrides": { 98 | "if": { "after": true }, 99 | "for": { "after": true }, 100 | "while": { "after": true }, 101 | "catch": { "after": true }, 102 | "switch": { "after": true } 103 | } 104 | }], 105 | "max-depth": "error", 106 | "max-len": ["error", 200, 2], 107 | "max-nested-callbacks": ["error", { "max": 4 }], 108 | "max-statements-per-line": ["error", { "max": 2 }], 109 | "new-cap": "error", 110 | "newline-per-chained-call": ["error", { "ignoreChainWithDepth": 6 }], 111 | "no-array-constructor": "error", 112 | "no-bitwise": "off", 113 | "no-lonely-if": "error", 114 | "no-mixed-operators": "error", 115 | "no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }], 116 | "no-new-object": "error", 117 | "no-spaced-func": "error", 118 | "no-trailing-spaces": "error", 119 | "no-unneeded-ternary": ["error", { "defaultAssignment": false }], 120 | "no-whitespace-before-property": "error", 121 | "object-curly-newline": "error", 122 | "object-curly-spacing": ["error", "always"], 123 | "operator-assignment": "error", 124 | "operator-linebreak": [ 125 | "error", 126 | "before", 127 | { 128 | "overrides": { 129 | "+": "after", 130 | "-": "after" 131 | } 132 | } 133 | ], 134 | "padded-blocks": ["error", { "classes": "always", "blocks": "never", "switches": "never" }], 135 | "quote-props": ["error", "as-needed"], 136 | "quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": true }], 137 | "semi-spacing": "error", 138 | "semi": "error", 139 | "space-before-blocks": "error", 140 | "space-before-function-paren": ["error", {"anonymous": "always", "named": "never", "asyncArrow": "always"}], 141 | "space-in-parens": "error", 142 | "space-infix-ops": "error", 143 | "space-unary-ops": "error", 144 | "spaced-comment": "error", 145 | "unicode-bom": "error", 146 | 147 | "arrow-body-style": "error", 148 | "arrow-spacing": "error", 149 | "no-duplicate-imports": "error", 150 | "no-useless-computed-key": "error", 151 | "no-useless-constructor": "error", 152 | "prefer-arrow-callback": "error", 153 | "prefer-const": "error", 154 | "prefer-destructuring": ["error", { 155 | "VariableDeclarator": { 156 | "array": false, 157 | "object": true 158 | }, 159 | "AssignmentExpression": { 160 | "array": true, 161 | "object": true 162 | } 163 | }, { 164 | "enforceForRenamedProperties": false 165 | }], 166 | "prefer-rest-params": "error", 167 | "prefer-spread": "error", 168 | "prefer-template": "error", 169 | "rest-spread-spacing": "error", 170 | "template-curly-spacing": "error", 171 | "yield-star-spacing": "error" 172 | } 173 | } -------------------------------------------------------------------------------- /Components/tag.jsx: -------------------------------------------------------------------------------- 1 | const { React } = require('powercord/webpack'); 2 | 3 | class Tag extends React.PureComponent { 4 | render () { 5 | return
WEBHOOK
; 6 | } 7 | } 8 | 9 | Tag.cache = {}; 10 | module.exports = Tag; 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Ben 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Webhook Tag 2 | A simple powercord plugin that shows you when a bot is really a webhook. It doesnt effect regular bot tags, system message tags or server announcement channel message tags. 3 | 4 | ![](https://cdn.discordapp.com/attachments/723241105323327581/792496211298353192/unknown.png) 5 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const { Plugin } = require('powercord/entities'); 2 | const { getModule, getModuleByDisplayName, React } = require('powercord/webpack'); 3 | const { inject, uninject } = require('powercord/injector'); 4 | const { findInReactTree } = require('powercord/util'); 5 | 6 | const Tag = require('./Components/tag'); 7 | 8 | module.exports = class WebTag extends Plugin { 9 | async startPlugin() { 10 | this.loadStylesheet('./style.css'); 11 | 12 | const MessageTimestamp = getModule([ 'MessageTimestamp' ], false) || getModule(m => ( 13 | typeof (m?.__powercordOriginal_default || m.default) === 'function' && 14 | (m?.__powercordOriginal_default || m.default).toString().includes('showTimestampOnHover') 15 | ), false); 16 | const botTagRegularClasses = getModule(['botTagRegular'], false); 17 | const botTagClasses = getModule(['botTagCozy'], false); 18 | const remClasses = getModule(['rem'], false); 19 | 20 | inject('webhook-tag-messages', MessageTimestamp, 'default', (args, res) => { 21 | const msg = args[0].message; 22 | 23 | if (msg.webhookId !== null && msg.messageReference === null && msg.author.discriminator === '0000') { 24 | const header = findInReactTree(res.props.username, e => Array.isArray(e?.props?.children) && e.props.children.find(c => c?.props?.message)); 25 | header.props.children[0].props.message.author.bot = false; 26 | header.props.children.push(React.createElement( 27 | 'span', 28 | { 29 | className: `${botTagClasses.botTagCozy} ${botTagClasses.botTagCompact} ${botTagRegularClasses.botTagRegular} ${remClasses.rem}` 30 | }, 31 | React.createElement(Tag, { 32 | className: botTagRegularClasses.botText 33 | }) 34 | )); 35 | } 36 | 37 | return res; 38 | }); 39 | 40 | const AnalyticsContext = await getModuleByDisplayName('AnalyticsContext'); 41 | inject('webhook-tag-popout', AnalyticsContext.prototype, 'renderProvider', (_, res) => { 42 | const elements = findInReactTree(res, a => Array.isArray(a) && a.find(c => c && c.type && c.type.displayName === 'CustomStatus')); 43 | if (!elements) return res; 44 | 45 | const { user } = findInReactTree(elements, p => p.user); 46 | if (user.discriminator !== '0000' || !user.bot) return res; 47 | 48 | elements[1].props.children[1].props.children = [ 49 | elements[1].props.children[1].props.children, 50 | React.createElement( 51 | 'span', 52 | { 53 | className: `webhook-tag-pop-out ${botTagClasses.botTagCozy} ${botTagClasses.botTagCompact} ` + 54 | `${botTagRegularClasses.botTagRegular} ${remClasses.rem}` 55 | }, 56 | React.createElement(Tag, { 57 | className: botTagRegularClasses.botText 58 | }) 59 | ) 60 | ] 61 | 62 | return res; 63 | }); 64 | } 65 | 66 | pluginWillUnload() { 67 | uninject('webhook-tag-messages'); 68 | uninject('webhook-tag-popout'); 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6" 5 | }, 6 | "include": ["../../../src/**/*"] 7 | } -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Webhook Tags", 3 | "version": "0.2.2", 4 | "description": "Replace bot tags with webhook tags for webhook messages", 5 | "author": "Ben855#0855", 6 | "license": "MIT" 7 | } -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | .webhook-tag-pop-out { 2 | margin-top: -2px !important; 3 | } 4 | --------------------------------------------------------------------------------