Chainlink How to encode to bytes32 for results from external adapter? - chainlink

I am trying to set up a job for an external adapter. I get the results from the api call. It processes all the way up to the task parse. But when I try the task Ethabiencode I get this error:
encode_data ethabiencode
ETHABIEncode: while converting argument 'value' from to bytes32: cannot convert decimal.Decimal to [32]uint8: bad input for task: bad input for task
abi: (bytes32 value)
data: { "value": $(multiply) }
Is the value from $(parse) there? or is it nil?
I am running v0.10.15
here's the job
type = "directrequest"
schemaVersion = 1
name = "Get > Bytes32"
contractAddress = "0x4dbDef7A9E395831FD2aD5754F6Bf81707017e28"
maxTaskDuration = "0s"
observationSource = """
decode_log [type="ethabidecodelog"
abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)"
data="$(jobRun.logData)"
topics="$(jobRun.logTopics)"]
decode_cbor [type="cborparse" data="$(decode_log.data)"]
fetch [type=bridge name="bet-ea" async="True" requestData="{\\"id\\": $(jobSpec.externalJobID), \\"data\\": { \\"fixtureId\\": $(decode_cbor.fixtureId)}}"]
parse [type="jsonparse" lax="True" path="result" data="$(fetch)"]
encode_data [type="ethabiencode" abi="(bytes32 value)" data="{ \\"value\\": $(parse) }"]
encode_tx [type="ethabiencode"
abi="fulfillOracleRequest(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes32 data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}"
]
submit_tx [type="ethtx" to="0x4dbDef7A9E395831FD2aD5754F6Bf81707017e28" data="$(encode_tx)"]
decode_log -> decode_cbor -> fetch -> parse -> encode_data -> encode_tx -> submit_tx
"""
externalJobID = "19f6be23-b75c-4858-9e7a-be02679b83cc"
{
"outputs": [
null
],
"errors": [
"task inputs: too many errors"
],
"inputs": {
"jobRun": {
"logAddress": "0xd2de9f0bbe99c7100f8456548cddb33103122e57",
"logBlockHash": "0x3ced7cf22e1b368b3c57580e66721dd632a216414c82caa26d6548b7a0aca842",
"logBlockNumber": 5292158,
"logData": "AAAAAAAAAAAAAAAACvp9jgodQj3rZ71Dh9pqxgl+Vjjydtvwp78RTtc+VslKVNFOPNmD4kPnG/qlvDyrZ/tyqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3gtrOnZAAAAAAAAAAAAAAAAAAACvp9jgodQj3rZ71Dh9pqxgl+VjhJVWr/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABh8BvmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARaWZpeHR1cmVJZGY3MTA1ODAAAAAAAAAAAAAAAAAAAAA=",
"logTopics": [
"0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65",
"0x6231653236353232353131383431613562636666333864336333326337353663"
],
"logTxHash": "0xf9c543ef3a4ca858ad7944af3b0970246f0002fcd76df5610b2be53b90a463ad",
"meta": {
"oracleRequest": {
"callbackAddr": "0x0aFA7d8e0A1d423Deb67BD4387Da6ac6097E5638",
"callbackFunctionId": "0x49556aff",
"cancelExpiration": "1643125734",
"data": "0x6966697874757265496466373130353830",
"dataVersion": "1",
"payment": "1000000000000000000",
"requestId": "0xf276dbf0a7bf114ed73e56c94a54d14e3cd983e243e71bfaa5bc3cab67fb72a8",
"requester": "0x0aFA7d8e0A1d423Deb67BD4387Da6ac6097E5638",
"specId": "0x6231653236353232353131383431613562636666333864336333326337353663"
}
}
},
"jobSpec": {
"databaseID": 36,
"externalJobID": "b1e26522-5118-41a5-bcff-38d3c32c756c",
"name": "Get > Bytes32"
}
},
"taskRuns": [
{
"type": "ethtx",
"createdAt": "2022-01-25T15:43:55.888153Z",
"finishedAt": "2022-01-25T15:43:57.688118Z",
"output": null,
"error": "task inputs: too many errors",
"dotId": "submit_tx",
"status": "not_run"
},
{
"type": "ethabidecodelog",
"createdAt": "2022-01-25T15:43:55.8927Z",
"finishedAt": "2022-01-25T15:43:55.8928Z",
"output": "{"callbackAddr":"0x0afa7d8e0a1d423deb67bd4387da6ac6097e5638","callbackFunctionId":[73,85,106,255],"cancelExpiration":1643125734,"data":"aWZpeHR1cmVJZGY3MTA1ODA=","dataVersion":1,"payment":1000000000000000000,"requestId":[242,118,219,240,167,191,17,78,215,62,86,201,74,84,209,78,60,217,131,226,67,231,27,250,165,188,60,171,103,251,114,168],"requester":"0x0afa7d8e0a1d423deb67bd4387da6ac6097e5638","specId":[98,49,101,50,54,53,50,50,53,49,49,56,52,49,97,53,98,99,102,102,51,56,100,51,99,51,50,99,55,53,54,99]}",
"error": null,
"dotId": "decode_log",
"status": "completed"
},
{
"type": "cborparse",
"createdAt": "2022-01-25T15:43:55.89282Z",
"finishedAt": "2022-01-25T15:43:55.892849Z",
"output": "{"fixtureId":"710580"}",
"error": null,
"dotId": "decode_cbor",
"status": "completed"
},
{
"type": "bridge",
"createdAt": "2022-01-25T15:43:55.892858Z",
"finishedAt": "2022-01-25T15:43:57.687947Z",
"output": ""{\"jobRunID\":\"1\",\"data\":{\"winner\":7105801,\"result\":7105801},\"result\":7105801,\"statusCode\":200}"",
"error": null,
"dotId": "fetch",
"status": "completed"
},
{
"type": "jsonparse",
"createdAt": "2022-01-25T15:43:57.68797Z",
"finishedAt": "2022-01-25T15:43:57.687988Z",
"output": "7105801",
"error": null,
"dotId": "parse",
"status": "completed"
},
{
"type": "ethabiencode",
"createdAt": "2022-01-25T15:43:57.688014Z",
"finishedAt": "2022-01-25T15:43:57.688071Z",
"output": null,
"error": "ETHABIEncode: while converting argument 'value' from <nil> to bytes32: cannot convert float64 to [32]uint8: bad input for task: bad input for task",
"dotId": "encode_data",
"status": "errored"
},
{
"type": "ethabiencode",
"createdAt": "2022-01-25T15:43:57.688093Z",
"finishedAt": "2022-01-25T15:43:57.688096Z",
"output": null,
"error": "task inputs: too many errors",
"dotId": "encode_tx",
"status": "errored"
}
],
"createdAt": "2022-01-25T15:43:55.886335Z",
"finishedAt": "2022-01-25T15:43:57.688124Z",
"pipelineSpec": {
"id": 36,
"jobID": 0,
"dotDagSource": " decode_log [type="ethabidecodelog" abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)" data="$(jobRun.logData)" topics="$(jobRun.logTopics)"] decode_cbor [type="cborparse" data="$(decode_log.data)"] fetch [type=bridge name="bet-ea" requestData="{\"id\": $(jobSpec.externalJobID), \"data\": { \"fixtureId\": $(decode_cbor.fixtureId)}}"] parse [type="jsonparse" path="result" data="$(fetch)"] encode_data [type="ethabiencode" abi="(bytes32 value)" data="{ \"value\": $(parse) }"] encode_tx [type="ethabiencode" abi="fulfillOracleRequest(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes32 data)" data="{\"requestId\": $(decode_log.requestId), \"payment\": $(decode_log.payment), \"callbackAddress\": $(decode_log.callbackAddr), \"callbackFunctionId\": $(decode_log.callbackFunctionId), \"expiration\": $(decode_log.cancelExpiration), \"data\": $(encode_data)}" ] submit_tx [type="ethtx" to="0xD2DE9f0bBe99C7100f8456548cDDb33103122e57" data="$(encode_tx)"] decode_log -> decode_cbor -> fetch -> parse -> encode_data -> encode_tx -> submit_tx "
},
"id": "32",
"jobId": "36",
"status": "errored",
"type": "Pipeline job run"
}

Related

Nifi - Route the JSON based on the Array Name

I am new to Nifi, i hv a requirement where we get multiple JSON inputs with different Header Names. I have to parse the JSON and insert into different tables based on the Header value.
Not sure how to use RouteonContent processor or EvaluateJSON Path processor
Input 1
{
"Location": [
{
"country": "US",
"division": "Central",
"region": "Big South",
"locationID": 1015,
"location_name": "Hattiesburg, MS (XF)",
"location_type": "RETAIL",
"location_sub_type": "COS",
"store_type": "",
"planned_open_date": "",
"planned_close_date": "",
"actual_open_date": "2017-07-26",
"actual_close_date": "",
"new_store_flag": "",
"address1": "2100 Lincoln Road",
"address2": "",
"city": "Hattiesburg",
"state": "MS",
"zip": 39402,
"include_for_planning": "Y"
},
{
"country": "US",
"division": "Central",
"region": "Big South",
"locationID": 1028,
"location_name": "Laurel, MS",
"location_type": "RETAIL",
"location_sub_type": "COS",
"store_type": "",
"planned_open_date": "",
"planned_close_date": "",
"actual_open_date": "",
"actual_close_date": "",
"new_store_flag": "",
"address1": "1225 5th street",
"address2": "",
"city": "Laurel",
"state": "MS",
"zip": 39440,
"include_for_planning": "Y"
}
]
Input 2
{
"Item": [
{
"npi_code": "NEW",
"cifa_category": "XM",
"o9_category": "Accessories"
},
{
"npi_code": "NEW",
"cifa_category": "XM0",
"o9_category": "Accessories"
}
]
Use the website https://jsonpath.com/ to figure out the proper JSON expression. But what you could potentially do is use: if the array contains either $.npi_code then do X and if it contains $. country, then do Y

Iterate Json Extractor

I need to Extract multiple key value from json response based on condition.
Below is json response I get in HTTP Request. I need to extract value of ID based on value of Document_ID value.
I am using $..result[?(#.Document_ID==${documentID})].ID to extract value.
But I need to use this multiple times. As there is list of DocumentIDs for which I need to Get respective List of IDs from the same response.
"result": [
{
"Owner": "PaperSave System",
"Company": "RENXT Support Test Environment 1",
"Document_ID": 46136,
"Type of Gift": "Donation",
"ContentType": "TIFF",
"Acknowledgement Date": null,
"IsRunning": true,
"FileName": "test.tif",
"Gift Amount": 10.0,
"DepositCheck": null,
"HasEventRaiseRights": true,
"Step": "Deposit_Issues",
"PaperSaveWorkflow_ID": 30,
"Submit for Deposit": "Yes",
"Created": "2022-02-09T14:11:24.6",
"CurrentUserName": "PaperSave System",
"Deposit Date": "2021-10-14T00:00:00",
"Bank Account Number": "0063130611",
"Number": null,
"Batch": "",
"Check Date": "2021-10-12T00:00:00",
"Lookup": null,
"ID": 25370,
"Check Number": 1220.0,
"Payment Method": "Direct Debit",
"RDSCanBeVoided": null,
"Constituent": "AAA Concretee",
"Status": "",
"Post Status": "Posted",
"Successful Deposit Submission": "Yes",
"Acknowledgement Status": null,
"Receipt Date": "2021-11-05T00:00:00",
"Receipt Status": "Receipted",
"Receipt Amount": 10.0,
"Gift Splits": "131043",
"Post Date": "2021-10-12T00:00:00",
"Has been associated field": "ps_database_ps",
"Gift Processor": "PaperSave System",
"Is Anonymous": "Yes",
"Routing Number": "122000496",
"Soft Credit": null,
"Gift Date": "2021-10-12T00:00:00",
"ContentId": 11474,
"Deposit Status": null,
"IsTerminated": null,
"FileSize": 8,
"Location": null
},
{
"Owner": "PaperSave System",
"Company": "RENXT Support Test Environment 1",
"Document_ID": 46137,
"Type of Gift": "Donation",
"ContentType": "TIFF",
"Acknowledgement Date": null,
"IsRunning": true,
"FileName": "test.tif",
"Gift Amount": 10.0,
"DepositCheck": null,
"HasEventRaiseRights": true,
"Step": "Deposit_Issues",
"PaperSaveWorkflow_ID": 30,
"Submit for Deposit": "Yes",
"Created": "2022-02-09T14:11:47.43",
"CurrentUserName": "PaperSave System",
"Deposit Date": "2021-10-14T00:00:00",
"Bank Account Number": "0063130611",
"Number": null,
"Batch": "",
"Check Date": "2021-10-12T00:00:00",
"Lookup": null,
"ID": 25371,
"Check Number": 1220.0,
"Payment Method": "Direct Debit",
"RDSCanBeVoided": null,
"Constituent": "AAA Concretee",
"Status": "",
"Post Status": "Posted",
"Successful Deposit Submission": "Yes",
"Acknowledgement Status": null,
"Receipt Date": "2021-11-05T00:00:00",
"Receipt Status": "Receipted",
"Receipt Amount": 10.0,
"Gift Splits": "131065",
"Post Date": "2021-10-12T00:00:00",
"Has been associated field": "ps_database_ps",
"Gift Processor": "PaperSave System",
"Is Anonymous": "Yes",
"Routing Number": "122000496",
"Soft Credit": null,
"Gift Date": "2021-10-12T00:00:00",
"ContentId": 11475,
"Deposit Status": null,
"IsTerminated": null,
"FileSize": 8,
"Location": null
}
Is there any way I can achieve this?

ODATA ASP .net core $Filter with Any or All

We are building an API to expose our account data for entities using ODATA REST API.
One of our downstream system wants to consume our API wants to filter data for all Internal Accounts only.
The Query used is $Filter=accounts/all(account: account/Type eq 'Internal')
They get all the Entities with accounts that have 'Internal' but few missing entities. One such missing entity in output payload is "EntityId": 140630.
The only difference between this entity '140630' and other entities that make up to the payload is that, has accounts that belong to both types 'Internal and External'.
But the expectation is that downstream wants all entities that have accounts with type 'Internal' invariably whether the entity has only Internal accounts or both (Internal and External).
Based on our initial analysis, ODATA 'All' filter considers entities that have only Account/Type that has 'Internal' and skips entities with accounts that have both 'Internal' and 'External'.
With 'Any' Filter, entities that have account type 'Internal' + entities that have account type 'Internal' and 'External' are fetched. In this case we see the payload having Entity 140630 with accounts both Internal and External. But as per requirement, the downstream system should not be exposed with 'External' accounts.
Need support to write a fitting ODATA Filter that brings Entities that contains internal accounts. Whether they have only internal accounts or have both internal and External accounts.
From the sample payload provided below
the filtered output should bring entities
"EntityId": 140278, and accounts (Only have internal accounts)
"EntityId": 440365, and accounts (Only have internal accounts)
"EntityId": 140630, and accounts "Id": 228643,"Id": 228647, (Only internal accounts from the list of accounts they have)
Any directions to achieve the above requirement will be much appreciated.
The json payload with out any filter looks like
{
"#odata.context": "https://abc.myteamtest.webdomain.com/TAcctService/API/$metadata#TAccount(Accounts(CIS(),accountRel()))",
"value": [
{
"EntityId": 140278,
"Accounts": [
{
"Id": 229016,
"Type": "Internal",
"TradingSourceSystem": "ABC",
"TradingCode": "18951",
"ShortName": "MyBank ABC 124543",
"FullName": "MyBank ABC (OU 124543)",
"TradingBusiness": "ASL",
"Status": "Active",
"accrualCode": "ACC",
"CreatedDt": "2017-11-18T04:29:31.552+05:30",
"UpdatedDt": "2022-01-31T13:06:12.053+05:30",
"UpdatedBy": "admin",
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 229016,
"id": "69776",
"description": "MyBank HOLDINGS INC.",
"CorpCode": "NY001",
"TradingLocation": "YORK SITE",
"OrgunitId": "124543",
"OrgunitDescription": "ABC - FUNDING",
"BusinessUnit": "OTHER",
"Location": "USA",
"ProfitCenter": "124543",
"CustomerGroup": "07956",
"CISLegalEntityId": "07956",
"CISLegalEntityName": "MyBank HOLDINGS INC."
},
"accountRel": {
"TradingCodeAttributesID": 229016,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
}
]
},
{
"EntityId": 440365,
"Accounts": [
{
"Id": 228919,
"Type": "Internal",
"TradingSourceSystem": "ABC",
"TradingCode": "21700",
"ShortName": "MyBank 69002",
"FullName": "MyBank Limited (69002)",
"TradingBusiness": "ASL",
"Status": "Active",
"accrualCode": "MTM",
"CreatedDt": "2017-11-18T04:29:33.228+05:30",
"UpdatedDt": "2022-01-31T13:06:12.053+05:30",
"UpdatedBy": "admin",
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 228919,
"id": "69002",
"description": "MyBank LIMITED",
"CorpCode": "WGINT",
"TradingLocation": "UnKnown",
"OrgunitId": "69002",
"OrgunitDescription": "MyBank LIMITED",
"BusinessUnit": "MANAGED",
"Location": "WES",
"ProfitCenter": "69002",
"CustomerGroup": "69002",
"CISLegalEntityId": "69002",
"CISLegalEntityName": "MyBank LIMITED"
},
"accountRel": {
"TradingCodeAttributesID": 228919,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
}
]
},
{
"EntityId": 140630,
"Accounts": [
{
"Id": 219926,
"Type": "External",
"TradingSourceSystem": "MSS",
"TradingCode": "MARINE",
"ShortName": null,
"FullName": "My Bank of Testing",
"TradingBusiness": null,
"Status": "Active",
"accrualCode": null,
"CreatedDt": "2021-01-26T19:24:03.327+05:30",
"UpdatedDt": "2021-01-26T19:19:21+05:30",
"UpdatedBy": null,
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 0,
"Boaid": null,
"Boadescription": null,
"CorpCode": null,
"TradingLocation": null,
"OrgunitId": null,
"OrgunitDescription": null,
"BusinessUnit": null,
"Location": null,
"ProfitCenter": null,
"CustomerGroup": null,
"CISLegalEntityId": null,
"CISLegalEntityName": null
},
"accountRel": {
"TradingCodeAttributesID": 0,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
},
{
"Id": 219927,
"Type": "External",
"TradingSourceSystem": "MSS",
"TradingCode": "PRESET",
"ShortName": null,
"FullName": "My Bank of Testing",
"TradingBusiness": null,
"Status": "Active",
"accrualCode": null,
"CreatedDt": "2021-02-23T15:50:46.013+05:30",
"UpdatedDt": "2021-02-23T15:50:45+05:30",
"UpdatedBy": null,
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 0,
"Boaid": null,
"Boadescription": null,
"CorpCode": null,
"TradingLocation": null,
"OrgunitId": null,
"OrgunitDescription": null,
"BusinessUnit": null,
"Location": null,
"ProfitCenter": null,
"CustomerGroup": null,
"CISLegalEntityId": null,
"CISLegalEntityName": null
},
"accountRel": {
"TradingCodeAttributesID": 0,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
},
{
"Id": 228643,
"Type": "Internal",
"TradingSourceSystem": "ABC",
"TradingCode": "24633",
"ShortName": "AB124 94189",
"FullName": "AB124 CRT",
"TradingBusiness": "MSL",
"Status": "Active",
"accrualCode": null,
"CreatedDt": "2017-11-18T04:29:34.409+05:30",
"UpdatedDt": "2022-01-31T13:06:12.053+05:30",
"UpdatedBy": null,
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 0,
"Boaid": "09902",
"Boadescription": "OFFICE",
"CorpCode": "ABCC1",
"TradingLocation": "York",
"OrgunitId": "94189",
"OrgunitDescription": "MAP",
"BusinessUnit": "CIO",
"Location": "PAN",
"ProfitCenter": "94189",
"CustomerGroup": "09902",
"CISLegalEntityId": "29997",
"CISLegalEntityName": "My PARENT BANK"
},
"accountRel": {
"TradingCodeAttributesID": 0,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
},
{
"Id": 228647,
"Type": "Internal",
"TradingSourceSystem": "ABC",
"TradingCode": "7574",
"ShortName": "ABC1234 COLL13122",
"FullName": "ABC1234 Collateral Pool",
"TradingBusiness": "MSL",
"Status": "Active",
"accrualCode": null,
"CreatedDt": "2017-11-18T04:29:35.234+05:30",
"UpdatedDt": "2022-01-31T13:06:12.053+05:30",
"UpdatedBy": null,
"EntityRole": "CUSTR",
"CIS": {
"TradingCodeAttributesID": 0,
"Boaid": "09602",
"Boadescription": "P&T",
"CorpCode": "ABC12342",
"TradingLocation": "YORK",
"OrgunitId": "13122",
"OrgunitDescription": "FIC",
"BusinessUnit": "MARKETS",
"Location": "PAN",
"ProfitCenter": "13122",
"CustomerGroup": "09602",
"CISLegalEntityId": "29997",
"CISLegalEntityName": "ABC1234 PARENT BANK"
},
"accountRel": {
"TradingCodeAttributesID": 0,
"RelatedEntityId": null,
"Relationshiptype": null,
"Restrictedpartyname": null,
"Confidentialityagreementind": null
}
}
]
}
]
}
I'm assuming that you're using EntityFramework in this scenario. If so, I suggest you try this:
public IQueryable<Entity> Get()
{
return _databaseContext.Entities
.Include(entity => entity.Accounts.Where(account => account.Type = "Internal"))
.AsNoTracking();
}```

Getting individual array elements from the data returned by a chainlink external adapter

In the job I'm adding for my external adapter, I'm looking to get results for the first 3 elements in the Results array one at a time.(see the data returned from my external adapter below)
So I'm adding "position" to my chainlink request in the consumer contract and wanting to use that in the jsonparse like below, rather than pass it to the external adapter. However, I get this error JSONParse task error: $(decode_cbor.position) is not a valid array index
parse [type=jsonparse path="data,MRData,RaceTable,Races,0,Results,$(decode_cbor.position),number" data="$(fetch)"]```
in my consumer contract
Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
request.add("position", "1");
The data returned from the external adapter looks like this.
{
"MRData": {
"xmlns": "http://ergast.com/mrd/1.4",
"series": "f1",
"url": "http://ergast.com/api/f1/current/last/results.json",
"limit": "30",
"offset": "0",
"total": "20",
"RaceTable": {
"season": "2021",
"round": "17",
"Races": [{
"season": "2021",
"round": "17",
"url": "http://en.wikipedia.org/wiki/2021_United_States_Grand_Prix",
"raceName": "United States Grand Prix",
"Circuit": {
"circuitId": "americas",
"url": "http://en.wikipedia.org/wiki/Circuit_of_the_Americas",
"circuitName": "Circuit of the Americas",
"Location": {
"lat": "30.1328",
"long": "-97.6411",
"locality": "Austin",
"country": "USA"
}
},
"date": "2021-10-24",
"time": "19:00:00Z",
"Results": [{
"number": "33",
"position": "1",
"positionText": "1",
"points": "25",
"Driver": {
"driverId": "max_verstappen",
"permanentNumber": "33",
"code": "VER",
"url": "http://en.wikipedia.org/wiki/Max_Verstappen",
"givenName": "Max",
"familyName": "Verstappen",
"dateOfBirth": "1997-09-30",
"nationality": "Dutch"
},.....
The full results can be found here. http://ergast.com/api/f1/current/last/results.json
Should I be able to do something like this? Is there a better way to go about this? Should I edit the adapter instead?
schemaVersion = 1
name = "f1latestresults2"
contractAddress = "0x765aCc258f3a7b2D8d103D1A9310fc51b07D5425"
maxTaskDuration = "0s"
observationSource = """
decode_log [type=ethabidecodelog
abi="OracleRequest(bytes32 indexed specId, address requester, bytes32 requestId, uint256 payment, address callbackAddr, bytes4 callbackFunctionId, uint256 cancelExpiration, uint256 dataVersion, bytes data)"
data="$(jobRun.logData)"
topics="$(jobRun.logTopics)"]
decode_cbor [type=cborparse data="$(decode_log.data)"]
fetch [type=bridge name="raceresults" requestData="{\\"id\\":$(jobSpec.externalJobID),\\"data\\":{\\"position\\":\\"0\\"}}"]
parse [type=jsonparse path="data,MRData,RaceTable,Races,0,Results,$(decode_cbor.position),number" data="$(fetch)"]
encode_data [type=ethabiencode abi="(uint256 value)" data="{ \\"value\\": $(parse) }"]
encode_tx [type=ethabiencode
abi="fulfillOracleRequest(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes32 data)"
data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}"
]
submit_tx [type=ethtx to="0x765aCc258f3a7b2D8d103D1A9310fc51b07D5425" data="$(encode_tx)"]
decode_log -> decode_cbor -> fetch -> parse -> encode_data -> encode_tx -> submit_tx
"""
externalJobID = "cfa059b4-a31d-4c30-99e4-3a2fd4c57739"
The syntax you are using looks correct to me, so I'm not 100% sure if the TOML jobs can support having a parameter like that within a string yet?
If the rest of the JSON path is static, suggest just having it as a built up string in your consuming contract, and just sending it as a full string in the request, then using that in your TOML spec, similar to the example in the docs
req.add("path", "data,MRData,RaceTable,Races,0,Results,0");
Then in your TOML job spec:
parse [type=jsonparse path="$(decode_cbor.path)" data="$(fetch)"]

get youtube videos listed in subsection of channel's 'videos'

How can I get videos listed in an item of the dropdown menu of a channel's 'videos' tab?
Is it a playlist with an ID? If I wanted to get all the uploaded videos, I could first query the id of playlist 'uploads' (here for channel UCj7IJ427cnavyq2ZOpSKYfA):
GET https://youtube.googleapis.com/youtube/v3/channels?part=contentDetails&id=UCj7IJ427cnavyq2ZOpSKYfA&key=[YOUR_API_KEY] HTTP/1.1
{
"kind": "youtube#channelListResponse",
...,
"items": [
{
"kind": "youtube#channel",
...,
"contentDetails": {
"relatedPlaylists": {
"likes": "",
"favorites": "",
"uploads": "UUj7IJ427cnavyq2ZOpSKYfA" # <- here it is!
}
}
}
]
}
and use it to run playlistItems. But what about that 'Upcoming livestreams' part only?
You should use the Search.list API endpoint, invoked with the request parameters channelId, type and eventType set accordingly:
GET https://www.googleapis.com/youtube/v3/search?key=${API_KEY}&type=video&eventType=upcoming&part=snippet&maxResults=50&channelId=${CHANNEL_ID},
where ${CHANNEL_ID} is the ID the the channel of your interest and ${API_KEY} is your API key.
For the channel you mentioned above -- that with ID UCj7IJ427cnavyq2ZOpSKYfA --, the JSON response looked like:
{
"kind": "youtube#searchListResponse",
"etag": "...",
"regionCode": "...",
"pageInfo": {
"totalResults": 4,
"resultsPerPage": 4
},
"items": [
{
"kind": "youtube#searchResult",
"etag": "quPJtDE4C_PAgFJU9QIjA5d_C4k",
"id": {
"kind": "youtube#video",
"videoId": "JksecRTzbgo"
},
"snippet": {
"publishedAt": "2021-05-19T10:33:39Z",
"channelId": "UCj7IJ427cnavyq2ZOpSKYfA",
"title": "LIVE: Т. Владимиров, фортепиано. Бах, Рахманинов, Шуберт",
"description": "Тимофей ВЛАДИМИРОВ, фортепиано В программе: И.С. Бах. Шестиголосный ричеркар из цикла «Музыкальное приношение» Рамо – Годовский.",
"thumbnails": {
...
},
"channelTitle": "MOSCOW INTERNATIONAL PERFORMING ARTS CENTER",
"liveBroadcastContent": "upcoming",
"publishTime": "2021-05-19T10:33:39Z"
}
},
{
"kind": "youtube#searchResult",
"etag": "7LTWdzCS0NDFayU3zbfDcb3xky4",
"id": {
"kind": "youtube#video",
"videoId": "G85Prxi4Mr0"
},
"snippet": {
"publishedAt": "2021-05-25T12:28:10Z",
"channelId": "UCj7IJ427cnavyq2ZOpSKYfA",
"title": "LIVE: Лауреаты IV Конкурса пианистов В. Крайнева в возрастной категории от 16 до 22 лет",
"description": "В День защиты детей Концерт победителей и лауреатов IV Международного конкурса пианистов Владимира Крайнева в возрастной категории от 16 ...",
"thumbnails": {
...
},
"channelTitle": "MOSCOW INTERNATIONAL PERFORMING ARTS CENTER",
"liveBroadcastContent": "upcoming",
"publishTime": "2021-05-25T12:28:10Z"
}
},
{
"kind": "youtube#searchResult",
"etag": "I4FOz2ykBQviPr_7vdF87240iG8",
"id": {
"kind": "youtube#video",
"videoId": "tKDEjh37BrA"
},
"snippet": {
"publishedAt": "2021-05-25T12:01:48Z",
"channelId": "UCj7IJ427cnavyq2ZOpSKYfA",
"title": "LIVE: Лауреаты IV Конкурса пианистов В. Крайнева в возрастной категории от 7 до 12 лет",
"description": "В День защиты детей Концерт победителей и лауреатов IV Международного конкурса пианистов Владимира Крайнева в возрастной категории от 7 до ...",
"thumbnails": {
...
},
"channelTitle": "MOSCOW INTERNATIONAL PERFORMING ARTS CENTER",
"liveBroadcastContent": "upcoming",
"publishTime": "2021-05-25T12:01:48Z"
}
},
{
"kind": "youtube#searchResult",
"etag": "tpF_wpRF43W6fv1MGpNnCBSvCDU",
"id": {
"kind": "youtube#video",
"videoId": "R9Em6BJW0e0"
},
"snippet": {
"publishedAt": "2021-05-25T12:08:55Z",
"channelId": "UCj7IJ427cnavyq2ZOpSKYfA",
"title": "LIVE: Лауреаты IV Конкурса пианистов В. Крайнева в возрастной категории от 13 до 15 лет",
"description": "В День защиты детей Концерт победителей и лауреатов IV Международного конкурса пианистов Владимира Крайнева в возрастной категории от 13 ...",
"thumbnails": {
...
},
"channelTitle": "MOSCOW INTERNATIONAL PERFORMING ARTS CENTER",
"liveBroadcastContent": "upcoming",
"publishTime": "2021-05-25T12:08:55Z"
}
}
]
}
Do note that the Search.list endpoint is relatively expensive: each call of it will cost you 100 units of quota (accounted from your daily quota, which by default is 10000 units).

Resources