ForrestKnight / yt-dislikes

Add the dislike count back to my YouTube videos via a comment containing that information.
https://youtu.be/1uAH93tzfQY
MIT License
155 stars 13 forks source link

Pin new or updated comments #1

Open ForrestKnight opened 2 years ago

ForrestKnight commented 2 years ago

I'd like to pin the automated comments, so it's visible at the top of the comment section and not drowned out by the other comments. However, I did not see a way to do this in the docs.

fitzypop commented 2 years ago

After using chrome devtools todo some investigating, I think the website is using 2 separate api calls, in a challenge-response auth flow, to setup a pinned comment:

Here's step 1's info from the network tab:

URI: https://www.youtube.com/youtubei/v1/att/log?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8 Payload:

{
    "challenge": "a=5&a2=5&b=YO2xHGvbhrEili8c6xOJLbMiGVQ&c=1637004629&d=1&e=M2zfWGmSeCo&e3=UCeNu_8o_FFaqEH9QGBR2AgQ&e4=UgyP98VE891tIT_NEGN4AaABAg&c1a=1&hh=7UIyYmxnQi83cNXHRLDGYJCB_Lh48HyZnNBX2xMeIyA",
    "webResponse": "$z1A5UB1RAAaK4O5OiuDeXmoLdgZAIEenACkAIwj8Rt3atiKnwYkpxUbL_Zrs7pNO_MZX0PQqDSAW_l2TyAmTU1XabZ4AAABRzgAAAAj0AQeWAHP1h4KomZFZf2Dmrl_AgCGwr4lk9ej5-ePJZHuZPhprIOYkyNCu3pQCJRO6Sk-klPukdLD5qutqdx4IjT1ueCLmGlp1iP0jwUtBL1MN4x2vPdCL8Q6i2C-pQ5hwsupDW3QsfZnnomNGWvJhgAPYKzhsSuPUBQKoBnmHxftcjHaGrcJi7t1jG4rPgPZIcvnrg2Gmp4CbmRlDcxfEMwf-Y05M1nlGk6QMh9gKhi_4V0Oe7H7xScSrARPpXpeBC5Gz13tD2CBeevANPXGMuAGGtZhMISGmiIyh72h2fkjkKvbTqK-Z-pcJJOwb3kvxCv32xigx1Bm9k3fz2bzNclm99ZxySRpKfXHJ8pMgJFozWLuGMH-IEI4nke1fME0gu9xmgxMNzPIIf79FqYLmGZ-H802YpfjvQd3PfUgESJYk-YBU1jzu-UXjBvtKV_CyywmAApZ1WqhifdnLmrh97UNVegtn1GHfwZGa9iBPYHqDfAhxlMwiCY6pBv_AH_xteKRS6-GH3bXVshThrRYGT1JmLYh4RFgb9u08lx6ifc0wkCOlbArlrvLTLkt6H6kvshf9v8xTBwd9SXilx0RSpUmWYyeRRKazGGZoQwHn3DTb_gmFS_T9uMiUI6s-D966s58DkeSpmSqeIyX9T8CcUNTBVwcQ1lVX5BOqplxu27tIPGh_c_zxTdChrUZTQvhEGs56YeZrQ7uvBm2_6ui1RYrghn8s3KCx3YXgGA-2bxdDn5EZhsFWxPLsgoijVf3XS4HNFewTKamTFLFrNTN8J4MDgmlVXZRtg58i_rQm3ZgJIRc3-rhVcAXS7LWLTglq68wTxVZXmSOBxWI9r0QaAgprzC_UDe_TcBcTUPiOQbmv7w-0GPrBbk388_pDmFnQY9shVpk60WbA-zv-eUAbk-xIbm1v_ww3IHYZnPKrmoyD2B3QN2RP3oPtqKg8GMh3I7UdXcgL8_-Cx4eLvJuBLtdT7EQuFyq5KoDNjPsa5HWLMx8bIHHDRZcrAay7SWEOFrE3_68Tmgxqfjy7VSmIxO7HE1OVIRLfaDcrfKjMZkYu-fw",
    "context": {
        "client": {
            "hl": "en",
            "gl": "US",
            "remoteHost": "75.161.14.176",
            "deviceMake": "Apple",
            "deviceModel": "",
            "visitorData": "Cgt5Z1ZNNmpmNENWayid6sqMBg%3D%3D",
            "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36,gzip(gfe)",
            "clientName": "WEB",
            "clientVersion": "2.20211115.01.00",
            "osName": "Macintosh",
            "osVersion": "10_15_7",
            "originalUrl": "https://www.youtube.com/watch?v=M2zfWGmSeCo",
            "screenPixelDensity": 2,
            "platform": "DESKTOP",
            "clientFormFactor": "UNKNOWN_FORM_FACTOR",
            "configInfo": {
                "appInstallData": "CJ3qyowGELDUrQUQktWtBRC3y60FEN_WrQUQ2L6tBRCR-PwS"
            },
            "screenDensityFloat": 2,
            "userInterfaceTheme": "USER_INTERFACE_THEME_DARK",
            "timeZone": "America/Denver",
            "browserName": "Chrome",
            "browserVersion": "95.0.4638.69",
            "screenWidthPoints": 885,
            "screenHeightPoints": 768,
            "utcOffsetMinutes": -420,
            "memoryTotalKbytes": "8000000",
            "mainAppWebInfo": {
                "graftUrl": "https://www.youtube.com/watch?v=M2zfWGmSeCo",
                "webDisplayMode": "WEB_DISPLAY_MODE_BROWSER",
                "isWebNativeShareAvailable": false
            }
        },
        "user": {
            "lockedSafetyMode": false
        },
        "request": {
            "useSsl": true,
            "internalExperimentFlags": [],
            "consistencyTokenJars": []
        },
        "adSignalsInfo": {
            "params": [
                {
                    "key": "dt",
                    "value": "1637004573436"
                },
                {
                    "key": "flash",
                    "value": "0"
                },
                {
                    "key": "frm",
                    "value": "0"
                },
                {
                    "key": "u_tz",
                    "value": "-420"
                },
                {
                    "key": "u_his",
                    "value": "2"
                },
                {
                    "key": "u_h",
                    "value": "900"
                },
                {
                    "key": "u_w",
                    "value": "1440"
                },
                {
                    "key": "u_ah",
                    "value": "900"
                },
                {
                    "key": "u_aw",
                    "value": "1440"
                },
                {
                    "key": "u_cd",
                    "value": "24"
                },
                {
                    "key": "bc",
                    "value": "31"
                },
                {
                    "key": "bih",
                    "value": "768"
                },
                {
                    "key": "biw",
                    "value": "869"
                },
                {
                    "key": "brdim",
                    "value": "0,0,0,0,1440,0,1440,900,885,768"
                },
                {
                    "key": "vis",
                    "value": "1"
                },
                {
                    "key": "wgl",
                    "value": "true"
                },
                {
                    "key": "ca_type",
                    "value": "image"
                }
            ]
        }
    }
}

Second request URI: https://www.youtube.com/youtubei/v1/comment/perform_comment_action?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8 Payload:

{
    "context": {
        "client": {
            "hl": "en",
            "gl": "US",
            "remoteHost": "75.161.14.176",
            "deviceMake": "Apple",
            "deviceModel": "",
            "visitorData": "Cgt5Z1ZNNmpmNENWayid6sqMBg%3D%3D",
            "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36,gzip(gfe)",
            "clientName": "WEB",
            "clientVersion": "2.20211115.01.00",
            "osName": "Macintosh",
            "osVersion": "10_15_7",
            "originalUrl": "https://www.youtube.com/watch?v=M2zfWGmSeCo",
            "screenPixelDensity": 2,
            "platform": "DESKTOP",
            "clientFormFactor": "UNKNOWN_FORM_FACTOR",
            "configInfo": {
                "appInstallData": "CJ3qyowGELDUrQUQktWtBRC3y60FEN_WrQUQ2L6tBRCR-PwS"
            },
            "screenDensityFloat": 2,
            "userInterfaceTheme": "USER_INTERFACE_THEME_DARK",
            "timeZone": "America/Denver",
            "browserName": "Chrome",
            "browserVersion": "95.0.4638.69",
            "screenWidthPoints": 885,
            "screenHeightPoints": 768,
            "utcOffsetMinutes": -420,
            "connectionType": "CONN_CELLULAR_4G",
            "memoryTotalKbytes": "8000000",
            "mainAppWebInfo": {
                "graftUrl": "https://www.youtube.com/watch?v=M2zfWGmSeCo",
                "webDisplayMode": "WEB_DISPLAY_MODE_BROWSER",
                "isWebNativeShareAvailable": false
            }
        },
        "user": {
            "lockedSafetyMode": false
        },
        "request": {
            "useSsl": true,
            "internalExperimentFlags": [],
            "consistencyTokenJars": [
                {
                    "encryptedTokenJarContents": "AGDxDeOq2RdhqZPtKiyUxTX2m8-QA_4IONt4eGeZ_lprAaIzBnymstH81FNf-O_8pAeLmZsBYV8FL4kyYJAuA9yZ7jjWF7t87WQLwQ",
                    "expirationSeconds": "600"
                }
            ]
        },
        "clickTracking": {
            "clickTrackingParams": "CCUQ8FsiEwilzra7jZv0AhXNHGQKHasRBw8="
        },
        "adSignalsInfo": {
            "params": [
                {
                    "key": "dt",
                    "value": "1637004573436"
                },
                {
                    "key": "flash",
                    "value": "0"
                },
                {
                    "key": "frm",
                    "value": "0"
                },
                {
                    "key": "u_tz",
                    "value": "-420"
                },
                {
                    "key": "u_his",
                    "value": "2"
                },
                {
                    "key": "u_h",
                    "value": "900"
                },
                {
                    "key": "u_w",
                    "value": "1440"
                },
                {
                    "key": "u_ah",
                    "value": "900"
                },
                {
                    "key": "u_aw",
                    "value": "1440"
                },
                {
                    "key": "u_cd",
                    "value": "24"
                },
                {
                    "key": "bc",
                    "value": "31"
                },
                {
                    "key": "bih",
                    "value": "768"
                },
                {
                    "key": "biw",
                    "value": "869"
                },
                {
                    "key": "brdim",
                    "value": "0,0,0,0,1440,0,1440,900,885,768"
                },
                {
                    "key": "vis",
                    "value": "1"
                },
                {
                    "key": "wgl",
                    "value": "true"
                },
                {
                    "key": "ca_type",
                    "value": "image"
                }
            ]
        }
    },
    "actions": [
        "CAsQAhoaVWd5UDk4VkU4OTF0SVRfTkVHTjRBYUFCQWcqC00yemZXR21TZUNvMABKFTExMDM1OTA2NDY4MDA2MTQ3ODYxNVABqAEMugEYVUNlTnVfOG9fRkZhcUVIOVFHQlIyQWdR8AEA"
    ]
}

All of this can be found using the network tab in chrome dev tools.

They may not have an "end user" friendly API endpoint setup yet, which is probably why it's not listed in the documentation.

Sidenote: It may be easier to use web scraping to pin the comment at this moment. It looks like youtube may be using a challenge-response authentication schema for these endpoints, which would be tricky to replicate.

SpencerPao commented 2 years ago

Hi @ForrestKnight Instead of doing the Pinned comment route (I would rather have this option for other use cases), you can always automatically update the YouTube description. I wrote out a few code snippets and applied that for all of my videos. The codebase is a bit clunky, but I do intend on streaming the scripts and packages for more developer friendly. Its not currently in production format (everything is localized) and am thinking of ways to do that i.e have a cron job on a cloud instance.

Perhaps this can help?

https://github.com/SpencerPao/YouTube_Automation

ForrestKnight commented 2 years ago

I don't want to go the description route considering most people don't read the description and the video gets re-indexed every time the description changes. I'm also too scared to overwrite my descriptions lol. And as for any potential workaround, I don't want to do that. I'm not sure if hacking something together would be within YouTube ToS, and I can't risk a ban or channel deletion. What I'm doing now is all from their docs and above board, so I'm good on that front.

SpencerPao commented 2 years ago

@ForrestKnight Oh very true. I hadn't taken into consideration of the reindexing of YouTube videos. That could potentially negatively effect the video recommendations. Though I have ran the updated description script a few times and hadn't noticed a difference in loss viewership & watch time. But, I'll monitor the situation and see if there is a drastic decrease in watch time & views.

As for the reading the description, I did add the updated line at the top of the description. So, when you are scrolling down to the comment section below, you can't miss it.

Everything I did in the codebase is with their API. So, it should be apart of their ToS. There is no third party API that goes around YouTube's API; nothing nefarious haha.