GAQL running on an MCC doesn't show a campaign - google-ads-api

I've tried to run this GAQL on an MCC, but didn't get any rows.
ads-script:
campaignIds query =SELECT customer.id, campaign.resource_name, campaign.name FROM campaign WHERE campaign.id IN ("123456");
_rowsToMap(accountToCampaignsMap, AdsApp.report(query, REPORTING_OPTIONS));
}
function _rowsToMap(map, response) {
rows = response.rows();
while (rows.hasNext()) {
var row = rows.next();
Logger.log(JSON.stringify(row));
...
}
Even though I see it in the UI under this MCC
What am I missing?

it's because you don't have campaigns on this account, but in managed accounts you do. Try first get list of managed accounts then query every one, lige this:
const query = 'selsct ... from ...'
const accounts = AdsManagerApp.accounts().get()
const campaignsData = []
while (accounts.hasNext()) {
var account = accounts.next();
AdsManagerApp.select(account)
const search = AdsApp.search(query)
while (search.hasNext()) {
const searchRow = search.next();
campaignsData.push({
accountName: account.getName(),
accointId: account.getCustomerId(),
...,
})
}
}

Related

How do you query using an index in the Architect Serverless Framework?

I am trying to query using an index but keep getting this error:
ValidationException: Query condition missed key schema element: trackID
Here is my .arc file
#tables
skytracks
trackID *String
_ttl TTL
#indexes
skytracks
skyTrackType *String
Here is the relevant piece of the http get handler:
const skyTrackType = req.queryStringParameters.skytracktype
const data = await arc.tables()
const trackingData = await data.skytracks.query({
KeyConditionExpression: `skyTrackType = :skyTrackType`,
ExpressionAttributeValues: {
':skyTrackType': skyTrackType
}
})
Architect automatically names the index attribute-index
This needs to be added to the query in the question: IndexName: 'skyTrackType-index'
const trackingData = await data.skytracks.query({
KeyConditionExpression: `skyTrackType = :skyTrackType`,
IndexName: 'skyTrackType-index',
ExpressionAttributeValues: {
':skyTrackType': skyTrackType
}
})

best way to get a profile image for each message in Firebase

I have the following case, I make a chat and use Firebase as a backend, I want to find the best solution to the next problem. If a group chat is open, each incoming message should have a sender profile image. Chat is divided into three structures, this is the conversation, userConversation, and message model. The Message Model contains only the senderID, since I find it not advisable to store the profileImageURL since the user can change the avatar. The second option I thought of was to save the profileImageURL in the Conversation model and when the user changes the avatar to change it using cloud functions this will work, but this is a very bad decision because of the resource costs (for example if the user has 300 conversations and he will change the avatar every day) . Please tell me, what is the best way to do this situation?
Message model
"-KmfKFxY2BsLjpGixowG" : {
"conversationID" : "-KmfK4m1t2nDKFX_MZr8",
"creationTimeStamp" : 1.497523097283577E9,
"id" : "-KmfKFxY2BsLjpGixowG",
"senderID" : "xpyM19QVjJTgrtdntlbcJPkb0jB2",
"sendingStatusIndex" : 0,
"textMessage" : "3reds",
"typeIndex" : 0
},
Conversation Model
"-KmfK4m1t2nDKFX_MZr8" : {
"id" : "-KmfK4m1t2nDKFX_MZr8",
"lastMessage" : {
"conversationID" : "-KmfK4m1t2nDKFX_MZr8",
"creationTimeStamp" : 1.497591480636771E9,
"id" : "-KmjP72nyEJUX7yQmwYp",
"senderID" : "AoG6HmxXE8ahAESx98C2UZ0ieAh1",
"sendingStatusIndex" : 0,
"textMessage" : "C",
"typeIndex" : 0
},
"typeIndex" : 0,
"userAcitivities" : [ {
"removedChatTimeStamp" : 0,
"userID" : "xpyM19QVjJTgrtdntlbcJPkb0jB2"
}, {
"removedChatTimeStamp" : 0,
"userID" : "AoG6HmxXE8ahAESx98C2UZ0ieAh1"
} ]
}
User conversation model
"AoG6HmxXE8ahAESx98C2UZ0ieAh1" : {
"-KmeqR8RYXo-5Pt0gue1" : {
"friendID" : "QscqImQoCGdAciaVMoRJN35KjEH2",
"id" : "-KmeqR8RYXo-5Pt0gue1",
"removedChatTimeStamp" : 0,
"typeIndex" : 0
},
Update description:
Hello! I'm doing the chat! Firebase is used as a backend. The problem is how to best upload user images in a group chat. The message model has a senderID, of course in the application. The worst option that came in (I will not use it) in each cell is to query the latest url and load and cache the image using Kingfisher. The second option at the time of launching the application / chat is to update or upload all the avatars of the users that are available in the chat rooms, but here there are two problems. The first problem, if the chat will be 50 and in each chat for 50 users, then doing 2500 queries at a time is also not an option. The second problem, if somehow to avoid, a lot of requests, then from this data it will be possible to make a dictionary and transfer it to a cell, and there by senderID get the actual url for Kingfisher, but I think it's awful, and Plus can say on performance. The simplest examples of this or that chats based on firebase.
There are also several options, but they are all bad. Can you advise how this is best done? Or where to find and read about the correct architecture of this "module".
you can cache all user basic data which include user avatar in server so that the front-end get its own user list and store as object or hash table. whenever new message comes, you can map sender id with your user list data.
to update real time whenever a user change his/her avatar, you can register a socket event.
I solved this issue as follows, when opening ChatViewController, I request links to all user images using cloud functions and I get the ready dictionary [userID: userAvatarPath] in the application.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
module.exports = functions.https.onRequest((req, res) => {
const conversationID = req.query.conversationID;
const currentUserID = req.query.currentUserID;
console.log("conversationID", conversationID, "currentUserID", currentUserID);
const conversationUsersRef = admin.database().ref("chat").child("conversationUsers").child(conversationID);
conversationUsersRef.once("value").then(conversationUsersRefSnap => {
var index = 0;
var totalIndex = 0;
var conversationUsersImagesArray = [];
conversationUsersRefSnap.forEach(function(conversationUserSnap) {
console.log("conversationUserSnap", conversationUserSnap.val());
console.log("$index", index);
const dict = conversationUserSnap.val();
const conversationUserID = dict["userID"];
if (conversationUserID != currentUserID) {
index += 1;
const userSenderImageQuery = admin.database().ref('userImages').child(conversationUserID).child('userProfileImages').orderByChild('timeStamp').limitToLast(1);
userSenderImageQuery.once('value', function (snapshot, error) {
var imagePath = '';
if (error) {
index -= 1;
if (conversationUsersImagesArray.length == index) {
console.log("total", conversationUsersImagesArray);
res.status(200).send(conversationUsersImagesArray);
};
} else {
if (snapshot.val()) {
const value = snapshot.val();
const key = Object.keys(value)[0];
const requestJSON = value[key];
console.log('senderImageQuery requestJSON', requestJSON);
const userImagePath = requestJSON['path'];
imagePath = userImagePath;
const compressPath = requestJSON["compressPath"];
if (compressPath) {
imagePath = compressPath;
};
conversationUsersImagesArray.push({"userID" : conversationUserID, "imagePath" : imagePath, "conversationID" : conversationID});
console.log("conversationUsersImages", conversationUsersImagesArray.length, "index", index);
if (conversationUsersImagesArray.length == index) {
console.log("total", conversationUsersImagesArray);
res.status(200).send(conversationUsersImagesArray);
};
} else {
index -= 1;
if (conversationUsersImagesArray.length == index) {
console.log("total", conversationUsersImagesArray);
res.status(200).send(conversationUsersImagesArray);
};
};
};
});
};
});
});
});

CommentThreads amount changes by order

CommentThreads amount changes by order
Hi I'm trying to fetch all comments of a video. For testing purpose I'm using this video Id U55NGD9Jm7M.
When I order by time I get 1538 comments the last wrote on the 02.05.2015.
If I’m using the relevance I only receive 1353 comment and the last was wrote on the 29.04.2015
This doesn’t seem right to me. I expected to receive the same comments but in a different order and not different comments.
I also tried this on a different video and the results were the same.
My code cut down to minimum
Thank you for your help
public class foo
{
public void bar(string videoId)
{
var allTopLevelComments = new List<CommentThread>();
var searchListResponse = getThread(videoId);
allTopLevelComments.AddRange(searchListResponse.Items);
string nextPage = searchListResponse.NextPageToken;
while (!String.IsNullOrEmpty(nextPage))
{
searchListResponse = getThread(videoId, searchListResponse.NextPageToken);
nextPage = searchListResponse.NextPageToken;
allTopLevelComments.AddRange(searchListResponse.Items);
}
var first = allTopLevelComments.OrderBy(c => c.Snippet.TopLevelComment.Snippet.PublishedAt).First();
}
private CommentThreadListResponse getThread(string videoId, string nextPageToken = "")
{
var youtubeService = new YouTubeService(new BaseClientService.Initializer
{
ApiKey = "my key",
ApplicationName = "my app"
});
var searchListRequest = youtubeService.CommentThreads.List("id, replies, snippet");
searchListRequest.VideoId = videoId;
searchListRequest.MaxResults = 100;
searchListRequest.Order = CommentThreadsResource.ListRequest.OrderEnum.Time;
searchListRequest.TextFormat = CommentThreadsResource.ListRequest.TextFormatEnum.PlainText;
if (!String.IsNullOrEmpty(nextPageToken))
{
searchListRequest.PageToken = nextPageToken;
}
return searchListRequest.Execute();
}
}

Get all clientID from MCC adwords account by adwordsAPI

I want to retrieve all clientID from my MCC account. I'm using this code
AdWordsUser user = new AdWordsUser(adwordsPropertyService.getEmail(), adwordsPropertyService.getPassword(),
null, adwordsPropertyService.getUseragent(), adwordsPropertyService.getDeveloperToken(),
adwordsPropertyService.getUseSandbox());
InfoServiceInterface infoService = user.getService(AdWordsService.V201109.INFO_SERVICE);
InfoSelector selector = new InfoSelector();
selector.setApiUsageType(ApiUsageType.UNIT_COUNT_FOR_CLIENTS);
String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
selector.setDateRange(new DateRange(today, today));
selector.setIncludeSubAccounts(true);
ApiUsageInfo apiUsageInfo = infoService.get(selector);
for (ApiUsageRecord record : apiUsageInfo.getApiUsageRecords()) {
......
But apiUsageInfo.getApiUsageRecords return my only some clientId.
Have you any suggests?
My Answer will be helpful for PHP Developers
I am using v201502(php), You will get all account details from ManagedCustomerService api. Please refer the following URL https://developers.google.com/adwords/api/docs/reference/v201502/ManagedCustomerService
This is the sample code i used,
function DisplayAccountTree($account, $link, $accounts, $links, $depth) {
print str_repeat('-', $depth * 2);
printf("%s, %s\n", $account->customerId, $account->name);
if (array_key_exists($account->customerId, $links)) {
foreach ($links[$account->customerId] as $childLink) {
$childAccount = $accounts[$childLink->clientCustomerId];
DisplayAccountTree($childAccount, $childLink, $accounts, $links,
$depth +1);
}
}
}
function GetAccountHierarchyExample(AdWordsUser $user) {
// Get the service, which loads the required classes.
$user->SetClientCustomerId('xxx-xxx-xxxx');
$managedCustomerService =
$user->GetService('ManagedCustomerService');
// Create selector.
$selector = new Selector();
// Specify the fields to retrieve.
$selector->fields = array('CustomerId', 'Name');
// Make the get request.
$graph = $managedCustomerService->get($selector);
// Display serviced account graph.
if (isset($graph->entries)) {
// Create map from customerId to parent and child links.
$childLinks = array();
$parentLinks = array();
if (isset($graph->links)) {
foreach ($graph->links as $link) {
$childLinks[$link->managerCustomerId][] = $link;
$parentLinks[$link->clientCustomerId][] = $link;
}
}
// Create map from customerID to account, and find root account.
$accounts = array();
$rootAccount = NULL;
foreach ($graph->entries as $account) {
$accounts[$account->customerId] = $account;
if (!array_key_exists($account->customerId, $parentLinks)) {
$rootAccount = $account;
}
}
// The root account may not be returned in the sandbox.
if (!isset($rootAccount)) {
$rootAccount = new Account();
$rootAccount->customerId = 0;
}
// Display account tree.
print "(Customer Id, Account Name)\n";
DisplayAccountTree($rootAccount, NULL, $accounts, $childLinks, 0);
} else {
print "No serviced accounts were found.\n";
}
}
GetAccountHierarchyExample($user);
SetClientCustomerId will be the parent ID of your all accounts, It will be appeared near the Sign Out button of you google AdWords account, Please see the attached image
I hope this answer will be helpful, Please add your comments below if you want any further help
If you need just the list of clientCustomerIds, try ServicedAccountService.
Here is a code example that shows how this may be done.
Next time, you might also want to consider asking the question on the official forum for AdWords API: https://groups.google.com/forum/?fromgroups#!forum/adwords-api

Get all tweets with specific hashtag

I've been experimenting with the Twitter API because I want to display a few lists of tweets on a special page.
Among those lists is a list with all tweets containing a specific hashtag (e.g. #test)
However I cannot find how to get that list in either XML or JSON (preferably the latter), does anyone know how? It is also fine if it can be done in TweetSharp
You can simply fetch http://search.twitter.com/search.json?q=%23test to get a list of tweets containing #test in JSON, where %23test is #test URL encoded.
I'm not familiar with TweetSharp, but I guess there must be a search command that you can use to search for #test, and then transform the resulting tweets into JSON yourself.
First install TweetSharp using github
https://github.com/danielcrenna/tweetsharp
Here is the code to do a search
TwitterService service = new TwitterService();
var tweets = service.Search("#Test", 100);
List<TwitterSearchStatus> resultList = new List<TwitterSearchStatus>(tweets.Statuses);
If you have more then one page results you can setup a loop and call each page
service.Search("#Test", i += 1, 100);
It seems like there is a change in the API since last few months. Here is the updated code:
TwitterSearchResult res = twitter.Search(new SearchOptions { Q = "xbox" });
IEnumerable<TwitterStatus> status = res.Statuses;
u access with this url for your tweet searchs. But u have to use OAuth protocols.
https://api.twitter.com/1.1/search/tweets.json?q=%40twitterapi
I struggled with the same problem. Here is my vague solution . Enjoy Programming.
It will get out of the function whenever your required number of tweets are acquired/fetched.
string maxid = "1000000000000"; // dummy value
int tweetcount = 0;
if (maxid != null)
{
var tweets_search = twitterService.Search(new SearchOptions { Q = keyword, Count = Convert.ToInt32(count) });
List<TwitterStatus> resultList = new List<TwitterStatus>(tweets_search.Statuses);
maxid = resultList.Last().IdStr;
foreach (var tweet in tweets_search.Statuses)
{
try
{
ResultSearch.Add(new KeyValuePair<String, String>(tweet.Id.ToString(), tweet.Text));
tweetcount++;
}
catch { }
}
while (maxid != null && tweetcount < Convert.ToInt32(count))
{
maxid = resultList.Last().IdStr;
tweets_search = twitterService.Search(new SearchOptions { Q = keyword, Count = Convert.ToInt32(count), MaxId = Convert.ToInt64(maxid) });
resultList = new List<TwitterStatus>(tweets_search.Statuses);
foreach (var tweet in tweets_search.Statuses)
{
try
{
ResultSearch.Add(new KeyValuePair<String, String>(tweet.Id.ToString(), tweet.Text));
tweetcount++;
}
catch { }
}
}

Resources