Tweet a picture with OAuth - twitter

I am using the following code for Tweeting pictures with OAuth. I have found this identical code in several tutorials however I cant get it to work while no errors occur.
<?php
// Insert your keys/tokens
$consumerKey = '***';
$consumerSecret = '***';
$OAuthToken = '***';
$OAuthSecret = '***';
// Full path to twitterOAuth.php (change OAuth to your own path)
require_once('connect/twitter/twitteroauth.php');
$params = array(
'status' => 'Testing API http://google.com',
'media[]' => 'http://diit.cz/sites/default/files/google_chrome_logo.png'
);
// create new instance
$tweet = new TwitterOAuth($consumerKey, $consumerSecret, $OAuthToken, $OAuthSecret);
// Send tweet
$tweet->post('statuses/update', $params);
?>
Just to be sure. Shall the $OAuthToken and $OAuthSecret be copied from Twitter dev? Or are these variables different for each individual user?
I have checked so far for errors in copying twitter keys and secrets, checked whether the twitteroatuh.php file is properly linked, checked whether my Twitter App is set to Read/Write permissions, checked whether cURL is enabled on my server.
Upon executing this code, no errors occur and nothing is posted to my Twitter.

Related

Hiding YouTube API for client using server

My inexperience has left me short of understanding how to hide an API Key. Sorry, but I've been away from web development for 15 years as I specialized in relational databases, and a lot has changed.
I've read a ton of articles, but don't understand how to take advantage of them. I want to put my YouTube API key(s) on the server, but have the client able to use them w/o exposure. I don't understand how setting an API Key on my server (ISP provided) enables the client to access the YouTube channel associated with the project. Can someone explain this to me?
I am not sure what you want to do but for a project I worked on I needed to get a specific playlist from YouTube and make the contents public to the visitors of the website.
What I did is a sort of proxy. I set up a php file contains the api key, and then have the end user get the YT content through this php file.
The php file gets the content form YT using curl.
I hope it helps.
EDIT 1
The way to hide the key is to put it in a PHP file on the server.
This PHP file will the one connecting to youtube and retrieving the data you want on your client page.
This example of code, with the correct api key and correct playlist id will get a json file with the 10 first tracks of the play list.
The $resp will have the json data. To extract it, it has to be decoded for example into an associative array. Once in the array it can be easily mixed in to the html that will be rendered on the client browser.
<?php
$apiKey = "AIza...";
$results = "10";
$playList = "PL0WeB6UKDIHRyXXXXXXXXXX...";
$request = "https://www.googleapis.com/youtube/v3/playlistItems?part=id,contentDetails,snippet&maxResults=" . $results .
"&fields=items(contentDetails%2FvideoId%2Cid%2Csnippet(position%2CpublishedAt%2Cthumbnails%2Fdefault%2Ctitle))" .
"&playlistId=" . $playList .
"&key=" . $apiKey;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $request,
CURLOPT_SSL_VERIFYPEER => false
));
$resp = curl_exec($curl);
if (curl_errno($curl)) {
$status = "CURL_ERROR";
}else{
// check the HTTP status code of the request
$resultStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($resultStatus == 200) {
$status = "OK";
//Do something with the $resp which is in JSON format.
//Like decoding it into an associative array
} else {
$status = "YT_ERROR";
}
}
curl_close($curl);
?>
<html>
<!-- your html here -->
</html>
Note: CURLOPT_SSL_VERIFYPEER is set to false. This is in development. For prod it should be true.
Also note that using the api this way, you can restrict the calls to your api key bounding them to your domain. You do that in the googla api console. (Tip for production)

Why is requesting for authorization of my Twitter app for a new user generating a PIN?

I've created a twitter app and I have all the credentials (access token, secret, consumer key and secret). I'm using Abraham's Twitter Oauth. I've been able to get the application running but I am currently unable to Authorize a new account successfully. Instead, it is requesting for a new user to input a PIN generated after the user has granted access, before the authorization is complete.
I've done some lookup on the internet and it pointed out to Twitter.com's manual here and here. From what I've been able to read up, Implementing a desktop sign in request requires oauth_callback value. I've tried to add a value to this parameter, but it returns an error: Fatal error: Uncaught exception 'Abraham\TwitterOAuth\TwitterOAuthException' with message '<?xml version="1.0" encoding="UTF-8"?> <hash> <error>Desktop applications only support the oauth_callback value 'oob'</error> <request>/oauth/request_token</request> </hash> ', but if I don't add a value to the oauth_callback parameter, it redirects to Twitter.com's authorization page successfully, but then, generates a PIN which will be required to be filled in the application.
I sincerely do not know how to go round this, any help will be much appreciated.
Here's my code below:
require_once "twitteroauth/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;
//Check if form was submitted
if(isset($_GET['activate-account']) && $_GET['activate-account'] == 'true'){
session_start();
//Get App Details (Consumer key and secret) from DB
$appID = 1;
$consumerKey = getAutoTweetPart($appID, 'consumer_key');
$consumerSecret = getAutoTweetPart($appID, 'consumer_secret');
$callBack = '';
$connection = new TwitterOAuth($consumerKey, $consumerSecret);
$request_token = $connection->oauth('oauth/request_token', array('oauth_callback' => $callBack));
$_SESSION['oauth_token'] = $request_token['oauth_token'];
$_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret'];
$url = $connection->url('oauth/authorize', array('oauth_token' => $request_token['oauth_token']));
header('Location: '. $url);
}
You should check that your app (linked from https://apps.twitter.com) has a callback URL specified, so that you are not using desktop mode. The callback URL should not be locked unless it is always the same e.g. constant host/port.
Then your request_token call can specify the URL you want the user redirected to.
This is part of the flow described here https://dev.twitter.com/web/sign-in/implementing

Gmail API returns 403 error code and "Delegation denied for <user email>"

Gmail API fails for one domain when retrieving messages with this error:
com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 OK
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Delegation denied for <user email>",
"reason" : "forbidden"
} ],
"message" : "Delegation denied for <user email>"
}
I am using OAuth 2.0 and Google Apps Domain-Wide delegation of authority to access the user data. The domain has granted data access rights to the application.
Seems like best thing to do is to just always have userId="me" in your requests. That tells the API to just use the authenticated user's mailbox--no need to rely on email addresses.
I had the same issue before, the solution is super tricky, you need to impersonate the person you need to access gmail content first, then use userId='me' to run the query. It works for me.
here is some sample code:
users = # coming from directory service
for user in users:
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
####IMPORTANT######
credentials_delegated = credentials.with_subject(user['primaryEmail'])
gmail_service = build('gmail', 'v1', credentials=credentials_delegated)
results = gmail_service.users().labels().list(userId='me').execute()
labels = results.get('labels', [])
for label in labels:
print(label['name'])
Our users had migrated into a domain and their account had aliases attached to it. We needed to default the SendAs address to one of the imported aliases and want a way to automate it. The Gmail API looked like the solution, but our privileged user with roles to make changes to the accounts was not working - we kept seeing the "Delegation denied for " 403 error.
Here is a PHP example of how we were able to list their SendAs settings.
<?PHP
//
// Description:
// List the user's SendAs addresses.
//
// Documentation:
// https://developers.google.com/gmail/api/v1/reference/users/settings/sendAs
// https://developers.google.com/gmail/api/v1/reference/users/settings/sendAs/list
//
// Local Path:
// /path/to/api/vendor/google/apiclient-services/src/Google/Service/Gmail.php
// /path/to/api/vendor/google/apiclient-services/src/Google/Service/Gmail/Resource/UsersSettingsSendAs.php
//
// Version:
// Google_Client::LIBVER == 2.1.1
//
require_once $API_PATH . '/path/to/google-api-php-client/vendor/autoload.php';
date_default_timezone_set('America/Los_Angeles');
// this is the service account json file used to make api calls within our domain
$serviceAccount = '/path/to/service-account-with-domain-wide-delagation.json';
putenv('GOOGLE_APPLICATION_CREDENTIALS=' . $serviceAccount );
$userKey = 'someuser#my.domain';
// In the Admin Directory API, we may do things like create accounts with
// an account having roles to make changes. With the Gmail API, we cannot
// use those accounts to make changes. Instead, we impersonate
// the user to manage their account.
$impersonateUser = $userKey;
// these are the scope(s) used.
define('SCOPES', implode(' ', array( Google_Service_Gmail::GMAIL_SETTINGS_BASIC ) ) );
$client = new Google_Client();
$client->useApplicationDefaultCredentials(); // loads whats in that json service account file.
$client->setScopes(SCOPES); // adds the scopes
$client->setSubject($impersonateUser); // account authorized to perform operation
$gmailObj = new Google_Service_Gmail($client);
$res = $gmailObj->users_settings_sendAs->listUsersSettingsSendAs($userKey);
print_r($res);
?>
I wanted to access the emails of fresh email id/account but what happened was, the recently created folder with '.credentials' containing a JSON was associated with the previous email id/account which I tried earlier. The access token and other parameters present in JSON are not associated with new email id/account. So, in order make it run you just have to delete the '.credentails' folder and run the program again. Now, the program opens the browser and asks you to give permissions.
To delete the folder containing files in python
import shutil
shutil.rmtree("path of the folder to be deleted")
you may add this at the end of the program
Recently I started exploring Gmail API and I am following the same approach as Guo mentioned. However, it is going to take of time and too many calls when we the number of users or more. After domain wide delegation my expectation was admin id will be able to access the delegated inboxes, but seems like we need to create service for each user.

google drive sdk/google drive api ----using PHP web application

I am creating website page using Google drive API which do following stuff:--
provide user set of pdf file which is stored in my Google drive without any type of Login / authentication by any means and file are public.
who visit that page and if he/she want to download that file/pdf then he/she can do so just by clicking on it without any signup and login.
i have no idea how to getting started with it...is it necessary to use OAuth 2...
in simple word i want to use google drive as file hosting site to host my file and reach users through website.
please give me your valuable solution...
thanks
For php look here for a full example and video. You have to download the Google Drive API for the programming language you are using. Then use that API to help you auth and access files. Here is an example from Google developers page using PHP
<?php
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_DriveService.php';
$client = new Google_Client();
// Get your credentials from the console
$client->setClientId('YOUR_CLIENT_ID');
$client->setClientSecret('YOUR_CLIENT_SECRET');
$client->setRedirectUri('urn:ietf:wg:oauth:2.0:oob');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$service = new Google_DriveService($client);
$authUrl = $client->createAuthUrl();
//Request authorization
print "Please visit:\n$authUrl\n\n";
print "Please enter the auth code:\n";
$authCode = trim(fgets(STDIN));
// Exchange authorization code for access token
$accessToken = $client->authenticate($authCode);
$client->setAccessToken($accessToken);
//Insert a file
$file = new Google_DriveFile();
$file->setTitle('My document');
$file->setDescription('A test document');
$file->setMimeType('text/plain');
$data = file_get_contents('document.txt');
$createdFile = $service->files->insert($file, array(
'data' => $data,
'mimeType' => 'text/plain',
));
print_r($createdFile);
?>
You will want to use the PHP client library located here: https://developers.google.com/api-client-library/php/
You will then want to authenticate against google using auth2.
Then you can make calls to the Drive API https://developers.google.com/drive/v2/reference/ using the PHP client library.

How to post statuses for users whos allow it for my application?

On my website, i want to allow for users, who is authorized with twitter, to post review on their own wall(page) in twitter, with my application.
I can do it for my page like this
$connection = new Twitter_TwitterOAuth(
$this->config->twitter->consumer_key,
$this->config->twitter->consumer_secret,
$this->config->twitter->token,
$this->config->twitter->token_secret
);
$connection->post('statuses/update', array('status' => $data['text'] . $data['name'] . "." . chr(13) . chr(10) . "More details " . $data['link'] .'?review='. $data['id']));
So what i need to do to post the same for another accounts ? i need to set account(where i want to post status with application) ID or i need to set other
$this->config->twitter->token,
$this->config->twitter->token_secret
with token and token_secret that i receive when user login with my application ?
Thanks for help.
for another account you should sleep(//someseconds); if you don't have a throttle in that library, then do the same for the other account. It looks like the account is yours, because in the code you posted I see so authorization from the user (callback). If my guess is right and you're using app authorization, you need to have authorized your own app with your other account, so ideally there should be no need to reset the tokens. If it doesn't work, try to reset them. If it still doesn't work, a trick is to have two applications (each account has an application, each account uses its own app to post). However, please bear in mind that a) Twitter counts the overall number of calls from your server and b) I'm not sure they like multiple accounts.
EDIT: if instead you need to post for users who have authorized your app and are currently online on your website, just store their tokens in a session (as Abraham Williams does in his library). In that case, you need to reset the variables to reflect the change of the tokens. Sample code, by Williams:
/* Get user access tokens out of the session. */
$access_token = $_SESSION['access_token'];
$access_token_secret = $_SESSION["access_token_secret"];
/* Create a TwitterOauth object with consumer/user tokens. */
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token,
$access_token_secret);
$message ="your message";
$parameters = (array('status' =>$message));
$status = $connection->post('statuses/update', $parameters);
twitteroauth_row('statuses/update', $status, $connection->http_code, $parameters);
if ($http_code = 200){
// echo "Done!";
} else {
// echo "Oops!";
}

Resources