cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Announcements
If you’ve changed your email address, now's the perfect time to update it on your Dropbox account and we’re here to help! Learn more here.

Discuss Dropbox Developer & API

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to use https://api.dropboxapi.com/2/files/copy_reference/save

How to use https://api.dropboxapi.com/2/files/copy_reference/save

Cyri129
New member | Level 2

Hello,

My goal is to transfer a file to DropboxAcc1 to DropboxAcc2 with this API : https://api.dropboxapi.com/2/files/copy_reference/save 

 

 

 

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://api.dropboxapi.com/2/files/copy_reference/get');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Authorization: Bearer ' . $accTemp['access_token'],
        'Content-Type: application/json'
    ));
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array('path' => '/stories/' . $post_filename)));
    $response = curl_exec($ch);
    curl_close($ch);
    $responseData = json_decode($response, true);
    $copy_reference = $responseData['copy_reference'];

 

 

 

 

 

 

 

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, 'https://api.dropboxapi.com/2/files/copy_reference/save');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Authorization: Bearer ' . $token,
            'Content-Type: application/json'
        ));
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array('copy_reference' => $copy_reference, 'path' => $path)));
        $response = curl_exec($ch);
        curl_close($ch);
        $responseData = json_decode($response, true);

 

 

 

 

Everything if i copy a file from DropboxAcc1 to DropboxAcc1 but if i copy to DropboxAcc2 iv got this error :

 

 

 

array(2) {
  ["error_summary"]=>
  string(15) "no_permission/."
  ["error"]=>
  array(1) {
    [".tag"]=>
    string(13) "no_permission"
  }
}

 

 

 

 

I know problem is because of token but i don't understand how to generate a valid token to transfer to DropboxAcc2 :

I have 2 apps : "DB1app" on DropboxAcc1 and "DB2app" on DropboxAcc2

I successfully generate token with oauth workflow on DB1app (source) and DB2app (target).

I authorized DB1app on DropboxAcc2 aswell

 

anyone can help please ?

 

Someone can explain how its works please ?

6 Replies 6

Greg-DB
Dropbox Staff

A 'no_permission' error from /2/files/copy_reference/save means:

no_permissionVoid You don't have permission to save the given copy reference. Please make sure this app is same app which created the copy reference and the source user is still linked to the app.

You mentioned you're using two different apps, so it sounds like that may be the cause. You'll need to instead make sure you're using the same app for both accounts. Additionally, make sure you haven't unlinked the account used to create the copy reference.

 

For example, the flow should work like this:

  • connect DB1app to DropboxAcc1, resulting in AccessToken1
  • use AccessToken1 to call /2/files/copy_reference/get, resulting in CopyReference1
  • connect DB1app (the same app as above) to DropboxAcc2, resulting in AccessToken2
  • use AccessToken2 to call /2/files/copy_reference/save with CopyReference1, resulting in the file being saved to DropboxAcc2

Keep in mind that your access tokens (assuming you aren't using any "team scopes") are specific to a particular app and account pair. You can't change which app or account a particular access token is for.

 

Also, you can only use the "Generate" button on the app's page on the App Console to generate an access token for an app on the particular account that owns the app. You'd need to use the OAuth app authorization flow to get an access token for the same app on the other account. (You can use the OAuth app authorization flow for the app owner account as well.)

 

You can't directly tell which app any given access token or copy reference is for just based on the access token or copy reference, so if you've lost track of which is for which, I recommend you start over and get new access tokens and copy reference(s) using a single app.

Cyri129
New member | Level 2

Hello,

Thanks for the answer, can you please give me more explanations about this : 

  • connect DB1app (the same app as above) to DropboxAcc2, resulting in AccessToken2

 

How can i connect my app to 2 differents accounts programmatically :

The only way to do it is like that ? :

Log in my browser with my email password to DropboxAcc1, then use Oauth flow with this code and App1 client_id and client_secret : 

    $tokenUrl = 'https://api.dropboxapi.com/oauth2/token';

    $tokenParams = http_build_query([
        'code' => $authorizationCode,
        'grant_type' => 'authorization_code',
        'client_id' => $clientId,
        'client_secret' => $clientSecret,
        'redirect_uri' => $redirectUri,
    ]);

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $tokenUrl);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $tokenParams);
    curl_setopt($ch, CURLOPT_COOKIESESSION, true);
    curl_setopt($ch, CURLOPT_COOKIEFILE, '');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/x-www-form-urlencoded',
    ]);

    $tokenResponse = curl_exec($ch);
    $tokenResponse = json_decode($tokenResponse, true);
    curl_close($ch);

 

Here i got DropboxAcc1 token and i can get copy_reference of a file on DropboxAcc1

Then :

Logout MANUALLY my browser to DropboxAcc1 and login with DropboxAcc2 informations and use again the php code above.

Now iv got a second token and can use it to save file on DropboxAcc2.

I think i can do it like that, but i need to login and logout manually and this is not what i want...

 

 

Здравко
Legendary | Level 20

Hi @Cyri129,

What you described in the last post is exactly what need to be done. 😉 It's a bit different than your initial post where you're using different applications for different accounts. Take a look and compare your posts. Can you see the difference? In other words, just use the same app key and app secret while changing only your account login.

Hope this sheds additional light.

Cyri129
New member | Level 2

Hello ! 

The problem with my last post is i need to login/out manually, if i want to use APIs its because i want things to be done programmatically.

I don't want to give my password and email to users who will use my app.

 

Or maybe i can refresh (programmatically) both tokens every hours with a CRON and i use refreshed tokens so i need to log in/out account only for the first access token ?

Здравко
Legendary | Level 20

@Cyri129 wrote:

...

I don't want to give my password and email to users who will use my app.

...


Where somebody asked you to give anything to anybody?! 🤷 It's not mentioned, but it's something (just opposite) assumed - anybody credentials (either yours or of your clients) should be keeps in secure place and never be exposed! This includes not only email and password, but also access token, refresh token, and anything else that may identify somebody and/or grant unwanted access.

 


@Cyri129 wrote:

...

Or maybe i can refresh (programmatically) both tokens every hours with a CRON and i use refreshed tokens so i need to log in/out account only for the first access token ?


Congratulations! 😉 That's what it is. You answer your question. Just for clarification: you don't need to "refresh" your token on any fixed period (either using cron job or anything else). When you get any access token, it comes with expires_in field (how long in seconds this token will keep valid). At that time you may calculate the expiration moment (summing current moment and validity period) and left some buffer (let's say 3 minutes - minus 3 minutes). Next, every time you perform some request you can compare current moment with pre-calculated expiration moment. Once the expiration has happened, you may refresh your access token, store the just refreshed token and use it in the ongoing request. Typical validity period is ~4 hours, but better don't keep it into account - it may vary. In such a way you'll do exactly so much refreshes as needed - neither more nor less. That's it.

Hope this helps.

Cyri129
New member | Level 2

 

Thanks for answers !

I think its clear for me now, I will  update my code and see if everything works.

Need more support?
Who's talking

Top contributors to this post

  • User avatar
    Cyri129 New member | Level 2
  • User avatar
    Здравко Legendary | Level 20
What do Dropbox user levels mean?