Пример #1
0
def start(bot):
    target_scope = [
        AuthScope.ANALYTICS_READ_GAMES, AuthScope.BITS_READ,
        AuthScope.CHANNEL_EDIT_COMMERCIAL, AuthScope.CHANNEL_MANAGE_BROADCAST,
        AuthScope.CHANNEL_MANAGE_POLLS, AuthScope.CHANNEL_MANAGE_PREDICTIONS,
        AuthScope.CHANNEL_MANAGE_REDEMPTIONS, AuthScope.CHANNEL_MODERATE,
        AuthScope.CHANNEL_READ_HYPE_TRAIN, AuthScope.CHANNEL_READ_POLLS,
        AuthScope.CHANNEL_READ_PREDICTIONS, AuthScope.CHANNEL_READ_REDEMPTIONS,
        AuthScope.CHANNEL_READ_SUBSCRIPTIONS, AuthScope.CHANNEL_SUBSCRIPTIONS,
        AuthScope.CHAT_EDIT, AuthScope.CHAT_READ, AuthScope.CLIPS_EDIT,
        AuthScope.MODERATION_READ, AuthScope.USER_EDIT_BROADCAST,
        AuthScope.USER_MANAGE_BLOCKED_USERS, AuthScope.USER_READ_BLOCKED_USERS,
        AuthScope.USER_READ_BROADCAST, AuthScope.USER_READ_FOLLOWS,
        AuthScope.USER_READ_SUBSCRIPTIONS
    ]

    twitch = Twitch(config['client_id'], config['client_secret'])
    twitch.authenticate_app([])
    twitch.set_user_authentication(config['twitch_token'], target_scope,
                                   config['refresh_token'])

    def callback_bits(uuid: UUID, data: dict):
        print(f"Got callback for UUID {str(uuid)}")
        print(data)
        pubsub.bits(bot, data['data'])

    def callback_subscriptions(uuid: UUID, data: dict):
        print(f"Got callback for UUID {str(uuid)}")
        print(data)
        pubsub.subscription(bot, data['data'])

    def callback_points(uuid: UUID, data: dict):
        print(f"Got callback for UUID {str(uuid)}")
        print(data)
        pubsub.points(bot, data['data'])

    user_id = twitch.get_users(logins=['will_am_i_'])['data'][0]['id']

    pubsubs = PubSub(twitch)
    pubsubs.start()

    bits_uuid = pubsubs.listen_bits(user_id, callback_bits)
    subscriptions_uuid = pubsubs.listen_channel_subscriptions(
        user_id, callback_subscriptions)
    points_uuid = pubsubs.listen_channel_points(user_id, callback_points)

    #pubsubs.stop()
Пример #2
0
def setup_platform(
    hass: HomeAssistant,
    config: ConfigType,
    add_entities: AddEntitiesCallback,
    discovery_info: DiscoveryInfoType | None = None,
) -> None:
    """Set up the Twitch platform."""
    channels = config[CONF_CHANNELS]
    client_id = config[CONF_CLIENT_ID]
    client_secret = config[CONF_CLIENT_SECRET]
    oauth_token = config.get(CONF_TOKEN)

    try:
        client = Twitch(
            app_id=client_id,
            app_secret=client_secret,
            target_app_auth_scope=OAUTH_SCOPES,
        )
        client.auto_refresh_auth = False
    except TwitchAuthorizationException:
        _LOGGER.error("Invalid client ID or client secret")
        return

    if oauth_token:
        try:
            client.set_user_authentication(token=oauth_token,
                                           scope=OAUTH_SCOPES,
                                           validate=True)
        except MissingScopeException:
            _LOGGER.error("OAuth token is missing required scope")
            return
        except InvalidTokenException:
            _LOGGER.error("OAuth token is invalid")
            return

    channels = client.get_users(logins=channels)

    add_entities(
        [TwitchSensor(channel, client) for channel in channels["data"]],
        True,
    )
Пример #3
0
class TwitchNotifier(commands.Cog):
    def __init__(self, bot):
        self.bot: 'PixlBot' = bot
        self.config = bot.config['TwitchNotifier']
        self.backend = FileBackend('db')
        self.backend.autocommit = True
        self.bot.logger.info("Twitch notifier plugin ready")
        self.uuids = []
        self.online_uuids = []
        self.sslcontext = ssl.SSLContext()
        self.sslcontext.load_cert_chain(self.config['cert_path'],
                                        self.config['key_path'])
        self._twitch_init_()

    def _twitch_init_(self):
        self.bot.logger.info("Registering with Twitch...")
        self.twitch = Twitch(self.config['id'], self.config['secret'])
        self.twitch.authenticate_app([])
        self.bot.logger.info(
            f"Registering webhook endpoint {self.config['myurl']} ...")
        self.hook = TwitchWebHook(self.config['myurl'],
                                  self.config['id'],
                                  self.config['port'],
                                  ssl_context=self.sslcontext)
        self.hook.authenticate(self.twitch)
        self.bot.logger.info("Clearing all hook subscriptions...")
        self.hook.unsubscribe_all(self.twitch)  # Clear all subs on startup
        self.hook.start()
        self._register_all()

    def _login_to_id(self, name: str) -> Optional[str]:
        """Returns the twitch ID for a given login name, or None if the name couldn't be resolved."""
        try:
            res: dict = self.twitch.get_users(logins=[name])
        except TwitchBackendException as e:
            self.bot.logger.error(f"Backend error fetching user! {e}")
            return None
        if len(res) == 0:
            return None
        else:
            return res['data'][0]['id']

    def _register_all(self):
        """Attempts to register stream_changed callbacks for all configured users."""
        self.bot.logger.info("Registering callbacks for all watched users..")
        users = self.backend.filter(TwitchWatchedUser,
                                    {'twitch_name': {
                                        "$exists": True
                                    }})
        if not users:
            self.bot.logger.info("No users to watch. No callbacks registered.")
        else:
            for u in users:
                self.bot.logger.info(f"Registering: {u['twitch_name']}")
                success, uuid = self.hook.subscribe_stream_changed(
                    u['twitch_id'], self._cb_stream_changed)
                if success and uuid:
                    self.uuids.append(uuid)
                    self.bot.logger.info(
                        f"{success}: registered subscription UUID: {uuid}")
                else:
                    self.bot.logger.error(
                        f"{success}: failed registering subscription: {uuid}")

    def _cb_stream_changed(self, uuid, data):
        """Callback for Twitch webhooks, fires on stream change event"""
        self.bot.logger.debug(f"Callback data for {uuid}: {data}")
        if data["type"] == "offline":
            if uuid in self.online_uuids:
                self.online_uuids.remove(
                    uuid
                )  # Stupid twitch sending the same damn webhook multiple times...
                return
            else:
                self.bot.logger.debug(
                    f"Ignoring duplicate offline callback for {uuid}")
                return
        elif data["type"] == "live":
            if uuid in self.online_uuids:
                self.bot.logger.debug(
                    f"Ignoring duplicate live callback for {uuid}")
                return
            else:
                self.online_uuids.append(uuid)
        else:
            self.bot.logger.error(
                f"Got a callback type we can't handle: {data['type']}")
            return

        if uuid not in self.uuids:
            self.bot.logger.error(
                f"Got a callback for a UUID we're not tracking: {uuid}, my UUIDs: {self.uuids}"
            )
            return

        try:
            item = self.backend.get(TwitchWatchedUser,
                                    {"twitch_id": data["user_id"]})
        except TwitchWatchedUser.DoesNotExist:
            self.bot.logger.error(
                f"Got a callback for a USER we're not tracking: {data['user_id']} -> {data['user_name']}"
            )
            return
        channel: discord.TextChannel = self.bot.get_channel(
            item['notify_channel'])

        width = 640
        height = 360
        url = data['thumbnail_url'].format(width=width, height=height)

        tu = self.twitch.get_users(data['user_id'])['data'][0]
        self.bot.logger.debug(tu)

        embed = discord.Embed(
            title=f"Now streaming {data['game_name']}",
            description=data['title'],
            color=discord.Color.green(),
        )
        embed.set_image(url=url)
        embed.set_thumbnail(url=tu["profile_image_url"])
        embed.set_author(name=item["twitch_name"],
                         url=f"https://twitch.tv/{data['user_name']}")
        embed.add_field(name="Watch live at",
                        value=f"https://twitch.tv/{data['user_name']}")
        self.bot.loop.create_task(
            channel.
            send(  # This isn't an async function, so enqueue it manually
                embed=embed))
        self.bot.logger.info(
            f"Successfully sent online notification for {data['user_id']}")

    @cog_ext.cog_subcommand(
        base="Twitchwatch",
        name="add_notification",
        description="Add a go live notification for Twitch",
        options=[twitch_name, notify_channel, notify_text],
        guild_ids=util.guilds)
    async def add_notification(self, ctx: SlashContext, twitch_name: str,
                               notify_channel: discord.TextChannel,
                               notify_text: str):
        twitch_id = self._login_to_id(twitch_name)
        try:
            self.backend.get(TwitchWatchedUser, {'twitch_name': twitch_name})
        except TwitchWatchedUser.DoesNotExist:
            pass
        except TwitchWatchedUser.MultipleDocumentsReturned:
            self.bot.logger.error(
                "Multiple users returned - database inconsistent???")
            return
        if not twitch_id:
            await ctx.send(embed=mkembed(
                'error',
                f"Unable to get the Twitch ID for the name {twitch_name}"))
            return
        await ctx.defer()  # This bit can take a minute.
        success, uuid = self.hook.subscribe_stream_changed(
            twitch_id, self._cb_stream_changed)
        if success and uuid:
            self.uuids.append(uuid)
            self.bot.logger.info(
                f"{success}: registered subscription UUID: {uuid}")
        else:
            self.bot.logger.error(
                f"{success}: failed registering subscription: {uuid}")
            await ctx.send("Bluh, couldn't register the webhook with twitch :("
                           )
            return
        item = TwitchWatchedUser({
            'twitch_name': twitch_name,
            'twitch_id': twitch_id,
            'discord_name': ctx.author.id,
            'notify_channel': notify_channel.id,
            'notify_text': notify_text,
            'uuid': str(uuid)
        })
        self.bot.logger.debug(f"DB object dump: {item.__dict__}")
        self.backend.save(item)
        await ctx.send(embed=mkembed("done",
                                     f"Notification added for {twitch_name}",
                                     channel=notify_channel.name))

    @cog_ext.cog_subcommand(
        base="Twitchwatch",
        name="del_notification",
        description="Remove a go live notification for Twitch",
        options=[twitch_name],
        guild_ids=util.guilds)
    async def del_notification(self, ctx: SlashContext, twitch_name: str):
        try:
            item = self.backend.get(TwitchWatchedUser,
                                    {'twitch_name': twitch_name})
        except TwitchWatchedUser.DoesNotExist:
            await ctx.send(embed=mkembed(
                "error", f"No notification exists for {twitch_name}"))
            return
        self.hook.unsubscribe(item['uuid'])
        self.bot.logger.info(f"Removing watch {item['uuid']}: {twitch_name}")
        self.backend.delete(item)
        if item['uuid'] in self.uuids:
            self.uuids.remove(item['uuid'])
        await ctx.send(
            embed=mkembed("done", f"Notification for {twitch_name} removed."))
Пример #4
0
class DiscordTwitchWebhook():
    def __init__(self, twitch_appid, twitch_secret, callback_url):
        self.discord_username = "******"
        self.twitch = Twitch(twitch_appid, twitch_secret)
        self.callback_url = callback_url
        self.hook = TwitchWebHook(callback_url, twitch_appid, 8080)
        self.authenticated = False
        self.subscriptions = []

    def authenticate(self):
        self.authenticated = False
        try:
            self.twitch.authenticate_app([])
            self.hook.authenticate(self.twitch)
        except TwitchAuthorizationException:
            print("Twitch authentication failed")
        except RuntimeError:
            print("Webhook must be https")
        else:
            self.authenticated = True
        return self.authenticated

    def subscribe_user(self, user: DiscordTwitchCallback):
        if not self.authenticated:
            raise Exception
        #TODO handle more exceptions

        user_data = self.twitch.get_users(logins=[user.username])
        user.data = user_data['data'][0]
        user.id = user.data['id']
        if user not in self.subscriptions:
            ret, user.uuid = self.hook.subscribe_stream_changed(
                user.id, self.callback_stream_changed)
            if ret:
                self.subscriptions.append(user)
            else:
                print(f"Failed to subscribe to {user.username}")

    def unsubscribe_user(self, user: DiscordTwitchCallback):
        #TODO
        return

    def start(self):
        self.hook.start()

    def stop(self):
        self.hook.unsubscribe_all(self.twitch)
        self.hook.stop()

    def callback_stream_changed(self, uuid, twdata):
        print('Callback for UUID ' + str(uuid), twdata)
        user = next((user for user in self.subscriptions if user.uuid == uuid),
                    None)
        if user == None:
            print("Callback failed")
            return
        if twdata['type'] == 'live':
            emb = self.create_embed(twdata)
            user.run_callback(emb)

    def create_embed(self, twdata):
        return Embed(title=f"{twdata['user_name']}",
                     description=f"{twdata['user_name']} is streaming {twdata['game_name']}! Get in here!",
                     color=6570404,
                     url=f"https://twitch.tv/{twdata['user_name']}") \
                    .set_image(url=twdata['thumbnail_url'].format(width="1280", height="720"))
Пример #5
0
    twitchSettings = json.load(f)

# Need to read and update channel redemptions
scopes = [
    AuthScope.CHANNEL_READ_REDEMPTIONS, AuthScope.CHANNEL_MANAGE_REDEMPTIONS
]

twitch = Twitch(twitchSettings["TwitchAppId"],
                app_secret=None,
                authenticate_app=False,
                target_app_auth_scope=scopes)
auth = UserAuthenticator(twitch, scopes, force_verify=False)

# this will open your default browser and prompt you with the twitch verification website
token, refresh_token = auth.authenticate()

# add User authentication
twitch.set_user_authentication(token, scopes, refresh_token)
user_id = twitch.get_users()


def channel_points(uuid: UUID, data: dict) -> None:
    print('got callback for UUID ' + str(uuid))
    pprint(data)


# starting up PubSub
pubsub = PubSub(twitch)
pubsub.start()
# you can either start listening before or after you started pubsub.
uuid = pubsub.listen_channel_points(user_id, channel_points)
Пример #6
0
# auth = UserAuthenticator(
#     twitch, auth_scope)
# token, refresh_token = auth.authenticate()  # this will open a webpage
# print(token, refresh_token)
# setting the user authentication so any api call will also use it
twitch.set_user_authentication(TOKEN, auth_scope, REFRESH_TOKEN)
# setting up the Webhook itself
sslContext = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS)
hook = TwitchWebHook(PUBLIC_ADDR, APP_ID, PORT, ssl_context=sslContext)
# this will use the highest authentication set, which is the user authentication.
hook.authenticate(twitch)
# some hooks don't require any authentication, which would remove the requirement to set up a https reverse proxy
# if you don't require authentication just dont call authenticate()
hook.start()

user_info = twitch.get_users()
user_id = user_info['data'][0]['id']
print(f'User ID : {user_id}')

# the hook has to run before you subscribe to any events since the twitch api will do a handshake this this webhook as soon as you subscribe
success, uuid_stream = hook.subscribe_stream_changed(str(user_id),
                                                     callback_stream_changed)
print(f'Was subscription successfull?: {success}')

# now we are fully set up and listening to our webhooks, lets wait for a user imput to stop again:
input('[+] Press enter to stop...')

# lets unsubscribe again
success = hook.unsubscribe(uuid_stream)
print(f'was unsubscription successfull?: {success}')
# since hook.unsubscribe_on_stop is true, we dont need to unsubscribe manually, so lets just stop
Пример #7
0
class TwitchState():
    """API documentation https://dev.twitch.tv/docs/api/reference#get-streams """
    def __init__(self):

        self.cfg = configs()

        self.CLIENT_ID = self.cfg.get_client_id()
        self.CLIENT_SECRET = self.cfg.get_client_secret()
        self.twitch = Twitch(self.get_client_id(), self.get_client_secret())
        self.OAUTH_TOKEN = self.twitch.get_app_token()
        self.HEADERS = {
            'Client-ID': self.get_client_id(),
            'Authorization': f'Bearer {self.get_oauth_token()}'
        }
        self.LIVE = True
        self.OFFLINE = False
        self.LIVE_CHANNEL_ID = self.cfg.get_live_channel_id()

        self.streamer_list = self.cfg.get_streamer_list()

    def streamer_factory(self, usr, discord_name, data):
        """Creates a streamer object to be stored."""

        stream_bro = self.twitch.get_users(logins=[usr])
        if len(stream_bro) > 0:
            self.cfg.setProperty("Streamers", data, discord_name)

            return stream_bro

        else:
            return False

    def get_live_channel_id(self):
        return self.LIVE_CHANNEL_ID

    def get_client_id(self):
        return self.CLIENT_ID

    def get_client_secret(self):
        return self.CLIENT_SECRET

    def get_oauth_token(self):
        return self.OAUTH_TOKEN

    def get_headers(self):
        return self.HEADERS

    def is_user_live(self, username, returnData=False):
        endpoint = 'https://api.twitch.tv/helix/streams'
        #endpoint = 'http://localhost:17563'
        my_params = {'user_login': username}

        response = requests.get(endpoint,
                                headers=self.get_headers(),
                                params=my_params)

        data = response.json()['data']
        #pprint(data)
        if len(data) == 0:
            return False

        if returnData:
            return data

        return data[0]['type'] == 'live'
Пример #8
0
import os
import ujson

from pygments import highlight, lexers, formatters
from twitchAPI.twitch import Twitch

# settings
TWITCH_CLIENT_ID = os.environ.get('TWITCH_CLIENT_ID')
TWITCH_CLIENT_SECRET = os.environ.get('TWITCH_CLIENT_SECRET')

# create instance of twitch API
twitch = Twitch(TWITCH_CLIENT_ID, TWITCH_CLIENT_SECRET)
twitch.authenticate_app([])

# get ID of user
user_info = twitch.get_users(logins=['inthevalley2020'])
formatted_json = ujson.dumps(user_info, sort_keys=True, indent=4)
colorful_json = highlight(formatted_json, lexers.JsonLexer(),
                          formatters.TerminalFormatter())
print(colorful_json)
Пример #9
0
from twitchAPI.pubsub import PubSub
from twitchAPI.twitch import Twitch
from twitchAPI.types import AuthScope
from uuid import UUID
from your_stuff import your_id, your_secret, your_oa, your_username
import rekters

# Authentication Setup and Info
twitch = Twitch(your_id, your_secret)
twitch.authenticate_app([])
twitch.set_user_authentication(your_oa, [AuthScope.CHANNEL_READ_REDEMPTIONS],
                               your_oa)
user_id = twitch.get_users(logins=[your_username])['data'][0]['id']


# Controllers
def Channel_Pt_Controller(uuid: UUID, data: dict) -> None:
    redeemer = data["data"]["redemption"]["user"]["display_name"]
    reward = data["data"]["redemption"]["reward"]["title"]
    command = data["data"]["redemption"]["user_input"]
    command = command.lower()
    print(redeemer + " Is going to rek you.")

    if reward == "Do a little dance":
        rekters.Do_Alittle_Dance(command, 5)
        print("\n press ENTER to close")
    elif reward == "Shoot'em Up":
        rekters.Mouse_Hold(command, 5)
        print("\n  press ENTER to close")
    else:
        print("That reward doesn't exist")
Пример #10
0
class TwitchClip(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.client_id = os.getenv('TWITCH_CLIENT_ID')
        self.client_secret = os.getenv('TWITCH_SECRET')
        self.twitch = Twitch(self.client_id, self.client_secret)

        self.conn = psycopg2.connect(user=os.getenv("PGUSER"),
                                     password=os.getenv("PGPASSWORD"),
                                     host=os.getenv("PGHOST"),
                                     port=os.getenv("PGPORT"),
                                     database=os.getenv("PGDATABASE"))

        self.curs = self.conn.cursor()
        self.fetch_tokens()

        self.scope = [AuthScope.CLIPS_EDIT]

        self.update_twitch_tokens()

        self.twitch.set_user_authentication(self.access_token, self.scope,
                                            self.refresh_token)

    @commands.command(aliases=['c'])
    async def clip(self, ctx, streamer):
        """Get a Twitch Clip"""

        self.update_twitch_tokens()

        # Get the streamer's ID
        streamer_info = self.streamer_check(streamer)

        if len(streamer_info) == 0:
            embed = discord.Embed(title="Streamer not found",
                                  color=discord.Colour.from_rgb(255, 0, 0))
            await ctx.send(embed=embed)
            return

        streamer_id = streamer_info[0]['id']
        create_clip = self.twitch.create_clip(broadcaster_id=streamer_id)

        if 'error' in create_clip:
            embed = discord.Embed(title=f"{create_clip['message']}",
                                  color=discord.Colour.from_rgb(255, 0, 0))
            await ctx.send(embed=embed)
            return
        elif len(create_clip['data']) == 0:
            embed = discord.Embed(title="Streamer not found",
                                  color=discord.Colour.from_rgb(255, 0, 0))
            await ctx.send(embed=embed)
            return

        clip_url = f"https://clips.twitch.tv/{create_clip['data'][0]['id']}"

        await ctx.send(clip_url)

    def update_twitch_tokens(self):
        self.fetch_tokens()

        # refresh twitch
        new_tokens = refresh_access_token(self.refresh_token, self.client_id,
                                          self.client_secret)
        self.access_token = new_tokens[0]
        self.refresh_token = new_tokens[1]

        # Update the access token
        update_access_query = f"UPDATE twitchclips SET token = '{new_tokens[0]}' WHERE id = 2"
        update_refresh_query = f"UPDATE twitchclips SET token = '{new_tokens[1]}' WHERE id = 3"

        self.curs.execute(update_access_query)
        self.curs.execute(update_refresh_query)

    def fetch_tokens(self):
        self.curs.execute("SELECT * FROM twitchclips")
        rows = self.curs.fetchall()

        for row in rows:
            if row[0] == 2:
                self.access_token = row[2]

            if row[0] == 3:
                self.refresh_token = row[2]

    def streamer_check(self, streamer):
        if streamer == "tt" or streamer == "t1" or streamer == "t":
            streamer = "loltyler1"
        elif streamer == "x" or streamer == "cow":
            streamer = "xqcow"
        elif streamer == "dlift" or streamer == "lift":
            streamer = "doublelift"

        return self.twitch.get_users(logins=[streamer])['data']
Пример #11
0
class Streamer:

    global TWITCH_APP_ID
    global TWITCH_SECRET
    global StreamerName
    global StreamerID
    isID = False

    def __init__(self, TWITCH_APP_ID, TWITCH_SECRET, User, isID = False):

        self.reader = codecs.getreader('utf-8')
        self.TWITCH_APP_ID = TWITCH_APP_ID
        self.TWITCH_SECRET = TWITCH_SECRET
        self.twitch = Twitch(self.TWITCH_APP_ID, self.TWITCH_SECRET)

        self.StreamerName = User
        self.isID = isID
        self.LOCK = False

        if not self.isID:
            self.StreamerID = self.getUserID()




    def getUserID(self):

        if self.isID: return self.StreamerName

        self.twitch.authenticate_app([])
        data = self.twitch.get_users(logins=[self.StreamerName])
        return data['data'][0]['id']


    def isStreaming(self):

        data = self.twitch.get_streams(user_id=self.StreamerID)
        if len(data['data']) != 0:
            if data['data'][0]['type'] == 'live':
                return True
        return False

    def getStreamLink(self): return 'https://www.twitch.tv/' + str(self.StreamerName.lower())

    def lock(self): self.LOCK = True

    def unlock(self): self.LOCK = False

    def lockStatus(self): return self.LOCK

    def getGame(self):

        if self.isStreaming():
            data = self.twitch.get_streams(user_id=self.StreamerID)
            game = data['data'][0]['game_name']
            return game
        return False

    def getViewers(self):

        if self.isStreaming():
            data = self.twitch.get_streams(user_id=self.StreamerID)
            viewers = data['data'][0]['viewer_count']
            return viewers
        return False

    def getTitle(self):

        if self.isStreaming():
            data = self.twitch.get_streams(user_id=self.StreamerID)
            title = data['data'][0]['title']
            return  title
        return False

    def getThumbnail(self):

        if self.isStreaming():
            data = self.twitch.get_streams(user_id=self.StreamerID)
            thumbnail = data['data'][0]['thumbnail_url']
            thumbnail = thumbnail.format(width='1920', height='1080')
            return thumbnail
        return False

    def getProfilePicture(self):

        data = self.twitch.get_users(logins=self.StreamerName)
        picture = data['data'][0]['profile_image_url']
        return picture

    def getStreamerName(self):
        return self.StreamerName
Пример #12
0
class TwitchAPIHandler:
    """
    A wrapper to interact with the twitch API
    """
    def __init__(self, client_id: str, client_secret: str):
        self.twitch = Twitch(client_id, client_secret)

    def get_streams_data(self, usernames):
        """
        Gets all stream information from a list of given usernames
        :param usernames: The list of usernames
        :return: The JSON data of the request
        """
        result = []
        batches = split_to_100s(usernames)
        for batch in batches:
            batch_result = []
            try:
                batch_result.extend(
                    self.twitch.get_streams(user_login=batch).get("data"))
            except TwitchAPIException:
                logger.error(
                    f"Streams data not received for batch, invalid request")
                for user in batch:
                    try:
                        batch_result.extend(
                            self.twitch.get_streams(
                                user_login=user).get("data"))
                    except TwitchAPIException:
                        logger.error(
                            "User data cannot be found, invalid request")

            result.extend(batch_result)

        return result

    def get_user_data(self, usernames=None, ids=None):
        """
        Gets the user information of a given user

        :param usernames: The display twitch usernames of the users
        :param ids: The unique twitch ids of the users
        :return: The JSON information of the user's data
        """
        result = []

        if usernames:
            user_list = split_to_100s(usernames)
            for u_batch in user_list:
                result += self.twitch.get_users(logins=u_batch).get("data")

        if ids:
            id_list = split_to_100s(ids)
            for id_batch in id_list:
                result += self.twitch.get_users(logins=id_batch).get("data")

        return result

    def get_game_data(self, game_id):
        """
        Gets the game information of a given game
        :param game_id: The twitch game ID of a game
        :return: The JSON information of the game's data
        """
        if game_id != "":
            game_data = self.twitch.get_games(game_ids=game_id)
            return game_data.get("data")[0]
        else:
            return None

    def get_team_users(self, team_id):
        """
        Gets the users data about a given team
        :param team_id: The team name of the twitch team
        :return: the JSON information of the users
        """
        return (self.get_team_data(team_id)).get("users")

    def get_team_data(self, team_id):
        """
        Gets the users data about a given team
        :param team_id: The team name of the twitch team
        :return: the JSON information of the users
        """
        a = self.twitch.get_teams(name=team_id)
        return a.get("data")[0]
Пример #13
0
auth = UserAuthenticator(twitch, target_scope, force_verify=False)
# this will open your default browser and prompt you with the twitch verification website
token, refresh_token = auth.authenticate()

print(token, refresh_token)

# add User authentication

twitch.set_user_authentication(token, target_scope, refresh_token)

# starting up PubSub
pubsub = PubSub(twitch)
pubsub.start()

user_id = twitch.get_users(logins=[TWITCH_CHANNEL_NAME])['data'][0]['id']
pprint(twitch.get_users(logins=[TWITCH_CHANNEL_NAME]))
# you can either start listening before or after you started pubsub.

# uuid1 = pubsub.listen_whispers(user_id, callback_function)
uuid2 = pubsub.listen_channel_points(user_id, callback_function)
uuid3 = pubsub.listen_channel_subscriptions(user_id, callback_function)
uuid4 = pubsub.listen_bits(user_id, callback_function)

# print(uuid2)
input('press ENTER to close...')

# you do not need to unlisten to topics before stopping but you can listen and unlisten at any moment you want

# pubsub.unlisten(uuid1)
pubsub.unlisten(uuid2)
Пример #14
0
class Twitch(commands.Cog):
    """Get live updates for your favourite twitch streamers
    """
    def __init__(self, disclient, twitch_id, twitch_sec):
        self.disclient = disclient
        self.disclient.loop.create_task(self.get_online_streams())
        self.twitch = Twitchy(
            twitch_id,
            twitch_sec,
        )
        self.twitch.authenticate_app([])
        self.time_format = '%Y-%m-%d %H:%M:%S'

    async def get_online_streams(self):
        await self.disclient.wait_until_ready()
        print('Looking for live Twitch streams!')
        while not self.disclient.is_closed():
            try:
                # print("checking twitch")
                check = get_all_twitch_channels_to_check(3)
                if not check:
                    await asyncio.sleep(60)
                    continue
                if len(check) > 100:
                    # need to split list into lengths of 100 in future
                    # get_streams only takes 100 inputs at a time
                    check = check[:99]
                ids = [str(x) for x in check.keys()]
                b = self.twitch.get_streams(user_id=ids)
                for stream in b["data"]:
                    c = self.twitch.get_users(user_ids=stream["user_id"])
                    linkend = c['data'][0]['login']
                    link = f"https://www.twitch.tv/{linkend}"
                    username = stream['user_name']
                    desc = stream['title']
                    msg = f"`{username}` is live! {link}"
                    image_url = f"""{stream['thumbnail_url'].format(
                                     width=852, height=480)}?{str(datetime.datetime.now().timestamp())}"""
                    embed = discord.Embed(title=msg,
                                          description=desc,
                                          color=discord.Color.purple())
                    embed.set_image(url=image_url)
                    embed.add_field(name='Playing', value=stream['game_name'])
                    check_time = datetime.datetime.strptime(
                        stream['started_at'], '%Y-%m-%dT%H:%M:%SZ')
                    check_time.strftime(self.time_format)
                    if check[int(stream['user_id'])] != check_time:
                        update_twitch_last_live(stream['user_id'], check_time)
                    else:
                        continue
                    channels = get_channels_following_twitch_stream(
                        stream['user_id'])
                    if not channels:
                        await asyncio.sleep(60)
                        continue
                    for chan in channels:
                        channel = self.disclient.get_channel(int(chan))
                        # set ping roles up in the future
                        # gid = channel.guild.id
                        # rol = self.disclient.get_guild(gid).roles
                        # tr = discord.utils.get(rol, name="twitch")
                        await channel.send(
                            embed=embed
                        )  # content=tr.mention, for when roles are assigned
            except Exception as e:
                print(e)
            # delay 60 seconds before checking again
            await asyncio.sleep(60)

    @commands.command(
        aliases=['followstream', 'follow_stream', 'followtwitch'])
    @commands.guild_only()
    @commands.has_permissions(administrator=True)
    async def follow_twitch(self, ctx, stream):
        """Follows a twitch stream in this channel! Live updates will be posted here.
        .follow_twitch <username or link>"""
        channel = ctx.channel.id
        if "twitch.tv" in stream:
            stream = stream.split("/")[-1].lower()
        else:
            stream = stream.lower()
        user = self.twitch.get_users(logins=stream)
        print(user)
        if not user:
            await ctx.send(
                embed=error_embed(f"Failed to find Twitch user {stream}!"))
            return
        for d in user["data"]:
            ayed = str(d["id"])
            add_channel(channel)
            add_twitch_channel_to_db(ayed)
            followed = follow_twitch_channel_db(channel, ayed)
            if followed:
                display_name = d['display_name']
                profile_image = d['profile_image_url']
                link = f"https://www.twitch.tv/{d['login']}"
                msg = f'This channel will now receive updates on when {display_name} goes live at {link}'
                embed = discord.Embed(
                    title=f'Successfully Followed {display_name}!',
                    description=msg,
                    color=discord.Color.purple())
                embed.set_thumbnail(url=profile_image)
                await ctx.send(embed=embed)
            else:
                await ctx.send(embed=error_embed(
                    f"Failed to follow {stream} in this channel!"))

    @commands.command(
        aliases=['unfollowstream', 'unfollow_stream', 'unfollowtwitch'])
    @commands.guild_only()
    @commands.has_permissions(administrator=True)
    async def unfollow_twitch(self, ctx, stream):
        """Unfollows a twitch stream followed in this channel.
        .unfollow_twitch <username or link>"""
        channel = ctx.channel.id
        if "twitch.tv" in stream:
            stream = stream.split("/")[-1].lower()
        else:
            stream = stream.lower()
        user = self.twitch.get_users(logins=stream)
        if not user:
            await ctx.send(
                embed=error_embed(f"Failed to find Twitch user {stream}!"))
            return
        for d in user["data"]:
            ayed = str(d["id"])
            unfollowed = unfollow_twitch_channel_db(channel, ayed)
            if unfollowed:
                await ctx.send(embed=success_embed(
                    f"Unfollowed {stream} in this channel!"))
            else:
                await ctx.send(embed=error_embed(
                    f"Failed to unfollow {stream} in this channel!"))

    @commands.command(name='twitch', aliases=['twitchs', 'twitches'])
    @commands.guild_only()
    async def twitches(self, ctx):
        """Returns a list of all twitch users followed in this server!"""
        guild = ctx.guild
        chans = get_all_twitch_followed_in_guild()
        chan_dict = {}
        for pair in chans:
            if pair[0] not in chan_dict:
                chan_dict.update({pair[0]: [pair[-1]]})
            else:
                chan_dict[pair[0]].append(pair[-1])
        msg = ''
        for channel in guild.channels:
            if channel.id in chan_dict:
                for twitch in chan_dict[channel.id]:
                    twitch_str = str(twitch)
                    twitch = self.twitch.get_users(user_ids=[twitch_str])
                    twitch = twitch['data'][0]['login']
                    spacing = 39 - len(channel.name + twitch)
                    chan_str = f"`#{channel.name}{' ' * spacing}{twitch}`\n"
                    msg = msg + chan_str
        if msg == '':
            await ctx.send(
                embed=error_embed('No Twitch streams followed in this server!')
            )
        else:
            add_to_start = f"`Channel Name{' ' * 17}Twitch User`\n"
            msg = add_to_start + msg
            embed = discord.Embed(
                title=f'Twitch Streams Followed in {guild.name}!',
                description=msg,
                color=discord.Color.purple())
            await ctx.send(embed=embed)
Пример #15
0
        )
    else:
        HUE_KEY = resp["success"]["username"]

print(
    f"Your key is: {HUE_KEY}\nEdit the script and add this key to `HUE_KEY` to skip this step in the future."
)

# setting up Authentication and getting your user id
twitch.authenticate_app([])

target_scope = [AuthScope.CHANNEL_READ_REDEMPTIONS]
auth = UserAuthenticator(twitch, target_scope, force_verify=False)

# this will open your default browser and prompt you with the twitch verification website
token, refresh_token = auth.authenticate()
twitch.set_user_authentication(token, target_scope, refresh_token)

user_id = twitch.get_users(logins=[USERNAME])['data'][0]['id']

# starting up PubSub
pubsub = PubSub(twitch)
pubsub.start()
# you can either start listening before or after you started pubsub.
uuid = pubsub.listen_whispers(user_id, callback)
# uuid = pubsub.listen_channel_points(user_id, callback)
input('press ENTER to close...\n')
# you do not need to unlisten to topics before stopping but you can listen and unlisten at any moment you want
pubsub.unlisten(uuid)

pubsub.stop()
Пример #16
0

if __name__ == '__main__':
    
    print('~starting script~')

    # Create an instance of the REST client.
    aio = Client(private_const.ADAFRUIT_IO_USERNAME, private_const.ADAFRUIT_IO_KEY)
    feed = Feed(name="ledfeed")

    # create instance of twitch API
    twitch = Twitch(private_const.app_id, private_const.app_secret)
    twitch.authenticate_app([])

    # get ID of user
    user_info = twitch.get_users(logins=[private_const.username])
    user_id = user_info['data'][0]['id']

    # set up channel point redemption pubsub
    target_scope = [AuthScope.CHANNEL_READ_REDEMPTIONS]
    auth = UserAuthenticator(twitch, target_scope, force_verify=False)
    token, refresh_token = auth.authenticate()
    twitch.set_user_authentication(token, target_scope, refresh_token)

    pubsub = PubSub(twitch)
    pubsub.start()
    # you can either start listening before or after you started pubsub.

    print('~connected to twitch~')

    # listen to channel points. enter callback function when redemption occurs 
Пример #17
0
for user_id_line in user_id_lines:
    user_id = user_id_line.strip()
    user_id_set.add(user_id)
user_id_list = list(sorted(user_id_set))

chunked_namelists = [*chunks(name_list, 100)]
chunked_user_id_lists = [*chunks(user_id_list, 100)]

with open("namelist_cleaned.txt",
          "w") as name_file, open("user_id_list_cleaned.txt", "w") as id_file:
    progressbar = tqdm.tqdm(chunked_namelists,
                            file=sys.stdout,
                            ascii=True,
                            desc="User names")
    for chunk in progressbar:
        user_infos = twitch.get_users(logins=chunk).get("data")
        for user_info in user_infos:
            name_file.write(f"{user_info.get('login')}\n")
            id_file.write(f"{user_info.get('id')}\n")
            name_file.flush()
            id_file.flush()

    progressbar = tqdm.tqdm(chunked_user_id_lists,
                            file=sys.stdout,
                            ascii=True,
                            desc="User id's")
    for chunk in progressbar:
        user_infos = twitch.get_users(user_ids=chunk).get("data")
        for user_info in user_infos:
            name_file.write(f"{user_info.get('login')}\n")
            id_file.write(f"{user_info.get('id')}\n")
Пример #18
0
else:
    try:
        TOKEN, REFRESH_TOKEN = refresh_access_token(
            REFRESH_TOKEN, CLIENT_ID, CLIENT_SECRET
        )
    except InvalidRefreshTokenException:
        TOKEN, REFRESH_TOKEN = auth.authenticate()


twitch_secrets["TOKEN"] = TOKEN
twitch_secrets["REFRESH_TOKEN"] = REFRESH_TOKEN
update_twitch_secrets(twitch_secrets)

twitch.set_user_authentication(TOKEN, target_scope, REFRESH_TOKEN)

user_id = twitch.get_users(logins=[USERNAME])["data"][0]["id"]

# starting up PubSub
pubsub = PubSub(twitch)
pubsub.start()
# you can either start listening before or after you started pubsub.
if WHISPER_MODE:
    uuid = pubsub.listen_whispers(user_id, callback)
else:
    uuid = pubsub.listen_channel_points(user_id, callback)

input("Now listening for events.\nPress ENTER at any time to stop.\n")
# you do not need to unlisten to topics before stopping but you can listen and unlisten at any moment you want
pubsub.unlisten(uuid)

pubsub.stop()