Coder Social home page Coder Social logo

kritzware / twitch-bot Goto Github PK

View Code? Open in Web Editor NEW
146.0 7.0 38.0 450 KB

🤖 Easily create chat bots for Twitch.tv

Home Page: https://www.npmjs.com/package/twitch-bot

License: MIT License

JavaScript 100.00%
nodejs javascript twitch twitchbot chatbot irc kappa

twitch-bot's Introduction

twitch-bot CircleCI

Easily create chat bots for Twitch.tv

Install

Install via NPM

$ npm install twitch-bot

Example

const TwitchBot = require('twitch-bot')

const Bot = new TwitchBot({
  username: 'Kappa_Bot',
  oauth: 'oauth:dwiaj91j1KKona9j9d1420',
  channels: ['twitch']
})

Bot.on('join', channel => {
  console.log(`Joined channel: ${channel}`)
})

Bot.on('error', err => {
  console.log(err)
})

Bot.on('message', chatter => {
  if(chatter.message === '!test') {
    Bot.say('Command executed! PogChamp')
  }
})

Index

Events

connected - ()

This event is emitted when the bot has connected to the IRC server.

Usage

Bot.on('connected', () => ... )

join - ()

This event is emitted when a channel has been joined successfully.

Usage

Bot.on('join', channel => ... )

part - ()

This event is emitted when a channel has been left successfully.

Usage

Bot.on('part', channel => ... )

message - (chatter: Object)

Emitted when a PRIVSMSG event is sent over IRC. Chatter object attributes can be found on the Twitch developers site

Usage

Bot.on('message', chatter => ... )

Example Response

{ color: '#3C78FD',
  display_name: 'kritzware',
  emotes: '88:18-25',
  id: 'c5ee7248-3cea-43f5-ae44-2916d9a1325a',
  mod: true,
  room_id: 44667418,
  sent_ts: 1501541672959,
  subscriber: true,
  tmi_sent_ts: 1501541673368,
  turbo: false,
  user_id: 44667418,
  user_type: 'mod',
  badges: { broadcaster: 1, subscriber: 0 },
  channel: '#kritzware',
  message: 'This is a message PogChamp',
  username: 'Kritzware' }

timeout - (event: Object)

Emitted when a user is timed out in the chat. The ban_reason attribute is null when no reason message is used.

Chat Trigger

kritzware: "/timeout {user} {duration} {reason}"

Usage

Bot.on('timeout', event => ... )

Example Response

{ ban_duration: 10, // seconds
  ban_reason: 'Using a banned word',
  room_id: 44667418,
  target_user_id: 37798112,
  tmi_sent_ts: 1503346029068,
  type: 'timeout',
  channel: '#kritzware',
  target_username: 'blarev' }

subscription - (event: Object)

Emitted when a user subscribes to a channel and chooses to share the subscription in chat.

Usage

Bot.on('subscription', event => ... )

Example Response

{
  "badges": {
   "broadcaster": 1,
   "staff": 1,
   "turbo": 1
  },
  "channel": "#dallas",
  "color": "#008000",
  "display_name": "ronni",
  "emotes": null,
  "id": "db25007f-7a18-43eb-9379-80131e44d633",
  "login": "ronni",
  "message": "Great stream -- keep it up!", // null if no message given
  "mod": 0,
  "msg_id": "resub",
  "msg_param_months": 6,
  "msg_param_sub_plan": "Prime",
  "msg_param_sub_plan_name": "Prime",
  "room_id": 1337,
  "subscriber": 1,
  "system_msg": "ronni has subscribed for 6 months!",
  "tmi_sent_ts": 1507246572675,
  "turbo": 1,
  "user_id": 1337,
  "user_type": "staff"
}

ban - (event: Object)

Emitted when a user is permanently banned from the chat. The ban_reason attribute is null when no reason message is used.

Usage

Bot.on('ban', event => ... )

Chat Trigger

kritzware: "/ban {user} {reason}"

Example Response

{ ban_reason: 'Using a banned word',
  room_id: 44667418,
  target_user_id: 37798112,
  tmi_sent_ts: 1503346078025,
  type: 'ban',
  channel: '#kritzware',
  target_username: 'blarev' }

error - (err: Object)

Emitted when any errors occurs in the Twitch IRC channel, or when attempting to connect to a channel.

Error types

Login authentication failed

This error occurs when either your twitch username or oauth are incorrect/invalid.

Response:

{ message: 'Login authentication failed' }
Improperly formatted auth

This error occurs when your oauth password is not formatted correctly. The valid format should be "oauth:your-oauth-password-123".

Response:

{ message: 'Improperly formatted auth' }
Your message was not sent because you are sending messages too quickly

This error occurs when a message fails to send due to sending messages too quickly. You can avoid this by making the bot a moderator in the channel, if applicable/allowed.

Response:

{ message: 'Your message was not sent because you are sending messages too quickly' }

Usage

Bot.on('error', err => ... )

Example Response

{ message: 'Some error happened in the IRC channel' }

close - ()

This event is emitted when the irc connection is destroyed via the Bot.close() method.

Usage

Bot.on('close', () => {
  console.log('closed bot irc connection')
})

Methods

join(channel: String)

Attempts to join a channel. If successful, emits the 'join' event.

Example

Bot.on('join', channel => {
  console.log(`Bot joined ${channel}`)
})
Bot.join('channel2')

part(channel: String)

Attempts to part from a channel. If successful, emits the 'part' event.

Example

Bot.on('part', channel => {
  console.log(`Bot left ${channel}`)
})
Bot.part('channel2')

say(message: String, channel: []Channel, err: Callback)

Send a message in the currently connected Twitch channel. channels parameter not needed when connected to a single channel. An optional callback is provided for validating if the message was sent correctly.

Example

Bot.say('This is a message')

Bot.say('Pretend this message is over 500 characters', err => {
  sent: false,
  message: 'Exceeded PRIVMSG character limit (500)'
  ts: '2017-08-13T16:38:54.989Z'
})

// If connected to multiple channels
Bot.say('message to #channel1', 'channel1')
Bot.say('message to #channel2', 'channel2')

timeout(username: String, channel: []Channel, duration: int, reason: String)

Timeout a user from the chat. channels parameter not needed when connected to a single channel. Default duration is 600 seconds. Optional reason message.

Example

Bot.timeout('kritzware', 10)
// "kritzware was timed out for 10 seconds"

Bot.timeout('kritzware', 5, 'Using a banned word')
// "kritzware was timed out for 5 seconds, reason: 'Using a banned word'"

Bot.on('message', chatter => {
  if(chatter.message === 'xD') Bot.timeout(chatter.username, 10)
})

ban(username: String, reason: String)

Permanently ban a user from the chat. channels parameter not needed when connected to a single channel. Optional reason message.

Example

Bot.ban('kritzware')
// "kritzware is now banned from the room"

Bot.timeout('kritzware', 'Using a banned word')
// "kritzware is now banned from the room, reason: 'Using a banned word'"

Bot.on('message', chatter => {
  if(chatter.message === 'Ban me!') Bot.ban(chatter.username)
})

close()

Closes the Twitch irc connection. Bot will be removed from the Twitch channel AND the irc server.

Example

Bot.close()

Running Tests

Running the test suite requires at least two twitch accounts, one moderator account and one normal account. The channel used must be the same - This is so timeout/ban methods can be tested with the mod account. Using these two accounts, set the following environment variables:

TWITCHBOT_USERNAME=mod_username
TWITCHBOT_OAUTH=oauth:mod-oauth-token
TWITCHBOT_CHANNEL=mod_channel
TWITCHBOT_USERNAME_NON_MOD=non_mod_username
TWITCHBOT_OAUTH_NON_MOD=oauth:non-mod-oauth-token
TWITCHBOT_CHANNEL_NON_MOD=mod_channel

To run the tests (powered with Mocha), use the following command:

yarn test

twitch-bot's People

Contributors

finlaydag33k avatar hammster avatar kritzware avatar metrotyranno avatar nordox avatar pbug90 avatar skullvalanche avatar theicemancometh 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  avatar  avatar  avatar

twitch-bot's Issues

Allow joining multiple channels with one instance

I see lots of use cases that involve being able to communicate in multiple channels with one Bot Instance, for example for long-term data analysis of chats in specific channels.

I can provide a PR if you like.

missing events

Hi, I'm missing the "follow" event.

Maybe it's already added and I can't find it or it's not added.

Can you add it? (Only, if it's not added. If it's added, please tell me, how I can use it)

Dynamically adding and removing channels that a bot connects to?

Hi there, I was wondering if this module helps satisfy the use case where you want to dynamically add or remove channel(s) that the bot is connected to.

I think currently, I would have to call close() on the bot which closes every channel and then instantiate another bot with the updated list of channels

New Features

Hello twitch-bot users!

This issue is for discussion around ideas/requests for new features, feel free to leave a comment if you have any thoughts 😄

Better IRC tests/mocking

Currently several of the test cases that depend on IRC Twitch events (e.g. timeouts/bans) tend to fail, due to random timeouts or messages not being received.

Perhaps we could add mocking for IRC events rather than creating an actual instance that connects to IRC and depends on the connection stability?

Arguments in command

I was working on a twitch bot, and it would be nice if I could add arguments to the command. How would I do this?

Channel joining/parting does not work properly

Hi there,

I found a interesting issue in the latest feature:

  • I join the channel '#hammster1911' but the bot has two elements in the channels property ['#hammster1911','hammster1911\r\n']

  • When i part from the channel it removes hammster1911\r\n but hammster remains in the array
    hammster1911\r\n apperently originates from a channel join of a myself, where the second line is removed, according to this log

"#hammster1911
:hammster1911![email protected] "

  • Upon joining the channel #honestdangames bot.say() will write in the remaining '#hammster' channel since it is not parted correctly.

I'm not 100% sure if this error originates from my code, you can check it out on GitHub though Hammster/twitch-chat#1

Btw this is for a Visual Studio Code extension that is using your library ;)

lib/parser.js formatPRIVMSG: Cannot read property 'split' of undefined

C:\Users\TheBlackParrot\Documents\Share\twitch-plays-bj2\node_modules\twitch-bot\lib\parser.js:33
    parsed.username = username.split('!')[0]
                               ^

TypeError: Cannot read property 'split' of undefined
    at Object.formatPRIVMSG (C:\Users\TheBlackParrot\Documents\Share\twitch-plays-bj2\node_modules\twitch-bot\lib\parser.js:33:32)
    at TLSSocket.irc.on.data (C:\Users\TheBlackParrot\Documents\Share\twitch-plays-bj2\node_modules\twitch-bot\lib\bot.js:77:32)
    at emitOne (events.js:116:13)
    at TLSSocket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:246:13)
    at TLSSocket.Readable.push (_stream_readable.js:208:10)
    at TLSWrap.onread (net.js:607:20)

Multiple channels duplicates messages

When I connect more than one channel the on message is repeated per the number of channels.
To see what i mean https://imgur.com/a/fidvI
All I'm doing is console logging the message and i'm connected to 3 channels

 twitch.on('message', msg => {
    console.log(`${msg.channel} ${msg.username}: ${msg.message}`);
}

Bot does not work

I get the following error message, when I try to test the bot (I just started the example with my oauth key, username and channel name):

badges = badges.split(',')
^

TypeError: Cannot read property 'split' of null
at Object.formatPRIVMSG (\lib\parser.js:37:20)
at TLSSocket.irc.on.data (\lib\bot.js:64:32)
at emitOne (events.js:115:13)
at TLSSocket.emit (events.js:210:7)
at addChunk (_stream_readable.js:252:12)
at readableAddChunk (_stream_readable.js:235:13)
at TLSSocket.Readable.push (_stream_readable.js:197:10)
at TLSWrap.onread (net.js:589:20)

EPIPE errors when disconnected from internet

I assume this project's support is waning, but I wanted to reach out and see if anyone could tell me in what part of the bot.js throws an EPIPE error when internet connectivity is not found.
Anytime wifi gets disconnected or the computer goes to sleep, this library will disconnect and doesnt seem to have reconnection logic.

Anyone willing to lead me in the right direction?

My basic assumption is, if i have a channels array connected to the bot, and I get an EPIPE error, I need to manually call Bot.join on those channels again? Or perhaps reinstantiate the Bot all together?

Thanks in advance

batch events

I've noticed batch joins will cause the bot to incorrectly parse and attempt to join a nonexistent channel.

Example: Let the data be

":[email protected] JOIN #channel
:[email protected] JOIN #channel
:jtv MODE #channel +o user1"

Bot will then parse and join "#channel:[email protected] "


How are JOIN/PART events supposed to be handled? Do we only care about our own events? If so, should we also listen for username?

Bot will crash when user hosts channel

When someone hosts a channel the bot has joined, it will crash and spit out the following error

C:\Users\Tristan\Desktop\test-bot\node_modules\twitch-bot\lib\parser.js:33
    parsed.username = username.split('!')[0]
                               ^

TypeError: Cannot read property 'split' of undefined
    at Object.formatPRIVMSG (C:\Users\Tristan\Desktop\test-bot\node_modules\twitch-bot\lib\parser.js:33:32)
    at TLSSocket.irc.on.data (C:\Users\Tristan\Desktop\test-bot\node_modules\twitch-bot\lib\bot.js:76:32)
    at TLSSocket.emit (events.js:198:13)
    at addChunk (_stream_readable.js:288:12)
    at readableAddChunk (_stream_readable.js:265:13)
    at TLSSocket.Readable.push (_stream_readable.js:224:10)
    at TLSWrap.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)

Cheer event?

Any plan on implementing an event for cheers in channels? (Assuming the API supports it...)

Bot methods

More both methods, such as:

  • say(message) - say a message in chat
  • whisper(user, message) - whisper a specific user
  • ban(user, reason) - ban
  • timeout(user, duration, reason) - timeout

Join event is not handled if the username is not lowercase

If the username is not lowercase the Join event is not detected which breaks joining channels after the bot is initialized and stops the emission of join events. There should be either an error when the username is not lowercase, automatically changing the username to lowercase or just detect the username when it is lowercase.

Events not Firing

So, randomly it seems this stopped working. All logs show that it connects successfully BUT the Bot does not show up in Twitch chat's and it no longer gets any event notifications. May be due to Twitch's recent changes for Bot protection. Any insight into this?

Display currentsong from text file, how?

Hello all.

First of all, thank you for the bot. I got the bot running and the !test command is working 👍
Is it possible to display the current song playing with a command? Since i have no programming knowledge i just tried my best and came up with this:

var fs = require('fs');
var myReadStream = fs.createReadStream(__dirname + '/trackinfo.txt', 'utf8');

myReadStream.on('data', function(chunk){
	
	console.log(chunk);
});

^ No problem here, it shows the current song playing in the console.

After that i tried combine the !test command with my code but that didn't work, hehe.

var fs = require('fs');
var myReadStream = fs.createReadStream(_dirname + '/trackinfo.txt', 'utf8');

Bot.on('join', () => {

  Bot.on('message', chatter => {
    if(chatter.message === '!currentsong'){ 
	myReadStream.on('data', function(chunk){
	
	console.log(chunk);
});

It keeps popping out syntax errors... Could you point me out how to fix this and is this even possible to do? Thanks in advance

Bot doesn't join Twitch Chat

I am trying using the example code, but when I run it with my OAuth and my channel name, nothing is written to the console, and the program ends straight away...

Code

Possible Error in Example?

Hey there - loving twitch-bot as it's so easy to use, but I think I've found an issue in the example.

When I use the following code from the documentation:-

Bot.on('join', () => {

  Bot.on('message', chatter => {
    if(chatter.message === '!test') {
      Bot.say('Command executed! PogChamp')
    }
  })
})

...the listener is created every time someone joins the channel. So when four people are in the room and someone says "!test", 'Command executred! PogChamp' is posted to the room four times.

I've gotten around it by taking the listener out of the Bot.on('join') block and everything is working fine. Just not sure if the doc is unclear or if I'm reading it incorrectly is all!

random disconnet

hey there.

I have this random disconnect where the bot just leaves the channel without any errors and I have to restart the script.

any ideas to how I can test what's happening?

'Join' event is not working

I can not see the Joined channel: $ {channel} message in console. The 'message' event worked fine.
Did I miss something?

require("dotenv").config();

const TwitchBot = require("twitch-bot");

const twitchBot = new TwitchBot({
  username: "KimDexBot",
  oauth: process.env.TWITCH_TOKEN,
  channels: ["twitch"]
});

twitchBot.on("join", channel => {
  console.log(`Joined channel: ${channel}`);
});

......
{
  "name": "KimDexBot",
  "version": "0.0.0",
  "scripts": {
    "start": "node ./index.js"
  },
  "dependencies": {
    "discord.js": "^11.4.2",
    "dotenv": "^6.1.0",
    "mysql2": "^1.6.1",
    "sequelize": "^4.41.0",
    "twitch-bot": "^1.2.5"
  }
}

I used Google Translator.

Is this still potentially maintained?

Anyone able to comment as to if there's anyone maintaining, or alternatively, what other libraries or forks of this one, might be good to check out, if this one is not?

Middleware functionality

Issue for discussion about Bot middleware functionality and ideas.

Inspired by Express middleware functions.

Express implementation:

app.use(function (req, res, next) {
  console.log('Time:', Date.now())
  next()
})
Bot.use((chatter, send) => {
  // ... some sort of operation with the chatter object, or message string

  send() // Allows the message to be sent
})

In relation to this, the idea of custom Bot plugins would be cool e.g.

const TwitchBotCommands = require('twitch-bot-commands')

// The custom bot module
const commands = TwitchBotCommands("!", {
  "test": "command executed!",
  "tweet": async chatter => {
    const latestTweet = await someAsyncApiRequest(chatter.username)
    return `Latest tweet: ${latestTweet}`
  }
})

// Instantiate the module
Bot.module(commands)

More events

Events:

  • error
  • sub/resub
  • roomstate
  • bans/timeouts

Bot disconnects without error

My bot usually stops running after a few weeks. There is no error event, close event or any other kind of event really, including a message event with a chatter object.

How is it possible to recieve the ouath

I tried everything with a client token to client secret and i still dont know how to recieve the oauth.
Could you make a tutorial about that / example. Will be aprieciated thanks

Rate Limiting Feature Discussion

As pointed out in the feature suggestion issue, seamless rate limitation is important for the usability of the bot. I think it's a good idea to dedicate an issue to this feature in order to discuss an approach for implemetnation.

The rate limitation threshold depends on the Bot's user status in the channel:

  • 20 per 30 seconds, if not mod / operator
  • 100 per 30 seconds if mod / operator
  • 50 per 30 seconds for known bots
  • 7500 per 30 seconds for known bots

Source

This requires to introduce a new data structure that fulfills the following tasks:

  • keep track of messages sent in a particular channel
  • if rate limit is reached, buffer messages in a FIFO queue and send them whenever a message slot becomes available again
  • keep track of the Bot's user level
  • keep track of a reference to the say-function so it can decide on its own when to send buffered messages

A useful data structure for implementation is a circular buffer.

In the future this data structure can also be used to save channel-specific information like current users.

Issuing commands like "/clear" cause code to crash

If you issue a command in chat such as /clear, the function formatCLEARCHAT(event) will crash, when it tries to parse out the username and there isn't one.

Possible fix

if (target_username)
  parsed.target_username = target_username.replace(/\r\n/g, '')

Sample data

Event: @room-id=#######;tmi-sent-ts=1516271888978 :tmi.twitch.tv CLEARCHAT #channelname

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.