Goal
I would like Slack to trigger a Firebase Cloud Function.
Example: A user sends a Slack message, and Firebase Cloud Functions writes part of the message to the Firebase Database.
Tools: Slack API \ Event Subscription, googleapis, nodejs, etc.
Issue
The Slack documentation here describes the challenge response requirement.
Once you receive the event, respond in plaintext with the challenge
attribute value.
However, I'm not sure how to let Firebase know the Slack request is authorized. An HTTP request to Firebase Cloud Functions must include a Firebase ID. I've let googleapis do the work of setting up the Firebase ID, and I don't see a way to alter Slack's initial verification request (if I had an ID to provide)
What's the best way to trigger Firebase with the Slack API?
Getting Slack to verify the Firebase URL is pretty easy.
Solution
Google Firebase Cloud Function
import * as functions from "firebase-functions";
export const helloSlack = functions.https.onRequest((request, response) => {
if (request) {
response.status(200).send(request.body);
} else {
console.log("Request Error...");
throw response.status(500);
}
});
Steps
Deploy your Firebase Cloud Function
Goto https://api.slack.com/apps
Your App > Event Subscriptions > Enable Events
Turn on Events
Enter your Firebase Cloud Functions URL
tl;dr
Slack instructions:
We’ll send HTTP POST requests to [your] URL when events occur. As soon
as you enter a URL, we’ll send a request with a challenge parameter,
and your endpoint must respond with the challenge value.
Cloud Function URL:
https://firebase-slack-adaptor.cloudfunctions.net/helloSlack
To meet the verification challenge, enter your Firebase Cloud Functions URL (example above) in Slack's Request URL field.
Your Firebase Cloud Function should return the body of the Slack request. Slack finds what it needs in request.body and should verify your URL.
Related
Firebase callable cloud functions can be accessed via client sdks, which requires a valid auth context for authentication and authorization. But and at the same time it is exposed as an HTTP endpoint, thus can be called but will receive an unauthorized response.
My questions is, is there a way to completely restrict public access for a callable cloud functions? since firebase will charge cloud functions based on function executions. Even to return an unauthorized response, the request has already gone through to the function, thus during a DDoS attack this could be problematic.
There is no built-in support for rejecting a request to a Cloud Function before it reaches your code. If you want such functionality consider setting up Cloud Endpoints in front of your Cloud Functions.
The best you can with just Cloud Functions do is check whether the caller is authorized as the first thing in your function code, so that you reduce the amount of time the function is active. You'll still be charged for the invocation in that case, but you'll minimize the GB-seconds and CPU-seconds.
I tried out as #Frank suggested using google cloud run to deploy and ESP container which can by used to invoke private cloud functions. A detailed overview is described in the documentations itself.
https://cloud.google.com/endpoints/docs/openapi/get-started-cloud-functions#deploy_endpoints_proxy
Above given answer by #Frank van Puffelen is perfect but you can utilize a trik to restrict the access by securing that route. Here is the example,
const functions = require('firebase-functions');
exports.scheduleSampleJob = functions.https.onRequest((req , res) => {
let auth = req.header('Authorization');
if(auth == 'YOUR_API_AUTHORIZATION_KEY'){
// valid Authorization key, process the call
}else{
//send forbidden if Authorization key not valid
return res.status(403).send('Access is Forbidden');
}
});
Now, if you want to call the endpoint, It will require a Authorization header in request having value your secret key.
As firebase cloud function can also be used with firebase-auth, you can create custom logic to allow access to users having auth only and restrict the access for public excluding your app's authentic users.
I'm a little stuck here.
I'm trying to hook a Calendar Push Notifications (https://developers.google.com/calendar/v3/push) to a Firebase HTTPS Function.
Pratically, I use a FF to create a calendar and I want to watch it for changes.
I authorized my domain and compose a request from the first function using the appspot service account ('#appspot.gserviceaccount.com') with the scope 'https://www.googleapis.com/auth/calendar' but I always received the error message: "Unauthorized WebHook callback channel: https://******.cloudfunctions.net/calendarWebHook"}],"
I'm trying to understand if the service account doesn't have the authorization to create the watcher or the webHook or something else.
I'm in the final stages of development for my new mobile app, but can't seem to find a way to allow Google Play Real-Time Developer Notifications to communicate to a firebase cloud function via the recommended Google Pub/Sub method.
The expected payload flow should go as follows:
User Purchases Subscription via Play Store > Play Store sends R-T Dev Notification to Pub/Sub > Pub/Sub sends message across to firebase cloud function > Cloud function runs with payload.
I currently have an Apple Developer webhook set-up in a similar way, which webhooks a receipt payload to an iOS cloud function I have setup.
During the pub/sub setup phase, the Pub/Sub page asks to verify the cloud function URL, which I cannot do as I am not the true webmaster of cloud function domain, hence halting me about halfway down the 'Add real-time developer notification' docs that google supplies.
Is there a way to get the RT notification to either a Pub/Sub cloud function or a HTTPS cloud function bypassing the google Pub/Sub and going directly to the webhook or another way to complete the flow above?
The ultimate aim is to provide a way to ensure the purchase made is actually a valid purchase, and not a forged request made by someone intercepting the client > server webhook and submitting one of their own accord.
After creating the new topic you DO NOT have to create manually a Pub/Sub subscription as explained in the documentation.
To make it work with firebase you have to deploy a new cloud function like this:
exports.YOUR_FUNCTION_NAME = functions.pubsub.topic('YOUR_TOPIC_NAME').onPublish((message) => {
// Decode the PubSub Message body.
const messageBody = message.data ? Buffer.from(message.data, 'base64').toString() : null;
// Print the message in the logs.
console.log(`Hello ${messageBody || 'World'}!`);
return null;
});
Please note that you need to replace YOUR_FUNCTION_NAME and YOUR_TOPIC_NAME.
When the deploy of this function finish, you will finally find the function in the subscription list.
At this point, you can edit the params of the automatically created subscription, and you will find the url endpoint already filled with an internal url.
Here you can find an example: how to setup a PubSub triggered Cloud Function using the Firebase SDK for Cloud Functions.
I'm wondering if it is possible to get a response message when Firebase Cloud Function is executed succesfully.
The case is I'm trying to send an email, but I would like to make sure it is sent and received by the receiver.
If you use Sendgrid to send emails, as recommended by Firebase (see https://github.com/firebase/functions-samples/tree/master/quickstarts/email-users), you can use Sendgrid's Events Webhooks, see https://sendgrid.com/docs/for-developers/tracking-events/event/#engagement-events and https://sendgrid.com/docs/for-developers/tracking-events/getting-started-event-webhook/.
As explained in the last link above, "SendGrid's Event Webhook will notify a URL of your choice via HTTP POST with information about events that occur as SendGrid processes your email. "
You just have to setup an HTTP Cloud Function that will be called by Sendgrid for the events of your choice.
I've created a cloud functions in firebase and I want to get response of the functions back to Android app.
Cloud functions is written in typescript and is like
exports.validateOtp = functions.https.onRequest((req,res)=>{
phoneNumber = req.query.phoneNumber;
otp = req.query.otp;
getVal();
function getVal(){
let result = authFunction.userValidation(phoneNumber,otp).then(function(boolResult){
return res.status(204).send(result);
});
}
});
How can I fetch the value of result at client side or android app?
Since your Cloud Function is an HTTPS one it will be triggered when you send an HTTP request (GET, POST, PUT, DELETE and OPTIONS) to the function endpoint.
In your case the function endpoint URL will be
https://us-central1-<your-project-id>.cloudfunctions.net/validateOtp
see https://firebase.google.com/docs/functions/http-events#invoke_an_http_function
There are several possible ways to send an HTTP request from an Android app to an HTTP endpoint. You could use the Volley library, the android-async-http library or the Retrofit one, for example.
Note that it may be interesting to switch to an HTTPS Callable Cloud Function instead of a "simple" HTTPS Cloud Function.
As explained in the doc, "the Cloud Functions for Firebase client SDKs let you call functions directly from a Firebase app. To call a function from your app in this way, write and deploy an HTTPS Callable function in Cloud Functions".
Among the advantages offered by HTTPS Callable functions you will find the fact that it "automatically deserializes the request body", that it "validates auth tokens" as well as the fact that you don't need to use an extra library to call the Function, but just to use the code detailed in the doc.