Trigger a cloud build pipeline using Cloud Function - google-cloud-functions

I'm trying to create a cloud function listening to cloudbuilds topic and making an API call to trigger the build. I think I'm missing something in my index.js file (I'm new to Node.js). Can you provide a sample example of a Cloud Function making an API call to the Cloud Build API?
Here is my function:
const request = require('request')
const accessToken = '$(gcloud config config-helper --format='value(credential.access_token)')';
request({
url: 'https://cloudbuild.googleapis.com/v1/projects/[PROJECT_ID]/builds',
auth: {
'bearer': accessToken
},
method: 'POST',
json: {"steps": [{"name":"gcr.io/cloud-builders/gsutil", "args": ['cp','gs://adolfo-test-cloudbuilds/cloudbuild.yaml', 'gs://adolfo-test_cloudbuild/cloudbuild.yaml']}]},
},
module.exports.build = (err, res) => {
console.log(res.body);
});
I was executing the command gcloud config config-helper --format='value(credential.access_token)', copying the token, and putting it as a value to the variable accessToken. But this didn't work for me.
Here is the error: { error: { code: 403, message: 'The caller does not have permission', status: 'PERMISSION_DENIED' } }

I had the same exact problem and I have solved it by writing a small package, you can use it or read the source code.
https://github.com/MatteoGioioso/google-cloud-build-trigger
With this package you can run a pre-configured trigger from cloud build.
You can also extend to call other cloud build API endpoints.
As my understanding cloud build API requires either OAuth2 or a service account. Make sure you gave the right permission to cloud build in the gcp console under IAM. After that you should be able to download the service-account.json file.

Related

How to I access an endpoint covered by next-auth through google app script

So recently I decided that I need to access a protected api endpoint in google app script. The only thing I can find is app-script-oauth2, the reason this does not work is because my middleware for the tRPC endpoint (code below) says if there is not a session (which is stored in a prisma db) you cannot access the api.
.middleware(async ({ ctx: { session }, next }) => {
if (!session) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
return next();
})
I have also tried to login and try to make the request but it seems as if the request is completely unrelated to the local session. I know this isn't a ton to work from but any help at all would be greatly appreciated.

create channel with flex api from twilio serverless function

I am trying t ocreate a chat channel through nodejs twilio flex api, I can create it from other server or node project, but if I deploy it in twilio's serverless function it causes error ,seems it doesn't recognize flex api.
It gives error can not read property create of undefined.
Does twilio function has not included flex api yet?
code is as below:
const twilio = require('twilio')(context.ACCOUNT_SID, context.AUTH_TOKEN);
threadID=from
fromName=from
fromAddress=from
const channelArgs = {
flexFlowSid: 'FO.....',
identity: from,
chatUniqueName: from,
chatUserFriendlyName: from,
chatFriendlyName: from,
target: from,
preEngagementData: JSON.stringify({
threadID,
fromName,
fromAddress,
subject
})
};
twilio.flexApi.channel.create(channelArgs).then(channel => {
console.log('got chat channel', channel.sid);
Verify the Twilio Helper Library in use by your Twilio Functions environment is up to date.
You can find the most up to date Twilio Node Helper Library for twilio is below.
twilio-node changelog

Parse JSON file uploaded in S3 using Lambda

I'm trying to parse a JSON file that get's uploaded in S3. I invoke the lambda function using an S3 PUT/POST method trigger.
I'm using the following code.. however i'm not able to parse the json file. Can someone please help me?
var aws = require('aws-sdk');
var s3 = new aws.S3();
exports.handler = async (event, context, callback) => {
var srcBucket = event.Records[0].s3.bucket.name;
var srcKey = event.Records[0].s3.object.key;
console.log("Params: srcBucket: " + srcBucket + " srcKey: " + srcKey + "\n");
var getParams = {
Bucket: srcBucket,
Key: srcKey,
};
s3.getObject(getParams, function (err, data) {
if (err) console.log(err, err.stack);
else {
console.log(JSON.stringify(data.Body.toString()));
}
});
};
Your code looks correct However, I'd suggest taking the example from AWS docs as your starting point. Since your Lambda handler is an async handler, you have to await the promise returned by s3.getObject() , otherwise your function will complete before the callback executes (see the example code from the link).
Since you mention that your Lambda function cannot parse the file, I assume the function gets invoked by S3 trigger (i.e. you can see the console.log('Params: ...) line in Cloudwatch Logs). If that's not the case, first check that the S3 trigger is configured correctly and S3 has permission to invoke the Lambda function. If you created the function via AWS Console, this permission would have been set automatically.
The next step I'd suggest is to check the Lambda function's IAM role. Check if the IAM role has s3:GetObject permission for your bucket and all objects under it or for the specific prefix you have configured S3 notification (e.g. <bucket>/* or <bucket>/prefix/*).
If the Lambda IAM permissions are correct, you'll have to check S3 bucket policies. I suspect you haven't set up bucket policies according to what you describe.

Using custom libraries from apps script in App Maker: Authorization problem

I am using this code in Apps script
function getUserObjByEmail(email){
// Same as using AdminDirectory class.
var apiUrl = "https://www.googleapis.com/admin/directory/v1/users/"+email+"?fields=id";
var token = ScriptApp.getOAuthToken();
var header = {"Authorization":"Bearer " + token};
var options = {
"method": "GET",
"headers": header
};
var response = JSON.parse(UrlFetchApp.fetch(apiUrl, options));
return response;
}
which I run as a function from App Maker project. Things go smoothly when I use the app since I have an admin role( I guess, not sure ) but the problem arises when other normal users in our domain start using the deployed app maker app. I checked the server logs and its full of this message:
Exception: Request failed for
https://www.googleapis.com/admin/directory/v1/users/email#domain.com?fields=id
returned code 403.
Truncated server response: { "error": { "errors": [ { "domain": "global",
"reason": "forbidden", "message": "Not Authorized to access this
resource/api" ... (use muteHttpExceptions option to examine full response)
Any idea how to fix this? I have manually added the required scopes for the apps script library, I added the following:
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/admin.directory.user"
The reason this happens is because YOU have admin rights, otherwise you'd be getting the same error message. The other users don't have admin rights hence they get the error. To solve this problem, you can either deploy the application running it as the developer or you can use a service account to impersonate an admin and do the process.
Regarding the first approach, you can find more info here https://developers.google.com/appmaker/security/identity.
Regarding the second approach, you can use the following app script library https://github.com/gsuitedevs/apps-script-oauth2#using-service-accounts
Moreover, if you do not require to get custom schemas information, then you can simply use a directory model and that should work for all users. Check the reference here: https://developers.google.com/appmaker/models/directory

Does sending mail via nodemailer in firebase cloud functions require billing account?

I had deployed a firebase cloud function to send a welcome mail when a user signs in for the first time.
In the firebase console, in firebase cloud function log messages, I saw this error message when the function was invoked.
Error Message:
Billing account not configured. External network is not accessible and quotas are severely limited. Configure billing account to remove these restrictions
Is it not possible to send emails for free using firebase cloud functions? if it is possible, please explain the procedure. (Possiblly with a sample code)
Edit 1:
1. I am currently using nodemailer for sending mail.
2. I am using Gmail as the mail service.
Does sending mail via nodemailer in firebase cloud functions require billing account?
NO, You DO NOT need a billing account to send email via nodmailer using cloud functions.
I was getting the billing error as yours in my cloud function. And I have done 2 simple steps and it's gone.
1. In your gmail account setting, enable Less secure app access to ON
2. Also go to this link and click continue https://accounts.google.com/DisplayUnlockCaptcha .
After doing the above 2 steps, the billing error is gone, and email is sending successfully from the cloud function.
And here is my nodejs code for your refernce:
const functions = require('firebase-functions');
const nodemailer = require('nodemailer');
const mailTransport = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'xyzz#gmail.com',
pass: '123'
},
});
exports.sendMail = functions.https.onRequest(async (req, res) => {
const mailOptions = {
from: '"Test." <noreply#firebase.com>',
to: 'xyz#gmail.com'
};
// Building Email message.
mailOptions.subject = 'Thanks and Welcome!'
mailOptions.text = 'Thanks you for subscribing to our newsletter. You will receive our next weekly newsletter.'
try {
await mailTransport.sendMail(mailOptions);
console.log('subscription confirmation email sent to');
return res.send('Sended');
} catch (error) {
console.error('There was an error while sending the email:', error);
return res.send(error.toString());
}
});
You can test locally before you deploy it
firebase serve --only functions
you will get a link http://localhost:5000/project-name/us-central1/sendMail; paste it in the browser and the cloud function will run. If any errors it will show up in the browser and console/powershell