I have an app that uses AzureFunction and EventGrid with Nodejs. I want to debug some Event Trigger Functions in localhost, but I don't want to use Ngrok, for particular reasons. There is another way to achieve EventGrid debugging without Ngrok?
When running Azure function locally, the EventGridTrigger can be access through this url:
http://localhost:7071/runtime/webhooks/EventGrid?functionName={functionname}
From Postman (for example), you would need these additional headers:
Content-Type: application/json
aeg-event-type: Notification
A full http request would looks like this
POST /runtime/webhooks/EventGrid?functionName={functionname}
Host: http://localhost:7071
Content-Type: application/json
aeg-event-type: Notification
{
"topic": "/subscriptions/5b4b650e-28b9-4790-b3ab-ddbd88d727c4/resourcegroups/test/providers/Microsoft.EventHub/namespaces/test",
"subject": "eventhubs/test",
"eventType": "captureFileCreated",
"eventTime": "2017-07-14T23:10:27.7689666Z",
"id": "7b11c4ce-1c34-4416-848b-1730e766f126",
"data": {
"fileUrl": "https://test.blob.core.windows.net/debugging/testblob.txt",
"fileType": "AzureBlockBlob",
"partitionId": "1",
"sizeInBytes": 0,
"eventCount": 0,
"firstSequenceNumber": -1,
"lastSequenceNumber": -1,
"firstEnqueueTime": "0001-01-01T00:00:00",
"lastEnqueueTime": "0001-01-01T00:00:00"
},
"dataVersion": "",
"metadataVersion": "1"
}
Related
I have an Azure Function App with a function at the URL http://localhost:7072/api/create-room along with other functions. This particular function is a HTTPTrigger with allowed anonymous access and accepts the GET verb:
[HttpTrigger(AuthorizationLevel.Anonymous, "get")]
Along with that, I have a separate function app that hosts only a proxies.json file and serves only as a functions proxy. My proxies function is running on port 7071 locally.
My proxies file currently looks like this:
{
"$schema": "http://json.schemastore.org/proxies",
"proxies": {
"chatNegotiate": {
"matchCondition": {
"route": "/api/chat/negotiate",
"methods": [
"POST"
]
},
"backendUri": "%chat_api%/api/BeginNegotiate"
},
"chatMessages": {
"matchCondition": {
"route": "/api/chat/messages",
"methods": [
"POST"
]
},
"backendUri": "%chat_api%/api/PostMessage"
},
"createRoom": {
"matchCondition": {
"route": "/api/create-room",
"methods": [
"GET"
]
},
"backendUri": "%session_api%/api/CreateRoom"
}
}
}
When both of these function apps are deployed to Azure, everything works like a dream. I can make requests, they're forwarded on, requests come back. It's all glorious.
However, when I run these functions locally, the request is never forwarded on from the proxy, with the proxy returning a 404. I can hit the function on the other function app running locally on 7072 directly and all is well there, but not at all when I got via the proxy.
The proxy itself returns:
[30/05/2020 18:24:30] Host lock lease acquired by instance ID '0000000000000000000000002D5B6BEA'.
[30/05/2020 18:24:34] Executing HTTP request: {
[30/05/2020 18:24:34] "requestId": "9004b8e2-f208-4a98-8b48-6f85bca41281",
[30/05/2020 18:24:34] "method": "GET",
[30/05/2020 18:24:34] "uri": "/api/create-room"
[30/05/2020 18:24:34] }
[30/05/2020 18:24:34] Executed HTTP request: {
[30/05/2020 18:24:34] "requestId": "9004b8e2-f208-4a98-8b48-6f85bca41281",
[30/05/2020 18:24:34] "method": "GET",
[30/05/2020 18:24:34] "uri": "/api/create-room",
[30/05/2020 18:24:34] "identities": [],
[30/05/2020 18:24:34] "status": 404,
[30/05/2020 18:24:34] "duration": 15
[30/05/2020 18:24:34] }
From examples I've looked at such as https://chsakell.com/2019/02/03/azure-functions-proxies-in-action/, this should be working fine.
Any suggestions? Thanks in advance for any help you can provide!
I've solved this after all.
proxies.json isn't set to copy to the output directory by default.
You need to ensure that it's set to copy always.
In Visual Studio:
Right click proxies.json > click properties > Set Copy to output directory to Copy Always.
In Visual Studio Code (and other editors):
Open ProjectName.csproj and add an entry to always copy proxies.json to output directory.
<ItemGroup>
<None Update="proxies.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
This solved the problem with the 404 on my local instance of the function app proxy. In local.settings.json add this to Values:
"AZURE_FUNCTION_PROXY_DISABLE_LOCAL_CALL": true,
Credit: https://chsakell.com/2019/02/03/azure-functions-proxies-in-action/
This Api on this URL can be helpfull ?
https://learn.microsoft.com/en-us/rest/api/dtl/virtualmachineschedules/get
Please Help !
No, the API you provided is for the VM in Azure DevTest Labs, if you want to change the auto shut downtime for a normal azure VM, use the one below.
To acquire an access token, see this link.
Request URL:
PUT https://management.azure.com/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/microsoft.devtestlab/schedules/shutdown-computevm-<VMname>?api-version=2018-09-15
Request header:
Content-Type: application/json; charset=utf-8
Authorization: Bearer eyJ0exxxxx6dyJ9
Request body(1900 means 19:00 i.e. 7:00:00 PM):
{
"properties": {
"taskType": "ComputeVmShutdownTask",
"timeZoneId": "China Standard Time",
"dailyRecurrence": {
"time": "1900"
},
"targetResourceId": "/subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Compute/virtualMachines/<VMname>",
"status": "Enabled",
"notificationSettings": {
"timeInMinutes": 30,
"status": "Disabled"
}
},
"location": "eastus"
}
I have an API.ai agent that sends a request (comes from the user) to a webhook which needs a lot of processing (more than 5 sec) to get the answer. As far as I know, that there is no way to increase the response timeout in API.ai
So, I have created 2 intents. The first one simply will call my webhook to start the processing the result, and at the same time the webhook will reply to the user, "Your request is under processing...".
The second intent has an event and action. The purpose of the new event is just to display the result to the user.
Once the result is ready, my backend application will send a curl statement to trigger the event in the second intent with the necessary parameter modifications like sessionID, v, and time zone … etc.
I have received the following JSON from API.AI (I created an example to simplify my case):
{ "id": "de31ee96-c42f-4f2d-8461-ee39279ec2ed", "timestamp": "2017-09-27T13:39:46.932Z", "lang": "en", "result": {
"source": "agent",
"resolvedQuery": "custom_event",
"action": "test",
"actionIncomplete": false,
"parameters": {
"user_name": "Sam"
},
"contexts": [
{
"name": "welcoming-followup",
"parameters": {
"name.original": "",
"user_name": "Sam",
"name": "",
"user_name.original": ""
},
"lifespan": 2
}
],
"metadata": {
"intentId": "c196a388-16ac-4966-b55c-7cd999a7d680",
"webhookUsed": false,
"webhookForSlotFillingUsed": "false",
"intentName": "Welcoming"
},
"fulfillment": {
"speech": "Hello Sam",
"messages": [
{
"type": 0,
"speech": "Hello Sam"
}
]
},
"score": 1.0 }, "status": {
"code": 200,
"errorType": "success" }, "sessionId": "67cb28fd-6871-750c-d668-d0b736b763ec" }
Here is the curl statement that was sent by my backend.
The curl statement is: curl -X POST -H "Content-Type: application/json; charset=utf-8" -H "Authorization: Bearer I INSERTED THE CORRECT CODE HERE" --data "{'event':{ 'name': 'custom_event', 'data': {'name': 'Sam'}}, 'timezone':'America/New_York', 'lang':'en', 'sessionId':'a6ac2555-4b19-40f8-92ec-397f6a042dde'}" "https://api.api.ai/v1/query?v=20150910"
As shown from the above JSON, the API.ai agent received the trigger successfully. But, The response that I have specified in the “Response Section” does not appear to the user.
I attached a screenshot for the second intent in the API.ai agent.
Note: I tried the agent in developer console, WebDemo and Slack. None of them shown to me (as a user) the specified response.
I am not sure if I did something wrong?
screenshot of the second intent
API.AI is not really meant to handle event-driven activities. It is meant to be the intermediary in a conversation - so the normal pattern is:
User says something
API.AI processes this, possibly with a webhook, and sends a response.
Devices such as Google Home do not have a way to get a notification, so unless the user says something (step 1), then you will never get to step 2.
When you try to trigger it manually, API.AI is treating your trigger as the step 1, and it is replying to your trigger. It has no way to send that reply back to the Assistant because it isn't having a conversation with the Assistant at that moment - it is having a conversation with however you manually triggered it.
There isn't really a good way to do what you want right now. We know notifications are coming to the Assistant eventually (it was announced at I/O 2017), but we don't know if it will have an API or what it will look like. The Transaction API does have notifications as part of it, but Transactions are meant for activities where you are purchasing or reserving something. If you need to, you can use something like Firebase Cloud Messaging to let your user know they can ask for the result, but that's a sub-optimal experience.
Using the REST API documentation I am encoding a video using the following request to azure:
{
"Name": "NewTestJob",
"InputMediaAssets": [{
"__metadata": {
"uri": "https://media.windows.net/api/Assets('nb%3Acid%3AUUID%3Ab5cb32de-AAAA-BBBB-a6eb-1b3a61c795be')"
}
}
],
"Tasks": [{
"Configuration": "H264 Single Bitrate 720p",
"MediaProcessorId": "nb:mpid:UUID:ff4df607-d419-42f0-bc17-a481b1331e56",
"TaskBody": "<?xml version=\"1.0\" encoding=\"utf-8\"?><taskBody><inputAsset>JobInputAsset(0)</inputAsset><outputAsset>JobOutputAsset(0)</outputAsset></taskBody>"
}
]
}
From what I can see in the Azure dashboard this creates an encoded version of my video, the problem I have is that the returned job information does not have any OutputMediaAssets. The response is:
{
"odata.metadata": "https://wamsamsclus001rest-hs.cloudapp.net/api/$metadata#Jobs/#Element",
"Id": "nb:jid:UUID:e4bf4cff-0300-80c0-c4c5-f1e75c34a72c",
"Name": "NewTestJob",
"Created": "2017-06-28T19:04:55.8442399Z",
"LastModified": "2017-06-28T19:04:55.8442399Z",
"EndTime": null,
"Priority": 0,
"RunningDuration": 0.0,
"StartTime": null,
"State": 0,
"TemplateId": null,
"JobNotificationSubscriptions": []
}
This means I can't locate the newly created encoded asset. What am I doing wrong? Is there another way to locate the generated asset?
Please start with querying for the Task(s) in the Job, via a call like
GET https://media.windows.net/API/Jobs('nb:jid:UUID:b1f956b3-774c-bb44-a3f7-ee47e23add31')/Tasks HTTP/1.1
The problem wasn't caused by the Request Body but instead the header.
I was passing the header:
Accept: application/json
Instead of the header:
Accept: application/json;odata=verbose
The lack of the odata=verbose means that only a subset of the available data is returned.
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!