-
-
Save afilhodaniel/09a1df8eafeabe1584c6 to your computer and use it in GitHub Desktop.
class InstagramPrivateController < ApplicationController | |
def initialize(username, password, photo, caption) | |
@username = username | |
@password = password | |
@photo = photo | |
@caption = caption | |
@cookiepath = Tempfile.new('cookies').path | |
@user_agent = generate_user_agent() | |
@guid = generate_guid() | |
@device_id = generate_device_id(@guid) | |
end | |
def send | |
login = login() | |
if login['status'] == 'ok' | |
media = upload() | |
if media['status'] == 'ok' | |
configure = configure(media['media_id']) | |
return configure | |
end | |
return media | |
end | |
return login | |
end | |
def generate_user_agent | |
resolution = ['720x1280', '320x480', '480x800', '1024x768', '1280x720', '768x1024', '480x320'].sample | |
version = ['GT-N7000', 'SM-N9000', 'GT-I9220', 'GT-I9100'].sample | |
dpi = ['120', '160', '320', '240'].sample | |
return 'Instagram 4.' + rand(1..2).to_s + '.' + rand(0..2).to_s + ' Android (' + rand(10..11).to_s + '/' + rand(1..3).to_s + '.' + rand(3..5).to_s + '.' + rand(0..5).to_s + '; #{dpi}; #{resolution}; samsung; #{version }; #{version}; smdkc210; en_US)' | |
end | |
def generate_guid | |
guid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', | |
rand(0..65535), | |
rand(0..65535), | |
rand(0..65535), | |
rand(16384..20479), | |
rand(32768..49151), | |
rand(0..65535), | |
rand(0..65535), | |
rand(0..65535)) | |
return guid | |
end | |
def generate_device_id(guid) | |
return 'android-#{guid}' | |
end | |
def generate_signature(data) | |
return OpenSSL::HMAC.hexdigest('sha256', 'b4a23f5e39b5929e0666ac5de94c89d1618a2916', data) | |
end | |
def request(url, data, upload, cookies) | |
http = Curl::Easy.new(url) | |
http.headers["User-Agent"] = @user_agent | |
http.multipart_form_post = upload | |
http.verbose = true | |
http.follow_location = true | |
http.enable_cookies = true | |
if cookies | |
http.cookiefile = @cookiepath | |
else | |
http.cookiejar = @cookiepath | |
end | |
if data.kind_of?(Array) | |
http.send('post', *data) | |
else | |
http.send('post', data) | |
end | |
response = JSON.parse(http.body) | |
http.close | |
return response | |
end | |
def login | |
url = 'https://instagram.com/api/v1/accounts/login/' | |
data = "{'username':'#{@username}','password':'#{@password}','guid':'#{@guid}','device_id':'#{@device_id}','Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}".gsub("'", '"') | |
signature = generate_signature(data) | |
body = 'ig_sig_key_version=4&signed_body=' + signature + '.' + URI::encode(data, /\W/) | |
response = request(url, body, false, false) | |
return response | |
end | |
def upload | |
url = 'https://instagram.com/api/v1/media/upload/' | |
device_timestamp = Time.now.to_i.to_s | |
data = [ | |
Curl::PostField.file('photo', @photo), | |
Curl::PostField.content('device_timestamp', device_timestamp) | |
] | |
response = request(url, data, true, true) | |
return response | |
end | |
def configure(media_id) | |
url = 'https://instagram.com/api/v1/media/configure/' | |
device_timestamp = Time.now.to_i.to_s | |
data = "{'guid':'#{@guid}','device_id':'#{@device_id}','device_timestamp':'#{device_timestamp}','media_id':'#{media_id}','caption':'#{@caption}','source_type':'5','filter_type':'0','extra':'{}','Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'}".gsub("'", '"') | |
signature = generate_signature(data) | |
body = 'ig_sig_key_version=4&signed_body=' + signature + '.' + URI::encode(data, /\W/) | |
response = request(url, body, false, true) | |
return response | |
end | |
end | |
Fonts: | |
http://lancenewman.me/posting-a-photo-to-instagram-without-a-phone/ | |
http://mokhdzanifaeq.github.io/reverse-engineering-instagram-private-api/ |
@lastbench I made my C# implementation based on the original PHP implementation by Lance Newman. I was suspecting that this was a flaw in my implementation, but I just tested the original code and it shows the same behavior. I've been spending quite a few hours in Fiddler trying to figure out why my phone can post images just fine and my application can't.
I haven't tested this particular Ruby implementation. I was just wondering if the author had experienced the same issue.
And if you ask me this shouldn't be a model or a controller. Instead it should be a separate service that you can inject into your controller.
@aclemmensen I would like to see your C# version. I wonder how you worked with the http requests.
// Your version of Instagram is out of date. Please upgrade your app to log in to Instagram.
@newstler How do you fix this?
Hi. Nice code! Thanks! But i have one problem with uploading video to instagram. Tell me pls, how i can fix this error:
configure response: {"status"=>"ok", "media"=>{"upload_id"=>"1453635345"}, "message"=>"media_needs_reupload", "error_title"=>"staged_position_not_found"}
success but SUCCESS: {
"error_title" = "staged_position_not_found";
media = {
"upload_id" = 1453825279;
};
message = "media_needs_reupload";
status = ok;
}
I want the script to video, can anyone?
mgp25 has a similar script that I use yet I also encounter the same media_needs_reupload / staged_position_not_found when I upload videos. I been posting on mgp25's GitHub trying to find a solution yet to find a solution. Some people suggest downgrade to 5.5.3 but that did not fix fyi.
mgp25/Instagram-API#191
mgp25/Instagram-API#185
Nada ainda né? :( 12/12/2018 e ainda nenhuma resolução do problema.
@aclemmensen have you migrated the ruby code to c# or did you use a different algorithm?can you share it if you don't mind?