Git Product home page Git Product logo

u.dcvs.ru's Introduction

Bot

Bot is powerful service what provide communication between people in community.

ALL STRUCUTRES UNDERWORK! ALL SIGNATUES UNSTABLE!

usage

Easy development start: npm i and npm run dev THEN u can create new modules. (using nedb and http adapter).

TIP for debugging used Debug, please set env debug=bot:* to see details then app started <3

other commands

  • npm run dev start in development mode (with nodemon, it will reload after any changes), u can use web adapter for local work, easy start and call //localhost:3000/api?message=/ping
  • npm test run jest and eslint (please check it before commit)
  • npm start start bundle in prod mode (TODO)

abstract

executor

Atomic element, we use it to build all bot functionality. It simple function what get request and context and return new mutated request object.

request like temp container what keep all session data (UNDERWORK! Signature unstable).

  • request.input: String User input, what emit proccess in adapter
  • request.from: Array Place where message getted, first item - adapter name, other - adapter-specific
  • requst.send: ({message, to, ...} | STRING | [{message, to, ...}]) => void basic method, for sending anything from executors. from and to have equal structure, u can send simple string to direct answer (like from === to) or array with multiple answers.

context immutable structure what contain basic functions provided by modules when app start __INIT__ or per each request by adapters (then process calling) see Adapters, DB and Modules for detail information

Basic example (signature):

async (request, context) => {
    //... CHECKERS (to prevent unexpected mutation)
    if (request.something) {
        return request; // if we return request, we skip executor
    }

    // OR skip executor-set
    if (request.something && context.someMethod()) {
        return; // if we return null, we skip executor and all executor set in this module (executor set) see later
    }

    //... request MUTATIONS
    request.someData = true;

    // OR
    try {
        request.test = await someAsyncCall(); // we can write like this
    } catch (error) {
        throw(new Error());
    }

    return request;
}

// Also good point to deconstruction context
async (request, { i18n, db }) => { ... }

module (executors set)

Module is array of executors. Each executor called by declared order and transmit mutated request to next executor in array.

If executor return null we prevent call rest executors in array! Also good point use this behavior for filtering in queue.

If executor throw('error') app also skip rest executors in array and add to esponse.error error tip. U can use it after filtering by some conditions and provide information for user.

examples:

instance.use([someFilter, errorer, mutate]);

// where
function someFilter(request, context) {
    if (request.input[0] === '1') {
        return request; // we pass only then first input symbol equal '!'
    }
}

function errorer(request, context) {
    if (request.input[0] !== '2') {
        throw('SECOND SYMBOL NOT 2');
    }

    return request;
}

function mutate(request) {
    request.output = '3';

    return request;
}

Also we can create advanced cases with different filters/filter factories and subchains

instance.use([
    [someFilter, filter2, mutate1, mutate2],
    [filter, filterFactory('someType'), mutate],
    otherCall,
    errorHandler
]);

adapter

Adapter is a executor with __INIT__ that must call context.process its start execute modules chain. Any client must emit proccess call then something happens and provide context with event data. Be sure to transform any handled data to universal form.

Client also must provide callback function, that will be called after all modules will be executed!

In general cases we provide input and _handleDirect and basic adapter ready to serve! :)

client.onEvent(data => {
    instance.process({
        input: data.msg,
        _handleDirect(request) {
            client.emitTextAnswer(request.output);
        },
    });
})

Also, if adapter can provide sending messages to several places, need setup in __INIT__ sectioncontext._handlers.${adapterName} function with ({ message, to, ...}) where

  • output.message: STRING message for sending
  • `output.to: [adapterName, ...] place to send message (first, adapterName, next adapterSpecific path, like channelId, or groupId etc)

executor init

App provide only one function: process, other features provided by modules in __INIT__ section. __INIT__ is a function, what get context and must return context. Init can mutate context to add some properties and call something then it need (it call once, then app starts.

It can be usefull for: setup/init something before app start get requests, provide functions for other modules (like i18n or db connectors) or emit proccess handler (as adapters).

Basic usecase:

const executor = () {
    console.log('i called every time, then someone call process')
};

executor.__INIT__ = (context) {
    console.log('i called once, then app starts')

    return context;
}

Advanced:

const twitterExample = (request, context) {
    if (context.event !== 'tweet') {
        return;
    }

    const id = parseIdFromPost(request.input);

    if (!id) {
        return;
    }

    const post = context.getTwitterPostById(id);
    context.emitLog(post);

    return request;
};

twitterExample.__INIT__ = (context) {
    context.getTwitterPostById = twitter.getTwitterPostById;

    twtitter.on('tweet').then(data =>
        context.process(
            event: 'tweet',
            input: data.tweet.toText(),
            _handleDirect: () => {}, // no back handler for this adapter!
        )
    )

    return context;
}

user model

  • signature
  • cross-client ?
  • ...

db

Module db must provide three basics

  • getUser: (userId, userData) => PROMISE(userData) get user data by user id and default data about user
  • getModuleData: (moduleName, scope = global) => PROMISE(moduleData) get module data from user scope, or global
  • updateModuleData: (moduleName, query, scope = global) => PROMISE(void) update module data to user scope, or global scope

adater details

  • mongo
  • nedb
  • ...

modules

This modules provide funcs to context:

  • i18n: (keyword: string) => string provide function what return string by unique keyword from string lib, see more in i18n

other modules

  • quiz
  • poll
  • ...

adapters

Each adapter must provide:

  • input: string contain text view of event (like user msg text in most cases)
  • _handleDirect: (request) => void method for calling client DIRECT callback (where to equal from, like answer)
  • from: [CLIENT_ID, ...] client name (discord/telegram/etc), and coords/place where we get message (adapter specific data, what we use in _handleTo)
  • userId: string client specific id (for unuqie provide client+id)
  • userData: USER current user data

adater details

  • http
  • discord
  • ...

TODO

  • local development (easy start)
  • nedb db
  • mongojs db
  • discord adapter
  • http adapter
  • more docs and examples
  • cross-client sending messages, and multiple message sending
  • cross-client merging reglament
  • telegram adapter
  • twitch adapter
  • youtube adapter
  • clans
  • missions
  • dashboard

u.dcvs.ru's People

Contributors

dcversus avatar fenruga avatar flameflashy avatar ponyunicorn avatar trelobit avatar alexva244 avatar timsmd avatar

Watchers

James Cloos avatar  avatar  avatar  avatar

u.dcvs.ru's Issues

missions re:work

main

  • isModerator module, check for moderator: true or his username equal settings.admin
  • mission checker validate active mission (check requirements if mission undone), restore missions (iterations) and use missionCheckers for active mission, check and complete (also give exp and write to exp logs mission details)

commands

  • /missions output available mission list FOR USER with details
id | description | reward | details
---------------------------------------------
ts-dog-10 | please send any messages 10 times | 5 | daily
ts-dog-1 | please send 'test' to any chat | 200 | daily
tom-fall-2 | go to my thitch! http://u.dcvs.ru/asADg7 | 100 | once, personal
  • /missionAdd user checkerName description reward iteration requirements checkerSettings create new mission with params: (ONLY FOR MODERATORS/ADMIN!)
  • user: userId | 'all' if ''all" any user can complete, in other cases it userId to create 'personal' missions
  • checkerName: string checker function name
  • description: string mission description
  • reward: number exp count, that be payd then user complete mission
  • iteration: once | 1,2,3,4,5,6,7 days, when mission 'restore'... simple 7, like mission restore once on week every sunday, 1,2,3,4,5,6,7 - like its - daily quest <3
  • requirements: string (JSON) json in string, must be in quotes and contain specific requirements for accessing to this mission (NEED DETAILS!) i suppose it contain some JSON structure, what be like filter to whole user-scope
  • checkerSettings: string (JSON) contain checker specifiс json configuration

checkers

settings. specified then u missionAdd =)

  • emptyChecker, every time return true
  • typingChecker, check input===settings.message (if not specified = true for any message) / event === 'message'
  • linkChecker, check then user click to link

emotions

  • command module with list of emotions (like !sad -> @dcversus is sad) and send gif in list for it and some random text for emotion
  • list of emotions gifs url + texts

fix db connection issue

  • add to db.js collections: 'users', 'logs', 'global'
  • check insert case in updateModuleData

subchains

  • all chain can be array or func, if it array, we check each element use recursion

also provide

  • needAuth,
  • needUser,
  • needModerator,
  • route? (or something for filtering input, for /commands and /commands with_named_params)

experience reason

  • addExp has second required parameter "reason"
  • add reason to logs collection (time / addExp / userId / reason)
  • print last 5 user addExp reasons and output it in /status like
STATUS
--------
level: 2
experience: 1000 / 2000

Reason | exp
--------
Send message x 12 times | 12 exp
Moderator @dcversus add experience | 100 exp
Send message x 2 times | 2 exp
Training completed | 100 exp 

PS merge same messages and add "count" after reason

i18n change format

now i18n use ${some} and it confuse, because it simple replacing, dont interpolating... need use another syntax, like {{some}}

  • change syntax from ${some} to {{some}}

calc balance

now balance its user prop, need calc it every time using mission data

keep all logs

collection logs, keep any user input and store

time / event ('message') / userId / client ('discord') / text message / hasLinks (boolean) / hasAttachments (boolean)

Turn off the bounty

Bot text:

Thank you for participating in HyperLoot bounty 1.0! We will calculate the end proceeding and airdrop them out on February 15th, 2019. Stay tuned for more missions in Bounty 2.0! I will contact everyone soon!

clans module

  • /add clan (for admin) arg - name
  • /add moderator to clan (for admin or clan moderators) (giving role named as ! arg - usertag
  • /add participate for user (for moderators) (giving role named such as clan) arg - usertag
  • add hided channel with text and voice channels for participates
  • /clan-stats with count MENTION POWER (count from messages with clan-name and reactions with clan-name) and lvl of clan (calc from exp)

polls

simple way to create polls, provide two commands /poll (overloaded with three realizations) and /vote (with context understanding etc)

  • create poll (name and variants) /poll What u want? me "my money" friends
    tip1: spaces inside "" ignored
    tip2: will return unique code like id (ID03, ID02 etc) in future will generate mnemonic unique id

  • vote in pull /vote ID03 3 (poll id and variant) or short variants like: /vote 1 (poll variant) or simple 1 (only poll variant) or me (poll variant text)
    tip1: keep in poll data client/chat_id to know active (last poll) in chat. It help u implement short checking poll
    tip2: i want case like /poll "We want more missions?" + - maybe and users start typing something like + + + + + - in chat and we can understand this
    tip3: we need keep all votes user id's, user cant cancel his vote, and cant vote more then 1 times
    tip4: also be good point to try implement votes using discord reactions, its hard, but we can experiment associate some words like 'ok', 'no' etc to some emojis and for other variants type random emoji

  • get poll list with statuses /poll and get

12/02 Whats next? | 21 votes | ID01
me (50%) | yo yo (30%) | other (20%)

11/02 test! (closed) | 2 votes  | ID02
yo yo (50%) | other (50%)

10/02 Hello? | 233 votes  | ID03
+ (50%) | - (30%) | other (20%)
  • get poll status /poll ID01
12/02 Whats next? | 21 votes | ID01
me (50%) | yo yo (30%) | other (20%)
  • close poll /close ID01
    output status and prevent getting any votes

experience re:work

  • exp logs / reasons in /status command
    need keep logs with exp changes events and exp changes reason, if event called more then one time, need increment call count

  • logText emit exp increment (dont use for it additional module) ONLY passed msgs

  • add ability to reduce exp, punish for spam may be

set limits

setup mission limits for rewards and deactivate missions when limit cap

maybe show near mission (in mission list) current progress?

giveaway

very similar to polls, please start work after that

provide command /giveaway (overloaded) and uncommand option to participate

  • create giveaway /giveaway description ...keywords time keyword title
    tip1: return ID01 what we use to close or reroll
    tip2: keep context (client/chat - from) to understand place where it call

  • participate by keyword, we check any type from user and if it equal to keyword we add user to userlist. like user type +
    tip: provide as discord reaction (some emoji and counter)
    tip2: dont forget user can participate once! and cant cancel

  • list /giveaway

ID01 | GETTING SOME PRIZE
5 minutes left! and 12 users

ID002 | OTHER PRIZE
closed | 12 users | @fenruga winner
  • status /giveaway ID02
GETTING SOME PRIZE
5 minutes left! and 12 users
  • close /giveaway close ID01 close and show random winner (also calling then timer end)
  • reroll /giveaway reroll ID002 like close (maybe it can be alias) overwrite winner data

twitch integration

  • twitch bot adapter (messages & events)
  • grab any stream data where bot inited (like online/followers/subscribers count etc) to some global namespace, like
twitch: {
 [stream.id]: {
  followers_count: 11,
  online: 1,
  ...
 }
}

see https://www.npmjs.com/package/twitch-api-v5#games

also we emit call by http event named "tick" what will be upd any data

keep statistics

  • messages counter with different coefficient (like #flood x-0.1 and #it x2)
  • discord emotion reaction counter
  • coub/twitch clip links counter + view/like counter
  • images? counter
    ... TO BE CONTINUED

basic command /status

get logged text input (for all time) * some coefficient and output
user experience
user lvl

web clients

two web clients

  • WebSocket with simple ui (sending/receiving) for local testing as client: web
  • http json client (for tech proposals, like cron call etc) as client: json

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.