Last active
June 8, 2023 20:08
-
-
Save chgrossMSFT/f42063cc99d4d751f34b7958704209d6 to your computer and use it in GitHub Desktop.
Makes Memes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: MEMES | |
| description: Makes Memes | |
| host: EXCEL | |
| api_set: {} | |
| script: | |
| content: > | |
| /** | |
| * Returns an array of collectibles. | |
| * @customfunction | |
| * @param queryString url to encode. | |
| * @returns {any} a qr code. | |
| */ | |
| function qrcode(queryString) { | |
| return new Promise(async function(resolve, reject) { | |
| var queryParams = queryString != undefined ? encodeURI(queryString) : ""; | |
| var url = "https://datatyperestproxy.azurewebsites.net/api/imgurupload?q=" + queryParams; | |
| console.log(url); | |
| fetch(url) | |
| .then(function(response) { | |
| return response.json(); | |
| }) | |
| .then(function(responseJSON) { | |
| if (responseJSON.link == undefined) { | |
| console.log("error in qrcode response"); | |
| } | |
| var qrCodeEntity = { | |
| type: "Entity", | |
| text: responseJSON.link, | |
| properties: { | |
| url: responseJSON.link, | |
| height: responseJSON.height, | |
| width: responseJSON.width, | |
| image: { | |
| type: "WebImage", | |
| address: responseJSON.link | |
| } | |
| }, | |
| layouts: { | |
| card: { | |
| mainImage: { | |
| property: "image" | |
| }, | |
| title: responseJSON.link | |
| } | |
| } | |
| }; | |
| console.log(qrCodeEntity); | |
| resolve(qrCodeEntity); | |
| }); | |
| }); | |
| } | |
| /** | |
| * Returns a new meme. | |
| * @customfunction | |
| * @returns {any} a new meme. | |
| */ | |
| async function makememe(meme, name?, text1?, text2?, text3?, text4?, text5?) | |
| { | |
| var memeProperties = { | |
| id: meme.properties.id.basicValue, | |
| name: meme.properties.name.basicValue, | |
| url: meme.properties.url.address, | |
| width: meme.properties.width.basicValue, | |
| height: meme.properties.height.basicValue, | |
| box_count: meme.properties.box_count.basicValue | |
| }; | |
| var myBoxes = [ | |
| createBox(memeProperties, text1), | |
| createBox(memeProperties, text2), | |
| createBox(memeProperties, text3), | |
| createBox(memeProperties, text4), | |
| createBox(memeProperties, text5) | |
| ]; | |
| var culledBoxes = []; | |
| for (var x = 0; x < memeProperties.box_count; x++) { | |
| culledBoxes.push(myBoxes[x]); | |
| } | |
| var newMeme = await memeCreator(memeProperties, culledBoxes, name); | |
| return newMeme; | |
| } | |
| var storedCreds = { | |
| template_id: 61579, //one does not simply | |
| username: "68637e657d66", | |
| password: "6765673b796d6b73" | |
| }; | |
| const exampleMeme = { | |
| id: "61579", | |
| name: "One Does Not Simply", | |
| url: "https://i.imgflip.com/1bij.jpg", | |
| width: 568, | |
| height: 335, | |
| box_count: 2 | |
| }; | |
| const exampleBoxes = [ | |
| { | |
| text: "One does not simply", | |
| x: 10, | |
| y: 10, | |
| width: 548, | |
| height: 100, | |
| color: "#ffffff", | |
| outline_color: "#000000" | |
| }, | |
| { | |
| text: "Make custom memes on the web via imgflip API", | |
| x: 10, | |
| y: 225, | |
| width: 548, | |
| height: 100, | |
| color: "#ffffff", | |
| outline_color: "#000000" | |
| } | |
| ]; | |
| /** EXAMPLE MEME RESPONSE | |
| * { | |
| "id": "61579", | |
| "name": "One Does Not Simply", | |
| "url": "https://i.imgflip.com/1bij.jpg", | |
| "width": 568, | |
| "height": 335, | |
| "box_count": 2 | |
| } | |
| */ | |
| function decrypt(salt, encoded) { | |
| const textToChars = (text) => text.split("").map((c) => c.charCodeAt(0)); | |
| const applySaltToChar = (code) => textToChars(salt).reduce((a, b) => a ^ b, code); | |
| return encoded | |
| .match(/.{1,2}/g) | |
| .map((hex) => parseInt(hex, 16)) | |
| .map(applySaltToChar) | |
| .map((charCode) => String.fromCharCode(charCode)) | |
| .join(""); | |
| } | |
| function createBox( | |
| meme, | |
| textString = "placeholder text", | |
| x?, | |
| y?, | |
| width = meme.width, | |
| height = meme.height / 2, | |
| color = "#ffffff", | |
| outlineColor = "#000000", | |
| font = "impact" | |
| ) { | |
| var box = { | |
| text: textString, | |
| width: width, | |
| height: height, | |
| color: color, | |
| outline_color: outlineColor | |
| }; | |
| if (x != undefined) box["x"] = x; | |
| if (y != undefined) box["y"] = y; | |
| if (x == undefined || y == undefined) { | |
| delete box["width"]; | |
| delete box["height"]; | |
| } | |
| return box; | |
| } | |
| function decryptUserPass(reqParams) { | |
| var returnParams = {}; | |
| var username = decrypt("salt", reqParams.username); | |
| var pw = decrypt("salt", reqParams.password); | |
| returnParams["username"] = username; | |
| returnParams["password"] = pw; | |
| return returnParams; | |
| } | |
| async function memeCreator(meme, boxes, name = meme.name) { | |
| var encodedBoxes = boxes; | |
| if (boxes == undefined) { | |
| encodedBoxes = [ | |
| { | |
| text: "text1" | |
| }, | |
| { | |
| text: "text2" | |
| } | |
| ]; | |
| } | |
| var memeData = meme; | |
| var myReqParams = decryptUserPass(storedCreds); | |
| myReqParams["template_id"] = meme.id; | |
| var newMeme = { | |
| reqParams: myReqParams, | |
| boxes: encodedBoxes | |
| }; | |
| var url = makeUrl(newMeme); | |
| var returnedMeme = await fetch(url) | |
| .then((response) => { | |
| return response.json(); | |
| }) | |
| .then((JSONData) => { | |
| return JSONData.data; | |
| }); | |
| var myNewEntity = await customMemeToEntity(returnedMeme, name, encodedBoxes); | |
| //console.log(myNewEntity); | |
| return myNewEntity; | |
| } | |
| function customMemeToEntity(customMeme, name, boxes) { | |
| var entity = { | |
| type: "Entity", | |
| text: name, | |
| properties: { | |
| pageUrl: customMeme.page_url, | |
| imageUrl: customMeme.url, | |
| image: { | |
| type: "WebImage", | |
| address: customMeme.url | |
| } | |
| }, | |
| layouts: { | |
| card: { | |
| mainImage: { | |
| property: "image" | |
| }, | |
| title: name | |
| } | |
| } | |
| }; | |
| for (var x = 0; x < boxes.length; x++) { | |
| var prop = "text" + (x + 1); | |
| entity["properties"][prop] = boxes[x].text; | |
| } | |
| console.log(entity); | |
| return entity; | |
| } | |
| function makeUrl(meme) { | |
| var boxes = meme.boxes; | |
| var url = "https://api.imgflip.com/caption_image?"; | |
| var params = makeImgParams(meme.reqParams, boxes); | |
| let paramsObj = params; | |
| let searchParams = new URLSearchParams(paramsObj); | |
| var finalUrl = url + searchParams; | |
| return finalUrl; | |
| } | |
| function makeImgParams(reqParams, boxes) { | |
| const data = boxes; | |
| var returnData = reqParams; | |
| //For each box | |
| for (var x = 0; x < boxes.length; x++) { | |
| var box = boxes[x]; | |
| var prependString = "boxes[" + x + "]["; | |
| //for each property in the box | |
| for (var key of Object.keys(box)) { | |
| var propertyName = key; | |
| var propertyValue = box[key]; | |
| var paramKey = prependString + propertyName + "]"; | |
| returnData[paramKey] = propertyValue; | |
| } | |
| } | |
| return returnData; | |
| } | |
| language: typescript | |
| libraries: | | |
| https://appsforoffice.microsoft.com/lib/beta/hosted/office.js | |
| https://appsforoffice.microsoft.com/lib/beta/hosted/office.d.ts | |
| @types/office-js | |
| office-ui-fabric-js@1.4.0/dist/css/fabric.min.css | |
| office-ui-fabric-js@1.4.0/dist/css/fabric.components.min.css | |
| core-js@2.4.1/client/core.min.js | |
| @types/core-js | |
| jquery@3.1.1 | |
| @types/jquery@3.3.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment