Skip to content

Commit

Permalink
Add a DiscordMedium class for high-level APIs, have Nuwani respond to…
Browse files Browse the repository at this point in the history
… mentions
  • Loading branch information
RussellLVP committed Aug 3, 2020
1 parent 50efcc6 commit 2c58032
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 4 deletions.
16 changes: 13 additions & 3 deletions javascript/features/nuwani_discord/discord_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,27 @@
// High-level manager that's responsible for our interaction with Discord. Builds upon many layers
// of Discord intelligence and behaviour, to end up with a convenient, easy to use API.
export class DiscordManager {
constructor() {
#medium_ = null;

constructor(medium) {
this.#medium_ = medium;
}

// ---------------------------------------------------------------------------------------------
// Events received from Discord
// ---------------------------------------------------------------------------------------------

// Called when the given |message| has been received in one of the Discord channels, as an
// instance of the Message class populated with all the relevant (and available) data.
// instance of the Message class populated with all the relevant (and available) data. Private
// messages will be ignored, as we want all interaction with Nuwani to be attributable.
onMessage(message) {
if (!message.guild)
return; // ignore private messages

const nuwani = message.guild.bot;
if (message.membersMentioned.has(nuwani) || message.content.includes('likeme'))
this.#medium_.createReaction(message, '🤖');

console.log(`Message from ${message.author?.nickname} (Id: ${message.id})`);
console.log(`-- channel: ${message.channel?.name}`);
console.log(`-- content: ${message.content}`);
Expand All @@ -26,6 +36,6 @@ export class DiscordManager {
// ---------------------------------------------------------------------------------------------

dispose() {

this.#medium_ = null;
}
}
50 changes: 50 additions & 0 deletions javascript/features/nuwani_discord/discord_medium.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2020 Las Venturas Playground. All rights reserved.
// Use of this source code is governed by the MIT license, a copy of which can
// be found in the LICENSE file.

import { DiscordAPI } from 'features/nuwani_discord/discord_api.js';

import { encode } from 'components/networking/html_encoding.js';

// Endpoint to which the Discord REST API requests should be made.
const kDiscordEndpoint = 'https://discordapp.com/api';

// The Discord medium is a communication channel through which interactions can be sent to Discord.
// It abstracts the low-level API calls in more convenient, high-level JavaScript APIs. Most of
// the APIs are documented in the following three articles on their Developer Portal:
//
// https://discord.com/developers/docs/resources/channel
// https://discord.com/developers/docs/resources/guild
// https://discord.com/developers/docs/resources/user
export class DiscordMedium {
#api_ = null;

constructor(configuration) {
this.#api_ = new DiscordAPI(configuration);
}

// ---------------------------------------------------------------------------------------------
// Actual Discord API methods
// ---------------------------------------------------------------------------------------------

// Creates the given |reaction| to the |message|, which must be one of the default emoji on the
// server. This requires the |message| to have been sent to a channel.
async createReaction(message, reaction) {
const channelId = message.channel?.id;
const messageId = message.id;
const emoji = encode(reaction);

if (!channelId || !messageId)
return false;

const path = `/channels/${channelId}/messages/${messageId}/reactions/${emoji}/@me`;
console.log('issuing request to: ' + kDiscordEndpoint + path);
return this.#api_.call('PUT', kDiscordEndpoint + path);
}

// ---------------------------------------------------------------------------------------------

dispose() {
this.#api_ = null;
}
}
11 changes: 10 additions & 1 deletion javascript/features/nuwani_discord/nuwani_discord.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// be found in the LICENSE file.

import { DiscordManager } from 'features/nuwani_discord/discord_manager.js';
import { DiscordMedium } from 'features/nuwani_discord/discord_medium.js';
import { DiscordRuntime } from 'features/nuwani_discord/discord_runtime.js';
import { Feature } from 'components/feature_manager/feature.js';

Expand All @@ -11,6 +12,7 @@ import { Feature } from 'components/feature_manager/feature.js';
// integration is specified in the README.md file, which also describes the architecture.
export default class NuwaniDiscord extends Feature {
manager_ = null;
medium_ = null;
nuwani_ = null;
runtime_ = null;

Expand All @@ -20,9 +22,13 @@ export default class NuwaniDiscord extends Feature {
// Depend on Nuwani because, well, we're part of the Nuwani system.
this.nuwani_ = this.defineDependency('nuwani');

// The medium allows us to interact with Discord and send messages, on top of our own high-
// level API. It abstracts this from the DiscordAPI class that issues REST calls.
this.medium_ = new DiscordMedium(this.nuwani_().configuration.discord);

// The manager is the high-level interface through which we'll react to Discord messages
// and state. It builds on top of the Runtime, which is the intelligence layer.
this.manager_ = new DiscordManager();
this.manager_ = new DiscordManager(this.medium_);

// The main Discord runtime, which owns the connection and decides what has to happen based
// on which messages are being received by the server. Responsible for keeping state.
Expand All @@ -37,6 +43,9 @@ export default class NuwaniDiscord extends Feature {
this.manager_.dispose();
this.manager_ = null;

this.medium_.dispose();
this.medium_ = null;

this.nuwani_ = null;
}
}

0 comments on commit 2c58032

Please sign in to comment.