Skip to content

Commit

Permalink
feat: wait for a post to be reported to Smokey before flagging it
Browse files Browse the repository at this point in the history
  • Loading branch information
double-beep authored May 27, 2024
1 parent 82b487d commit 9512f6c
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 11 deletions.
9 changes: 6 additions & 3 deletions src/UserscriptTools/ChatApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,20 @@ export class ChatApi {
}

private closeWS(): void {
this.websocket?.close();
// websocket already closed
if (!this.websocket) return;

this.websocket.close();
this.websocket = null;

if (Store.dryRun) {
console.log('WebSocket connection closed.');
console.log('Chat WebSocket connection closed.');
}
}

public async waitForReport(postId: number): Promise<void> {
await withTimeout<void>(
10000,
10_000,
new Promise<void>(resolve => {
this.websocket?.addEventListener('message', (event: MessageEvent<string>) => {
const data = JSON.parse(event.data) as ChatWsMessage;
Expand Down
110 changes: 102 additions & 8 deletions src/UserscriptTools/MetaSmokeAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ import {
PostType,
delay,
getFormDataFromObject,
withTimeout,
} from '../shared';
import { Modals, Input, Buttons } from '@userscripters/stacks-helpers';
import { displayToaster, page } from '../AdvancedFlagging';
import Reporter from './Reporter';

const metasmokeKey = '0a946b9419b5842f99b052d19c956302aa6c6dd5a420b043b20072ad2efc29e0';
const metasmokeApiFilter = 'GGJFNNKKJFHFKJFLJLGIJMFIHNNJNINJ';
const metasmokeReportedMessage = 'Post reported to Smokey';
const metasmokeFailureMessage = 'Failed to report post to Smokey';

Expand All @@ -28,15 +27,30 @@ interface MetasmokeData {
[key: number]: number;
}

interface MetasmokeWsMessage {
type: string;
message: {
event_class: string;
event_type: string;
object: {
link: string;
};
};
}

export class MetaSmokeAPI extends Reporter {
public static accessToken: string;
public static isDisabled: boolean = Store.get<boolean>(Cached.Metasmoke.disabled) || false;

public smokeyId: number;

private static readonly appKey = metasmokeKey;
private static readonly appKey = '0a946b9419b5842f99b052d19c956302aa6c6dd5a420b043b20072ad2efc29e0';
private static readonly filter = 'GGJFNNKKJFHFKJFLJLGIJMFIHNNJNINJ';
private static metasmokeIds: MetasmokeData = {};

private websocket: WebSocket | null = null;
private readonly wsUrl = 'wss://metasmoke.erwaysoftware.com/cable';

constructor(
id: number,
private readonly postType: PostType,
Expand All @@ -57,6 +71,80 @@ export class MetaSmokeAPI extends Reporter {
MetaSmokeAPI.accessToken = await MetaSmokeAPI.getUserKey();
}

private initWS(): void {
this.websocket = new WebSocket(this.wsUrl);

const auth = JSON.stringify({
identifier: JSON.stringify({
channel: 'ApiChannel',
key: MetaSmokeAPI.appKey,
events: 'posts#create'
}),
command: 'subscribe'
});

this.websocket.addEventListener('open', () => {
this.websocket?.send(auth);
});

if (Store.dryRun) {
console.log('MS WebSocket initialised.');
}
}

private closeWS(): void {
// websocket already closed
if (!this.websocket) return;

this.websocket.close();
this.websocket = null;

if (Store.dryRun) {
console.log('MS WebSocket connection closed.');
}
}

private async waitForReport(): Promise<void> {
if (!this.websocket) return;

await withTimeout(
10_000,
new Promise<void>(resolve => {
this.websocket?.addEventListener('message', (event: MessageEvent<string>) => {
const data = JSON.parse(event.data) as MetasmokeWsMessage;

// https://github.com/Charcoal-SE/userscripts/blob/master/sim/sim.user.js#L381-L400
if (data.type) return; // not interested

if (Store.dryRun) {
console.log('New post reported to Smokey', data);
}

const {
object,
event_class: evClass,
event_type: type
} = data.message;

// not interested
if (type !== 'create' || evClass !== 'Post') return;

const link = object.link;
const url = new URL(link, location.href);

const postId = Number(/\d+/.exec(url.pathname)?.[0]);

if (
url.host !== location.host // different sites
|| postId !== this.id // different posts
) return;

resolve();
});
})
).finally(() => this.closeWS());
}

private static getMetasmokeTokenPopup(): HTMLElement {
const codeInput = Input.makeStacksInput(
'advanced-flagging-metasmoke-token-input',
Expand Down Expand Up @@ -157,7 +245,7 @@ export class MetaSmokeAPI extends Reporter {
urls: urlString,
key: MetaSmokeAPI.appKey,
per_page: 1000,
filter: metasmokeApiFilter // only include id and link fields
filter: this.filter // only include id and link fields
})
.map(item => item.join('='))
.join('&');
Expand Down Expand Up @@ -209,7 +297,7 @@ export class MetaSmokeAPI extends Reporter {
});
}

public async reportRedFlag(): Promise<string> {
public async reportRedFlag(): Promise<void> {
const urlString = MetaSmokeAPI.getQueryUrl(this.id, this.postType);

const { appKey, accessToken } = MetaSmokeAPI;
Expand Down Expand Up @@ -243,8 +331,6 @@ export class MetaSmokeAPI extends Reporter {

throw new Error(metasmokeFailureMessage);
}

return metasmokeReportedMessage;
}

public override canBeReported(): boolean {
Expand Down Expand Up @@ -276,7 +362,15 @@ export class MetaSmokeAPI extends Reporter {

// not reported, feedback is tpu AND the post isn't deleted => report it!
if (!this.smokeyId && feedback === 'tpu-' && !this.deleted) {
return await this.reportRedFlag();
// see: https://chat.stackexchange.com/transcript/message/65076878
this.initWS();
await this.reportRedFlag();
await this.waitForReport();

// https://chat.stackexchange.com/transcript/message/65097399
await new Promise(resolve => setTimeout(resolve, 3 * 1000));

return metasmokeReportedMessage;
} else if (!accessToken || !this.smokeyId) {
// user hasn't authenticated or the post hasn't been reported => don't send feedback
return '';
Expand Down

0 comments on commit 9512f6c

Please sign in to comment.