1 (изменено: shahlik002, 2018-07-10 13:33:37)

Тема: AHK: Instagram API

Доброго здоровья, форумчане!)
Подскажте, есть ли что-нибудь интересное с инстаграмом? Библиотеки??
На форуме ничего такого не нашел.
Можно конечно и интернет запросы использовать, но тогда понадобиться ваша помощь, ибо я в них не понимаю.
Хочется буржуйского функционала и все что б по полочкам было.

2

Re: AHK: Instagram API

А в гугле пробовали искать?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Instagram API

shahlik002, смайлик точку не заменяет. Требую исправить!

4

Re: AHK: Instagram API

teadrinker
Да, пробовал.
На AHK дельного ничего не нашел, только через ie и не то что я хочу.
Нашел на питоне, тут красота.

5

Re: AHK: Instagram API

shahlik002 пишет:

На AHK дельного ничего не нашел, только через ie и не то что я хочу.

А что вы хотите?

6

Re: AHK: Instagram API

Malcev
Как можно больше функционала.
Как минимум возможность войти, поставить лайк, подписаться, искать посты, ждать постов от других аккаунтов.

Сайты для взаимной раскрутки так и хотят автоматизации.
Так же неплохо б было организовать директ для переписок с ПК.
Сейчас пользуюсь python-instagram API.
Можно как-то эту библиотеку перенести в AHK?

7

Re: AHK: Instagram API

shahlik002 пишет:

Можно как-то эту библиотеку перенести в AHK?

Можно. Переносите .

8

Re: AHK: Instagram API

А как перенесете не забудьте поделиться результатами.

9

Re: AHK: Instagram API

alexii
Malcev
А как это сделать?
Если бы я мог, я бы не создавал эту тему.

10 (изменено: DD, 2018-07-10 18:47:22)

Re: AHK: Instagram API

Да, каким будет напутствие Шахлику от наших опытных товарищей?)

11 (изменено: DD, 2018-07-10 18:51:08)

Re: AHK: Instagram API

Шахлик, а вам надо усвоить, как тут все работает:

12

Re: AHK: Instagram API

shahlik002, Смотреть код на питоне, что он посылает и повторить такое же в ахк.
А так-как, там отправляются http запросы, то я вижу 3 варианта:
1) Продолжать пользоваться питоновской библиотекой.
2) Понять как использовать веб-запрсы и перевести питон на ахк.
3) Обратиться за помощью в коммерческий раздел.

13 (изменено: Malcev, 2019-08-09 05:30:23)

Re: AHK: Instagram API

Вот так логинится по этому недокументированному апи.
Токен даётся на 1 год.

username := "gmail@gmail.com"
password := "password"

API_URL := "https://i.instagram.com/api/v1/"
DEVICE_SETTINTS := {manufacturer: "Xiaomi", model: "HM 1SW", android_version: 18, android_release: 4.3}
USER_AGENT := "Instagram 85.0.0.21.100 Android (" DEVICE_SETTINTS["android_version"] "/" DEVICE_SETTINTS["android_release"] "; 320dpi; 720x1280; " DEVICE_SETTINTS["manufacturer"] "; " DEVICE_SETTINTS["model"] "; armani; qcom; en_US)"
IG_SIG_KEY := "937463b5272b5d60e9d20f0f8d7d192193dd95095a3ad43725d494300a5ea5fc"
SIG_KEY_VERSION := 4

device_id := "android-" SubStr(bcrypt_md5(bcrypt_md5(username password) 12345), 1, 16)
uuid := generateUUID(true)
HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")
HTTP.Open("GET", API_URL "si/fetch_headers/?challenge_type=signup&guid=" generateUUID(False), true)
HTTP.SetRequestHeader("Connection", "close")
HTTP.SetRequestHeader("Accept", "*/*")
HTTP.SetRequestHeader("Cookie2", "$Version=1")
HTTP.SetRequestHeader("Accept-Language", "en-US")
HTTP.SetRequestHeader("User-Agent", USER_AGENT)
HTTP.Send()
HTTP.WaitForResponse()
csrftoken := RegexReplace(HTTP.getAllResponseHeaders, "s)^.*Set-Cookie: csrftoken=(.+?);.*$", "$1")   ; даётся на год
data := "{""phone_id"": """ generateUUID(true) """, ""_csrftoken"": """ csrftoken """, ""username"": """ username """, ""guid"": """ uuid """, ""device_id"": """ device_id """, ""password"": """ password """, ""login_attempt_count"": ""0""}"
Signature := "ig_sig_key_version=" SIG_KEY_VERSION "&signed_body=" HMAC(IG_SIG_KEY, data, "SHA256") "." UriEncode(data)

HTTP.Open("POST", API_URL "accounts/login/", true)
HTTP.SetRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
HTTP.SetRequestHeader("Connection", "close")
HTTP.SetRequestHeader("Accept", "*/*")
HTTP.SetRequestHeader("Cookie2", "$Version=1")
HTTP.SetRequestHeader("Accept-Language", "en-US")
HTTP.SetRequestHeader("User-Agent", USER_AGENT)
HTTP.Send(Signature)
HTTP.WaitForResponse()
msgbox % HTTP.responsetext
return



generateUUID(type)
{
   VarSetCapacity(puuid, 16, 0)
   if !(DllCall("rpcrt4.dll\UuidCreate", "ptr", &puuid))
   {
      if !(DllCall("rpcrt4.dll\UuidToString", "ptr", &puuid, "uint*", suuid))
      {
         if type
            return StrGet(suuid), DllCall("rpcrt4.dll\RpcStringFree", "uint*", suuid)
         else
            return StrReplace(StrGet(suuid), "-"), DllCall("rpcrt4.dll\RpcStringFree", "uint*", suuid)
      }
   }
   return ""
}



UriEncode(Uri, RE="[0-9A-Za-z]")
{
   VarSetCapacity(Var, StrPut(Uri, "UTF-8"), 0), StrPut(Uri, &Var, "UTF-8")
   While Code := NumGet(Var, A_Index - 1, "UChar")
      Res .= (Chr:=Chr(Code)) ~= RE ? Chr : Format("%{:02X}", Code)
   Return, Res
}



bcrypt_md5(string)
{
    static BCRYPT_MD5_ALGORITHM := "MD5"
    static BCRYPT_OBJECT_LENGTH := "ObjectLength"
    static BCRYPT_HASH_LENGTH   := "HashDigestLength"

    if !(hBCRYPT := DllCall("LoadLibrary", "str", "bcrypt.dll", "ptr"))
        throw Exception("Failed to load bcrypt.dll", -1)

    if (NT_STATUS := DllCall("bcrypt\BCryptOpenAlgorithmProvider", "ptr*", hAlgo, "ptr", &BCRYPT_MD5_ALGORITHM, "ptr", 0, "uint", 0) != 0)
        throw Exception("BCryptOpenAlgorithmProvider: " NT_STATUS, -1)

    if (NT_STATUS := DllCall("bcrypt\BCryptGetProperty", "ptr", hAlgo, "ptr", &BCRYPT_OBJECT_LENGTH, "uint*", cbHashObject, "uint", 4, "uint*", cbResult, "uint", 0) != 0)
        throw Exception("BCryptGetProperty: " NT_STATUS, -1)

    if (NT_STATUS := DllCall("bcrypt\BCryptGetProperty", "ptr", hAlgo, "ptr", &BCRYPT_HASH_LENGTH, "uint*", cbHash, "uint", 4, "uint*", cbResult, "uint", 0) != 0)
        throw Exception("BCryptGetProperty: " NT_STATUS, -1)

    VarSetCapacity(pbHashObject, cbHashObject, 0)
    if (NT_STATUS := DllCall("bcrypt\BCryptCreateHash", "ptr", hAlgo, "ptr*", hHash, "ptr", &pbHashObject, "uint", cbHashObject, "ptr", 0, "uint", 0, "uint", 0) != 0)
        throw Exception("BCryptCreateHash: " NT_STATUS, -1)

    VarSetCapacity(pbInput, StrPut(string, "UTF-8"), 0) && cbInput := StrPut(string, &pbInput, "UTF-8") - 1
    if (NT_STATUS := DllCall("bcrypt\BCryptHashData", "ptr", hHash, "ptr", &pbInput, "uint", cbInput, "uint", 0) != 0)
        throw Exception("BCryptHashData: " NT_STATUS, -1)

    VarSetCapacity(pbHash, cbHash, 0)
    if (NT_STATUS := DllCall("bcrypt\BCryptFinishHash", "ptr", hHash, "ptr", &pbHash, "uint", cbHash, "uint", 0) != 0)
        throw Exception("BCryptFinishHash: " NT_STATUS, -1)

    loop % cbHash
        hash .= Format("{:02x}", NumGet(pbHash, A_Index - 1, "uchar"))

    DllCall("bcrypt\BCryptDestroyHash", "ptr", hHash)
    DllCall("bcrypt\BCryptCloseAlgorithmProvider", "ptr", hAlgo, "uint", 0)
    DllCall("FreeLibrary", "ptr", hBCRYPT)

    return hash
}




HMAC(Key, Message, Algo := "MD5")
{
   static Algorithms := {MD2:    {ID: 0x8001, Size:  64}
                                   , MD4:    {ID: 0x8002, Size:  64}
                                   , MD5:    {ID: 0x8003, Size:  64}
                                   , SHA:    {ID: 0x8004, Size:  64}
                                   , SHA256: {ID: 0x800C, Size:  64}
                                   , SHA384: {ID: 0x800D, Size: 128}
                                   , SHA512: {ID: 0x800E, Size: 128}}
   static iconst := 0x36
   static oconst := 0x5C
   if (!(Algorithms.HasKey(Algo)))
   {
      return ""
   }
   Hash := KeyHashLen := InnerHashLen := ""
   HashLen := 0
   AlgID := Algorithms[Algo].ID
   BlockSize := Algorithms[Algo].Size
   MsgLen := StrPut(Message, "UTF-8") - 1
   KeyLen := StrPut(Key, "UTF-8") - 1
   VarSetCapacity(K, KeyLen + 1, 0)
   StrPut(Key, &K, KeyLen, "UTF-8")
   if (KeyLen > BlockSize)
   {
      LC_CalcAddrHash(&K, KeyLen, AlgID, KeyHash, KeyHashLen)
   }

   VarSetCapacity(ipad, BlockSize + MsgLen, iconst)
   Addr := KeyLen > BlockSize ? &KeyHash : &K
   Length := KeyLen > BlockSize ? KeyHashLen : KeyLen
   i := 0
   while (i < Length)
   {
      NumPut(NumGet(Addr + 0, i, "UChar") ^ iconst, ipad, i, "UChar")
      i++
   }
   if (MsgLen)
   {
      StrPut(Message, &ipad + BlockSize, MsgLen, "UTF-8")
   }
   LC_CalcAddrHash(&ipad, BlockSize + MsgLen, AlgID, InnerHash, InnerHashLen)

   VarSetCapacity(opad, BlockSize + InnerHashLen, oconst)
   Addr := KeyLen > BlockSize ? &KeyHash : &K
   Length := KeyLen > BlockSize ? KeyHashLen : KeyLen
   i := 0
   while (i < Length)
   {
      NumPut(NumGet(Addr + 0, i, "UChar") ^ oconst, opad, i, "UChar")
      i++
   }
   Addr := &opad + BlockSize
   i := 0
   while (i < InnerHashLen)
   {
      NumPut(NumGet(InnerHash, i, "UChar"), Addr + i, 0, "UChar")
      i++
   }
   return LC_CalcAddrHash(&opad, BlockSize + InnerHashLen, AlgID)
}



LC_CalcAddrHash(addr, length, algid, byref hash = 0, byref hashlength = 0)
{
   static h := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f"]
   static b := h.minIndex()
   hProv := hHash := o := ""
   if (DllCall("advapi32\CryptAcquireContext", "Ptr*", hProv, "Ptr", 0, "Ptr", 0, "UInt", 24, "UInt", 0xf0000000))
   {
      if (DllCall("advapi32\CryptCreateHash", "Ptr", hProv, "UInt", algid, "UInt", 0, "UInt", 0, "Ptr*", hHash))
      {
         if (DllCall("advapi32\CryptHashData", "Ptr", hHash, "Ptr", addr, "UInt", length, "UInt", 0))
         {
            if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", 0, "UInt*", hashlength, "UInt", 0))
            {
               VarSetCapacity(hash, hashlength, 0)
               if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", &hash, "UInt*", hashlength, "UInt", 0))
               {
                  loop % hashlength
                  {
                     v := NumGet(hash, A_Index - 1, "UChar")
                     o .= h[(v >> 4) + b] h[(v & 0xf) + b]
                  }
               }
            }
         }
         DllCall("advapi32\CryptDestroyHash", "Ptr", hHash)
      }
      DllCall("advapi32\CryptReleaseContext", "Ptr", hProv, "UInt", 0)
   }
   return o
}
+ DD

14

Re: AHK: Instagram API

Malcev, в последнем коде — переменная csrftoken содержит токен? Спрашиваю, потому что там формат короче и он меняется после каждого запуска.

15

Re: AHK: Instagram API

Уже и не вспомню.
Но судя по коду для использования этого апи нам надо сгенерировать Signature, которая в свою очередь использует токен, который дается на год.
Так что, наверное, сгенерировав один раз Signature мы можем ее использовать целый год.

16

Re: AHK: Instagram API

Интересно, в чём разница, если скачивать через это апи с токеном — со скачиванием, как при переходах через браузер?

17

Re: AHK: Instagram API

Без понятия.
Никогда ни тем ни другим не пользовался.
Надо бы добавить загрузку фотографий для теста.

18 (изменено: DD, 2019-02-23 14:26:01)

Re: AHK: Instagram API

Знаю, что браузерные страницы тоже используют json, так что когда лимит запросов в час исчерпается — приходит сообщение «{"message": "rate limited", "status": "fail"}» и в браузере соответственно страницы не подгружаются. Так что, наверно, в любом случае лимитов не избежать.

19 (изменено: DD, 2019-02-23 14:29:37)

Re: AHK: Instagram API

Хотя, было бы интересно, за сколько запросов можно получить комментарии к посту? Может, там они все за минимум запросов выдаются, в отличие от имитации скачивания через браузер?

20 (изменено: Malcev, 2019-02-23 14:53:38)

Re: AHK: Instagram API

Похоже 20 комментариев за 1 запрос.
https://instagram-private-api.readthedo … media.html

+ DD

21 (изменено: DD, 2019-02-26 15:03:13)

Re: AHK: Instagram API

Вроде, маловато. Через браузер уже в первой партии — больше 50.

22 (изменено: Malcev, 2019-08-09 05:30:47)

Re: AHK: Instagram API

Решил проверить - после логина отправляем запрос:

mediaId := "448979387270691659_45818965"
n := 1   ; pagination
HTTP.Open("GET", API_URL "media/" mediaId "/comments/?max_id=" n, true)
HTTP.SetRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
HTTP.SetRequestHeader("Connection", "close")
HTTP.SetRequestHeader("Accept", "*/*")
HTTP.SetRequestHeader("Cookie2", "$Version=1")
HTTP.SetRequestHeader("Accept-Language", "en-US")
HTTP.SetRequestHeader("User-Agent", USER_AGENT)
HTTP.Send()
HTTP.WaitForResponse()
msgbox % clipboard := HTTP.ResponseText

Результат 20.
Также перенес функцию заливки фото:

username := "username"
password := "password"

API_URL := "https://i.instagram.com/api/v1/"
DEVICE_SETTINTS := {manufacturer: "Xiaomi", model: "HM 1SW", android_version: 18, android_release: 4.3}
USER_AGENT := "Instagram 85.0.0.21.100 Android (" DEVICE_SETTINTS["android_version"] "/" DEVICE_SETTINTS["android_release"] "; 320dpi; 720x1280; " DEVICE_SETTINTS["manufacturer"] "; " DEVICE_SETTINTS["model"] "; armani; qcom; en_US)"
IG_SIG_KEY := "937463b5272b5d60e9d20f0f8d7d192193dd95095a3ad43725d494300a5ea5fc"
SIG_KEY_VERSION := 4

device_id := "android-" SubStr(bcrypt_md5(bcrypt_md5(username password) 12345), 1, 16)
uuid := generateUUID(true)
HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1")

; 1 time in 90 days
HTTP.Open("GET", API_URL "si/fetch_headers/?challenge_type=signup&guid=" generateUUID(False), true)
HTTP.SetRequestHeader("Connection", "close")
HTTP.SetRequestHeader("Accept", "*/*")
HTTP.SetRequestHeader("Cookie2", "$Version=1")
HTTP.SetRequestHeader("Accept-Language", "en-US")
HTTP.SetRequestHeader("User-Agent", USER_AGENT)
HTTP.Send()
HTTP.WaitForResponse()
csrftoken := RegexReplace(HTTP.getAllResponseHeaders, "s)^.*Set-Cookie: csrftoken=(.+?);.*$", "$1")   ; даётся на год
data := "{""phone_id"": """ generateUUID(true) """, ""_csrftoken"": """ csrftoken """, ""username"": """ username """, ""guid"": """ uuid """, ""device_id"": """ device_id """, ""password"": """ password """, ""login_attempt_count"": ""0""}"
Signature := "ig_sig_key_version=" SIG_KEY_VERSION "&signed_body=" HMAC(IG_SIG_KEY, data, "SHA256") "." UriEncode(data)

HTTP.Open("POST", API_URL "accounts/login/", true)
HTTP.SetRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
HTTP.SetRequestHeader("Connection", "close")
HTTP.SetRequestHeader("Accept", "*/*")
HTTP.SetRequestHeader("Cookie2", "$Version=1")
HTTP.SetRequestHeader("Accept-Language", "en-US")
HTTP.SetRequestHeader("User-Agent", USER_AGENT)
HTTP.Send(Signature)
HTTP.WaitForResponse()
username_id := RegexReplace(HTTP.getAllResponseHeaders, "s)^.*Set-Cookie: ds_user_id=(.+?);.*$", "$1")
token := RegexReplace(HTTP.getAllResponseHeaders, "s)^.*Set-Cookie: csrftoken=(.+?);.*$", "$1")
match := "", Pos := 1
While Pos := regexmatch(HTTP.getAllResponseHeaders, "s)Set-Cookie: (.+?)\R", match, pos+StrLen(match))
   cookie .= match1 "; "
msgbox % clipboard := "username_id := " username_id "`r`ntoken := """ token """`r`ncookie := """ StrReplace(cookie, """", """""") """"

photo := "C:\001.jpg"
caption := "test"
disable_comments := false

pToken := Gdip_StartUp()
pBitmap := Gdip_CreateBitmapFromFile(photo)
Gdip_GetImageDimensions(pBitmap, width, height)
Gdip_DisposeImage(pBitmap)
Gdip_ShutDown(pToken)
upload_id := A_NowUTC
EnvSub, upload_id, 1970, seconds
upload_id .= A_MSec
data := {photo: [photo], upload_id: upload_id,  _csrftoken: csrftoken, image_compression: "{""lib_name"":""jt"",""lib_version"":""1.3.0"",""quality"":""87""}"}

CreateFormData(PostData, hdr_ContentType, data)
HTTP.Open("POST", API_URL "upload/photo/", true)
HTTP.SetRequestHeader("Content-Type", hdr_ContentType)
HTTP.SetRequestHeader("X-IG-Capabilities", "3Q4=")
HTTP.SetRequestHeader("X-IG-Connection-Type", "WIFI")
HTTP.SetRequestHeader("Cookie2", "$Version=1")
HTTP.SetRequestHeader("Accept-Language", "en-US")
HTTP.SetRequestHeader("Accept-Encoding", "gzip, deflate")
HTTP.SetRequestHeader("Connection", "close")
HTTP.SetRequestHeader("User-Agent", USER_AGENT)
HTTP.SetRequestHeader("Cookie", cookie)
HTTP.Send(PostData)
HTTP.WaitForResponse()
if (HTTP.Status = 200)
{
   data := "{""_csrftoken"": """ token """, ""media_folder"": ""Instagram"", ""source_type"": 4, ""_uid"": " username_id ", ""_uuid"": """ uuid """, ""caption"": """ caption """, ""upload_id"": """ upload_id """, ""device"": {""manufacturer"": """ DEVICE_SETTINTS["manufacturer"] """, ""model"": """ DEVICE_SETTINTS["model"] """, ""android_version"": " DEVICE_SETTINTS["android_version"] ", ""android_release"": """ DEVICE_SETTINTS["android_release"] """}, ""edits"": {""crop_original_size"": [" width ".0 , " height ".0], ""crop_center"": [0.0, 0.0], ""crop_zoom"": 1.0}, ""extra"": {""source_width"": " width ", ""source_height"": " height "}}"
   if disable_comments
      data := SubStr(data, 1, -1) ", ""disable_comments"": 1}"
   Signature := "ig_sig_key_version=" SIG_KEY_VERSION "&signed_body=" HMAC(IG_SIG_KEY, data, "SHA256") "." UriEncode(data)
   HTTP.Open("POST", API_URL "media/configure/?", true)
   HTTP.SetRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
   HTTP.SetRequestHeader("Connection", "close")
   HTTP.SetRequestHeader("Accept", "*/*")
   HTTP.SetRequestHeader("Cookie2", "$Version=1")
   HTTP.SetRequestHeader("Accept-Language", "en-US")
   HTTP.SetRequestHeader("User-Agent", USER_AGENT)
   HTTP.SetRequestHeader("Cookie", cookie)
   HTTP.Send(Signature)
   HTTP.WaitForResponse()
   if (HTTP.Status = 200)
   {
      data := "{""_uuid"": """ uuid """, ""_uid"": " username_id ", ""id"": " username_id ", ""_csrftoken"": """ token """, ""experiment"": ""ig_android_profile_contextual_feed""}"
      Signature := "ig_sig_key_version=" SIG_KEY_VERSION "&signed_body=" HMAC(IG_SIG_KEY, data, "SHA256") "." UriEncode(data)
      HTTP.Open("POST", API_URL "qe/expose/", true)
      HTTP.SetRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
      HTTP.SetRequestHeader("Connection", "close")
      HTTP.SetRequestHeader("Accept", "*/*")
      HTTP.SetRequestHeader("Cookie2", "$Version=1")
      HTTP.SetRequestHeader("Accept-Language", "en-US")
      HTTP.SetRequestHeader("User-Agent", USER_AGENT)
      HTTP.SetRequestHeader("Cookie", cookie)
      HTTP.Send(Signature)
      HTTP.WaitForResponse()
      msgbox done
   }
   else
   {
      msgbox % HTTP.ResponseText
      return
   }
}
else
{
   msgbox % HTTP.ResponseText
   return
}






generateUUID(type)
{
   VarSetCapacity(puuid, 16, 0)
   if !(DllCall("rpcrt4.dll\UuidCreate", "ptr", &puuid))
   {
      if !(DllCall("rpcrt4.dll\UuidToString", "ptr", &puuid, "uint*", suuid))
      {
         if type
            return StrGet(suuid), DllCall("rpcrt4.dll\RpcStringFree", "uint*", suuid)
         else
            return StrReplace(StrGet(suuid), "-"), DllCall("rpcrt4.dll\RpcStringFree", "uint*", suuid)
      }
   }
   return ""
}



UriEncode(Uri, RE="[0-9A-Za-z]")
{
   VarSetCapacity(Var, StrPut(Uri, "UTF-8"), 0), StrPut(Uri, &Var, "UTF-8")
   While Code := NumGet(Var, A_Index - 1, "UChar")
      Res .= (Chr:=Chr(Code)) ~= RE ? Chr : Format("%{:02X}", Code)
   Return, Res
}



bcrypt_md5(string)
{
    static BCRYPT_MD5_ALGORITHM := "MD5"
    static BCRYPT_OBJECT_LENGTH := "ObjectLength"
    static BCRYPT_HASH_LENGTH   := "HashDigestLength"

    if !(hBCRYPT := DllCall("LoadLibrary", "str", "bcrypt.dll", "ptr"))
        throw Exception("Failed to load bcrypt.dll", -1)

    if (NT_STATUS := DllCall("bcrypt\BCryptOpenAlgorithmProvider", "ptr*", hAlgo, "ptr", &BCRYPT_MD5_ALGORITHM, "ptr", 0, "uint", 0) != 0)
        throw Exception("BCryptOpenAlgorithmProvider: " NT_STATUS, -1)

    if (NT_STATUS := DllCall("bcrypt\BCryptGetProperty", "ptr", hAlgo, "ptr", &BCRYPT_OBJECT_LENGTH, "uint*", cbHashObject, "uint", 4, "uint*", cbResult, "uint", 0) != 0)
        throw Exception("BCryptGetProperty: " NT_STATUS, -1)

    if (NT_STATUS := DllCall("bcrypt\BCryptGetProperty", "ptr", hAlgo, "ptr", &BCRYPT_HASH_LENGTH, "uint*", cbHash, "uint", 4, "uint*", cbResult, "uint", 0) != 0)
        throw Exception("BCryptGetProperty: " NT_STATUS, -1)

    VarSetCapacity(pbHashObject, cbHashObject, 0)
    if (NT_STATUS := DllCall("bcrypt\BCryptCreateHash", "ptr", hAlgo, "ptr*", hHash, "ptr", &pbHashObject, "uint", cbHashObject, "ptr", 0, "uint", 0, "uint", 0) != 0)
        throw Exception("BCryptCreateHash: " NT_STATUS, -1)

    VarSetCapacity(pbInput, StrPut(string, "UTF-8"), 0) && cbInput := StrPut(string, &pbInput, "UTF-8") - 1
    if (NT_STATUS := DllCall("bcrypt\BCryptHashData", "ptr", hHash, "ptr", &pbInput, "uint", cbInput, "uint", 0) != 0)
        throw Exception("BCryptHashData: " NT_STATUS, -1)

    VarSetCapacity(pbHash, cbHash, 0)
    if (NT_STATUS := DllCall("bcrypt\BCryptFinishHash", "ptr", hHash, "ptr", &pbHash, "uint", cbHash, "uint", 0) != 0)
        throw Exception("BCryptFinishHash: " NT_STATUS, -1)

    loop % cbHash
        hash .= Format("{:02x}", NumGet(pbHash, A_Index - 1, "uchar"))

    DllCall("bcrypt\BCryptDestroyHash", "ptr", hHash)
    DllCall("bcrypt\BCryptCloseAlgorithmProvider", "ptr", hAlgo, "uint", 0)
    DllCall("FreeLibrary", "ptr", hBCRYPT)

    return hash
}




HMAC(Key, Message, Algo := "MD5")
{
   static Algorithms := {MD2:    {ID: 0x8001, Size:  64}
                                   , MD4:    {ID: 0x8002, Size:  64}
                                   , MD5:    {ID: 0x8003, Size:  64}
                                   , SHA:    {ID: 0x8004, Size:  64}
                                   , SHA256: {ID: 0x800C, Size:  64}
                                   , SHA384: {ID: 0x800D, Size: 128}
                                   , SHA512: {ID: 0x800E, Size: 128}}
   static iconst := 0x36
   static oconst := 0x5C
   if (!(Algorithms.HasKey(Algo)))
   {
      return ""
   }
   Hash := KeyHashLen := InnerHashLen := ""
   HashLen := 0
   AlgID := Algorithms[Algo].ID
   BlockSize := Algorithms[Algo].Size
   MsgLen := StrPut(Message, "UTF-8") - 1
   KeyLen := StrPut(Key, "UTF-8") - 1
   VarSetCapacity(K, KeyLen + 1, 0)
   StrPut(Key, &K, KeyLen, "UTF-8")
   if (KeyLen > BlockSize)
   {
      LC_CalcAddrHash(&K, KeyLen, AlgID, KeyHash, KeyHashLen)
   }

   VarSetCapacity(ipad, BlockSize + MsgLen, iconst)
   Addr := KeyLen > BlockSize ? &KeyHash : &K
   Length := KeyLen > BlockSize ? KeyHashLen : KeyLen
   i := 0
   while (i < Length)
   {
      NumPut(NumGet(Addr + 0, i, "UChar") ^ iconst, ipad, i, "UChar")
      i++
   }
   if (MsgLen)
   {
      StrPut(Message, &ipad + BlockSize, MsgLen, "UTF-8")
   }
   LC_CalcAddrHash(&ipad, BlockSize + MsgLen, AlgID, InnerHash, InnerHashLen)

   VarSetCapacity(opad, BlockSize + InnerHashLen, oconst)
   Addr := KeyLen > BlockSize ? &KeyHash : &K
   Length := KeyLen > BlockSize ? KeyHashLen : KeyLen
   i := 0
   while (i < Length)
   {
      NumPut(NumGet(Addr + 0, i, "UChar") ^ oconst, opad, i, "UChar")
      i++
   }
   Addr := &opad + BlockSize
   i := 0
   while (i < InnerHashLen)
   {
      NumPut(NumGet(InnerHash, i, "UChar"), Addr + i, 0, "UChar")
      i++
   }
   return LC_CalcAddrHash(&opad, BlockSize + InnerHashLen, AlgID)
}



LC_CalcAddrHash(addr, length, algid, byref hash = 0, byref hashlength = 0)
{
   static h := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f"]
   static b := h.minIndex()
   hProv := hHash := o := ""
   if (DllCall("advapi32\CryptAcquireContext", "Ptr*", hProv, "Ptr", 0, "Ptr", 0, "UInt", 24, "UInt", 0xf0000000))
   {
      if (DllCall("advapi32\CryptCreateHash", "Ptr", hProv, "UInt", algid, "UInt", 0, "UInt", 0, "Ptr*", hHash))
      {
         if (DllCall("advapi32\CryptHashData", "Ptr", hHash, "Ptr", addr, "UInt", length, "UInt", 0))
         {
            if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", 0, "UInt*", hashlength, "UInt", 0))
            {
               VarSetCapacity(hash, hashlength, 0)
               if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", &hash, "UInt*", hashlength, "UInt", 0))
               {
                  loop % hashlength
                  {
                     v := NumGet(hash, A_Index - 1, "UChar")
                     o .= h[(v >> 4) + b] h[(v & 0xf) + b]
                  }
               }
            }
         }
         DllCall("advapi32\CryptDestroyHash", "Ptr", hHash)
      }
      DllCall("advapi32\CryptReleaseContext", "Ptr", hProv, "UInt", 0)
   }
   return o
}



Gdip_Startup()
{
   Ptr := A_PtrSize ? "UPtr" : "UInt"
   if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
      DllCall("LoadLibrary", "str", "gdiplus")
   VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
   DllCall("gdiplus\GdiplusStartup", A_PtrSize ? "UPtr*" : "uint*", pToken, Ptr, &si, Ptr, 0)
   return pToken
}

Gdip_Shutdown(pToken)
{
   Ptr := A_PtrSize ? "UPtr" : "UInt"
   DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
   if hModule := DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
      DllCall("FreeLibrary", Ptr, hModule)
   return 0
}

Gdip_CreateBitmapFromFile(sFile, IconNumber=1, IconSize="")
{
   Ptr := A_PtrSize ? "UPtr" : "UInt"
   , PtrA := A_PtrSize ? "UPtr*" : "UInt*"
   if (!A_IsUnicode)
   {
      VarSetCapacity(wFile, 1024)
      DllCall("kernel32\MultiByteToWideChar", "uint", 0, "uint", 0, Ptr, &sFile, "int", -1, Ptr, &wFile, "int", 512)
      DllCall("gdiplus\GdipCreateBitmapFromFile", Ptr, &wFile, PtrA, pBitmap)
   }
   else
      DllCall("gdiplus\GdipCreateBitmapFromFile", Ptr, &sFile, PtrA, pBitmap)
   return pBitmap
}

Gdip_GetImageDimensions(pBitmap, ByRef Width, ByRef Height)
{
   Ptr := A_PtrSize ? "UPtr" : "UInt"
   DllCall("gdiplus\GdipGetImageWidth", Ptr, pBitmap, "uint*", Width)
   DllCall("gdiplus\GdipGetImageHeight", Ptr, pBitmap, "uint*", Height)
}

Gdip_DisposeImage(pBitmap)
{
   return DllCall("gdiplus\GdipDisposeImage", A_PtrSize ? "UPtr" : "UInt", pBitmap)
}



; CreateFormData() by tmplinshi, AHK Topic: https://autohotkey.com/boards/viewtopic.php?t=7647
; Thanks to Coco: https://autohotkey.com/boards/viewtopic.php?p=41731#p41731
; Modified version by SKAN, 09/May/2016

CreateFormData(ByRef retData, ByRef retHeader, objParam) {
	New CreateFormData(retData, retHeader, objParam)
}

Class CreateFormData {

	__New(ByRef retData, ByRef retHeader, objParam) {

		Local CRLF := "`r`n", i, k, v, str, pvData
		; Create a random Boundary
		Local Boundary := this.RandomBoundary()
		Local BoundaryLine := "------------------------------" . Boundary

    this.Len := 0 ; GMEM_ZEROINIT|GMEM_FIXED = 0x40
    this.Ptr := DllCall( "GlobalAlloc", "UInt",0x40, "UInt",1, "Ptr"  )          ; allocate global memory

		; Loop input paramters
		For k, v in objParam
		{
			If IsObject(v) {
				For i, FileName in v
				{
					str := BoundaryLine . CRLF
					     . "Content-Disposition: form-data; name=""" . k . """; filename=""" . FileName . """" . CRLF
					     . "Content-Type: " . this.MimeType(FileName) . CRLF . CRLF
          this.StrPutUTF8( str )
          this.LoadFromFile( Filename )
          this.StrPutUTF8( CRLF )
				}
			} Else {
				str := BoundaryLine . CRLF
				     . "Content-Disposition: form-data; name=""" . k """" . CRLF . CRLF
				     . v . CRLF
        this.StrPutUTF8( str )
			}
		}

		this.StrPutUTF8( BoundaryLine . "--" . CRLF )

    ; Create a bytearray and copy data in to it.
    retData := ComObjArray( 0x11, this.Len ) ; Create SAFEARRAY = VT_ARRAY|VT_UI1
    pvData  := NumGet( ComObjValue( retData ) + 8 + A_PtrSize )
    DllCall( "RtlMoveMemory", "Ptr",pvData, "Ptr",this.Ptr, "Ptr",this.Len )

    this.Ptr := DllCall( "GlobalFree", "Ptr",this.Ptr, "Ptr" )                   ; free global memory 

    retHeader := "multipart/form-data; boundary=----------------------------" . Boundary
	}

  StrPutUTF8( str ) {
    Local ReqSz := StrPut( str, "utf-8" ) - 1
    this.Len += ReqSz                                  ; GMEM_ZEROINIT|GMEM_MOVEABLE = 0x42
    this.Ptr := DllCall( "GlobalReAlloc", "Ptr",this.Ptr, "UInt",this.len + 1, "UInt", 0x42 )   
    StrPut( str, this.Ptr + this.len - ReqSz, ReqSz, "utf-8" )
  }
  
  LoadFromFile( Filename ) {
    Local objFile := FileOpen( FileName, "r" )
    this.Len += objFile.Length                     ; GMEM_ZEROINIT|GMEM_MOVEABLE = 0x42 
    this.Ptr := DllCall( "GlobalReAlloc", "Ptr",this.Ptr, "UInt",this.len, "UInt", 0x42 )
    objFile.RawRead( this.Ptr + this.Len - objFile.length, objFile.length )
    objFile.Close()       
  }

	RandomBoundary() {
		str := "0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z"
		Sort, str, D| Random
		str := StrReplace(str, "|")
		Return SubStr(str, 1, 12)
	}

	MimeType(FileName) {
		n := FileOpen(FileName, "r").ReadUInt()
		Return (n        = 0x474E5089) ? "image/png"
		     : (n        = 0x38464947) ? "image/gif"
		     : (n&0xFFFF = 0x4D42    ) ? "image/bmp"
		     : (n&0xFFFF = 0xD8FF    ) ? "image/jpeg"
		     : (n&0xFFFF = 0x4949    ) ? "image/tiff"
		     : (n&0xFFFF = 0x4D4D    ) ? "image/tiff"
		     : "application/octet-stream"
	}

}

После успешного логина нужно сохранить кукисы, token и username_id.
И в дальнейшем эти кукисы отправлять в запросах, чтобы каждый раз не логиниться.
Так как за постоянный логин может последовать бан.
Кукисы действительны в течении 90 дней.

+ DD

23

Re: AHK: Instagram API

Malcev пишет:

После успешного логина нужно сохранить кукисы, token и username_id.
И в дальнейшем эти кукисы отправлять в запросах, чтобы каждый раз не логиниться.

А при использовании token`a, требуется отправлять куки?

24

Re: AHK: Instagram API

Надо. Но насколько я помню, там достаточно было одного куки.

25 (изменено: DD, 2019-08-07 04:50:05)

Re: AHK: Instagram API

Можно пример, как их отправлять, а то в поиске вместо кукисов — кукиш))? Достаточно куда-то вписать? —

mediaId := "448979387270691659_45818965"
n := 1   ; pagination
HTTP.Open("GET", API_URL "media/" mediaId "/comments/?max_id=" n, true)
HTTP.SetRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
HTTP.SetRequestHeader("Connection", "close")
HTTP.SetRequestHeader("Accept", "*/*")
HTTP.SetRequestHeader("Cookie2", "$Version=1")
HTTP.SetRequestHeader("Accept-Language", "en-US")
HTTP.SetRequestHeader("User-Agent", USER_AGENT)
HTTP.Send()
HTTP.WaitForResponse()
msgbox % clipboard := HTTP.ResponseText

26

Re: AHK: Instagram API

Я вам уже приводил пример:
http://forum.script-coding.com/viewtopi … 08#p126508

+ DD

27

Re: AHK: Instagram API

Не пойму, как через этот код следующие страницы с 20 коментами доставать?

n := 1   ; pagination

После того, как скачается первая страница, вроде из нее надо получить значение "next_max_id" и подставить его вместо приведённой единицы из переменной "n"

n := "%next_max_id%"

Только каждый раз скачивается одна и та же первая страница.

28

Re: AHK: Instagram API

DD пишет:

n := "%next_max_id%"

Что за странное выражение?

29

Re: AHK: Instagram API

Это для намёка, что переменную заключал в кавычки)).

30

Re: AHK: Instagram API

Не понимаю ваших намёков, но там кавычки не нужны.
У меня пароль утерян от инстаграма, а при возврате там идет какой-то глюк с капчей - так что проверить не смогу.

31

Re: AHK: Instagram API

Там принцип же вроде такой, что вот так должна первая ссылка выглядеть —

https://i.instagram.com/api/v1/media/448979387270691659_45818965/comments/?max_id=1

А вот так вторая, для которой значение max_id получено из первой ссылки —

https://i.instagram.com/api/v1/media/448979387270691659_45818965/comments/?max_id=QVFBZ0xjbWJYZWVoRnMtcENOYndDWWtBcFFBMnVRZ2xyTlFpYnRHMC1NdUJ5dWNvMElDdlBRTFdMWVVGbUxpNEZkc3hNRGtDQVl6UE5RWFBISnJ5UHVDSQ==

Но скачивается каждый раз первая страница комментариев, независимо от значения max_id, вместо которого можно что угодно вписать.

32

Re: AHK: Instagram API

Так попробуйте:

mediaId := "448979387270691659_45818965"
n := ""   ; pagination
loop
{
   HTTP.Open("GET", API_URL "media/" mediaId "/comments/?max_id=" n, true)
   HTTP.SetRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
   HTTP.SetRequestHeader("Connection", "close")
   HTTP.SetRequestHeader("Accept", "*/*")
   HTTP.SetRequestHeader("Cookie2", "$Version=1")
   HTTP.SetRequestHeader("Accept-Language", "en-US")
   HTTP.SetRequestHeader("User-Agent", USER_AGENT)
   HTTP.Send()
   HTTP.WaitForResponse()
   msgbox % clipboard := HTTP.ResponseText
   RegexMatch(HTTP.ResponseText, "s)""next_max_id"":.+?: \\""(.+?)\\""", match)
   n := """" match1 """"
}
+ DD

33

Re: AHK: Instagram API

shahlik002 пишет:

python-instagram API

Интересно, была ли в этом API возможность получать лайкосы к постам/коментам, а то в явном виде не нашёл?

34

Re: AHK: Instagram API

DD пишет:

в чём разница, если скачивать через это апи с токеном — со скачиванием, как при переходах через браузер?

Оказалось, через браузер сложнее — надо формировать ссылки из ряда данных, которые к тому же меняются в зависимости от профиля, формата файла в посте и тп.

35

Re: AHK: Instagram API

Плохо искали.

def getMediaLikers(self, mediaId):

https://github.com/LevPasha/Instagram-A … PI.py#L689
Функции для подсчета лайков к комментариям там действительно нету, зато есть на php:

public function getCommentLikers

https://github.com/mgp25/Instagram-API/ … a.php#L541

+ DD

36

Re: AHK: Instagram API

Сложновато, однако. Даже непонятно, каков формат ссылок для того и другого. И почему-то в JSON из наших скриптов отсутствует "comment_id", по которому собственно и можно получать лайки к ним.

37

Re: AHK: Instagram API

Вам надо понять алгоритм создания этих ссылок - будет проще.
Используйте мои примеры и сравнивайте их с кодом с которого я перенес.

HTTP.Open("GET", API_URL "media/" mediaId "/likers/?", true)
HTTP.Open("GET", API_URL "media/" commentId "/comment_likers/", true)

comment_id - это "pk".

+ DD

38

Re: AHK: Instagram API

Malcev, а имеется ли в API возможность получения списка ссылок к профилю? То есть, ссылки к каждому из подгружающихся по мере прокручивания медиа-файлов, которые находятся в профиле?

39

Re: AHK: Instagram API

Интересно, если правильно изменить USER_AGENT, появится ли возможность скачивать JSON в формате, выдаваемом браузером, в котором присутствует инфа о тредах (edge_threaded_comments), благодаря чему коменты можно группировать по ответам и под-ответам, тогда как здесь они идут сплошным текстом?

40

Re: AHK: Instagram API

На все эти вопросы ответа не знаю, так как инстаграмом не пользуюсь и апи его тоже, а вникать в него глубже интереса нет.
Попробуйте искать по слову "media" и "thread" в кодах на пхп и питоне.
Вот тут еще один враппер на питоне:
https://instagram-private-api.readthedo … index.html

+ DD

41

Re: AHK: Instagram API

А по какой причине может USER_AGENT может не подходить? Первый вместо второго? —

DEVICE_SETTINTS := {manufacturer: "Xiaomi", model: "HM 1SW", android_version: 18, android_release: 4.3}
USER_AGENT := "Instagram 10.26.0 Android (" DEVICE_SETTINTS["android_version"] "/" DEVICE_SETTINTS["android_release"] "; 320dpi; 720x1280; " DEVICE_SETTINTS["manufacturer"] "; " DEVICE_SETTINTS["model"] "; armani; qcom; en_US)"
USER_AGENT := "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36"

42

Re: AHK: Instagram API

Апи написано для телефона, подозреваю, что могут забанить.

43

Re: AHK: Instagram API

А-а, ясно. И для телефона наверно ограничений действует меньше по вызовам к Апи?

44 (изменено: DD, 2019-08-08 23:16:55)

Re: AHK: Instagram API

Я кстати для Хрома пользуюсь расширением User-Agent Switcher, в котором можно автоматически страницы Инсты открывать будто в телефоне.

45 (изменено: Malcev, 2019-08-09 02:07:55)

Re: AHK: Instagram API

Посмотрел код, там они зачем-то инициализируют набор каких-то экспериментов после логина.
Может тоже надо и это на что-то влияет.

EXPERIMENTS := "ig_promote_reach_objective_fix_universe,ig_android_universe_video_production,ig_search_client_h1_2017_holdout,ig_android_live_follow_from_comments_universe,ig_android_carousel_non_square_creation,ig_android_live_analytics,ig_android_follow_all_dialog_confirmation_copy,ig_android_stories_server_coverframe,ig_android_video_captions_universe,ig_android_offline_location_feed,ig_android_direct_inbox_retry_seen_state,ig_android_ontact_invite_universe,ig_android_live_broadcast_blacklist,ig_android_insta_video_reconnect_viewers,ig_android_ad_async_ads_universe,ig_android_search_clear_layout_universe,ig_android_shopping_reporting,ig_android_stories_surface_universe,ig_android_verified_comments_universe,ig_android_preload_media_ahead_in_current_reel,android_instagram_prefetch_suggestions_universe,ig_android_reel_viewer_fetch_missing_reels_universe,ig_android_direct_search_share_sheet_universe,ig_android_business_promote_tooltip,ig_android_direct_blue_tab,ig_android_async_network_tweak_universe,ig_android_elevate_main_thread_priority_universe,ig_android_stories_gallery_nux,ig_android_instavideo_remove_nux_comments,ig_video_copyright_whitelist,ig_react_native_inline_insights_with_relay,ig_android_direct_thread_message_animation,ig_android_draw_rainbow_client_universe,ig_android_direct_link_style,ig_android_live_heart_enhancements_universe,ig_android_rtc_reshare,ig_android_preload_item_count_in_reel_viewer_buffer,ig_android_users_bootstrap_service,ig_android_auto_retry_post_mode,ig_android_shopping,ig_android_main_feed_seen_state_dont_send_info_on_tail_load,ig_fbns_preload_default,ig_android_gesture_dismiss_reel_viewer,ig_android_tool_tip,ig_android_ad_logger_funnel_logging_universe,ig_android_gallery_grid_column_count_universe,ig_android_business_new_ads_payment_universe,ig_android_direct_links,ig_android_audience_control,ig_android_live_encore_consumption_settings_universe,ig_perf_android_holdout,ig_android_cache_contact_import_list,ig_android_links_receivers,ig_android_ad_impression_backtest,ig_android_list_redesign,ig_android_stories_separate_overlay_creation,ig_android_stop_video_recording_fix_universe,ig_android_render_video_segmentation,ig_android_live_encore_reel_chaining_universe,ig_android_sync_on_background_enhanced_10_25,ig_android_immersive_viewer,ig_android_mqtt_skywalker,ig_fbns_push,ig_android_ad_watchmore_overlay_universe,ig_android_react_native_universe,ig_android_profile_tabs_redesign_universe,ig_android_live_consumption_abr,ig_android_story_viewer_social_context,ig_android_hide_post_in_feed,ig_android_video_loopcount_int,ig_android_enable_main_feed_reel_tray_preloading,ig_android_camera_upsell_dialog,ig_android_ad_watchbrowse_universe,ig_android_internal_research_settings,ig_android_search_people_tag_universe,ig_android_react_native_ota,ig_android_enable_concurrent_request,ig_android_react_native_stories_grid_view,ig_android_business_stories_inline_insights,ig_android_log_mediacodec_info,ig_android_direct_expiring_media_loading_errors,ig_video_use_sve_universe,ig_android_cold_start_feed_request,ig_android_enable_zero_rating,ig_android_reverse_audio,ig_android_branded_content_three_line_ui_universe,ig_android_live_encore_production_universe,ig_stories_music_sticker,ig_android_stories_teach_gallery_location,ig_android_http_stack_experiment_2017,ig_android_stories_device_tilt,ig_android_pending_request_search_bar,ig_android_fb_topsearch_sgp_fork_request,ig_android_seen_state_with_view_info,ig_android_animation_perf_reporter_timeout,ig_android_new_block_flow,ig_android_story_tray_title_play_all_v2,ig_android_direct_address_links,ig_android_stories_archive_universe,ig_android_save_collections_cover_photo,ig_android_live_webrtc_livewith_production,ig_android_sign_video_url,ig_android_stories_video_prefetch_kb,ig_android_stories_create_flow_favorites_tooltip,ig_android_live_stop_broadcast_on_404,ig_android_live_viewer_invite_universe,ig_android_promotion_feedback_channel,ig_android_render_iframe_interval,ig_android_accessibility_logging_universe,ig_android_camera_shortcut_universe,ig_android_use_one_cookie_store_per_user_override,ig_profile_holdout_2017_universe,ig_android_stories_server_brushes,ig_android_ad_media_url_logging_universe,ig_android_shopping_tag_nux_text_universe,ig_android_comments_single_reply_universe,ig_android_stories_video_loading_spinner_improvements,ig_android_collections_cache,ig_android_comment_api_spam_universe,ig_android_facebook_twitter_profile_photos,ig_android_shopping_tag_creation_universe,ig_story_camera_reverse_video_experiment,ig_android_direct_bump_selected_recipients,ig_android_ad_cta_haptic_feedback_universe,ig_android_vertical_share_sheet_experiment,ig_android_family_bridge_share,ig_android_search,ig_android_insta_video_consumption_titles,ig_android_stories_gallery_preview_button,ig_android_fb_auth_education,ig_android_camera_universe,ig_android_me_only_universe,ig_android_instavideo_audio_only_mode,ig_android_user_profile_chaining_icon,ig_android_live_video_reactions_consumption_universe,ig_android_stories_hashtag_text,ig_android_post_live_badge_universe,ig_android_swipe_fragment_container,ig_android_search_users_universe,ig_android_live_save_to_camera_roll_universe,ig_creation_growth_holdout,ig_android_sticker_region_tracking,ig_android_unified_inbox,ig_android_live_new_watch_time,ig_android_offline_main_feed_10_11,ig_import_biz_contact_to_page,ig_android_live_encore_consumption_universe,ig_android_experimental_filters,ig_android_search_client_matching_2,ig_android_react_native_inline_insights_v2,ig_android_business_conversion_value_prop_v2,ig_android_redirect_to_low_latency_universe,ig_android_ad_show_new_awr_universe,ig_family_bridges_holdout_universe,ig_android_background_explore_fetch,ig_android_following_follower_social_context,ig_android_video_keep_screen_on,ig_android_ad_leadgen_relay_modern,ig_android_profile_photo_as_media,ig_android_insta_video_consumption_infra,ig_android_ad_watchlead_universe,ig_android_direct_prefetch_direct_story_json,ig_android_shopping_react_native,ig_android_top_live_profile_pics_universe,ig_android_direct_phone_number_links,ig_android_stories_weblink_creation,ig_android_direct_search_new_thread_universe,ig_android_histogram_reporter,ig_android_direct_on_profile_universe,ig_android_network_cancellation,ig_android_background_reel_fetch,ig_android_react_native_insights,ig_android_insta_video_audio_encoder,ig_android_family_bridge_bookmarks,ig_android_data_usage_network_layer,ig_android_universal_instagram_deep_links,ig_android_dash_for_vod_universe,ig_android_modular_tab_discover_people_redesign,ig_android_mas_sticker_upsell_dialog_universe,ig_android_ad_add_per_event_counter_to_logging_event,ig_android_sticky_header_top_chrome_optimization,ig_android_rtl,ig_android_biz_conversion_page_pre_select,ig_android_promote_from_profile_button,ig_android_live_broadcaster_invite_universe,ig_android_share_spinner,ig_android_text_action,ig_android_own_reel_title_universe,ig_promotions_unit_in_insights_landing_page,ig_android_business_settings_header_univ,ig_android_save_longpress_tooltip,ig_android_constrain_image_size_universe,ig_android_business_new_graphql_endpoint_universe,ig_ranking_following,ig_android_stories_profile_camera_entry_point,ig_android_universe_reel_video_production,ig_android_power_metrics,ig_android_sfplt,ig_android_offline_hashtag_feed,ig_android_live_skin_smooth,ig_android_direct_inbox_search,ig_android_stories_posting_offline_ui,ig_android_sidecar_video_upload_universe,ig_android_promotion_manager_entry_point_universe,ig_android_direct_reply_audience_upgrade,ig_android_swipe_navigation_x_angle_universe,ig_android_offline_mode_holdout,ig_android_live_send_user_location,ig_android_direct_fetch_before_push_notif,ig_android_non_square_first,ig_android_insta_video_drawing,ig_android_swipeablefilters_universe,ig_android_live_notification_control_universe,ig_android_analytics_logger_running_background_universe,ig_android_save_all,ig_android_reel_viewer_data_buffer_size,ig_direct_quality_holdout_universe,ig_android_family_bridge_discover,ig_android_react_native_restart_after_error_universe,ig_android_startup_manager,ig_story_tray_peek_content_universe,ig_android_profile,ig_android_high_res_upload_2,ig_android_http_service_same_thread,ig_android_scroll_to_dismiss_keyboard,ig_android_remove_followers_universe,ig_android_skip_video_render,ig_android_story_timestamps,ig_android_live_viewer_comment_prompt_universe,ig_profile_holdout_universe,ig_android_react_native_insights_grid_view,ig_stories_selfie_sticker,ig_android_stories_reply_composer_redesign,ig_android_streamline_page_creation,ig_explore_netego,ig_android_ig4b_connect_fb_button_universe,ig_android_feed_util_rect_optimization,ig_android_rendering_controls,ig_android_os_version_blocking,ig_android_encoder_width_safe_multiple_16,ig_search_new_bootstrap_holdout_universe,ig_android_snippets_profile_nux,ig_android_e2e_optimization_universe,ig_android_comments_logging_universe,ig_shopping_insights,ig_android_save_collections,ig_android_live_see_fewer_videos_like_this_universe,ig_android_show_new_contact_import_dialog,ig_android_live_view_profile_from_comments_universe,ig_fbns_blocked,ig_formats_and_feedbacks_holdout_universe,ig_android_reduce_view_pager_buffer,ig_android_instavideo_periodic_notif,ig_search_user_auto_complete_cache_sync_ttl,ig_android_marauder_update_frequency,ig_android_suggest_password_reset_on_oneclick_login,ig_android_promotion_entry_from_ads_manager_universe,ig_android_live_special_codec_size_list,ig_android_enable_share_to_messenger,ig_android_background_main_feed_fetch,ig_android_live_video_reactions_creation_universe,ig_android_channels_home,ig_android_sidecar_gallery_universe,ig_android_upload_reliability_universe,ig_migrate_mediav2_universe,ig_android_insta_video_broadcaster_infra_perf,ig_android_business_conversion_social_context,android_ig_fbns_kill_switch,ig_android_live_webrtc_livewith_consumption,ig_android_destroy_swipe_fragment,ig_android_react_native_universe_kill_switch,ig_android_stories_book_universe,ig_android_all_videoplayback_persisting_sound,ig_android_draw_eraser_universe,ig_direct_search_new_bootstrap_holdout_universe,ig_android_cache_layer_bytes_threshold,ig_android_search_hash_tag_and_username_universe,ig_android_business_promotion,ig_android_direct_search_recipients_controller_universe,ig_android_ad_show_full_name_universe,ig_android_anrwatchdog,ig_android_qp_kill_switch,ig_android_2fac,ig_direct_bypass_group_size_limit_universe,ig_android_promote_simplified_flow,ig_android_share_to_whatsapp,ig_android_hide_bottom_nav_bar_on_discover_people,ig_fbns_dump_ids,ig_android_hands_free_before_reverse,ig_android_skywalker_live_event_start_end,ig_android_live_join_comment_ui_change,ig_android_direct_search_story_recipients_universe,ig_android_direct_full_size_gallery_upload,ig_android_ad_browser_gesture_control,ig_channel_server_experiments,ig_android_video_cover_frame_from_original_as_fallback,ig_android_ad_watchinstall_universe,ig_android_ad_viewability_logging_universe,ig_android_new_optic,ig_android_direct_visual_replies,ig_android_stories_search_reel_mentions_universe,ig_android_threaded_comments_universe,ig_android_mark_reel_seen_on_Swipe_forward,ig_internal_ui_for_lazy_loaded_modules_experiment,ig_fbns_shared,ig_android_capture_slowmo_mode,ig_android_live_viewers_list_search_bar,ig_android_video_single_surface,ig_android_offline_reel_feed,ig_android_video_download_logging,ig_android_last_editAs,ig_android_exoplayer_4142,ig_android_post_live_viewer_count_privacy_universe,ig_android_activity_feed_click_state,ig_android_snippets_haptic_feedback,ig_android_gl_drawing_marks_after_undo_backing,ig_android_mark_seen_state_on_viewed_impression,ig_android_live_backgrounded_reminder_universe,ig_android_live_hide_viewer_nux_universe,ig_android_live_monotonic_pts,ig_android_search_top_search_surface_universe,ig_android_user_detail_endpoint,ig_android_location_media_count_exp_ig,ig_android_comment_tweaks_universe,ig_android_ad_watchmore_entry_point_universe,ig_android_top_live_notification_universe,ig_android_add_to_last_post,ig_save_insights,ig_android_live_enhanced_end_screen_universe,ig_android_ad_add_counter_to_logging_event,ig_android_blue_token_conversion_universe,ig_android_exoplayer_settings,ig_android_progressive_jpeg,ig_android_offline_story_stickers,ig_android_gqls_typing_indicator,ig_android_chaining_button_tooltip,ig_android_video_prefetch_for_connectivity_type,ig_android_use_exo_cache_for_progressive,ig_android_samsung_app_badging,ig_android_ad_holdout_watchandmore_universe,ig_android_offline_commenting,ig_direct_stories_recipient_picker_button,ig_insights_feedback_channel_universe,ig_android_insta_video_abr_resize,ig_android_insta_video_sound_always_on"

; логин
HTTP.Open("POST", API_URL "accounts/login/", true)
HTTP.SetRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
HTTP.SetRequestHeader("Connection", "close")
HTTP.SetRequestHeader("Accept", "*/*")
HTTP.SetRequestHeader("Cookie2", "$Version=1")
HTTP.SetRequestHeader("Accept-Language", "en-US")
HTTP.SetRequestHeader("User-Agent", USER_AGENT)
HTTP.Send(Signature)
HTTP.WaitForResponse()

; инициализация экспериментов
username_id := RegexReplace(HTTP.getAllResponseHeaders, "s)^.*Set-Cookie: ds_user_id=(.+?);.*$", "$1")
csrftoken := RegexReplace(HTTP.getAllResponseHeaders, "s)^.*Set-Cookie: csrftoken=(.+?);.*$", "$1")
data := "{""_uuid"": """ uuid """, ""_uid"": """ username_id """, ""id"": """ username_id """, ""_csrftoken"": """ csrftoken """, ""experiments"": """ EXPERIMENTS """}"
Signature := "ig_sig_key_version=" SIG_KEY_VERSION "&signed_body=" HMAC(IG_SIG_KEY, data, "SHA256") "." UriEncode(data)

HTTP.Open("POST", API_URL "qe/sync/", true)
HTTP.SetRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
HTTP.SetRequestHeader("Connection", "close")
HTTP.SetRequestHeader("Accept", "*/*")
HTTP.SetRequestHeader("Cookie2", "$Version=1")
HTTP.SetRequestHeader("Accept-Language", "en-US")
HTTP.SetRequestHeader("User-Agent", USER_AGENT)
HTTP.Send(Signature)
HTTP.WaitForResponse()
msgbox % HTTP.responsetext

Должен прийти JSON, с настройками экспериментов.
Чтобы в JSON получать информацию о дочерних комментариях нужно отправлять с таким параметром :

can_support_threading=true
HTTP.Open("GET", API_URL "media/" mediaId "/comments/?max_id=" n "&can_support_threading=true", true)

46

Re: AHK: Instagram API

"Эксперимент" удался, но вот инфа о дочерних комментариях не выводится — JSON в точности такой, каким был до этого. У Вас именно так срабатывает? —

HTTP.Open("GET", API_URL "media/" mediaId "/comments/?max_id=" n "&can_support_threading=true", true)

47

Re: AHK: Instagram API

У меня в каждом комментарии появляется ключ child_count... что-то там.
А вы с своем аккаунте телефон вписали, активизировали?
Может это влияет?
Фиды пользователя:

HTTP.Open("GET", API_URL "feed/user/" user_id, true)

Вот тут более-менее внятно написано о методах:
https://instagram-private-api.readthedo … index.html

+ DD

48 (изменено: DD, 2019-08-09 03:18:35)

Re: AHK: Instagram API

Сам я телефон не вписывал, не активизировал. Как это сделать?
Если верно запустил — по Вашему коду такой ответ:

{"items": [], "num_results": 0, "status": "ok"}

49

Re: AHK: Instagram API

В профиле в своём через броузер.
Наверное что-то не так делаете - выберите чей-нибудь профиль, посмотрите его ай-ди (через онлайн сервисы либо через справку, которую я вам дал по ссылке) и эксперементируйте.

50

Re: AHK: Instagram API

Вы имели в виду, привязывал ли я номер телефона к аккаунту? Это да.

51 (изменено: DD, 2019-08-09 05:06:38)

Re: AHK: Instagram API

Видимо через мой профиль не было результата, потому что он пуст, но через айди чужих профилей тредовые комментарии выводятся. Но когда скачиваю с mediaId

HTTP.Open("GET", API_URL "media/" mediaId "/comments/?max_id=" n "&can_support_threading=true", true)

JSON приходит в формате без тредовых комментариев, как в коде по ссылке.

52

Re: AHK: Instagram API

Замените:

USER_AGENT := "Instagram 10.26.0 Android (" DEVICE_SETTINTS["android_version"] "/" DEVICE_SETTINTS["android_release"] "; 320dpi; 720x1280; " DEVICE_SETTINTS["manufacturer"] "; " DEVICE_SETTINTS["model"] "; armani; qcom; en_US)"
IG_SIG_KEY := "4f8732eb9ba7d1c8e8897a75d6474d4eb3f5279137431b2aafb71fafe2abe178"

на

USER_AGENT := "Instagram 85.0.0.21.100 Android (" DEVICE_SETTINTS["android_version"] "/" DEVICE_SETTINTS["android_release"] "; 320dpi; 720x1280; " DEVICE_SETTINTS["manufacturer"] "; " DEVICE_SETTINTS["model"] "; armani; qcom; en_US)"
IG_SIG_KEY := "937463b5272b5d60e9d20f0f8d7d192193dd95095a3ad43725d494300a5ea5fc"

На питоне коycтанты устарели.
Надо брать отсюда:
https://github.com/mgp25/Instagram-API/ … stants.php

+ DD

53

Re: AHK: Instagram API

Заработало, спасибо!

54

Re: AHK: Instagram API

Malcev пишет:

У меня в каждом комментарии появляется ключ child_count... что-то там.

Судя по всему, эти вложенные комментарии потребуют дополнительных обращений к АПИ, из-за чего наверно буду пользовать старый USER_AGENT, с легкой JSON-строкой, группируя под-ответы через обработку.

55 (изменено: Malcev, 2019-08-11 17:23:37)

Re: AHK: Instagram API

DD пишет:

Судя по всему, эти вложенные комментарии потребуют дополнительных обращений к АПИ

Требуют. Но ведь в коде всё явно написано:
https://instagram-private-api.readthedo … media.html

DD пишет:

буду пользовать старый USER_AGENT, с легкой JSON-строкой

Описание вэб апи там тоже имеется:
https://instagram-private-api.readthedo … lient.html

+ DD

56

Re: AHK: Instagram API

А если настраивать получение сообщений из Директа — тут об этом? —

Instagram-API-python-master\InstagramAPI\InstagramAPI.py пишет:

    def direct_message(self, text, recipients):
        if type(recipients) != type([]):
            recipients = [str(recipients)]
        recipient_users = '"",""'.join(str(r) for r in recipients)
        endpoint = 'direct_v2/threads/broadcast/text/'
        boundary = self.uuid

57

Re: AHK: Instagram API

Судя по всему да.

58

Re: AHK: Instagram API

Почему-то так ничего не качает:

   HTTP.Open("GET", API_URL "direct_v2/threads/broadcast/text/", true)
   HTTP.SetRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
   HTTP.SetRequestHeader("Connection", "close")
   HTTP.SetRequestHeader("Accept", "*/*")
   HTTP.SetRequestHeader("Cookie", cookies)
   HTTP.SetRequestHeader("Cookie2", "$Version=1")
   HTTP.SetRequestHeader("Accept-Language", "en-US")
   HTTP.SetRequestHeader("User-Agent", USER_AGENT)
   HTTP.Send()
   HTTP.WaitForResponse()
   ResponseText := HTTP.ResponseText
   msgbox % ResponseText

59

Re: AHK: Instagram API

Это функция для отправки.
Ищите нужную вам функцию тут:
https://github.com/mgp25/Instagram-API/ … Direct.php
И потом ее аналог на питоновском коде.

+ DD

60 (изменено: Malcev, 2019-08-28 13:25:21)

Re: AHK: Instagram API

Ну и я бы вообще не полагался на 100% правильность переноса кода с пхп на питон (питоновская библиотека давно не обновлялась) и смотрел бы какие рараметры или постзапросы отправляются в пхп и учтены ли они в питоне.
А лучше всего, конечно, сразу переносить с пхп на ахк.

61

Re: AHK: Instagram API

По какой причине код не скачивает коменты к видосам из закрытых профилей? То есть, если подписаться на пользователя и его профиль будет доступен, потом выбрать любой пост содержащий видео (а не картинку) — то коменты к нему не скачиваются.

62

Re: AHK: Instagram API

По идее все посты закрытого профиля должны либо показываться либо не показываться.

63

Re: AHK: Instagram API

Помню, при загрузке через браузер была разница с видео, картинками и тп, для каждой разновидности медиа нужны были какие-то данные. Вот через instaloader загрузка идёт — и он вроде по тому же принципу через API работает.

64

Re: AHK: Instagram API

Я сомневаюсь, что кто-то кроме вас тут на форуме этот апи использует, поэтому надо самому тестить и смотреть, когда, что и в каких случаях не приходит.
Браузер использует WEB API, которое, также использует instaloader.
Изначальный же код в теме использует Private API.

65 (изменено: DD, 2020-03-27 21:26:18)

Re: AHK: Instagram API

Странное дело. Если войти в профиль закрытой группы (недоступную для неподписанных пользователей), открыть первое видео, потом из кода этой страницы там же в браузере достать значение "instagram://media?id=" и подставить в следующую ссылку вместо нулей, открыв через адресную строку браузера —


https://i.instagram.com/api/v1/media/0000000000000000000/comments/?max_id=1

то для таких свежих видео коменты будут нормально выведены в браузере в json формате. Но если спуститься ниже в профиле и открыть какое-нибудь старое видео из той же группы, то будет сообщение "Media is unavailable". Уже к видео за 5 марта коменты у меня переставали выводится, не говоря о более старых — за прошлый-позапрошлый год и тп. При этом с картинками проблем нет. С чем это может быть связано?

66

Re: AHK: Instagram API

Я не пользовался инстаграмом для закрытых групп.
Может ограничение у АПИ такое.
Может IG_SIG_KEY устарел и надо новый отправлять.
https://github.com/adrifkat/instagram-api
Или, например, каждый раз ACCESS_TOKEN отправлять.
https://www.instagram.com/developer/endpoints/

67

Re: AHK: Instagram API

Еще можно попробовать max_id заменить на min_id.

68

Re: AHK: Instagram API

А если у меня через куки происходит вход и IG_SIG_KEY вообще не бывает задействован? 

С min_id и ACCESS_TOKEN не работает, проверял так (подставив нужное):


https://api.instagram.com/v1/media/{media-id}/comments?access_token=ACCESS-TOKEN

69

Re: AHK: Instagram API

ХЗ. Я только помню, что со старым IG_SIG_KEY вам не приходили комментарии треда.