Skip to content
/ soop Public

An unofficial API library for the SOOP live streaming platform

License

Notifications You must be signed in to change notification settings

maro5397/soop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

122 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

soop

npm version npm downloads license language createAt

Unofficial API library for SOOP, a live streaming service.

The currently implemented features are as follows:

  • Check live stream status and detailed information
  • Log in (retrieve session/cookie)
  • Send/receive chat messages
    • Be especially careful when using chat send/receive features.
    • When sending/receiving chat, user information (fan club, subscription, fan join) may be exposed in the chat room.
    • The author is not responsible for malicious use.

Installation

Developed on Node.js v20.17.0.

npm install soop-extension

Examples

API code example

import { SoopChatEvent, SoopClient } from 'soop-extension'

(async function () {
    const streamerId = process.env.STREAMER_ID
    const client = new SoopClient();

    // Live details
    // Login (returns cookie)
    // You can directly enter SOOP ID and PASSWORD strings as shown below
    // (if pushed to VCS as-is, they may be exposed in public repositories)
    // const cookie = await client.auth.signIn("USERID", "PASSWORD");
    const cookie  = await client.auth.signIn(process.env.USERID, process.env.PASSWORD);
    console.log(cookie)

    // Live details (after login)
    const liveDetailWithCookie = await client.live.detail(streamerId, cookie);
    console.log(liveDetailWithCookie);

    // Live details
    const liveDetailWithoutCookie = await client.live.detail(streamerId);
    console.log(liveDetailWithoutCookie);

    // Channel information
    const stationInfo = await client.channel.station(streamerId);
    console.log(stationInfo)
})();

WebSocket (chat) code example

import { SoopChatEvent, SoopClient } from 'soop-extension'

(async function () {
    const streamerId = process.env.STREAMER_ID
    const client = new SoopClient();

    const soopChat = client.chat({
        streamerId: streamerId,
        login: { userId: process.env.USERID, password: process.env.PASSWORD } // required if you want to use sendChat
    })

    // Connection successful
    soopChat.on(SoopChatEvent.CONNECT, response => {
        if(response.username) {
            console.log(`[${response.receivedTime}] ${response.username} is connected to ${response.streamerId}`)
        } else {
            console.log(`[${response.receivedTime}] Connected to ${response.streamerId}`)
        }
        console.log(`[${response.receivedTime}] SYN packet: ${response.syn}`)
    })

    // Enter chat room
    soopChat.on(SoopChatEvent.ENTER_CHAT_ROOM, response => {
        console.log(`[${response.receivedTime}] Entered ${response.streamerId}'s chat room`)
        console.log(`[${response.receivedTime}] SYN/ACK packet: ${response.synAck}`)
    })

    // Chat room notice
    soopChat.on(SoopChatEvent.NOTIFICATION, response => {
        console.log('-'.repeat(50))
        console.log(`[${response.receivedTime}]`)
        console.log(response.notification.replace(/\r\n/g, '\n'))
        console.log('-'.repeat(50))
    })

    // Regular chat
    soopChat.on(SoopChatEvent.CHAT, response => {
        console.log(`[${response.receivedTime}] ${response.username}(${response.userId}): ${response.comment}`)
    })

    // Emoticon chat
    soopChat.on(SoopChatEvent.EMOTICON, response => {
        console.log(`[${response.receivedTime}] ${response.username}(${response.userId}): ${response.emoticonId}`)
    })

    // Text/voice donation chat
    soopChat.on(SoopChatEvent.TEXT_DONATION, response => {
        console.log(`\n[${response.receivedTime}] ${response.fromUsername}(${response.from}) donated ${response.amount} to ${response.to}`)
        if (Number(response.fanClubOrdinal) !== 0) {
            console.log(`[${response.receivedTime}] Welcome to fan club #${response.fanClubOrdinal}.\n`)
        } else {
            console.log(`[${response.receivedTime}] This user is already in the fan club.\n`)
        }
    })

    // Video donation chat
    soopChat.on(SoopChatEvent.VIDEO_DONATION, response => {
        console.log(`\n[${response.receivedTime}] ${response.fromUsername}(${response.from}) donated ${response.amount} to ${response.to}`)
        if (Number(response.fanClubOrdinal) !== 0) {
            console.log(`[${response.receivedTime}] Welcome to fan club #${response.fanClubOrdinal}.\n`)
        } else {
            console.log(`[${response.receivedTime}] This user is already in the fan club.\n`)
        }
    })

    // Ad balloon donation chat
    soopChat.on(SoopChatEvent.AD_BALLOON_DONATION, response => {
        console.log(`\n[${response.receivedTime}] ${response.fromUsername}(${response.from}) donated ${response.amount} to ${response.to}`)
        if (Number(response.fanClubOrdinal) !== 0) {
            console.log(`[${response.receivedTime}] Welcome to fan club #${response.fanClubOrdinal}.\n`)
        } else {
            console.log(`[${response.receivedTime}] This user is already in the fan club.\n`)
        }
    })

    // Subscription chat
    soopChat.on(SoopChatEvent.SUBSCRIBE, response => {
        console.log(`\n[${response.receivedTime}] ${response.fromUsername}(${response.from}) subscribed to ${response.to}.`)
        console.log(`[${response.receivedTime}] ${response.monthCount} months, tier ${response.tier}\n`)
    })

    // Exit info
    soopChat.on(SoopChatEvent.EXIT, response => {
        console.log(`\n[${response.receivedTime}] ${response.username}(${response.userId}) has left.\n`)
    })

    // Enter info
    soopChat.on(SoopChatEvent.VIEWER, response => {
        if(response.userId.length > 1) {
            console.log(`[${response.receivedTime}] Received ${response.userId.length} users in the chat room.`)
        } else {
            console.log(`[${response.receivedTime}] ${response.userId[0]} has entered.`)
        }
    })

    // Stream ended
    soopChat.on(SoopChatEvent.DISCONNECT, response => {
        console.log(`[${response.receivedTime}] ${response.streamerId}'s stream has ended`)
    })

    // Unidentified packet
    soopChat.on(SoopChatEvent.UNKNOWN, packet => {
        console.log(packet)
    })

    // Inspect packets in binary form
    soopChat.on(SoopChatEvent.RAW, packet => {
        console.log(packet)
    })

    // Chat sent by yourself
    soopChat.on(SoopChatEvent.CHAT, response => {
        if( response.userId.includes(process.env.USERID) ) {
            console.log(`[${response.receivedTime}] ${response.username}(${response.userId}): ${response.comment}`)
        }
    })

    // Connect to chat
    await soopChat.connect()

    // Send chat
    // If sent immediately, it waits until the chat room connection is established
    // If sending repeatedly, set a delay before sending to avoid bans or failed sends
    await soopChat.sendChat("hi");
    setInterval(async () => {
        await soopChat.sendChat("This is interesting");
    }, 5000)
})();

About

An unofficial API library for the SOOP live streaming platform

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •