Subscribe to webhook with PHP CURL command

php
webhooks

#1

How can I subscribe to my webhook by using CURL in PHP? Please guide me.

API :- https://api.twitter.com/1.1/account_activity/webhooks/:webhook_id/subscriptions.json


Not getting direct message on registered webhook
#2

Following is my code but I am not aware what I need to pass for user context auth only.

@abraham Will you please help me to short out the auth issue I am facing with my code.

Each time I am getting error like following

Error: call to token URL https://api.twitter.com/1.1/account_activity/webhooks/546329593564654/subscriptions.json failed with status 400, response {“errors”:[{“code”:215,“message”:“Bad Authentication data.”}]}, curl_error , curl_errno 0

$consumer_key = 'AGFwc3fA8aJSr'; $consumer_secret = 'jnUoybbXsOLwsXIHx7nFDEYxuOy5p1NyAdJ825'; $token = '89777824-VLeK34u2qJPusuMo'; $token_secret = 'kb3uEf4Ve926NVJalE4DLYO1k9cngCEul'; $webhook_id = 546329593564654; $base_uri = 'https://api.twitter.com/1.1/account_activity/webhooks/546329593564654/subscriptions.json';

$nonce = time();
$timestamp = time();
$oauth = array(
‘oauth_consumer_key’ => $consumer_key,
‘oauth_consumer_secret’ => $consumer_secret,
‘oauth_token’ => $token,
‘oauth_token_secret’ => $token_secret,
‘oauth_nonce’ => $nonce,
‘oauth_signature_method’ => ‘HMAC-SHA1’,
‘oauth_timestamp’ => $timestamp,
‘oauth_version’ => ‘1.0’,
‘oauth_verify’ => true);

$fields = array(
‘consumer_key’ => $consumer_key,
‘consumer_secret’ => $consumer_secret,
‘token’ => $token,
‘token_secret’ => $token_secret,
‘webhook_id’ => $webhook_id
);

function buildBaseStringGet($base_uri, $params) {
$temp_array = array();
ksort($params);
foreach($params as $key=>$value){
$temp_array[] = “$key=” . rawurlencode($value);
}
return ‘GET&’ . rawurlencode($base_uri) . ‘&’ . rawurlencode(implode(’&’, $temp_array)); //return complete base string
}

function encodeParams($params) {
$temp_array = array();
ksort($params);
foreach($params as $key=>$value){
$temp_array[] = “$key=” . rawurlencode($value);
}
return implode(’&’, $temp_array);
}

function getCompositeKey($consumer_secret, $request_token){
return rawurlencode($consumer_secret) . ‘&’ . rawurlencode($request_token);
}

function buildAuthorizationHeader($oauth){
$head = 'Authorization: Basic ‘; //header prefix
$values = array();
foreach($oauth as $key=>$value){
$values[] = “$key=”" . rawurlencode($value) . “”";
}
$head .= implode(’, ', $values);
return $head;
}

$base_string = buildBaseStringGet($base_uri, $oauth); //build the base string
$composite_key = getCompositeKey($consumer_secret, null); //first request, no request token yet
$oauth_signature = base64_encode(hash_hmac(‘sha1’, $base_string, $composite_key, true)); //sign the base string
$oauth[‘oauth_signature’] = $oauth_signature; //add the signature to our oauth array

$header = array( buildAuthorizationHeader($oauth)); //create header array and add ‘Expect:’
$fields_string = encodeParams($fields);

$options = array(CURLOPT_HTTPHEADER => $header, //use our authorization and expect header
//CURLOPT_CAINFO => dirname(dirname(FILE)) . ‘/cacert.pem’,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_HEADER => false, //don’t retrieve the header back from Twitter
CURLOPT_URL => $base_uri, //the URI we’re sending the request to
CURLOPT_POST => false, //this is going to be a POST - required
CURLOPT_RETURNTRANSFER => true, //return content as a string, don’t echo out directly
CURLOPT_SSL_VERIFYPEER => false
); //don’t verify SSL certificate, just do it

try {
$ch = curl_init();
curl_setopt_array($ch, $options); //set options
$response = curl_exec($ch);
$result = json_decode($response);
}
//catch exception
catch(Exception $e) {
echo 'Message: ’ .$e->getMessage();
}

$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ( $status != 200 ) {
die("Error: call to token URL $base_uri failed with status $status, response $response, curl_error " . curl_error($ch) . ", curl_errno " . curl_errno($ch));
} else {
print_r($result);
}
curl_close($ch); //hang up


#3

I have made change in header function authorization set Basic to OAuth and set it to below.

function buildAuthorizationHeader($oauth) {
$head = 'Authorization: OAuth ‘; //header prefix
$values = array();
foreach($oauth as $key=>$value){
$values[] = “$key=”" . rawurlencode($value) . “”";
}
$head .= implode(’, ', $values);
return $head;
}

Now I am facing a new error

Error: call to token URL https://api.twitter.com/1.1/account_activity/webhooks/546329593564654/subscriptions.json failed with status 401, response HTTP/1.1 401 Authorization Required cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0 content-disposition: attachment; filename=json.json content-length: 64 content-type: application/json; charset=utf-8 date: Thu, 23 Nov 2017 10:48:13 GMT expires: Tue, 31 Mar 1981 05:00:00 GMT last-modified: Thu, 23 Nov 2017 10:48:13 GMT pragma: no-cache server: tsa_k set-cookie: personalization_id=“v1_asdasdJg654654VAy2UM==”; Expires=Sat, 23 Nov 2019 10:48:13 UTC; Path=/; Domain=.twitter.com set-cookie: guest_id=v1%3A15114347444; Expires=Sat, 23 Nov 2019 10:48:13 UTC; Path=/; Domain=.twitter.com strict-transport-security: max-age=631138519 x-connection-hash: dc89beabd5d7a3ea1dd7981 x-content-type-options: nosniff x-frame-options: SAMEORIGIN x-response-time: 178 x-xss-protection: 1; mode=block {“errors”:[{“code”:32,“message”:“Could not authenticate you.”}]}, curl_error , curl_errno 0


#4

Please help me to understand the auth needed to subscribe the webhook @andypiper & @abraham. I have created a script which is in Nodejs and working fine but I have to code in PHP and I am not able to subscribe to my webhook id. I have passed consumer_key, consumer_secret, token and token_secret urlencoded in the request header. I have passed webhook_id in body but every time I am getting error { “code”: 32, “message”: “Could not authenticate you.” } would you tell me what I am missing here. I have seen the reference for POST account_activity/webhooks/:webhook_id/subscriptions.

There is Authentication required which is user context only What’s the meaning of this. The user has already authorized my app.

Below code is in NodeJs which is working fine but when I am sending request from PHP Curl command it’s not authenticated, user. I have posted my PHP code above.

NODEJS Working code

let twitter_oauth = { consumer_key: env.config.twitter.consumer_key, consumer_secret: env.config.twitter.consumer_secret, token: env.config.twitter.access_token, token_secret: env.config.twitter.access_token_secret } let request_options = { url: 'https://api.twitter.com/1.1/account_activity/webhooks/' + WEBHOOK_ID + '/subscriptions.json', oauth: twitter_oauth }

// POST request to subscribe to webhook
request.post(request_options, function (error, response, body) {
if (response.statusCode == 204) {
console.log(‘Subscription added.’)
} else {
console.log(‘User has not authorized your app.’)
}
})


#5

Did u try the postman example which u had mentioned in earlier thread?

Thanks,
Sajid


#6

@sajidcis

Yes, I did but same error is coming in postman too.


#7

@sajidcis

I want to know about the user context what should be passed in a header to make authentication header as user context. I am just aware of app-only authentication but didn’t find any example related to user context authentication.

What I understood is that I have to pass the oauth_token in a header and create the oauth_signature with a combination of consumer_secret and token.

Let me know if I misunderstood it.

@abraham Can you help me to understand the difference between app-only & user context authorization?


#8

Hi Rahul,
There are few tweeks to your request.

  1. Uncheck all the boxes in the right. (ie…add params,etc)
  2. Update your request

For the start, can you try the GET https://api.twitter.com/1.1/account_activity/webhooks.json API

Later work your way up to POST .

I did a quick test, works flawlessly.

Regards,
Saajid


#9

@tahultagove

Rahul,
Did you try reading this?

https://developer.twitter.com/en/docs/basics/authentication/overview/oauth


#10

Hello Saajid,

I have Nodejs code and PHP code which is working fine for https://api.twitter.com/1.1/account_activity/webhooks.json API and I am able to get my webhookId which is valid true.

POSTMAN:
I have unchecked the right side checkbox and request to GET https://api.twitter.com/1.1/account_activity/webhooks.json API. It’s showing me could not authenticate you. I am not getting why it’s working for you but not for me. As per my knowledge, each param would be encoded.


#11

I have already read that stuff. https://developer.twitter.com/en/docs/basics/authentication/overview/oauth

There is no explanation regarding user context authentication and what should be passed in authentication header while we are requesting to webhook API.


#12

My bad…yes u r right.
Check the encode box.
Also ensure you have not passed anything in body.

Your request should only have

  1. OAuth headers (which the postMan client autormaticcaly does it for u )

Dont specify the conten-type or any other parameters.

  1. Ensure your request body is empty

Regards,
Sajid


#13

I have checked the encode checkbox and there are no params in a body. It worked I got my webhook id with the postman.

What I have to do for post request with user context? I want to subscribe to my webhook.

https://api.twitter.com/1.1/account_activity/webhooks/webhookid:/subscriptions.json


#14

Good…now since GET worked…now try the below

  1. Change your request to POST
  2. Change the url to https://api.twitter.com/1.1/account_activity/webhooks/YOURWEBHOOKID/subscriptions.json

Run your request.

Should work


#15

I have change GET to POST and change the URL, got Following in a response

{
“errors”: [
{
“code”: 215,
“message”: “Bad Authentication data.”
}
]
}


#16

I want to know that how can i use Web hook by using CURL in PHP?