how to create a CreativeAsset in dfp api - google-dfp

I'm trying to create an asset (CreativeAsset) to be used in a template Creative later. I cannot find in the documentation any way to create the asset itself, only to provide the base64 bytes, but I'd like to use this asset in multiple places, so I would prefer to load it once..Is there a way to create only a CreativeAsset?
https://developers.google.com/doubleclick-publishers/docs/reference/v201705/CreativeService.CreativeAsset

Here is the solution from the DFP API team:
A CreativeAsset must be created as a part of a creative. There is no dedicated service to create a CreativeAsset alone. But then, you can use the assetId to copy a CreativeAsset to a new creative. Basically, you can first create a creative, then get the creative asset's assetId and use it to create multiple creatives

This is a code example using python:
with open(f, "rb") as html_file:
html_file_data = base64.b64encode(html_file.read())
html_file_data = html_file_data.decode("utf-8")
# USING TEMPLATE
creative1 = {
'xsi_type': 'TemplateCreative',
'name': '',
'advertiserId': '',
'size': {'width': 1, 'height': 1},
'creativeTemplateId': '',
'creativeTemplateVariableValues': [
{
'xsi_type': 'AssetCreativeTemplateVariableValue',
'uniqueName': 'HTMLFile',
'asset': {
'assetByteArray': html_file_data,
'fileName': ''
}
}
# other variables
]
}
# USING CUSTOM
creative2 = {
'xsi_type': 'CustomCreative',
'name': '',
'advertiserId': '',
'size': {'width': 1, 'height': 1},
'destinationUrl': '',
'customCreativeAssets': []
}
creative2['customCreativeAssets'].append({
'xsi_type': 'CustomCreativeAsset',
'macroName': '',
'asset': {
'assetByteArray': html_file_data,
'fileName': ''
}
})
creative_service = dfp_client.GetService('CreativeService', version='v201702')
upload_creative1 = creative_service.createCreatives(creative1)
upload_creative2 = creative_service.createCreatives(creative2)
I hope this works.

Related

Codesys interface properties in ST

I'm trying to make a interface with properties in st instead of having to add them as property with getter and setting by doing a lot of clicking.
How I am doing it now
How I want to do it:
INTERFACE Door
VAR
sensorBack : BOOL;
END_VAR
Is there a possibility to do something like this or do you always need to add them through the program structure?
Structured Text in codesys always felt like an after thought.
The short answer is that you need to use the GUI to add them one by one.
The long answer is, you can use the bultin (ScriptEngine) Python APIs to simplify the generation of interfaces with many properties:
from __future__ import print_function
import re
import sys
app = projects.primary.active_application
# Fill in the following:
interface_name = '' # Example 'IMyInterface'
base_interface_type = None # Example 'IMyBaseInterface', leave as None if there's no base interface
interface_properties = [
{
'name': '', # Example 'MyProperty'
'return_type': '', # Example 'BOOL'
'getter': True, # Set to False if you want no getter
'setter': True # Set to False if you want no setter
}# , # Include as many properties as you want in a comma (,) separated list
# {
# 'name': ''
# 'return_type': ''
# 'getter': True,
# 'setter': True
# }
]
# Don't touch the code below
if base_interface_type is None:
interface = app.create_interface(name=interface_name)
else:
interface = app.create_interface(name=interface_name, baseInterfaces=base_interface_type)
for property_data in interface_properties:
property_name = property_data['name']
return_type = property_data['return_type']
include_getter = property_data['getter']
include_setter = property_data['setter']
property = interface.create_property(name=property_name, return_type=return_type)
getter = property.find('Get')[0]
setter = property.find('Set')[0]
if not include_getter:
getter.remove()
if not include_setter:
setter.remove()
Save the above script as a *.py file, change the parameters according to your needs and run the script:
View -> Scripting -> scripting Immediate:
Press on the three dots (...):
Navigate to the script (*.py) file and open it. A new Interface with the desired properties should be generated.
Heres an example of me running the script with the following parameters:
interface_name = 'IMyInterface'
base_interface_type = None
interface_properties = [
{
'name': 'MyProperty1',
'return_type': 'BOOL',
'getter': True,
'setter': False
},
{
'name': 'MyProperty2',
'return_type': 'INT',
'getter': False,
'setter': True
},
{
'name': 'MyProperty3',
'return_type': 'DINT',
'getter': True,
'setter': True
},
{
'name': 'MyProperty4',
'return_type': 'WORD',
'getter': False,
'setter': False
},
{
'name': 'MyProperty5',
'return_type': 'BOOL',
'getter': True,
'setter': False
}
]
You need to add them via the program structure as far as I know.

Flutter how to add doc id with data

I ma just entering my data in Firestore. I need to know how can I put my doc id in data?
My simple code
_firestore.collection('Users').add({
'shopname': 'Aam Dukaan',
'number': '9232313131',
'lastupdate': '',
'sendQty': '',
'id': 'here i need doc id '
});
More explanation
From image you can see I need this document id in my data.
Do it like this:
String id = FirebaseFirestore.instance.collection('Users').doc().id;
FirebaseFirestore.instance.collection('Users').doc(id).set({
'shopname': 'Aam Dukaan',
'number': '9232313131',
'lastupdate': '',
'sendQty': '',
'id': id,
});
You can get the ID before you create the new document with add and use set instead of add:
final document = _firestore.collection('Users').doc();
_firestore.collection('Users').doc(document.id).set({
'shopname': 'Aam Dukaan',
'number': '9232313131',
'lastupdate': '',
'sendQty': '',
'id': 'here i need doc id '
});
You can add a document with desired id.
final usersRef = FirebaseFirestore.instance.collection("Users");
String id = "123";
usersRef.doc(id).set(
{
"name":"somename" ,
"id":"$id",
}

Word addin inserting complex list structure with styling in a contentControl using office.js done or not?

I'm trying to insert a complex list structure into a contentControl in MS Word using the javascript API. The structure is build according to an object that contains nested arrays: Different items containing sub items that contain different properties. These items arrays can change in size so it needs to be generic. Maybe the Office.js API isn't really build for what I am trying to achieve and I should be using either insertHTML (with the structure build in HTML) or OOXML.
This is the structure I already build
The function that produced this:
import ContentControl = Word.ContentControl;
import {formatDate} from '../formatters';
let firstItem = true;
let listId;
export async function resolveItems(contentControl: ContentControl, data: Array<any>, t) {
Word.run( contentControl, async (context) => {
contentControl.load('paragraphs');
await context.sync();
for (const item of data) {
if (firstItem) {
const firstPara = contentControl.paragraphs.getFirst();
firstPara.insertText('ITEM (' + formatDate(item.date) + ')', 'Replace');
firstItem = false;
const contactList = firstPara.startNewList();
contactList.load('id');
await context.sync().catch((error) => {
console.log('Error: ' + error);
if (error instanceof OfficeExtension.Error) {
console.log('Debug info: ' + JSON.stringify(error.debugInfo));
}
});
listId = contactList.id;
} else {
const otherItem = contentControl.insertParagraph('ITEM (' + formatDate(item.date) + ')', 'End');
otherItem.load(['isListItem']);
await context.sync();
otherItem.attachToList(listId, 0);
}
for (const subItem of item.subItems) {
let descriptionParaList = new Array();
let subItemPara = contentControl.insertParagraph(subItem.title + ' (' + formatDate(subItem.date) + ')', 'End');
subItemPara.load(['isListItem']);
await context.sync();
if (subItemPara.isListItem) {
subItemPara.listItem.level = 1;
} else {
subItemPara.attachToList(listId, 1);
}
let descriptions = subItem.descriptions;
for (const description of descriptions) {
let descriptionPara = contentControl.insertParagraph('', 'End');
descriptionPara.insertText(t(description.descriptionType) + ': ', 'Start').font.set({
italic: true
});
descriptionPara.insertText(description.description, 'End').font.set({
italic: false
});
descriptionPara.load(['isListItem', 'leftIndent']);
descriptionParaList.push(descriptionPara);
}
await context.sync();
for (const subItemPara of descriptionParaList) {
if (subItemPara.isListItem) {
subItemPara.detachFromList();
}
subItemPara.leftIndent = 72;
}
}
}
return context.sync().catch((error) => {
console.log('Error: ' + error);
if (error instanceof OfficeExtension.Error) {
console.log('Debug info: ' + JSON.stringify(error.debugInfo));
}
});
});}
The data structure looks like this:
'LAST_5_Items': [
{
'date': '2019-03-14T14:51:29.506+01:00',
'type': 'ITEM',
'subItems': [
{
'date': '2019-03-14T14:51:29.506+01:00',
'title': 'SUBITEM 1',
'descriptions': [
{
'descriptionType': 'REASON',
'description': 'Reason 1',
'additionalInformation': ''
}
]
},
{
'date': '2019-03-14T14:51:29.506+01:00',
'title': 'SUBITEM 2',
'descriptions': [
{
'descriptionType': 'REASON',
'description': 'Reason 1',
'additionalInformation': ''
}
]
}
]
},
{
'date': '2019-03-14T14:16:26.220+01:00',
'type': 'ITEM',
'subItems': [
{
'date': '2019-03-14T14:16:26.220+01:00',
'title': 'SUBITEM 1',
'descriptions': [
{
'descriptionType': 'REASON',
'description': 'Reason 1',
'additionalInformation': ''
}
]
},
{
'date': '2019-03-14T14:16:26.220+01:00',
'title': 'SUBITEM 2',
'descriptions': [
{
'descriptionType': 'REASON',
'description': 'Reason 1',
'additionalInformation': ''
},
{
'descriptionType': 'SUBJECTIVE',
'description': 'Subjective 1',
'additionalInformation': ''
},
{
'descriptionType': 'SUBJECTIVE',
'description': 'Subjective 2',
'additionalInformation': ''
},
{
'descriptionType': 'OBJECTIVE',
'description': 'Objective 1',
'additionalInformation': ''
},
{
'descriptionType': 'OBJECTIVE',
'description': 'Objective 2',
'additionalInformation': ''
},
{
'descriptionType': 'EVALUATION',
'description': 'Evaluation',
'additionalInformation': ''
},
{
'descriptionType': 'REASON',
'description': 'Reason 1',
'additionalInformation': ''
}
]
}
]
}
]
What I am trying to achieve is a template resolver. The addin will allow the user to put placeholder (ContentControls), tags like First name, Last name,... and the 5 last contacts (the one I am now describing) in the document and when he resolves the file it will fetch all the data needed and start replacing the ContentControls with this structured layout.
Yes the code works, but I highly doubt that the code is well structured with so many context.sync() calls. It is too slow and it is not usable.
I need so many context.sync() because I need the properties of the List ID and if a Paragraph belongs to a list.
Is there a better way to achieve what I am trying to achieve using the office.js API?
Ideally the queue should be synced once so the user would not see the content being added and changed in a very strange way like it is now behaving.
Thanks
There is a technique for avoiding having context.sync inside a loop. The basic idea is that you have two loops, with a single context.sync in between them. In the first loop, you create an array of objects. Each object contains a reference to one of the Office objects that you want to process (e.g., change, delete, etc.) It looks like paragraphs in your case. But the object has other properties. Each of them holds some item of data that you need to process the object. These other items may be properties of other Office objects or they may be other data. Also, either in your loop or just after it, you load all the properties you're going to need of all the Office objects in the objects in your array. (This is usually easier to do inside the loop.)
Then you have context.sync.
After the sync, you loop through the array of objects that you created before the context.sync. The code inside this second loop processes the first item in each object (which is the Office object that you want to process) using the other properties of the object you created.
Here are a couple of examples of this technique:
My answer to this StackOverflow question: Document not in sync after replace text.
This code sample:
https://github.com/OfficeDev/Word-Add-in-Angular2-StyleChecker/blob/master/app/services/word-document/word.document.service.js.

Set CivCRM Email to Blank by REST API

I am trying to set the email address to blank in CiviCRM. I serialise an array as below and post via REST (code is groovy):
def rest = [
json: 1,
api_key: apiKey,
key: siteKey,
debug: 1,
version: 3,
entity: 'Contact',
action: 'create',
contact_type: contact_type,
overwriteblank:true,
id: record.crID,
rest["email[1][email]"] = modified.value as String
rest["email[1][location_type_id]"] = 1
]
I have tried the 'overwriteblank' option - but the email still does not seem to be set to blank.
Thanks
An email address is a separate API entity from the contact (since a contact can have an infinite number of email addresses). All you need to do is get the email entries where the contact_id = whatever and then delete them.
$result = civicrm_api3('Email', 'get', array('contact_id' => $YOUR_CONTACT_ID));
then after checking for errors and iterating over $result['values']:
$deleted = civicrm_api3('Email', 'delete', array('id' => $YOURRESULTROW['id']));
With the SQL method, you're not deleting the email so much as setting that person's email to be an empty string.
The best that I could do was by sql.
String sql_update = """update civicrm_email set email = "" where contact_id = ?"""

How do I use Perl's WWW::Facebook::API to publish to a user's newsfeed?

We use Facebook Connect on our site in conjunction with the WWW::Facebook::API CPAN module to publish to our users newsfeed when requested by the user.
So far we've been able to successfully update the user's status using the following code:
use WWW::Facebook::API;
my $facebook = WWW::Facebook::API->new(
desktop => 0,
api_key => $fb_api_key,
secret => $fb_secret,
session_key => $query->cookie($fb_api_key.'_session_key'),
session_expires => $query->cookie($fb_api_key.'_expires'),
session_uid => $query->cookie($fb_api_key.'_user')
);
my $response = $facebook->stream->publish(
message => qq|Test status message|,
);
However, when we try to update the code above so we can publish newsfeed stories that include attachments and action links as specified in the Facebook API documentation for Stream.Publish, we have tried about 100 different ways without any success.
According to the CPAN documentation all we should have to do is update our code to something like the following and pass the attachments & action links appropriately which doesn't seem to work:
my $response = $facebook->stream->publish(
message => qq|Test status message|,
attachment => $json,
action_links => [#links],
);
For example, we are passing the above arguments as follows:
$json = qq|{ 'name': 'i\'m bursting with joy', 'href': ' http://bit.ly/187gO1', 'caption': '{*actor*} rated the lolcat 5 stars', 'description': 'a funny looking cat', 'properties': { 'category': { 'text': 'humor', 'href': 'http://bit.ly/KYbaN'}, 'ratings': '5 stars' }, 'media': [{ 'type': 'image', 'src': 'http://icanhascheezburger.files.wordpress.com/2009/03/funny-pictures-your-cat-is-bursting-with-joy1.jpg', 'href': 'http://bit.ly/187gO1'}] }|;
#links = ["{'text':'Link 1', 'href':'http://www.link1.com'}","{'text':'Link 2', 'href':'http://www.link2.com'}"];
The above, nor any of the other representations we tried seem to work. I'm hoping some other perl developer out there has this working and can explain how to create the attachment and action_links variables appropriately in Perl for posting to the Facebook news feed through WWW::Facebook::API.
Thanks in advance for your help!
I think the problem is that your JSON string might be invalid. I was able to get it to work by just using JSON::Any to serialize a Perl data structure instead of building the JSON string manually. (WWW::Facebook::API uses JSON::Any under the hood; it would be nice if it could take a Perl data structure instead of a JSON string. I will try to submit a patch this weekend.)
use WWW::Facebook::API;
use JSON::Any;
my $j = JSON::Any->new;
my $fb = WWW::Facebook::API->new(
desktop => 0,
api_key => $api_key,
secret => $secret,
session_key => $session,
session_expires => $expires,
session_uid => $fb_uid
);
my $res = $fb->stream->publish(
message => 'Test message',
attachment => $j->objToJson(
{ name => 'Foo bar baz',
href => 'http://www.google.com/',
description => "this is a thing"
} ),
action_links => $j->objToJson(
[ { text => 'action link text',
href => 'http://www.foobar.com/'
} ] )
);
The result:
http://www.friedo.com/fb_attach.jpg