Git Product home page Git Product logo

slash-create's Introduction

NPM version NPM downloads ESLint status DeepScan grade discord chat

Create and sync Discord slash commands.

Features

  • Multiple server support (Express, Fastify, etc.)
  • Hook into an existing Discord bot client
  • Sync loaded commands to Discord from slash-create
  • Load commands from a folder
  • Command throttling/cooldowns

Quickstart

If you want an easy start on getting slash commands on your bot, you can use slash-up to create a project using a template.

npx slash-up init

After creating a project, you can edit commands to your liking and start it up with yarn start.

You can also deploy a slash-create template to the following services:

Cloudflare Workers Vercel Heroku Railway
Deploy to Cloudflare Workers Deploy with Vercel Deploy Deploy on Railway

Installation

npm i slash-create

Or, using yarn:

yarn add slash-create

Using webservers

In order to use a specific webserver, you will need to install the dependency associated with that server. The following server types require these dependencies:

Examples

Useful Links

Resources & References

This project borrows resources and references from the following repositories:

slash-create's People

Contributors

acidmyke avatar blobfysh avatar busybox11 avatar chris-bitler avatar conman1161 avatar cyntheon avatar dependabot[bot] avatar drdrjojo avatar dukeofsussex avatar fbrettnich avatar fdasfsafsa avatar ionaru avatar jayydoesdev avatar keyboardrage avatar kitsunedev avatar lavadesu avatar lukasfri avatar mergify[bot] avatar micschwarz avatar multimeric avatar nickantx avatar norbsdev avatar polvallverdu avatar snazzah avatar sotrx avatar sudojunior avatar vegeta897 avatar xirpy avatar ytausch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

slash-create's Issues

Let the GuildID property be an array

By placing this property as a matrix, you could create commands for X number of servers and not have to create a file for each server command if it will be the same. This can be solved in a number of ways, but it would be very useful if it could be placed directly in the GuildID property.
For example:

{
    name: "premium",
    description: "Special command for 5 servers",
    guildID: ["ID1", "ID2", "ID3", "ID4", "ID5"]
}

This would also be useful when testing global bot commands where you have two or more servers to test on.

Use BigInts in Permission BitField

permissions use a string instead of a number at the moment. Right now, its converted to a number, but I should've actually done a proper use of bigints here.

How to use callback function in run(ctx)

Sorry if this is a novice question

I'm trying to call an async function from the run(ctx). The function is just designed to call a shell command, and looks like:

function bash(cmd, callback) {
  console.log(cmd);
  exec(cmd, (err, stdout, stderr) => {
    console.log(`err: ${err}`);
    console.log(`stderr: ${stderr}`);
    console.log(`stdout: ${stdout}`);

    if (err) { callback(err.message); }
    else if (stderr.length > 0) { callback(stderr); }
    else if (stdout.length > 0) { callback(stdout); }
    else { callback("no ouptut :("); }

  });
}

With typical discord bot messaging, I was able to wait to send a message like this:

bash(command, output => message.channel.send("```" + output + "```") );

How would I achieve the equivalent with the run(ctx) function? Is there somewhere I can read more about the run(ctx) pattern?

As another question, what's the proper pattern for having multiple commands in the commands/ directory. Can each module have a run(ctx) func?

Ability to sending a message to the dm

In discord.js you can send direct messages with

message.author.send(content)

and I would like that in the same way with this library it could be sent with for example

ctx.member.send(content)

because sending it from the client is not it can simply if the user is not cached.

Class constructor SlashCommand cannot be invoked without 'new'

Hello! I'm trying to use this library with TypeScript.
I'm currently on version 3.0.1

Here's an example command I have:

HelloCommand.ts

import { SlashCommand } from 'slash-create';

export class HelloCommand extends SlashCommand {
    constructor(creator) {
        super(creator, {
            name: 'hello',
            description: 'Says hello to you.'
        });

        this.filePath = __filename;
    }

    async run(ctx) {
        return `Hello, ${ctx.user.username}!`;
    }
}

And here's how I'm trying to register the command:

import { HelloCommand } from './commands/HelloCommand';

creator.registerCommand(new HelloCommand(creator)).syncCommands();

Whenever I try to construct the HelloCommand, I get this error:

TypeError: Class constructor SlashCommand cannot be invoked without 'new'
    at new HelloCommand (src/commands/HelloCommand.ts:5:9)
    at Object.<anonymous> (src/index.ts:20:22)
[ERROR] 16:05:14 TypeError: Class constructor SlashCommand cannot be invoked without 'new'

There's no errors when I import them using .registerCommandsIn(directory), but that does not work with ts-node, so I'm trying to avoid it.

"BotName is thinking..." Issue

I am not sure how is this being caused, it randomly started happening, where whenever I type a command, above the response discord adds "BotName is thinking...". An example is shown below:

image

Acknowledgement is also set to true.

feat/patch: Allow epheremal messages on follow up contexts

Given the documentation on follow up messages, it would be logical to modify the edit options to allow this. In doing so, this would make EditMessageOptions preferable over MessageOptions as the latter would become an empty child interface.

const data = await this.creator.requestHandler.request(
'POST',
Endpoints.FOLLOWUP_MESSAGE(this.creator.options.applicationID, this.interactionToken),
true,
{
tts: options.tts,
content: options.content,
embeds: options.embeds,
allowed_mentions: allowedMentions,
components: options.components
},
options.file
);

How to create guild commands?

For testing and developing commands, discord recommends using Guild Commands. Is there a property of SlashCreator which supports this?

ps: Great work, you're fast to the punch

How to do a poll?

I'm trying to create a poll using a slash command.

So basically I just want to do a message with an embed and once people react to that, I want to call a Lambda function which count the vote.

This poll will also have an end date at which another Lambda function will be called to perform an action with the poll results.

I'm using Lambda as the server, with this repository: https://github.com/ytausch/serverless-discord-bot

My main question here is, what's the best way to listen to those events (reaction and poll expiration date) using slash-create? I'm kind of lost in the documentation.

--

I'm thinking that perhaps the most direct way would be creating the poll message using a slash command and then schedule another lambda to be triggered at expiration date, to do the final reaction counting (so counting the votes just at the end), but I'm wondering if there's a smarter way to go about it.

Add components functionality

Will work on once this is published in documentation.

New interaction type: MESSAGE_COMPONENT = 3 (example)
New component types: ACTION_ROW = 1, BUTTON = 2
New button styles: PRIMARY = 1, SECONDARY = 2, SUCCESS = 3, DESTRUCTIVE = 4, LINK = 5

Example Payload

{
  "content": "buttons!",
  "components": [
    {
      "type": 1,
      "components": [
        {
          "type": 2,
          "style": 1,
          "custom_id": "test",
          "label": "Blurple Button"
        },
        {
          "type": 2,
          "style": 2,
          "custom_id": "test",
          "label": "Gray Button"
        },
        {
          "type": 2,
          "style": 3,
          "custom_id": "test",
          "label": "Green Button"
        },
        {
          "type": 2,
          "style": 4,
          "custom_id": "test",
          "label": "Red Button"
        },
        {
          "type": 2,
          "style": 5,
          "url": "https://google.com",
          "label": "Link Button"
        }
      ]
    }
  ]
}

Command Docs Generator

Add a doc generator that generates (markdown) docs from the commands.

Reasoning

Now that we know arguments and their types we could use this information to generate documentation. There could also be a property for a longer description or longer descriptions, this is just a quick idea I wanted to share.

As I already mentioned, I opened this issue to discuss the idea, if its decided to be added, I'd be happy to submit a pull request.

Guild only

Is there a way to make them only for guilds? It's not possible for me to enter each guild in the guildIDs as my bot is public. It's useful for commands like kick or ban

Make registerCommands() support extended class from SlashCommand

I'm making a bot using Discord.js, and I created a command that creates a new channel in a server. I noticed that I can't access the instance of my Discord.js client (I need it to get the Guild instance) inside the SlashCommand instance so I decided to create another class which is equal to something like that:

// base/Command.ts
export default class Command extends SlashCommand {
    public client: ThizzClient;

    constructor (client: ThizzClient, options: SlashCommandOptions) {
        super(client.creator, options);
        this.client = client;
    }

};
// commands/ping.ts
class PingCommand extends Command {

	constructor (client: ThizzClient) {
         super (client: ThizzClient, {
              name: 'ping',
              // ...
         });
	}

	async run () {
        // this.client can be used here
    }

}
// index.ts

// and then I can make my loop over each command (using something like fs)
client.creator.registerCommands([ PingCommand, CreateCommand ].map((command) => new Command(client));

The problem is that it doesn't work because it fails when checking instance of in slash-create.

if (!(command instanceof SlashCommand)) throw new Error(`Invalid command object to register: ${command}`);

So I would like to know if there is another solution planned? It would be good to be able to pass extra properties when creating the SlashCreator instance. Extending class is a thing, being able to do something like the code below would be even easier (the SlashCreator would pass the property to the SlashCommand instance when creating it).

this.slashCommandHandler = new SlashCreator({
    applicationID: process.env.BOT_ID!,
    token: process.env.BOT_TOKEN!,
    publicKey: process.env.BOT_PUB_KEY!,

	customClient: client
});

Thanks

404 when using deferral

I'm trying to use your library (v3.3.0) and everything was working when running it as a discord bot, but as soon as I moved everything into an AWS Lambda that is accessible via API Gateway I'm having issues sending followup and replacement messages via deferral (see code below). In discord the bot shows This interaction failed instead of the thinking message.

As part of debugging I attempted to have run return just a string instead of using ctx.defer(false) and the hook works as expected, but I need to use deferral due to the lengthy computation time required to properly respond. I also attempted to manually GET the webhook endpoint that the PATCH request is sent to, to see the original message (which failed) and I received the following response from discord

{
    "message": "Unknown Webhook",
    "code": 10015
}

Example code:

async run(ctx: CommandContext) {
    console.log('Received voyage');
    if (!ctx.guildID) {
      return 'Voyages are not supported in direct message';
    }

    // It takes a while to login and retrieve sheet info, defer the call as it
    // is unlikely we will consistently respond within 3000ms
    await ctx.defer(false);
    
    return ctx.send(...generateMessages());   
}

Lambda Logs:

START RequestId: f4383aab-c6c0-4e08-b602-9adcfaa88498 Version: $LATEST
--
2021-09-16T09:00:46.309Z	f4383aab-c6c0-4e08-b602-9adcfaa88498	INFO	Got request
2021-09-16T09:00:47.108Z	f4383aab-c6c0-4e08-b602-9adcfaa88498	INFO	Running command: voyage (XXX, guild XXX)


2021-09-16T09:00:48.733Z	f4383aab-c6c0-4e08-b602-9adcfaa88498	INFO	Request: 
{
    "content": "",
    "embeds": [
        {
            "timestamp": "2021-09-18T06:16:30.067Z",
            "footer": {
                "text": "Next roll available after"
            },
            "author": {
                "name": "Sea Worthy Voyages - No rolls available",
                "icon_url": "https://i.imgur.com/hVTcL4l.png"
            },
            "color": 16711680
        },
        {
            "timestamp": "2021-09-18T06:16:30.067Z",
            "footer": {
                "text": "Next roll available after",
                "icon_url": "https://i.imgur.com/hVTcL4l.png"
            },
            "thumbnail": {
                "url": "https://i.imgur.com/lgtKWy4.png"
            },
            "author": {
                "name": "Sea Worthy Voyages - Easy Task",
                "icon_url": "https://i.imgur.com/hVTcL4l.png"
            },
            "color": 12050893,
            "description": "Advance your skills as a lumberjack by Chopping 135 Oak or Willow logs. Post screenshot proof, with timestamp, in the appropriate text channel. If a main account show history proving you didn't buy the product.\n\nYou can complete this task at any time, however; you will not be able to roll another task until 7 days from now",
            "title": "Lumberjack Apprentice"
        }
    ],
    "allowed_mentions": {
        "parse": [
            "roles",
            "users"
        ]
    }
}



2021-09-16T09:00:48.786Z	f4383aab-c6c0-4e08-b602-9adcfaa88498	INFO	 1631782848734 /webhooks/XXX/:token/messages/@original 404: 245ms (474ms avg) \| 1/1 left \| Reset 1631782848734 (0ms left)
--
END RequestId: f4383aab-c6c0-4e08-b602-9adcfaa88498

Remove timeout for webservers when editing messages

An update was made today that made any edits/follow-up messages wait for a reply or /callback from the interaction before being used, removing the need of an artificial timeout and no longer needing CommandContext#webserverMode in general, however the latter may be kept out of deprecation for updates of the future.

Doing any processing on Google Cloud Run causes "An error occurred while running the command", despite returning a 200

Here's a simple example run function to replicate the issue. This is packaged in docker, and deployed on Google Cloud Run. Google Cloud Run does not support any async processing (because it bills by the time between receiving the request and sending response), so I need to do some processing before acking or sending any response.

According to discord documentation, the interaction token is good for 15 minutes, and I can't find anything else about a timeout, so I don't think the issue is caused by discord.

  async run(ctx) {
    var subcommand = ctx.subcommands[0];

    if (subcommand == "sleep") {
      var delayMS = 10;
      console.log("functions working, sleeping " + delayMS + " milliseconds before responding");
      await sleep(delayMS);
      return "functions working";
    }

    if (subcommand == "noop") {
      console.log("functions working, noop");
      return "noop";
    }
  }

Running /functions noop returns a message and log line, as expected.

functions working, noop
Info  POST 200  164ms  Discord-Interactions 1.0 (+https://discord.com)

Running /functions sleep causes discord to immediately respond in the UI with an error,

An error occurred while running the command. Only you can see this โ€ข Dismiss message

however the logs also look fine:

functions working, sleeping 0 milliseconds before responding
Info  POST 200  31ms  Discord-Interactions 1.0 (+https://discord.com)

Support bulk updating commands

You can now PUT multiple command objects into an array to update them all at once. This update somehow might've broke regular command updating.

Inquiry

This might sound stupid, but I can't find a way to only register a command in a guild for testing since it instantly registers it?

Unknown Command Handling (using a command to handle unknown commands)

At the moment, unknown commands respond with a message. I plan to have the unknown command optionally be a set SlashCommand that will not be registered normally in order to not be synced with regular commands and serve only as a catch-all for unknown commands.

These unknown commands will bypass permission checking and throttling but still process SlashCommand#onError normally. This can be set with an unknown boolean in initialization. Options will still be validated, but should not be considered while handling (since it can technically be any command with any options).

Slash-create will spam error if Sync is impossible and error is not caught properly

Slash-create 3.0, Gateway- Eris

I have bad coding skills. I say this because I have a catch-all error system that'll output the error to a Discord Channel and console. error(), before going on its way. I'm sure many bots do this for the sole reason of keeping their bot online.

Pair this with a broken script. and Slash will (supposedly) try using the broken command, over and over, and will attempt to continuously sync the broken command, until it's been rate-limited.

Discord: slash-create + discordjs buttons cause Unkonw Interaction 404

404 unknown interaction when using button interactions causing the entire run function to throw and fail.
......... response: { message: 'Unknown interaction', code: 10062 }, code: 404

It only fails once I call a function that is part of the interaction collected by the collector in the on-collect event (i.reply, and i.update).

If I call the methods on the message itself, I'm able to update the message and continue receiving interactions. This is particularly annoying when I want to tell users these aren't their buttons via ephemeral messages or when I want to update the look of a button via the interaction.update.

notice despite the try-catch around the entire contents of run this issue still halts my bot and throws a large error on the shell running it

const { SlashCommand } = require('slash-create');
const { MessageActionRow, MessageButton } = require('discord.js');

module.exports = class extends SlashCommand {
    constructor(creator) {
        super(creator, {
            name: 'bruh',
            description: 'Bruh',
            guildIDs: process.env.DISCORD_GUILD_ID ? [ process.env.DISCORD_GUILD_ID ] : undefined
        });
    }

    async run (ctx) {
        try{
            await ctx.defer();
            const row = new MessageActionRow()
                .addComponents(
                    new MessageButton()
                        .setCustomId('primary')
                        .setLabel('Primary')
                        .setStyle('PRIMARY'),
                );
            const { client } = require('..');
            const channel = await client.channels.fetch(ctx.channelID);
            const message = await channel.send({ content: 'Bruh!', components: [row] });
            
            // doesn't work either...
            // const filter = i => i.isButton() && i.user.id === ctx.user.id
            // const collector = channel.createMessageComponentCollector({ filter, time: 15000 });
            
            const collector = message.createMessageComponentCollector({ componentType: 'BUTTON', time: 15000 });
    
            collector.on('collect', async i => {
                try{
                    if (i.user.id === ctx.user.id) {
                        // message.edit(`${i.user.id} clicked on the ${i.customId} button.`) // this works
                        await i.update(`${i.user.id} clicked on the ${i.customId} button.`);
                    } else {
                        await i.reply({ content: `These buttons aren't for you!`, ephemeral: true });
                    }
                }
                catch(err){
                    console.log(err)
                }
            });
            
            collector.on('end', collected => {
                console.log(`Collected ${collected.size} interactions.`);
            }); 
            await ctx.sendFollowUp('bwo');
        } catch(err) {
            console.log(err);
        }
    }
};

My bot is actually built on top of androz music-discord-bot, which sets up the discordjs client as an export of the main/index script.

Requiring the client doesnt work as described

Passing the client instance as described in the FAQ and in #35 doesn't work; an error is returned when calling the command and a Node warning appears on the console.

Attached are screenshots of my exact setup (which, apart from using dotenv for the bot itself, is identical to the examples):
main_file
command_file
error_msg

Using node --trace-warnings bot.js as the error message specified allowed me to trace the issue to the command file itself, which was indicated by the ${client.user.id} bit I appended at the end of the command, and subsequently ran without providing the food option.

I have also attempted to add this.client = client to the command constructor as well, but the results were the same.

Another Question

So it works after using the example, but unlike other libs, when you use a command the log doesnt pops up which says something like "User used /hello" thingy, is it a discord bug or do I have to enable something?

Get a client from the command

This is a question.

I started using the library relatively recently, and I have a question. How can I get the Discord client from the command without using require? For example, output the client's websocket ping in the ping command. I looked through all the documentation, but didn't find anything related to this.

Slash Command API Changes

According to discord/discord-api-docs#2615, there will be API changes to interactions.

  • InteractionResponseType.ACKNOWLEDGE will be deprecated
  • InteractionResponseType.CHANNEL_MESSAGE will be deprecated
  • InteractionResponseType.ACKNOWLEDGE_WITH_SOURCE will be renamed to InteractionResponseType.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE (will keep both names for compatibility until major release)
  • Using ephemeral flags will now make both source and message ephemeral or public.
  • You can edit the original message from a deferred channel message. Some internal changes may be needed for this to be friendly for devs.
  • Deferred messages can be ephemeral.

These changes should also follow:

  • SlashCreatorOptions#autoAcknowledgeSource will be deprecated
  • MessageOptions#includeSource will be deprecated
  • CommandContext#acknowledge: The includeSource argument will be deprecated, in place of a ephemeral argument.
  • Add deferEphemeral prop to SlashCommandOptions, allowing command to auto-defer to ephemeral.
  • Change "auto-acknowledge" to "auto-defer"
  • Add internal props to check if slash-create auto-deferred, making ctx.send edit the original message rather than following up.
  • Changes to tests

This is separate from the PR but should be noted anyways:

  • Command choices limit is now 25

SlashCommand.onBlock/onError can return a Message object, for which there is no constructor?

Hi there. I'm writing bindings to this library, and as I work through the types, I've come across the oddity described in the title.

See:

It's clear why that type is hidden; but that leaves there being no obvious way to construct a Message type to return from an onBlock() handler? Is this intentional? How, within your API, would a user be intended to return a complex message after the onBlock-handler is triggered?

Only send components

async run(ctx) {
		await ctx.defer();
		await ctx.send('here is some buttons', {
			components: [{
				type: ComponentType.ACTION_ROW,
				components: [{
					type: ComponentType.BUTTON,
					style: ButtonStyle.PRIMARY,
					label: 'button',
					custom_id: 'example_button',
					emoji: {
						name: '๐Ÿ‘Œ',
					},
				}],
			}],
		});

		ctx.registerComponent('example_button', async (btnCtx) => {
			await btnCtx.editParent('hello');
			return ctx.unregisterComponent('example_button');
		});
	}

Is there a way to only send the button? So there is no need for the 'here is some buttons' field?

feat: Context Menu Commands

Per the new PR discord/discord-api-docs#3614:

  • "Slash Commands" are now "Application Commands"
  • App Commands have a type now, 1 being USER_INPUT or slash commands and 2 and 3 being USER and MESSAGE context menu targets respectively
  • Context menu items have two props: name and type
  • Permission changes
    • USE_SLASH_COMMANDS -> USE_APPLICATION_COMMANDS
    • MANAGE_EMOJIS -> MANAGE_EMOJIS_AND_STICKERS

WIP Documentation

Send Attachments

From this comment:

interesting; looks like its undocumented but you can upload attachments while editing webhook messages and interaction responses, not for normal messages tho

Note: PR after #30

Using native discord.js message system causes the "Thinking issue"

I am not sure where to report or seek help for this issue, but after some more testing and research, the "Bot is thinking" being stuck on unlimited loop is being caused if you use discord.js message system instead of this library's. You may ask why I use it? I use it because its easier to generate/construct an embed. Using the mentioned code below causes the issue.

Now it may not be your issue, but I am not just reporting the issue but as well seeking help to somehow go around this or something so i can stick to the same method I used for dozens of commands:

   let guild = await client.guilds.fetch(GuildID);
   let channel = await guild.channels.cache.get(ctx.channelID)
   channel.send("message")

feat: New Permissions

MANAGE_THREADS 0x0400000000 (1 << 34)
USE_PUBLIC_THREADS 0x0800000000 (1 << 35)
USE_PRIVATE_THREADS 0x1000000000 (1 << 36)
USE_EXTERNAL_STICKERS 0x2000000000 (1 << 37)

Interactions failing with 404 sometimes

I've been noticing some strange behaviour on our bot we're using with slash-create.

After initially launching the bot the commands would work fine, but if it has been running for a couple minutes all interactions would fail with the code 10062 unless I add a await ctx.defer() in front of every command.

More importantly if I use the new MessageComponents the interaction will also fail after 2-3 minutes or so after not interacting with it, even though the interaction is supposed to last up to 15 minutes.

I'm not sure if it's just a timing issue, intended or if it's actually a bug.

here is the full stack of the error that occurs (for the gserv command in this case):

(node:3523014) UnhandledPromiseRejectionWarning: DiscordRESTError [404]: Unknown interaction
Error: 
    at RequestHandler.request (/home/metaconcord/node-metaconcord/node_modules/slash-create/lib/util/requestHandler.js:62:15)
    at SlashCreatorAPI.interactionCallback (/home/metaconcord/node-metaconcord/node_modules/slash-create/lib/api.js:79:45)
    at ComponentContext._respond (/home/metaconcord/node-metaconcord/node_modules/slash-create/lib/creator.js:585:28)
    at ComponentContext.acknowledge (/home/metaconcord/node-metaconcord/node_modules/slash-create/lib/structures/interfaces/componentContext.js:35:24)
    at Timeout.<anonymous> (/home/metaconcord/node-metaconcord/node_modules/slash-create/lib/structures/interfaces/componentContext.js:24:47)
    at listOnTimeout (internal/timers.js:549:17)
    at processTimers (internal/timers.js:492:7)

The code for the bot is public and the commands are located here:
https://github.com/Metastruct/node-metaconcord/tree/master/app/services/discord/commands

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.