Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.2.0 #13

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## v1.2.0

### New

- New action `AddOutgoingRaidBannerAction` and `AddIncomingRaidBannerAction`
- Removed `AddRedirectBannerAction`
- New action `RemoveChatItemAction`
- New action `AddProductBannerAction`

## v1.1.0

### New
Expand Down
60 changes: 44 additions & 16 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,83 @@
# Contribution Guide

- Use Masterchat with `DEBUG=masterchat` and [report](https://github.com/holodata/masterchat/issues/new) logs that are prefixed with `[action required]`
- Squash [TODOs](https://github.com/holodata/masterchat/search?l=TypeScript&q=TODO)

[Join our Discord](https://holodata.org/discord) to participate in discussions.

## Build

```bash
git clone https://github.com/holodata/masterchat
cd masterchat
git switch dev
yarn install
yarn build
npm install
npm run build
```

## Development Flow

In `masterchat` dir:

```bash
yarn dev
npm run build
npm link # link local masterchat package
npm run dev # watch and transpile files
```

Clone and build [Masterchat CLI](https://github.com/holodata/masterchat-cli):

```bash
yarn build
yarn link
git clone https://github.com/holodata/masterchat-cli ../masterchat-cli
cd masterchat-cli
npm install
npm run build
npm link # make local `masterchat` and `mc` command available on the shell
```

cd ..
In `masterchat-cli` dir, link local `masterchat` module and rebuild the cli:

git clone https://github.com/holodata/masterchat-cli
cd masterchat-cli
yarn install
yarn build
yarn link
yarn link masterchat
```bash
npm link masterchat # now `masterchat-cli` uses local `masterchat` module
npm run build
DEBUG=masterchat mc live <videoId>
DEBUG=masterchat mc events
```

## Testing

### Setup

Export necessary env vars:

```bash
export MC_TEST_VIDEO_ID=<video ID of the unlisted live stream from the `MC_TEST_CHANNEL_ID` channel>
export MC_TEST_CHANNEL_ID=<primary test channel id>
export MC_TEST_CHANNEL_ID_2=<secondary test channel id>
export MC_TEST_CREDENTIAL=<base64-encoded credentials of primary test channel id>
export MC_TEST_CREDENTIAL_2=<base64-encoded credentials of secondary test channel id>
```

Use [https://github.com/holodata/masterchat/tree/master/extra/credential-fetcher](credential-fetcher) to obtain base64-encoded credentials.

### Record API response while testing

Test while recording response (run only once):

```bash
NOCK_BACK_MODE=record jest
NOCK_BACK_MODE=record vitest --run
```

Test using recorded response:
### Run tests using recorded response

```bash
jest
vitest
```

Disable fixtures completely:

```bash
NOCK_BACK_MODE=wild jest
NOCK_BACK_MODE=wild vitest
```

## Release Flow (Maintainers only)
Expand Down
39 changes: 20 additions & 19 deletions MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ await mc
.iter()
.filter((action) => action.type === "addChatItemAction") // only chat events
.map((chat) => JSON.stringify(chat) + "\n") // convert to JSONL
.forEach((jsonl) => appendFile("./chats.jsonl", jsonl)) // append to the file
.forEach((jsonl) => appendFile("./chats.jsonl", jsonl)); // append to the file
```

### Chat moderation bot
Expand All @@ -122,7 +122,7 @@ await mc
import { Masterchat, stringify } from "masterchat";
import { isSpam } from "spamreaper";

// `credentials` is an object containing YouTube session cookie or a base64-encoded JSON string of them
// `credentials` is an object containing YouTube session cookie, or a base64-encoded JSON string of the object
const credentials = {
SAPISID: "<value>",
APISID: "<value>",
Expand All @@ -133,19 +133,19 @@ const credentials = {

const mc = await Masterchat.init("<videoId>", { credentials });

const iter = mc.iter().filter((action) => action.type === "addChatItemAction");
const chats = mc.iter().filter((action) => action.type === "addChatItemAction");

for await (const chat of iter) {
for await (const chat of chats) {
const message = stringify(chat.message, {
// omit emojis
emojiHandler: (emoji) => "",
});

// delete chat
// if flagged as spam by Spamreaper
// or contains "UGLY"
if (isSpam(message) || /UGLY/.test(message)) {
// delete chat
// if flagged as spam by Spamreaper
// or contains "UGLY"
await mc.remove(action.id);
await mc.remove(chat.id);
}
}
```
Expand All @@ -155,7 +155,7 @@ for await (const chat of iter) {
```js
import { Masterchat } from "masterchat";

const mc = new Masterchat("<videoId>", "");
const mc = await Masterchat.init("<videoId>");

// Iterate over all comments
let res = await mc.getComments({ top: true });
Expand All @@ -176,7 +176,7 @@ console.log(comment);
```js
import { Masterchat, stringify } from "masterchat";

const mc = new Masterchat("<videoId>", "");
const mc = await Masterchat.init("<videoId>");

const transcript = await mc.getTranscript();

Expand All @@ -189,19 +189,14 @@ for (const item of transcript) {

### Faster instantiation

To skip loading watch page, use `new Masterchat(videoId: string, channelId: string, { mode?: "live" | "replay" })`:
For faster instantiation, you can totally skip fetching metadata (channelId, title, isLive) phase which happens behind `Masterchat.init()`. To do this, use `new Masterchat(videoId: string, channelId: string, { mode?: "live" | "replay" })`:

```js
// const live = Masterchat.init(videoId);
const live = new Masterchat(videoId, channelId, { mode: "live" });
```

instead of:

```js
const live = await Masterchat.init(videoId);
```

The former won't fetch metadata. If you need metadata, call:
Since with this way Masterchat won't fetch metadata, should you need metadata later on, manually call `populateMetadata`:

```js
await live.populateMetadata(); // will scrape metadata from watch page
Expand All @@ -210,6 +205,9 @@ console.log(live.title);
console.log(live.channelName);
```

> **Note**
> Fetching watch page is rate limited

### Fetch credentials

```bash
Expand Down Expand Up @@ -279,7 +277,10 @@ const mc = await Masterchat.init("<videoId>", { axiosInstance });
| [membershipGiftPurchaseAction](https://holodata.github.io/masterchat/interfaces/MembershipGiftPurchaseAction.html) | Membership gift purchase notification |
| [membershipGiftRedemptionAction](https://holodata.github.io/masterchat/interfaces/MembershipGiftRedemptionAction.html) | Membership gift redemption notification |
| [moderationMessageAction](https://holodata.github.io/masterchat/interfaces/ModerationMessageAction.html) | Moderation message |
| [addRedirectBannerAction](https://holodata.github.io/masterchat/interfaces/AddRedirectBannerAction.html) | Redirect banner notification (raid event) |
| [addIncomingRaidBannerAction](https://holodata.github.io/masterchat/interfaces/AddIncomingRaidBannerAction.html) | Incoming raid notification |
| [addOutgoingRaidBannerAction](https://holodata.github.io/masterchat/interfaces/AddOutgoingRaidBannerAction.html) | Outgoing raid notification |
| [addProductBannerAction](https://holodata.github.io/masterchat/interfaces/AddProductBannerAction.html) | Product promotion banner notification |
| [removeChatItemAction](https://holodata.github.io/masterchat/interfaces/RemoveChatItemAction.html) | Remove chat item action |

### Stream type

Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@

Masterchat is the most powerful library for YouTube Live Chat, supporting parsing 20+ actions, video comments and transcripts, as well as sending messages and moderating chats.

- 🎓 [Getting Started](https://github.com/holodata/masterchat/tree/master/MANUAL.md)
- 📖 [References](https://holodata.github.io/masterchat/)
- 🪁 [Examples](https://github.com/holodata/masterchat/tree/master/examples)
- 🙋‍♀️ [Ask Questions](https://github.com/holodata/masterchat/discussions)
- 🐞 [Report a Bug](https://github.com/holodata/masterchat/issues)
- 🦄 [Join Community](https://holodata.org/discord)

## Install

```
Expand Down
6 changes: 3 additions & 3 deletions docs/assets/highlight.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
--dark-hl-6: #DCDCAA;
--light-hl-7: #000000FF;
--dark-hl-7: #D4D4D4;
--light-code-background: #F5F5F5;
--light-code-background: #FFFFFF;
--dark-code-background: #1E1E1E;
}

Expand Down Expand Up @@ -43,7 +43,7 @@
--code-background: var(--dark-code-background);
} }

body.light {
:root[data-theme='light'] {
--hl-0: var(--light-hl-0);
--hl-1: var(--light-hl-1);
--hl-2: var(--light-hl-2);
Expand All @@ -55,7 +55,7 @@ body.light {
--code-background: var(--light-code-background);
}

body.dark {
:root[data-theme='dark'] {
--hl-0: var(--dark-hl-0);
--hl-1: var(--dark-hl-1);
--hl-2: var(--dark-hl-2);
Expand Down
Loading