Cloud Function triggered by Pub Sub doesn't publish expected message - google-cloud-functions

I have the following google cloud function:
def run_msg(event, context):
print(event["data"])
url = 'google_chat_hook'
bot_message = {
'text' : '{}'.format(event["data"])}
message_headers = { 'Content-Type': 'application/json; charset=UTF-8'}
http_obj = Http()
response = http_obj.request(
uri=url,
method='POST',
headers=message_headers,
body=dumps(bot_message),
)
When I'm testing the function directly from the Cloud Function Interface with the following trigger event {"data": {"message": "test"}} I have the right message being published in google chat => {"message": "test"} but when I'm publishing a message from pub sub manually I have the following kind of stuff being posted on google chat iB7Im1lc3NhZ2UiOiAibXNnX2Nvb2wifX
I can't understand what's happening here.

Simply copy paste the sample code in the documentation
base64.b64decode(event['data']).decode('utf-8')
VoilĂ ! It's base64 encoded. Decode it and you will see it!

Related

HTTP Request to Discord API Through Google Apps Script Results in 403 Error With Response "Error Code 1020"

I'm having trouble getting guild channels with this code in Google Apps Script.
var token = "MY_TOKEN"
var url = "https://discord.com/api/v10/guilds/[GUILD_ID]/channels"
var header = {
Authorization: "Bot " + token
}
function myFunction(){
var params = {
method: "get",
headers: header,
muteHttpExceptions: false
}
var response = UrlFetchApp.fetch(url,params)
Logger.log(response.getContentText())
}
Running myFunction() results in this error message:
Exception: Request failed for https://discord.com returned code 403. Truncated server response: error code: 1020 (use muteHttpExceptions option to examine full response)
or just this if the muteHttpExceptions value is true:
error code: 1020
Some information that may be useful to diagnose my problem:
My bot is in my server, but it's shown to be offline in the member list (does it matter?)
My bot is a private bot
I have made sure that the bot token and guild ID are correct
I invited the bot to my server via a generated link in OAuth2 URL generator in Discord Developer Portal. I checked the bot scope only with administrator permission. (Additional info: The first time I tried generating URL, it didn't need a redirect URL. But for some reason, it requires me to select one from a dropdown list now, but when I click on the dropdown, the list is empty as shown in the screenshot, so I can't select one and can't generate URL from there anymore.)
Get Current User Guild (/users/#me/guilds) runs perfectly fine. It returns this array:
[
{
"id": "[GUILD_ID]",
"name": "[GUILD_NAME]",
"icon": null,
"owner": false,
"permissions": "4398046511103",
"features": [
"APPLICATION_COMMAND_PERMISSIONS_V2"
]
}
]
I think my problem has something to do with the bot permissions, but I'm just lost.

GET method for an Azure function within Azure Data Factory fails

I am trying to invoke an HTTP triggered Azure function built on with a GET request. I setup the linked service as per the recommended steps and the function itself works with a query string through POSTMAN or internet browser, but fails when I try to invoke through Data factory.
{
"errorCode": "3608",
"message": "Call to provided Azure function '' failed with status-'NotFound' and message - 'Invoking Azure function failed with HttpStatusCode - NotFound.'.",
"failureType": "UserError",
"target": "Azure Function1",
"details": []
}
I came across another stackoverflow post https://stackoverflow.com/a/54497119/4212430 where there was a mention of a JSON response for ADF.
I have since changed my python code to provide an HTTP response as a JSON object as below
def main(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
statename = req.params.get('statename')
if not statename:
try:
req_body = req.get_json()
except ValueError:
pass
else:
statename = req_body.get('statename')
if statename:
initiate_main(statename)
host.close()
function_message = {"Response":"Successfully trasnferred BOM files"}
return func.HttpResponse(
json.dumps(function_message),
mimetype="application/json",
status_code=200)
else:
function_message = {"Response":"Error in transferring files"}
return func.HttpResponse(
json.dumps(function_message),
mimetype="application/json",
status_code=400)
But that hasn't helped either.
It turns out that I was using the wrong URI with an api added at the end while I should have just been giving the plain function name

Scraping - catch json response with python

I need to scrape a website with a "load more" button.
I need to catch the json response (which is invisible in the html code) and parse it to build URLs
This is the JSON post request response
I'm using Selenium, python.
how do I ?
tHX
You can bypass actually clicking on the "load more" button by reading the API call that the website is sending when you click the button and then sending it via Selenium. If you send it through Selenium, you can capture the response. Here's what I've been using an Angular website. You'll have to modify it to work with the website you're using, but this should get you started.
call = """
$http = angular.element(document.body).injector().get('$http');
var done = arguments[0];
$http({
method: 'POST',
headers: {
"Content-Type": "application/json"
},
data: {
foo: "bar"
},
url: "https://request.url/"
}).then(data => done(data));
"""
json_response = driver.execute_async_script(call)
The execute_async_script method will make the call and wait for a JSON response.
You can also right-click on the xhr in Chrome DevTools and copy the API call, which should make it easier to recreate it with selenium.
Let me know if you have follow-up questions.

Stackdriver export to .txt or PDF on drive/mail

I've set up an script which reads data from a spreadsheet and sends emails according this data.
Now, I've also set it up to do some simple logging via stackdriver.
What I'd like to do is to export these logs (after/at the end of every execution of the mail-script) to a .txt or .pdf file which then get saved to a specific Google Drive folder or been send by mail.
Unfortunately I can't seem to find out how to do this, or if its even posible?
There is no way to edit a Google docs file if this is what you where thinking of doing. Your going to have to create your .txt or .pdf file locally then upload the file to Google drive or send it as an email. Technically if you upload the file as a .txt i think that Google drive will allow you to export it as pdf but i haven't tried with the new version of Google drive.
var fileId = '1ZdR3L3qP4Bkq8noWLJHSr_iBau0DNT4Kli4SxNc2YEo';
var dest = fs.createWriteStream('/tmp/resume.pdf');
drive.files.export({
fileId: fileId,
mimeType: 'application/pdf'
})
.on('end', function () {
console.log('Done');
})
.on('error', function (err) {
console.log('Error during download', err);
})
.pipe(dest);
Downloading google Documents
I also dont think that you will be able to email a file directly from Google Drive you will have to download the file locally then add send your email.
Stackdriver has an error reporting API. Documentation for Stackdriver The API has REST capability, which means that you can call it from Apps Script using UrlFetchApp.fetch(url) where url is the url needed to get error reporting information. The base url for the Stackdriver API is: https://clouderrorreporting.googleapis.com The API must be enabled.
There are multiple methods that can be used with the API.
The method that you probably need is the list method, which requires the url:
https://clouderrorreporting.googleapis.com/v1beta1/{projectName=projects/*}/events
where the projectName parameter must be a Google Cloud Platform project ID.
See documentation on list at: projects.events.list
The return value for that HTTPS Request, if successful, is a "response body" with the following structure and data:
{
"errorEvents": [
{
object (ErrorEvent)
}
],
"nextPageToken": string,
"timeRangeBegin": string
}
The ErrorEvent is a JSON object with the following structure and data:
{
"eventTime": string,
"serviceContext": {
object (ServiceContext)
},
"message": string,
"context": {
object (ErrorContext)
}
}
So, if you want to send an email with error data from Stackdriver, it won't be sent directly from Stackdriver, you need to make a request to Stackdriver from Apps Script, get the error information, and then send an email from Apps Script.
Of course, you could have your own error handling system, that logged error information to some external target, (Eg. your spreadsheet, or a database) using UrlFetchApp.fetch(url);
To make the request to the Stackdriver API you would need code something like this:
var projectID = "Enter project ID";
var url = 'https://clouderrorreporting.googleapis.com/v1beta1/' + projectID
+ '/events';
var tkn = ScriptApp.getOAuthToken();
var options = {};
options.headers = {Authorization: 'Bearer ' + tkn}
options.muteHttpExceptions = true;
var rtrnObj = UrlFetchApp.fetch(url,options);
Logger.log(rtrnObj.getContentText())
I haven't use this API and I haven't tested this code. If anyone uses it, and has information or finds an error, please make a comment.

Invalid Argument on basic API call using UrlFetchApp.fetch(url)

I'm new to Google Apps Scripts and I've been trying to make a simple Get call to a URL. I make this call from my browser: https://accounting.sageone.co.za/api/1.1.1/Supplier/Get?apikey={4CFEEFE1-CE04-425F-82C3-DCB179C817D5}&companyid=164740 and get the respons I'm looking for. I now try to make the call from Google Apps Scripts using the following code:
function myFunction() {
var url = 'https://accounting.sageone.co.za/api/1.1.1/Supplier/Get?apikey={4CFEEFE1-CE04-425F-82C3-DCB179C817D5}&companyid=164740
var response = UrlFetchApp.fetch(url);
Logger.log(response);
}'
I get a respons stating '
Message details
Invalid argument: https://accounting.sageone.co.za/api/1.1.1/Supplier/Get?apikey={4CFEEFE1-CE04-425F-82C3-DCB179C817D5}&companyid=164740 (line 4, file "Code")'
I've tried a whole bunch of permutations with no luck...
When using UrlFetchApp, you need to enter your URL parameters as part of a request parameters rather than in the URL itself. For a GET request these go directy as part of the parameters, for a POST request the parameters would be part of a payload object. Reference Documentation
Here is a modified function:
function myFunction() {
var url = 'https://accounting.sageone.co.za/api/1.1.1/Supplier/Get'
var params = {
"method": 'GET',
"apikey": "{4CFEEFE1-CE04-425F-82C3-DCB179C817D5}",
"companyid": "164740"
}
var response = UrlFetchApp.fetch(url, params);
Logger.log(response)
}
Note: This corrects your method, however, the server still requires further authentication. If you run into issues with that, ask another questions specific to that issue as well.