I'm trying to remove the pooling and integrate webhooks in the process of file conversion. The problem is that the webhook is created but the callback is never called back.
I'm following the instructions from here: https://forge.autodesk.com/en/docs/webhooks/v1/tutorials/create-a-hook-model-derivative/
The web server is started by the following command : ngrok http host-header=rewrite https://localhost:44366
The callback is http://f36a47b8.ngrok.io/derivative and is up and running. Post requests from postman(internal network) and Post requests from external networks (cellular data) are reaching the endpoint and are successfully redirected.
A hook is created:
"hookId": "51897b50-522a-11ea-b885-f34f23e3435e",
"tenant": "c0761189-32dd-4ca3-9e52-3ae400f91651",
"callbackUrl": "http://f36a47b8.ngrok.io/derivative",
"createdBy": "HUpqLPysSUmbFGlhQo0uG8XMqimfQnRG",
"event": "extraction.updated",
"createdDate": "2020-02-18T08:40:29.829+0000",
"system": "derivative",
"creatorType": "Application",
"status": "active",
"scope": {
"workflow": "c0761189-32dd-4ca3-9e52-3ae400f91651"
},
"urn": "urn:adsk.webhooks:events.hook:51897b50-522a-11ea-b885-f34f23e3435e",
"__self__": "/systems/derivative/events/extraction.updated/hooks/51897b50-522a-11ea-b885-f34f23e3435e"
}
Than a call to modelderivative/v2/designdata/job is issued with the following content:
var job = new JobRequest
{
Input = new Input
{
Urn = urnBase64,
},
Output = new Output
{
Formats = new List<Format>
{
new Format
{
Type = "svf",
Views = new List<string> { "2d", "3d" }
}
},
Destination = new Destination { Region = "EMEA" }
},
Misc = new Misc
{
Workflow = workflowId
}
};
The response is success with an urn (like before);
And from that point nothing follows from the webhook. The callback is never reached, even though that within some time the file is converted and it can be loaded in the viewer as before.
I've viewed those topics:
Unable to receive Forge webhooks, or unable to get them to fire
Why is webhook workflow not taken into consideration when creating modelderivative job?
but they didn't helped.
What am i missing ?
It turns out that there is a problem with jobs for derivative API in 'EMEA' region where no callbacks are called when a job finishes. Changing the region to 'us' fixes the issue and callback is hit when a job event occurs.
From the documentation example change the region parameter:
curl -X 'POST' \
-H 'Content-Type: application/json; charset=utf-8' \
-H 'Authorization: Bearer PtnrvrtSRpWwUi3407QhgvqdUVKL' \
-H 'x-ads-force: false' -v 'https://developer.api.autodesk.com/modelderivative/v2/designdata/job' \
-d
'{
"input": {
"urn": "dXJuOmFkc2sub2JqZWN0czpvcy5vYmplY3Q6bW9kZWxkZXJpdmF0aXZlL0E1LnppcA",
"compressedUrn": true,
"rootFilename": "A5.iam"
},
"output": {
"destination": {
"region": "us" <- Change the region form 'EMEA' to 'us'
},
"formats": [
{
"type": "svf",
"views": [
"2d",
"3d"
]
}
]
}
}'
Related
I wanted to know if its possible to perform a file upload request to azure logic app's HTTP listener?
I am not looking for built-in HTTP trigger which makes an HTTP call to the specified URL OR built-in HTTP action which makes an HTTP call to the specified URL
One of the workarounds is through postman. Here is my logic app for your reference
postman request :-
Here is the output :-
Yes, it's possible for an Azure Logic App to receive files via an HTTP POST request. Here is the request body JSON schema to use in the Logic App:
{
"properties": {
"formdata": {
"items": {
"properties": {
"key": {
"type": "string"
},
"type": {
"type": "string"
},
"value": {
"type": "string"
}
},
"required": [
"key",
"value",
"type"
],
"type": "object"
},
"type": "array"
},
"mode": {
"type": "string"
}
},
"type": "object"
}
The Python script below will send a request to the Logic App, including a dictionary of parameters and a separate dictionary associating each filename with its contents.
import requests
import pathlib
attachments = ["path/to/first_file.txt", "path/to/second_file.txt"] # Insert file paths
logic_app_url = "paste_logic_app_url_here" # Insert URL in quote marks
file_dict = {}
for filepath in attachments:
file_dict[pathlib.Path(filepath).name] = open(filepath, 'rb')
payload = {"first_key": "first_val"} # Extra fields to include in your request
response = requests.post(logic_app_url, headers=None, data=payload,
files=file_dict)
I've run the request above, and it works. The request is received and processed by the Logic App. However, I haven't yet figured out how to parse the individual attachments in the Azure Logic App GUI. I think this may require a For Each loop as explained in Microsoft docs. I hope this helps!
I'm successfully creating PR requests in Azure DevOps using API-call.
However, I would like to add the reviewer's name to my PR. As per the sample in the link, I have to add the reviewer id in the body.
So, my question is how to dynamically find the reviewer's id prior to submitting the PR from my project? I was following Pull Request Reviewers and nothing seems coming up to provide me the id based on name.
As per branch policy, I have to add 2 reviewers' name.
{
"sourceRefName": "refs/heads/npaulk/my_work",
"targetRefName": "refs/heads/new_feature",
"title": "A new feature",
"description": "Adding a new feature",
"reviewers": [
{
"id": "d6245f20-2af8-44f4-9451-8107cb2767db"
}
]
}
Like #Krzysztof Madej suggested in his answer, you can use the Subject Query endpoint to search and get the GraphSubject response.
However, the Id values in the GraphSubject response does not work for the IdentityRef Id used as parameter for the Pull Request Reviewers endpoint (used to add Reviewers to an existing pull request).
To get the correct IdentityRef Id, you need to do a GET on the URL from the storageKey.href value in the GraphSubject Response. E.g.:
"storageKey": {
"href": "https://vssps.dev.azure.com/thecodemanual/_apis/Graph/StorageKeys/msa.MDQ5MGM0N2ItODNiNC03MmEzLTk2MzgtZTJhMmNjOTY3NWQ3"
},
The response should look something like this:
"value": "73b67dcb-6969-62f2-8075-99834ae11234",
"_links": {
"self": {
"href": "https://vssps.dev.azure.com/thecodemanual/_apis/Graph/StorageKeys/msa.MDQ5MGM0N2ItODNiNC03MmEzLTk2MzgtZTJhMmNjOTY3NWQ3"
},
"descriptor": {
"href": "https://vssps.dev.azure.com/thecodemanual/_apis/Graph/Descriptors/73b67dcb-6969-62f2-8075-99834ae11234"
}
}
The GUID for value is what you use for IdentityRef.Id. The payload to POST to the Pull Request Reviewers endpoint would look something like this:
[
{
"id": "73b67dcb-6969-62f2-8075-99834ae11234"
}
]
You can use Subject Query Endpoint
POST https://vssps.dev.azure.com/{organization}/_apis/graph/subjectquery?api-version=6.0-preview.1
Body should look like this:
{
"query": "Term to search (e.g. Krzysztof)",
"subjectKind": [ "User" ]
}
and then you will get response like this:
{
"count": 3,
"value": [
{
"subjectKind": "user",
"metaType": "member",
"domain": "Windows Live ID",
"principalName": "mail#mail.com,
"mailAddress": "mail#mail.com",
"origin": "msa",
"originId": "0006BFFDBC3FE9A1",
"displayName": "Krzysztof Madej",
"_links": {
"self": {
"href": "https://vssps.dev.azure.com/thecodemanual/_apis/Graph/Users/msa.MDQ5MGM0N2ItODNiNC03MmEzLTk2MzgtZTJhMmNjOTY3NWQ3"
},
"memberships": {
"href": "https://vssps.dev.azure.com/thecodemanual/_apis/Graph/Memberships/msa.MDQ5MGM0N2ItODNiNC03MmEzLTk2MzgtZTJhMmNjOTY3NWQ3"
},
"membershipState": {
"href": "https://vssps.dev.azure.com/thecodemanual/_apis/Graph/MembershipStates/msa.MDQ5MGM0N2ItODNiNC03MmEzLTk2MzgtZTJhMmNjOTY3NWQ3"
},
"storageKey": {
"href": "https://vssps.dev.azure.com/thecodemanual/_apis/Graph/StorageKeys/msa.MDQ5MGM0N2ItODNiNC03MmEzLTk2MzgtZTJhMmNjOTY3NWQ3"
},
"avatar": {
"href": "https://dev.azure.com/thecodemanual/_apis/GraphProfile/MemberAvatars/msa.MDQ5MGM0N2ItODNiNC03MmEzLTk2MzgtZTJhMmNjOTY3NWQ3"
}
},
"url": "https://vssps.dev.azure.com/thecodemanual/_apis/Graph/Users/msa.MDQ5MGM0N2ItODNiNC03MmEzLTk2MzgtZTJhMmNjOTY3NWQ3",
"descriptor": "msa.MDQ5MGM0N2ItODNiNC03MmEzLTk2MzgtZTJhMmNjOTY3NWQ3"
},
as next ise originId in reviewers collection.
You can use Identities - Read Identities API to get user id. For example:
Get https://vssps.dev.azure.com/{org}/_apis/identities?searchFilter=General&filterValue=cece dong&api-version=6.1-preview.1
I'm using the FullContact Card Reader API. From what I can tell when making a request to process a business card I need to send the FullContact API a image of a business card along with a webhook.
sending script:
<?php
$APIkey = 'my FullContact api key';
$callback_url = 'https://www.my-domain.com/my-callback-listener.php';
$url = "https://api.fullcontact.com/v2/cardReader?format=json&webhookUrl=$callback_url;
$imageAsBase64 = base64_encode(file_get_contents('path-to-image-including-extension'));
$requestBody = array();
$requestBody['front'] = $imageAsBase64;
$connection = curl_init();
curl_setopt($connection, CURLOPT_URL, $url);
curl_setopt($connection, CURLOPT_RETURNTRANSFER, true);
curl_setopt($connection, CURLOPT_POST, true);
curl_setopt($connection, CURLOPT_POSTFIELDS, json_encode($requestBody));
curl_setopt($connection, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'X-FullContact-APIKey: $APIkey'));
$result = curl_exec($connection);
echo json_encode(array('result' => $result));
?>
callback listener script:
<?php
header('HTTP/1.1 200 OK');
?>
I know the sending script is working because the curl result contains an id assigned by the FullContact API. Then, when I reference that id by manually typing the following url into my browser:
https://api.fullcontact.com/v2/cardReader/{id-assigned-from-FullContact}?apiKey={my-FullContact-api-key}
This is what I receive:
{
"id": "id-assigned-from-FullContact",
"lastWebhookAttempt": "2017-03-20T18:41:57.000Z",
"vCardUrl": "https://d1h3f0foa0xzdz.cloudfront.net/2971518/special-link-to-vcf-card.vcf",
"status": "CALLBACK_FAILED",
"webhookAttempts": 5,
"webhookUrl": "https://www.my-domain.com/my-callback-listener.php",
"quality": "LOW",
"submitted": "2017-03-20T18:28:27.000Z",
"contact": {
"photos": [{
"primary": true,
"value": "https://d1h3f0foa0xzdz.cloudfront.net/2971518/special-link-to-image-of-business-card.png",
"type": "BusinessCard"
}],
"organizations": [{
"title": "Senior Sales Consultant",
"isPrimary": true,
"name": "Company ABC"
}],
"name": {
"middleName": null,
"honorificPrefix": null,
"familyName": "Meek",
"givenName": "Jack",
"honorificSuffix": null
},
"emails": [{
"value": "person#something.com",
"type": "Work"
}],
"phoneNumbers": [
{
"value": "+1 123-987-6543 ext. 5159069",
"type": "Work"
},
{
"value": "+1 123-456-6789",
"type": "Mobile"
},
{
"value": "886 123-4567",
"type": "Work Fax"
}
],
"addresses": [{
"region": null,
"streetAddress": "1234 Nowhere Dr,",
"formatted": null,
"postalCode": "48377",
"extendedAddress": null,
"locality": "Novi",
"type": "Work",
"country": "United States"
}]
}
}
You can see in the above result the FullContact API is making 5 attempts to call my callback listener script ultimately resulting in CALLBACK_FAILED. However, my callback script only contains HTTP/1.1 200 OK which should work just fine. This tells me my callback script is not reachable for some reason. My site is being hosted on GoDaddy using their shared hosting platform SSL.
Anyone know if GoDaddy blocks certain webhook traffic? Any help would be appreciated!
I tried reviewing the FullContact documentation but, it failed to provide any clear detail on how there webhooks send back data.
So I ended up reaching out to both my web host (GoDaddy) and FullContact. I have a shared hosting platform with GoDaddy so they restrict a ton of port numbers. FullContact assured me they only use either port 80 or 443.
To solve this one I ended up having to create a local xampp server and make it publicly available. Then I directed FullContact to use my local server as my webhook.
I ran a few tests and used php to pull the ip address, host name, and port number. Here are the results:
Test 1.
Host address: 52.70.48.63
host name: ec2-52-70-48-63.compute-1.amazonaws.com
port#: 63498
Test 2.
Host address: 52.70.48.63
host name: ec2-52-70-48-63.compute-1.amazonaws.com
port#: 4169
Test 3.
Host address: 52.70.48.63
host name: ec2-52-70-48-63.compute-1.amazonaws.com
port#: 61425
All the port number returned are blocked by GoDaddy. The only way for me to receive data back from FullContact was to use my local server. Case Closed. Hope This ended up helping someone someday!
I followed the subscription api(https://www.instagram.com/developer/subscriptions/) and created a subscription request like this:
curl -F 'client_id=clientId' \
-F 'client_secret=clientSecret' \
-F 'object=user' \
-F 'aspect=media' \
-F 'verify_token=my-verify-token' \
-F 'callback_url=https://xx.xx.com/igwh' \
https://api.instagram.com/v1/subscriptions/
and got response as bellow:
{
"meta": {
"code": 200
},
"data": {
"object": "user",
"object_id": null,
"aspect": "media",
"subscription_id": 0,
"callback_url": "https://xx.xx.com/igwh",
"type": "subscription",
"id": 0
}
}
My app is in live mode, so is that normal to get the "object_id": null, "subscription_id": 0 and "id": 0 onto the response?
After that when my another authenticated instagram account shared a media then I got notification to my callback url but seems to me lack of information:
[
{
"changed_aspect": "media",
"object": "user",
"object_id": "111111",
"time": 1484290271,
"subscription_id": 0,
"data": {
"media_id": "1111-11"
}
}
]
I said lack of information because a media have "id", "images", "caption", "link" etc which I was expecting as a response.
Because otherwise I have to call normal api(Media enpoints) call again to get those things. Is there anything I missed to get the subscription or have different way to get?
https://www.instagram.com/developer/subscriptions/
this endpoint says "When we have new data, we'll POST this data to your callback URL. We'll explain more about what this URL needs to do later on this page."
Although I can't get the subscription api response if I comment on the media(which I had got the notification in my callback url) or liked on the media/comment.
Is that those things not supported by instagram? Does anyone have this issue or any help will be appreciated?
May be this answer of mine will be helpful to people having same problem.
Iam trying to upload an image to object storage container and get the url of that image deployed on bluemix using a node js app.To achieve this i need to use a post or put api call.I could able to authenticate with the object storage but not able to achieve the functionality through the api calls.So,I need some help on the api calls.So can some one help me out in this if you had worked on such kind of api calls with images on object storage.(using object-storage npm).Even share any kind of sample working api calls.Any help appreciated.
Object storage api's are derived from the OpenStack Swift API spec. In order to add an object of any sort to a Bluemix Object Storage container, you'll need to do 2 things:
Authenticate to the Object Storage instance to obtain an authorization token.
Perform actions on the container using the token obtained.
I assume that you already have access to the JSON credentials provided by the object storage service ... similar to:
{
"auth_url": "https://identity.open.softlayer.com",
"domainId": "nice_long_hex_value",
"domainName": "some_number",
"password": "not_gonna_tell_you",
"project": "object_storage_hex_value",
"projectId": "project_hex_value",
"region": "dallas",
"userId": "another_fine_hex_value",
"username": "some_text_with_hex_values"
}
Step 1: Obtain X-Auth-token. 4 items (user_id, user_name, password and auth_url) should come from your provided credentials.
curl -i -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
"auth": {
"identity": {
"methods": [
"password"
],
"password": {
"user": {
"id": "another_fine_hex_value",
"password": "not_gonna_tell_you"
}
}
},
"scope": {
"project": {
"id": "project_hex_value"
}
}
}
}' "{auth_url}/v3/auth/tokens" | tee response.txt | grep X-Subject-Token | sed 's/.*X-Subject-Token: \([^ ]*\).*/\1/g' | tee >(awk '{printf("\nX-Auth-Token: %s\n\nJSON Response Body:\n", $0)}' > /dev/tty) | sed -n '/{/,$p' <response.txt | python -m json.tool && rm response.txt
This should result in a 500+ Line JSON Response BODY (take note of the public interface for the region of dallas within the swift endpoints array) similar to …
{
"token": {
"methods": [
"password"
],
"roles": [
{
"id": "redacted",
"name": "ObjectStorageOperator"
}
],
"expires_at": "2016-03-09T20:26:39.192753Z",
"project": {
"domain": {
"id": "some_hex_value",
"name": "some_int"
},
"id": "another_hex_value",
"name": "one_more_hex_value"
},
"catalog": [
...
{
"endpoints": [
{
"region_id": "london",
...
},
{
...
},
{
"region_id": "dallas",
"url": "https://dal.objectstorage.open.softlayer.com/v1/AUTH_",
"region": "dallas",
"interface": "public",
"id": "some_unique_id"
},
{
...
},
{
...
},
{
...
}
],
"type": "object-store",
"id": "hex_values_rock",
"name": "swift"
},
...
],
"extras": {},
"user": {
"domain": {
"id": "hex_value",
"name": "another_fine_int"
},
"id": "tired_of_hex_values_yet?",
"name": "cheers_one_more_hex_value_for_the_road"
},
...
}
}
Specifically, we want to identify the Swift Object Storage API url in the form:
https://dal.objectstorage.open.softlayer.com/v1/AUTH_some-hex-value
https://dal.objectstorage.open.softlayer.com/v1/AUTH_some-hex-value is
linked to your desired object storage region (dallas, london, …) and associated with a public interface. This will be found within the endpoints section which includes the name “swift”.
Even more importantly, within the generated HTTP Response Header of this /v3/auth/tokens call is an authentication token that we also need to record to facilitate subsequent authenticated HTTP API calls.
Here is a sample of the HTTP Response Headers
Connection: Keep-Alive
Content-Length: 12089
Content-Type: application/json
Date: Wed, 09 Mar 2016 19:26:39 GMT
Keep-Alive: timeout=5, max=21
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.1e-fips mod_wsgi/3.4 Python/2.7.5
Vary: X-Auth-Token
X-Subject-Token: gAAAAABW4Hjv5O8yQRwYbkV81s7KC0mTxlh_tXTFtzDEf3ejsP_CByfvvupOeVWWcWrB6pfVbUyG5THZ6qM1-BiQcBUo1WJOHWDzMMrEB5nru69XBd-J5f5GISOGFjIxPPnNmEDZT_pahnBwaBQiJ8vrg9p5obdtRJeuxk7ADVRQFcBcRhAL-PI
x-openstack-request-id: req-26a078fe-d0a7-4a75-b32d-89d3461c55f1
The X-Subject-Token is the important response header. Its value will be reused within all subsequent HTTP Request Headers using the header X-Auth-Token. Obvious, right?
Step 2: With this token, let's add an object to a container named "ibmjstart".
curl -s -X PUT -i -H "Content-Type: text/plain"\
-H "X-Auth-Token: X-Subject-Token from above"\
-H "Cache-Control: no-cache"\
-d "Awesome sauce is best served warm" "{API AUTH URL obtained above}/ibmjstart/test.txt"
If all goes well, this should result in a new container named ibmjstart which contains a text file named test.txt with a single line of content.