Finding an API for getting lottery numbers from EuroMillions - javascript

I have been trying to create a google assistant interaction for checking to see if the most recently drawn lottery results match the user's
I have tried an API created by 'CreativeSolutions' however the API does not seem to be responding to requests and I cannot find any other alternatives.
'use strict';
const { dialogflow } = require('actions-on-google');
const functions = require('firebase-functions');
const app = dialogflow({ debug:true });
app.intent('wednesdays number', (conv, {number}) => {
var lottoNumber = number;
if (lottoNumber == '01') {
return conv.ask('Thats correct, want to try again?');
}
var unirest = require("unirest");
var req = unirest("GET", "https://euromillions.p.rapidapi.com/ResultsService/FindLast");
req.headers({
"x-rapidapi-host": "euromillions.p.rapidapi.com",
"x-rapidapi-key": "6176bf0ce5mshda3ef945e5d809fp156f41jsnd333104ff8d2"
});
req.end(function (res) {
if (res.error) throw new Error(res.error);
console.log(res.body);
});
});

The EuroMillions does not have a free public-facing official API so this would be unable to be completed.

But you can use this API on RapidAPI: https://rapidapi.com/jribeiro19/api/euro-millions/
There is a free access to get results and paid access to get some more features.
disclaimer: I'm the developer/owner.

Related

Analytics.js data to PubSub GCP

I am using analytics.js to make a custom tracking over my website. As I wish to send the hit to PubSub, I used this documentation (Node.JS tab) to connect my TypeScript code to PubSub (not perfect I know. I am trying to make it work before cleaning).
ga(() => {
ga("set", "cookieExpires", 0);
const tracker = ga.getByName(trackerName);
tracker.set("sendHitTask", (model: any) => {
var refusedParam = ["_gid", "tid"];
let hit = model.get("hitPayload").split("&").filter((paramValue: string) => {
let param = paramValue.split("=")[0];
return (refusedParam.indexOf(param) == -1);
}).join("&");
/**
* TODO(developer): Uncomment these variables before running the sample.
*/
const topicNameOrId = 'tracking-test';
const data = JSON.stringify(hit);
// Creates a client; cache this for further use
const pubSubClient = new PubSub();
console.log("DATA IS " + data);
async function publishMessage() {
// Publishes the message as a string, e.g. "Hello, world!" or JSON.stringify(someObject)
const dataBuffer = Buffer.from(data);
try {
const messageId = await pubSubClient
.topic(topicNameOrId)
.publishMessage({data: dataBuffer});
console.log(`Message ${messageId} published.`);
} catch (error) {
console.error(`Received error while publishing: ${error.message}`);
process.exitCode = 1;
}
}
publishMessage();
});
});
I don't have any error when building and running this code. But, when I locally connect to my website, I have the following error inside the JS console Uncaught TypeError: a.grpc is undefined.
I tried to put grpc inside my package.json, but no success at removing the error and having a correct behavior.
Did I miss something ? How can I use analytics.js, and send data directly to PubSub ?

How to fetch Amazon Cognito Identity ID (user_identity_id) for the user from the lambda function?

In the Amplify documentation, under the Storage/File access levels section there is a paragraph that states:
Files are stored under private/{user_identity_id}/ where the user_identity_id corresponds to the unique Amazon Cognito Identity ID for that user.
How to fetch user_identity_id from the lambda function?
Request to the lambda is authorized, the event.requestContext.authorizer.claims object is available, I can see the user data, but not the user_identity_id.
EDIT: Now I see that there is a field event.requestContext.identity.cognitoIdentityId, but the value is null. Still need to find the way to fetch it.
Ok, so there's no right way to map Cognito identity ID and Cognito user. There is a lengthy discussion here where a couple of workarounds can be found. For now, I'm going to use this solution where, instead of identity_id, you can specify a custom attribute (most likely a sub) as a folder name.
EDIT: There is another solution that might help (found somewhere on the internet, and I verified that it works)
const AWS = require('aws-sdk')
const cognitoIdentity = new AWS.CognitoIdentity();
function getCognitoIdentityId(jwtToken) {
const params = getCognitoIdentityIdParams(jwtToken);
return cognitoIdentity
.getId(params)
.promise()
.then(data => {
if (data.IdentityId) {
return data.IdentityId;
}
throw new Error('Invalid authorization token.');
});
}
function getCognitoIdentityIdParams(jwtToken) {
const loginsKey = `cognito-idp.${process.env.REGION}.amazonaws.com/${process.env.USERPOOLID}`;
return {
IdentityPoolId: `${process.env.IDENTITY_POOL_ID}`,
Logins: {
[loginsKey]: jwtToken,
},
};
}
If the user accesses the lambda through graphql via the AppSync service then the identity is stored event.identity.owner
Here is some typescript code I use to pull the user_identity_id from the event. However, the user doesn't always call the lambda direct sp the user_identity can also be based in if from an authorized IAM role.
export function ownerFromEvent(event: any = {}): string {
if (
event.identity.userArn &&
event.identity.userArn.split(":")[5].startsWith("assumed-role")
) {
// This is a request from a function over IAM.
return event.arguments.input.asData.owner;
} else {
return event.identity.owner;
}
}
For anyone else still struggling with this, I was finally able to use the aws-sdk for JavaScript v3 to obtain a Cognito User's IdentityId & Credentials in a Lambda Function invoked via API-Gateway with a Cognito User Pool Authorizer from the Cognito User's identity jwtToken passed into the Authorization header of the request.
Here is the code used in my JavaScript Lambda Function:
const IDENTITY_POOL_ID = "us-west-2:7y812k8a-1w26-8dk4-84iw-2kdi849sku72"
const USER_POOL_ID = "cognito-idp.us-west-2.amazonaws.com/us-west-2_an976DxVk"
const { CognitoIdentityClient } = require("#aws-sdk/client-cognito-identity");
const { fromCognitoIdentityPool } = require("#aws-sdk/credential-provider-cognito-identity");
exports.handler = async (event,context) => {
const cognitoidentity = new CognitoIdentityClient({
credentials: fromCognitoIdentityPool({
client: new CognitoIdentityClient(),
identityPoolId: IDENTITY_POOL_ID,
logins: {
[USER_POOL_ID]:event.headers.Authorization
}
}),
});
var credentials = await cognitoidentity.config.credentials()
console.log(credentials)
// {
// identityId: 'us-west-2:d393294b-ff23-43t6-d8s5-59876321457d',
// accessKeyId: 'ALALA2RZ7KTS7STD3VXLM',
// secretAccessKey: '/AldkSdt67saAddb6vddRIrs32adQCAo99XM6',
// sessionToken: 'IQoJb3JpZ2luX2VjEJj//////////...', // sessionToken cut for brevity
// expiration: 2022-07-17T08:58:10.000Z
// }
var identity_ID = credentials.identityId
console.log(identity_ID)
// us-west-2:d393294b-ff23-43t6-d8s5-59876321457d
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods" : "OPTIONS,POST,GET,PUT"
},
body:JSON.stringify(identity_ID)
};
return response;
}
After a Cognito User has signed in to my application, I can use the Auth directive of aws-amplify and fetch() in my React-Native app to invoke the lambda function shown above by sending a request to my API-Gateway trigger (authenticated with a Cognito User Pool Authorizer) by calling the following code:
import { Auth } from 'aws-amplify';
var APIGatewayEndpointURL = 'https://5lstgsolr2.execute-api.us-west-2.amazonaws.com/default/-'
var response = {}
async function getIdentityId () {
var session = await Auth.currentSession()
var IdToken = await session.getIdToken()
var jwtToken = await IdToken.getJwtToken()
var payload = {}
await fetch(APIGatewayEndpointURL, {method:"POST", body:JSON.stringify(payload), headers:{Authorization:jwtToken}})
.then(async(result) => {
response = await result.json()
console.log(response)
})
}
More info on how to Authenticate using aws-amplify can be found here https://docs.amplify.aws/ui/auth/authenticator/q/framework/react-native/#using-withauthenticator-hoc

Streaming video from AWS Kinesis to JS client

I'm trying to consume the video from an AWS Kinesis stream. The stream is visible in the AWS console, but I cannot consume it in the JS application I'm trying to create.
I've been following this tutorial, but cannot get the streaming URL.
My code is here:
import React, { Component} from 'react'
import ReactPlayer from 'react-player'
import AWS from "aws-sdk";
import { STREAM_NAME, ACCESS_KEY_ID, SECRET_ACCESS_KEY, REGION } from '../secrets'
var streamName = STREAM_NAME;
// Step 1: Configure SDK Clients
var options = {
accessKeyId: ACCESS_KEY_ID,
secretAccessKey: SECRET_ACCESS_KEY,
region: REGION
}
var kinesisVideo = new AWS.KinesisVideo(options);
var kinesisVideoArchivedContent = new AWS.KinesisVideoArchivedMedia(options);
// Step 2: Get a data endpoint for the stream
kinesisVideo.getDataEndpoint({
StreamName: streamName,
APIName: "GET_HLS_STREAMING_SESSION_URL"
}, function(err, response) {
if (err) { return console.error(err); }
console.log('Data endpoint: ' + response.DataEndpoint);
kinesisVideoArchivedContent.endpoint = new AWS.Endpoint(response.DataEndpoint);
});
// Step 3: Get an HLS Streaming Session URL
console.log('Fetching HLS Streaming Session URL');
var playbackMode = 'LIVE'; // 'LIVE' or 'ON_DEMAND'
//var startTimestamp = new Date('START_TIMESTAMP'); // For ON_DEMAND only
//var endTimestamp = new Date('END_TIMESTAMP'); // For ON_DEMAND only
var fragmentSelectorType = 'SERVER_TIMESTAMP'; // 'SERVER_TIMESTAMP' or 'PRODUCER_TIMESTAMP'
const SESSION_EXPIRATION_SECONDS = 60*60
console.log(kinesisVideo)
const hlsUrl = kinesisVideoArchivedContent.getHLSStreamingSessionURL({
StreamName: streamName,
//StreamARN: "arn:aws:kinesisvideo:us-east-1:635420739373:stream/mr-pinchers-dot-org/1561848963391",
PlaybackMode: playbackMode,
HLSFragmentSelector: {
FragmentSelectorType: fragmentSelectorType,
TimestampRange: playbackMode === 'LIVE' ? undefined : {
// StartTimestamp: startTimestamp,
// EndTimestamp: endTimestamp
}
},
Expires: parseInt(SESSION_EXPIRATION_SECONDS)
}, function(err, response) {
if (err) { return console.error("Darn", err); }
console.log('HLS Streaming Session URL: ' + response.HLSStreamingSessionURL, response);
}
)
console.log("here", hlsUrl)
class Home extends Component {
render () {
return <ReactPlayer url={hlsUrl} playing={true} />
}
}
export default Home
The response I'm getting in Step 3 (response.HLSStreamingSessionURL) is undefined.
Step 2 runs fine, and I get an endpoint back, so I'm confident that it's not a permissions problem.
Part of me thinks that I should be using some async/await calls but I'm not sure, still pretty new to JS and all that async stuff so didn't know how to incorporate it into this.
I've spent quite a bit of time trying to figure this out but the documentation on Kinesis is still pretty light, although if someone has a good resource for it, please let me know.
This is basic JavaScript async behavior. You're executing step 3 before step 2 is complete. You can't use the response before it's happened.
You can fix this by starting step 3 when step 2 has completed, as follows:
kinesisVideo.getDataEndpoint({
StreamName: streamName,
APIName: "GET_HLS_STREAMING_SESSION_URL"
}, function(err, response) {
if (err) { return console.error(err); }
console.log('Data endpoint: ' + response.DataEndpoint);
kinesisVideoArchivedContent.endpoint = new AWS.Endpoint(response.DataEndpoint);
var playbackMode = 'LIVE';
var fragmentSelectorType = 'SERVER_TIMESTAMP';
const SESSION_EXPIRATION_SECONDS = 60*60
kinesisVideoArchivedContent.getHLSStreamingSessionURL({...});
// remainder of code here
});
Or you can use async/await and promise variants of the AWS SDK methods like so:
(async () => {
const kv_response = await kv.getDataEndpoint({...}).promise();
// ...
const hls_response = await kvac.getHLSStreamingSessionURL({...}).promise();
})();
Note that await may only be used inside an async function, hence the anonymous async wrapper.

Graphql Yoga Playground with Lambda - "Server cannot be reached"

I'm in the process of setting a graphql endpoint with servlerless/ lambda and am receiving an error when trying to connect to the graphql playground that comes with graphql-yoga. When I go to my route that has the playground (/playground) it launches the playground interface however it just says:
Server cannot be reached
In the top right of the playground. It's worth noting i'm using the makeRemoteExecutableSchema utility to proxy to another graphql endpoint (which is my CMS called Prismic). I don't believe this is the issue as I have successfully connected to it with the playground when testing on a normal express server.
Here is the code in my handler.js
'use strict';
const { makeRemoteExecutableSchema } = require('graphql-tools');
const { PrismicLink } = require("apollo-link-prismic");
const { introspectSchema } = require('graphql-tools');
const { ACCESS_TOKEN, CMS_URL } = process.env;
const { GraphQLServerLambda } = require('graphql-yoga')
const lambda = async () => {
const link = PrismicLink({
uri: CMS_URL,
accessToken: ACCESS_TOKEN
});
const schema = await introspectSchema(link);
const executableSchema = makeRemoteExecutableSchema({
schema,
link,
});
return new GraphQLServerLambda({
schema: executableSchema,
context: req => ({ ...req })
});
}
exports.playground = async (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
const graphQl = await lambda();
return graphQl.playgroundHandler(event, context, callback);
};
I have followed this guide for getting it running up till here and am fairly sure i've followed similar steps for what applies to what i'm trying to do but can't seem to figure out where i've gone wrong.
Thanks,
Could you take a look at what version of the graphql-yoga package you are using?
I had a similar problem using the Apollo server in combination with Kentico Cloud Headless CMS and I found this issue:
https://github.com/prisma/graphql-yoga/issues/267

By using ledger nano s, I wanna sign a transaction and send it

I'm trying to send ethereum transaction that sends ERC20 tokens to someone with Ledger Nano S through Node.JS but I'm not able to successfully sign and send this transaction.
First of all, I signed the transaction through the method, signTransaction, of ledgerhq API and then after signing it, I sended it to the main net by using sendSignedTransaction. When I execute below code, Ledger receives request and shows details of a transaction. However, after pressing Ledger's confirm button, the console returns error 'Returned error: Invalid signature: Crypto error (Invalid EC signature)'.
import AppEth from "#ledgerhq/hw-app-eth";
import TransportU2F from "#ledgerhq/hw-transport-u2f";
import TransportNodeHid from "#ledgerhq/hw-transport-node-hid";
import EthereumTx from "ethereumjs-tx"
const Web3 = require('web3');
import { addHexPrefix, bufferToHex, toBuffer } from 'ethereumjs-util';
const web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
var destAddresses = ['0xa6acFa18468786473269Dc1521fd4ff40F6481D9'];
var amount = 1000000000000;
var i=0;
var contract = new web3.eth.Contract([token contract ABI... ], '0x74a...');
const data1 = contract.methods.transfer(destAddresses[0], amount).encodeABI();
const exParams = {
gasLimit: 6e6,
gasPrice: 3e9,
from: '0x1A...',
data : data1,
to: '0x74a...',
value: '0x00',
nonce: "0x0",
chainId: 1,
v: "0x01",
r: "0x00",
s: "0x00"
}
async function makeSign(txParams) {
const tx = new EthereumTx(txParams);
const txHex = tx.serialize().toString("hex");
const signedTransaction = '0x' + txHex;
let transport;
try {
transport = await TransportNodeHid.create();
let eth2 = new AppEth(transport);
const result = await eth2.signTransaction("m/44'/60'/0'/0", txHex).then(result => {
web3.eth.sendSignedTransaction('0x' + txHex)
.then(res => {
console.log(res);
}).catch(err => {
console.log('sendSignedTransaction');
console.log(err);
});
}).catch(err => {
console.log('signTransaction');
console.log(err);
});
txParams.r = `0x${result.r, 'hex'}`;
txParams.s = `0x${result.s, 'hex'}`;
txParams.v = `0x${result.v, 'hex'}`;
return result;
} catch (e) {
console.log(e);
}
}
makeSign(exParams).then(function () {
console.log("Promise Resolved2");
}.catch(function () {
console.log("Promise Rejected2");
});
When I only use signTransaction function, I can confirm the transaction in the ledger device and return txhash on the console. However, ultimately I want to broadcast a transaction to the main net. Could you please give me any idea? I want any feedback. Also, if there are any examples of creating and broadcasting a raw transaction by using the ledger, notice me please.
Your code already sends the transaction to the network. However, just awaiting the "send" promise only gives you the transaction hash, not the receipt. You need to treat it as an event emitter and wait for the 'confirmation' event.
const serializedTx = tx.serialize();
web3.eth.sendSignedTransaction(serializedTx.toString('hex'))
.once('transactionHash', hash => console.log('Tx hash', hash))
.on('confirmation', (confNumber, receipt) => {
console.log(`Confirmation #${confNumber}`, receipt);
})
.on('error', console.error);
To send it to mainnet as you mention, you can either run a local geth node on port 8545 and use your code unchanged, or point web3 at infura or similar.

Categories

Resources