Google-script; Conversion from the format application / octet-stream to application / pdf is not supported - pdf

I have a similar error to ERROR Get pdf-attachments from Gmail as text but it doesn't work in my case. Drive API's enable. Document has the extension .pdf.
This script works for other documents (also pdf).
Read pdf as text is from Get pdf-attachments from Gmail as text
Please help.
This is my code:
function searchEmails() {
var threads = GmailApp.search('in:inbox newer_than:6d');
if (threads.length > 0) {
for (var t=threads.length-1; t>=0; t--) {
var thread = threads[t];
var message = thread.getMessages()[0];
var from = message.getFrom();
var subject = message.getSubject();
var to = message.getTo();
var date = message.getDate();
var body = message.getBody();
var attachments = message.getAttachments();
if (subject == 'subject') {
Messages(message)
}
}
}
}
function Messages(message) {
var attachments = message.getAttachments();
var blob = attachments[0].getAs(MimeType.PDF);
var body = message.getBody();
var filetext = pdfToText(blob);
filetext = filetext.substr(filetext.search("Title:"));
filetext = filetext.split(' ');
var msgValue = filetext[12];
var msgDate = filetext[6];
var msgID = message.getId();
// rest of my code
function pdfToText (blob, options) {
options = options || {};
var parents = [];
if (options.path) {
parents.push(getDriveFolderFromPath(options.path));
}
var pdfName = blob.getName();
var resource = {
title: pdfName,
mimeType: blob.getContentType(),
parents: parents
};
// Save PDF as GDOC
resource.title = pdfName.replace(/pdf$/, 'gdoc');
var insertOpts = {
ocr: true,
ocrLanguage: options.ocrLanguage || 'pl'
}
var gdocFile = Drive.Files.insert(resource, blob, insertOpts);
// Get text from GDOC
var gdocDoc = DocumentApp.openById(gdocFile.id);
var text = gdocDoc.getBody().getText();
// Delete document.
if (!options.keepGdoc) {
Drive.Files.remove(gdocFile.id);
}
return text;
}
function getDriveFolderFromPath (path) {
return (path || "/").split("/").reduce ( function(prev,current) {
if (prev && current) {
var fldrs = prev.getFoldersByName(current);
return fldrs.hasNext() ? fldrs.next() : null;
}
else {
return current ? null : prev;
}
},DriveApp.getRootFolder());
}

First of all my first code works. However, if there is more than one attachment in email, you will have problems I had originally. Solution below:
function searchEmails() {
var threads = GmailApp.search('in:inbox newer_than:6d');
if (threads.length > 0) {
for (var t=threads.length-1; t>=0; t--) {
var msgs = GmailApp.getMessagesForThreads(threads);   
for (var i = 0 ; i < msgs.length; i++) {   
for (var j = 0; j < msgs[i].length; j++) {     
var attachments = msgs[i][j].getAttachments();               
for (var k = 0; k < attachments.length; k++) {         
var content = attachments[k].getContentType();               
Logger.log(attachments[k].getName()) //check file extension
if (content == 'application/pdf'){
 
/*
you can check if the attachment has the expected name
var attachmentsName = attachments[k].getName();
          if (attachmentsName == 'looking name'){
*/
      var blob = attachments[k].getAs(MimeType.PDF);           
var filetext = pdfToText(blob);           
filetext = filetext.substr(filetext.search("SZCZEGÓŁY"));           
filetext = filetext.split(' ');                       
var msgValue = filetext[14] + filetext[15];           
var msgDate = filetext[6];           
var type = filetext[3];           
// rest of my code
function pdfToText (blob, options) {
options = options || {};
var parents = [];
if (options.path) {
parents.push(getDriveFolderFromPath(options.path));
}
var pdfName = blob.getName();
var resource = {
title: pdfName,
mimeType: blob.getContentType(),
parents: parents
};
// Save PDF as GDOC
resource.title = pdfName.replace(/pdf$/, 'gdoc');
var insertOpts = {
ocr: true,
ocrLanguage: options.ocrLanguage || 'pl'
}
var gdocFile = Drive.Files.insert(resource, blob, insertOpts);
// Get text from GDOC
var gdocDoc = DocumentApp.openById(gdocFile.id);
var text = gdocDoc.getBody().getText();
// Delete document.
if (!options.keepGdoc) {
Drive.Files.remove(gdocFile.id);
}
return text;
}
function getDriveFolderFromPath (path) {
return (path || "/").split("/").reduce ( function(prev,current) {
if (prev && current) {
var fldrs = prev.getFoldersByName(current);
return fldrs.hasNext() ? fldrs.next() : null;
}
else {
return current ? null : prev;
}
},DriveApp.getRootFolder());
}

Related

How to send LTI 1.3 LtiDeepLinkingResponse using .NET Core

We are struggling to send LtiDeepLinkingResponse using .NET core. Getting Error as {"errors":{"jwt":[{"attribute":"jwt","type":"JWT format is invalid","message":"JWT format is invalid"}]}}
We are referring the solution provided here https://github.com/LtiLibrary/LtiAdvantage
In Code forming a response as
var Token = handler.ReadJwtToken(idToken);
LtiDeepLinkRequest = new LtiDeepLinkingRequest(Token.Payload);
var response = new LtiDeepLinkingResponse
{
Data = LtiDeepLinkRequest.DeepLinkingSettings.Data,
DeploymentId = LtiDeepLinkRequest.DeploymentId
};
var contentItems = new List<ContentItem>();
var customParameters = LtiDeepLinkRequest.Custom;
var platformId = "1000000101";
List<UseCase> selectedUsecases = new List<UseCase>();
selectedUsecases.Add(new UseCase
{
WebGLUrl = "our_web_page.html",
Module = "ModuleName",
Description = "Module Description",
Topics = "Module Topics"
});
foreach (var useCase in selectedUsecases)
{
var url = Url.Page("/Index", null, new { platformId = platformId }, Request.Scheme);
var contentItem = new LtiLinkItem
{
Title = useCase.Module,
Text = useCase.Description,
Url = url,
Custom = new Dictionary<string, string>
{
{ "activity_id", useCase.Id.ToString() }
}
};
if (customParameters != null)
{
foreach (var keyValue in LtiDeepLinkRequest.Custom)
{
contentItem.Custom.TryAdd(keyValue.Key, keyValue.Value);
}
}
contentItems.Add(contentItem);
}
response.ContentItems = contentItems.ToArray();
response.AddClaim(new Claim(JwtRegisteredClaimNames.Iss, LtiDeepLinkRequest.Aud[0]));
response.AddClaim(new Claim(JwtRegisteredClaimNames.Aud, LtiDeepLinkRequest.Iss));
response.AddClaim(new Claim(JwtRegisteredClaimNames.Sub, LtiDeepLinkRequest.Sub));
response.AddClaim(new Claim(JwtRegisteredClaimNames.Iat, EpochTime.GetIntDate(DateTime.UtcNow).ToString()));
response.AddClaim(new Claim(JwtRegisteredClaimNames.Nbf, EpochTime.GetIntDate(DateTime.UtcNow.AddSeconds(-5)).ToString()));
response.AddClaim(new Claim(JwtRegisteredClaimNames.Exp, EpochTime.GetIntDate(DateTime.UtcNow.AddMinutes(5)).ToString()));
response.AddClaim(new Claim(JwtRegisteredClaimNames.Nonce, IdentityModel.CryptoRandom.CreateUniqueId(8)));
RsaSecurityKey key = new RsaSecurityKey(RSA.Create());
key.KeyId = "ourjwkskeyid";
var credentials = new SigningCredentials(key, SecurityAlgorithms.RsaSha256);
var header = new JwtHeader(credentials);
var jwt = handler.WriteToken(new JwtSecurityToken(header, response));
return Post("JWT", jwt, LtiDeepLinkRequest.DeepLinkingSettings.DeepLinkReturnUrl);
Other required methods are-
private static ContentResult Post(string name, string value, string url)
{
return new ContentResult
{
Content = "<html><head><title></title></head><body onload=\"document.contentitems.submit()\">"
+ $"<form name=\"contentitems\" method=\"post\" action=\"{url}\">"
+ $"<input type=\"hidden\" name=\"{name}\" value=\"{value}\" /></body></html>",
ContentType = "text/html",
StatusCode = StatusCodes.Status200OK
};
}
We have confirmed that the payload is getting formatted correctly. Payload is
{
  "https://purl.imsglobal.org/spec/lti/claim/message_type": "LtiDeepLinkingResponse",
  "https://purl.imsglobal.org/spec/lti/claim/version": "1.3.0",
  "iss": "1000000101",
  "aud": "https://canvas.instructure.com",
  "exp": "1674104792",
  "iat": "1674104492",
  "nonce": "gdT446jJTgc",
  "azp": "0omiNPx2v5Q",
  "https://purl.imsglobal.org/spec/lti/claim/deployment_id": "11767:105256654",
  "https://purl.imsglobal.org/spec/lti-dl/claim/content_items": [
    {
      "custom": {
        "activity_id": "0"
      },
      "text": "Module Description",
      "title": "ModuleName",
      "type": "ltiResourceLink",
      "url": "our_web_page.html"
    }
  ]
}
Could you please guide what could be missing in this? Or any .NET Core libraries reference from where we can explore how can we send LtiDeepLinkingResponse

Why "not defined" error returned when rendering an EJS template from ExpressJS app.locals variable?

ExpressjS Application End-Point (request)
app.get('/', (req, res, next) => {
db.collection('sys_params').find().toArray((err, sysParams) => {
if (err) throw err;
app.locals.landPageRolloverStatus = sysParams[0].landPageRolloverStatus;
app.locals.ludenourOnlineStatus = sysParams[0].ludenourOnlineStatus;
app.locals.ludenourContactUsEnabled = sysParams[0].ludenourContactUsEnabled;
app.locals.ludenourJobsEnabled = sysParams[0].ludenourJobsEnabled;
console.log(sysParams)
app.locals.sysParams = sysParams;
});
res.render('index2');
next()
});
The error is related to the app.locals.sysParams.
ReferenceError: /Users/falswaimil/Documents/Project3X/Master/AIRECP/AirECPRetails/online-store/views/index2.ejs:39
   37|
   38| <a class="navbar-brand float-xs-right float-sm-left" href="http://localhost:3002/?clang=en"><img src="img/lu3.svg" class="img-fluid"/></a>
>> 39|         <% if (sysParams[0].ludenourOnlineStatus == "UC" ) { %>
   40|
   41|             <% if (clang == "en") {  %>
   42|                 <p style="color:red; font-family:Arial Rounded MT Bold; font-size:130%; text-align:center; width: 100%;"><%= __('SiteUnderConstruction') %></p>  
sysParams is not defined
However; when I refresh the page, the page is rendered without errors.
Because I am passing an expressJS application-level variable, it should be available on the EJS template across requests.
The issue with properly handling async operations. After using async/await in my middleware, the error resolved.
const readBootstrap = async(req, res, next) => {
await db.collection('sys_params').find().toArray()
.then(sysParams => {
app.locals.landPageRolloverStatus = sysParams[0].landPageRolloverStatus;
app.locals.ludenourOnlineStatus = sysParams[0].ludenourOnlineStatus;
app.locals.ludenourContactUsEnabled = sysParams[0].ludenourContactUsEnabled;
app.locals.ludenourJobsEnabled = sysParams[0].ludenourJobsEnabled;

Google pay not visible on android chrome device if the allowedCardAuthMethod is CRYPTOGRAM 3DS

In Android Chrome, When trying to initialize Google pay with allowedCardAuthMethod as Cryptogram 3ds, not able to view the google pay button
I am trying from India.
sample code: https://jsfiddle.net/dummy4150/8e2cbs6d/
const baseRequest = {
  apiVersion: 2,
  apiVersionMinor: 0
};
const allowedCardNetworks = ["AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA"];
const allowedCardAuthMethods = ["CRYPTOGRAM_3DS"];
const tokenizationSpecification = {
  type: 'PAYMENT_GATEWAY',
  parameters: {
    'gateway': 'example',
    'gatewayMerchantId': 'exampleGatewayMerchantId'
  }
};
const baseCardPaymentMethod = {
  type: 'CARD',
  parameters: {
    allowedAuthMethods: allowedCardAuthMethods,
    allowedCardNetworks: allowedCardNetworks
  }
};
const cardPaymentMethod = Object.assign(
  {},
  baseCardPaymentMethod,
  {
    tokenizationSpecification: tokenizationSpecification
  }
);
Since you've specified allowedCardAuthMethods as CRYPTOGRAM_3DS and that you are trying from India, Here are a couple of things you could try:
Add a tokenized card to Google Pay (one that can be used for Tap and Pay)
Generally, Google Pay isn't currently supported in India, join the googlepay-test-mode-stub-data to use predefined test data that can be used in India (more info)
Create a new Google Account for testing based outside of India (suggest using USA) and add a tokenized card to that account

Bings Ads Script - Calling Google Services not working

I'm trying to run a script in Bing Ads that will get the performance data and write it in Google Sheets. I based my code on Microsoft example: https://learn.microsoft.com/en-us/advertising/scripts/examples/calling-google-services
However, my code won't work.
function main() {
// Set these fields based on the option you chose for getting an access token.
const credentials = {
accessToken: '',
clientId: '',
clientSecret: '',
refreshToken: ''
};
 
// To get a fileId or spreadsheetId, please see
// https://developers.google.com/sheets/api/guides/concepts#spreadsheet_id.
 
// The file must contain a single bid multiplier value (for example,1.1),
// which is used to update keyword bids.
const fileId = 'INSERT FILE ID HERE';
 
// The spreadsheet must contain 3 valid keyword IDs in cells A2, A3, and A4.
const spreadsheetId = 'INSERT SPREADSHEET ID HERE';
// The email address to send a notification email to at the end of the script.
const notificationEmail = 'INSERT EMAIL HERE';
 
var driveApi = GoogleApis.createDriveService(credentials);
 
// Read bid multiplier from the file.
// Reference: https://developers.google.com/drive/api/v3/reference/files/export
var bidMultiplier = driveApi.files.export({ fileId: fileId, mimeType: 'text/csv' }).body;
 
Logger.log(`read bid multiplier ${bidMultiplier}`);
 
var sheetsApi = GoogleApis.createSheetsService(credentials);
 
// Write the old and new bid values back to the spreadsheet.
// Reference: https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/batchUpdate
var campaignData = [];
var campaigns = AdsApp.campaigns().withCondition('Cost > 0').forDateRange('THIS_MONTH');
var campaignIterator = campaigns.get();
var iterator = 0;
while(campaignIterator.hasNext()) {
var campaign = campaignIterator.next();
var campaignName = campaign.getName();
var stats = campaign.getStats();
var cost = stats.getCost();
var clicks = stats.getClicks();
var conversions = stats.getConversions();
   var impressions = stats.getImpressions();
campaignData[iterator] = {"CampaignName":campaignName,"cost":cost,"clicks":clicks,"conversions":conversions,"impressions":impressions};
iterator++;
}
var updateResponse = sheetsApi.spreadsheets.values.batchUpdate({ spreadsheetId: spreadsheetId }, {
data: [
{ range: 'A2:G2', values: campaignData.map(x => [x]) },
],
valueInputOption: 'USER_ENTERED'
});
 
Logger.log(`updated ${updateResponse.result.totalUpdatedCells} cells`);
 
var gmailApi = GoogleApis.createGmailService(credentials);
 
var email = [
`To: ${notificationEmail}`,
'Subject: Google Services script',
'',
`You script ran successfully ✓ and updated ${updateResponse.result.totalUpdatedCells} cells.`
].join('\n');
 
// Send the notification email.
// Reference: https://developers.google.com/gmail/api/v1/reference/users/messages/send
var sendResponse = gmailApi.users.messages.send({ userId: 'me' }, { raw: Base64.encode(email) });
 
Logger.log(`sent email thread ${sendResponse.result.threadId}`);
}
 
var GoogleApis;
(function (GoogleApis) {
function createSheetsService(credentials) {
return createService("https://sheets.googleapis.com/$discovery/rest?version=v4", credentials);
}
GoogleApis.createSheetsService = createSheetsService;
 
function createDriveService(credentials) {
return createService("https://www.googleapis.com/discovery/v1/apis/drive/v3/rest", credentials);
}
GoogleApis.createDriveService = createDriveService;
 
function createGmailService(credentials) {
return createService("https://www.googleapis.com/discovery/v1/apis/gmail/v1/rest", credentials);
}
GoogleApis.createGmailService = createGmailService;
 
// Creation logic based on https://developers.google.com/discovery/v1/using#usage-simple
function createService(url, credentials) {
var content = UrlFetchApp.fetch(url).getContentText();
var discovery = JSON.parse(content);
var baseUrl = discovery['rootUrl'] + discovery['servicePath'];
var accessToken = getAccessToken(credentials);
var service = build(discovery, {}, baseUrl, accessToken);
return service;
}
 
function createNewMethod(method, baseUrl, accessToken) {
return (urlParams, body) => {
var urlPath = method.path;
var queryArguments = [];
for (var name in urlParams) {
var paramConfg = method.parameters[name];
if (!paramConfg) {
throw `Unexpected url parameter ${name}`;
}
switch (paramConfg.location) {
case 'path':
urlPath = urlPath.replace('{' + name + '}', urlParams[name]);
break;
case 'query':
queryArguments.push(`${name}=${urlParams[name]}`);
break;
default:
throw `Unknown location ${paramConfg.location} for url parameter ${name}`;
}
}
var url = baseUrl + urlPath;
if (queryArguments.length > 0) {
url += '?' + queryArguments.join('&');
}
var httpResponse = UrlFetchApp.fetch(url, { contentType: 'application/json', method: method.httpMethod, payload: JSON.stringify(body), headers: { Authorization: `Bearer ${accessToken}` }, muteHttpExceptions: true });
var responseContent = httpResponse.getContentText();
var responseCode = httpResponse.getResponseCode();
var parsedResult;
try {
parsedResult = JSON.parse(responseContent);
} catch (e) {
parsedResult = false;
}
var response = new Response(parsedResult, responseContent, responseCode);
if (responseCode >= 200 && responseCode <= 299) {
return response;
}
throw response;
}
}
 
function Response(result, body, status) {
this.result = result;
this.body = body;
this.status = status;
}
Response.prototype.toString = function () {
return this.body;
}
 
function build(discovery, collection, baseUrl, accessToken) {
for (var name in discovery.resources) {
var resource = discovery.resources[name];
collection[name] = build(resource, {}, baseUrl, accessToken);
}
for (var name in discovery.methods) {
var method = discovery.methods[name];
collection[name] = createNewMethod(method, baseUrl, accessToken);
}
return collection;
}
 
function getAccessToken(credentials) {
if (credentials.accessToken) {
return credentials.accessToken;
}
var tokenResponse = UrlFetchApp.fetch('https://www.googleapis.com/oauth2/v4/token', { method: 'post', contentType: 'application/x-www-form-urlencoded', muteHttpExceptions: true, payload: { client_id: credentials.clientId, client_secret: credentials.clientSecret, refresh_token: credentials.refreshToken, grant_type: 'refresh_token' } });
var responseCode = tokenResponse.getResponseCode();
var responseText = tokenResponse.getContentText();
if (responseCode >= 200 && responseCode <= 299) {
var accessToken = JSON.parse(responseText)['access_token'];
return accessToken;
}
throw responseText;
}
})(GoogleApis || (GoogleApis = {}));
 
// Base64 implementation from https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/master/lib/msal-core/src/Utils.ts
class Base64 {
static encode(input) {
const keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
let output = "";
let chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = this.utf8Encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
}
else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
}
return output.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
}
static utf8Encode(input) {
input = input.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < input.length; n++) {
var c = input.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
}
The first part of the code which brings back values from the spreadsheet works, but when it gets to writing the data in Google Sheets, I get an error and I don't know what it means.
{
"error": {
"code": 404,
"message": "Requested entity was not found.",
"status": "NOT_FOUND"
}
}
at (script code:142:7)

what is Jenkins file and how you will write

What is Jenkins file and How we will write?
How to create Jenkins job dynamically using DSL(I'm not aware of DSL)
From 30 page of Jenkins User Handbook: `Jenkinsfile is a text file that contains the definition of a Jenkins Pipeline and is checked into source control. In his chapter you can find examples of pipelines.
// Declarative //
pipeline {
agent any
  stages {
  stage('Build') {
  steps {
  echo 'Building..'
  }
  }
  stage('Test') {
  steps {
  echo 'Testing..'
  }
  }
  stage('Deploy') {
  steps {
  echo 'Deploying....'
  }
  }
}
// Script //
node {
  stage('Build') {
  echo 'Building....'
  }
  stage('Test') {
  echo 'Building....'
  }
  stage('Deploy') {
  echo 'Deploying....'
  }
}