Twitter StatusId - twitter

I am using Linq2Twitter in my ASP.net Web Forms application to return recent user tweets
var tweets = await
(from tweet in ctx.Status
where (
(tweet.Type == StatusType.User)
&& (tweet.ScreenName == screenName)
&& (tweet.ExcludeReplies == true)
&& (tweet.IncludeMyRetweet == false)
&& (tweet.Count == 10)
&& (tweet.RetweetCount < 1)
)
select tweet)
.Take(count)
.ToListAsync();
This seems to work well and I get the expected Json return, but...
When I try and construct a link to the original tweet...
“https://twitter.com/” + ScreenName + “/status/” + data.StatusId
I get a "Sorry, page does not exist error".
Upon investigation it appears that the returned StatusId is incorrect. For example, the returned StatusId is:
500244784682774500
When the actual tweet refers to:
500244784682774528
In other words, in this case, the StatusId seem to be 28 adrift.
Can anyone throw any light on what is happening/what I am doing wrong?
IThanks.

After some debugging I found that the ID returned to the LinqtoTwitter application was correct, the problem occurred either in the JSON converter or in JavaScript itself being unable to handle the unsigned-integer id value.
The solution was to create a simple view model from the returned results (using an extension method against the LinqToTwitter.Status object) and passing that to the client instead of the whole data graph.

Related

How to retrieve Slack messages via API identified by permalink?

I'm trying to retrieve a list of Slack reminders, which works fine using Slack API's reminders.list method. However, reminders that are set using SlackBot (i.e. by asking Slackbot to remind me of a message) return the respective permalink of that message as text:
{
"ok": true,
"reminders": [
{
"id": "Rm012C299C1E",
"creator": "UV09YANLX",
"text": "https:\/\/team.slack.com\/archives\/DUNB811AM\/p1583441290000300",
"user": "UV09YANLX",
"recurring": false,
"time": 1586789303,
"complete_ts": 0
},
Instead of showing the permalink, I'd naturally like to show the message I wanted to be reminded of. However, I couldn't find any hints in the Slack API docs on how to retrieve a message identified by a permalink. The link is presumably generated by chat.getPermalink, but there seems to be no obvious chat.getMessageByPermalink or so.
I tried to interpet the path elements as channel and timestamp, but the timestamp (transformed from the example above: 1583441290.000300) doesn't seem to really match. At least I don't end up with the message I expected to retrieve when passing this as latest to conversations.history and limiting to 1.
After fiddling a while longer, here's how I finally managed in JS:
async function downloadSlackMsgByPermalink(permalink) {
const pathElements = permalink.substring(8).split('/');
const channel = pathElements[2];
var url;
if (permalink.includes('thread_ts')) {
// Threaded message, use conversations.replies endpoint
var ts = pathElements[3].substring(0, pathElements[3].indexOf('?'));
ts = ts.substring(0, ts.length-6) + '.' + ts.substring(ts.length-6);
var latest = pathElements[3].substring(pathElements[3].indexOf('thread_ts=')+10);
if (latest.indexOf('&') != -1) latest = latest.substring(0, latest.indexOf('&'));
url = `https://slack.com/api/conversations.replies?token=${encodeURIComponent(slackAccessToken)}&channel=${channel}&ts=${ts}&latest=${latest}&inclusive=true&limit=1`;
} else {
// Non-threaded message, use conversations.history endpoint
var latest = pathElements[3].substring(1);
if (latest.indexOf('?') != -1) latest = latest.substring(0, latest.indexOf('?'));
latest = latest.substring(0, latest.length-6) + '.' + latest.substring(latest.length-6);
url = `https://slack.com/api/conversations.history?token=${encodeURIComponent(slackAccessToken)}&channel=${channel}&latest=${latest}&inclusive=true&limit=1`;
}
const response = await fetch(url);
const result = await response.json();
if (result.ok === true) {
return result.messages[0];
}
}
It's not been tested to the latest extend, but first results look alright:
The trick with the conversations.history endpoint was to include the inclusive=true parameter
Messages might be threaded - the separate endpoint conversations.replies is required to fetch those
As the Slack API docs state: ts and thread_ts look like timestamps, but they aren't. Using them a bit like timestamps (i.e. cutting off some characters at the back and inserting a dot) seems to work, gladly, however.
Naturally, the slackAccessToken variable needs to be set beforehand
I'm aware the way to extract & transform the URL components in the code above might not the most elegant solution, but it proves the concept :-)

Pull pagespeed in seconds from Chrome User Experience Report into a google sheet

By following the guide Create Your Own Google Pagespeed & Mobile Usability Tracking Google Sheet in 5 Steps I managed to set up mobile pagespeed score for a list of (up to 50) URLs.
However since late 2017 or something there is real data available from the Chrome User Experience Report that displays an average load time in seconds for a page based on chrome user data.
(This data is being used for example when using Pagespeed Insights by google.)
Instead of pulling a page score I as described above I would like to pull the average load time into my google sheet.
Is it possible to adapt the script used from the article above to pull load time in seconds instead of pagescore? Or is there any other way to do this?
Thanks in advance your help is much appreciated.
This is the script I run in script editor to get pagescore into google sheet according to the linked article with function =checkAll(C3):
/**
* Returns Mobile Pagespeed, Mobile Usability, and Desktop Pagespeed values in three adjacent columns
* by Cagri Sarigoz
*/
function checkAll(Url) {
//CHANGE YOUR API KEY WITH YOUR_API_KEY BELOW
var key = "AIzaSyB2SeOumbCd6YNfFWRg5Jo_WpISZi4gCFs";
var serviceUrlMobile = "https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url="+Url+"&strategy=mobile&key="+key;
var serviceUrlDesktop = "https://www.googleapis.com/pagespeedonline/v2/runPagespeed?url="+Url+"&strategy=desktop&key="+key;
var array = [];
if (key == "YOUR_API_KEY")
return "Please enter your API key to the script";
var responseMobile = UrlFetchApp.fetch(serviceUrlMobile);
if(responseMobile.getResponseCode() == 200) {
var contentMobile = JSON.parse(responseMobile.getContentText());
if ( (contentMobile != null) && (contentMobile["ruleGroups"] != null) )
{
if (contentMobile["responseCode"] == 200)
{
var speedScoreMobile = contentMobile["ruleGroups"]["SPEED"]["score"];
var usabilityScoreMobile = contentMobile["ruleGroups"]["USABILITY"]["score"];
}
else
{
array.push(["Not Found!", "Not Found!", "Not Found!"]);
return array;
}
}
}
var responseDesktop = UrlFetchApp.fetch(serviceUrlDesktop);
if(responseDesktop.getResponseCode() == 200) {
var contentDesktop = JSON.parse(responseDesktop.getContentText());
if ( (contentDesktop != null) && (contentDesktop["ruleGroups"] != null) )
var speedScoreDesktop = contentDesktop["ruleGroups"]["SPEED"]["score"];
}
array.push([speedScoreMobile, usabilityScoreMobile, speedScoreDesktop]);
return array;
}
I am the writer of the blog post that you shared. As you said, the Google Apps Script there was using Google Pagespeed API v2. The current API version is v4, and v2 will be depreciated on June 30th.
So I updated the code with v4 on my own copy of the spreadsheet. You can make your own copy from here.
I also wanted to add the mobile-friendly test results but it turned out that Google Search Console's API quota restrictions were too tight, returning error almost all the time. So I commented out that part of the code for the time being.
I didn't have the time to update my blog post yet. You can see the new version of the script here.

Get users that a given user is FOLLOWING (not followers) in LinqToTwitter

How can I get UserId and ScreenName of the users that a given user is FOLLOWING (not followers) in LinqToTwitter?
??
The Twitter API uses the terms follower to mean people who follow a user and friends to mean people that a user follows and LINQ to Twitter continues that approach. So, you would use a Friendship/FriendshipType.FriendsList query, like this:
static async Task FriendsListAsync(TwitterContext twitterCtx)
{
Friendship friendship;
long cursor = -1;
do
{
friendship =
await
(from friend in twitterCtx.Friendship
where friend.Type == FriendshipType.FriendsList &&
friend.ScreenName == "JoeMayo" &&
friend.Cursor == cursor &&
friend.Count == 200
select friend)
.SingleOrDefaultAsync();
if (friendship != null &&
friendship.Users != null &&
friendship.CursorMovement != null)
{
cursor = friendship.CursorMovement.Next;
friendship.Users.ForEach(friend =>
Console.WriteLine(
"ID: {0} Name: {1}",
friend.UserIDResponse, friend.ScreenNameResponse));
}
} while (cursor != 0);
}
This example pages through the results in a do/while loop. Notice that the cursor is set to -1, which starts off the query without a Twitter API cursor. Each query assigns the cursor, which gets the next page of users. In the if block, the first statement reads the friendship.CursorMovement.Next to the get cursor for the next page of users. When the next cursor is 0, you've read all of the followers.
After the query executes, the Users property has a List<User> where you can get user information. This demo prints each member of the list.
One of the things you might run into with large friend lists is that Twitter will return an error for exceeding the rate limit. You'll be able to catch this, in a try/catch block, by catching TwitterQueryException and examining properties for the Rate Limit Exceeded. To minimize rate limit propblems, set count to 200, the max. Otherwise count defaults to 20.
You can download samples and view documentation for this on the LINQ to Twitter Web site.

Instagram API request single username

I'm using this way to get the username data from Instagram:
https://api.instagram.com/v1/users/search?q=[USERNAME]&client_id=[CLIENT ID]
It works fine, but has a flaw - the username search actually gets ALL usernames starting with the string you set.
Why/How is that happening ?
There is a limit of 52 username results, so is there a way to increase it, because if you search "asdasd" (which is an existing account!) you would get probably a million accounts ?
Is there a work-around, because I want to search for the exact username ?
So it seems there is only this API for this functionality. You can simply use this workaround: make your request as you are doing it right now, then you can filter out the single item you need. You can iterate through the list of users, and only keep the one, where the username is exactly the same as you have specified.
SOLUTION:
Put the username in quotations like this (username: asdasdasd):
https://api.instagram.com/v1/users/search?q="asdasdasd"&client_id=[CLIENT ID]
Which results in (the results that interests you is highlighted):
- if you don't use the quotations there's a big chance that the desired username won't appear in the results!
If there are more than one results use this code the iterate through the response data to find your one and get it's ID, full_name etc.
function getUserID() {
//send request for the user info on click
$('.btn-user-request').click(function(){
var searchTerm = $('.input-user-request').val();
if(searchTerm == ''){
$('.user-id-value').html('Enter a username!');
}
else{
$.ajax({
url: "https://api.instagram.com/v1/users/search?q=\"" + searchTerm + "\"&client_id=5fc90c90b885487485125d6df440fefd",
dataType: 'jsonp'
}).done(function(data) {
if(data.data[0] == []){
$('.user-id-value').html('No username found!');
}
else{
for(i=0;i<data.data.length;i++){
var userInformation = data.data[i];
if(userInformation.username == searchTerm){
$('.user-id-value').html(userInformation.id);
break;
}
}
}
});
}
});
//simulate the button click, on click of the Enter key
$(".input-user-request").on('keydown', function(){
if(event.keyCode == 13){
$(".btn-user-request").click();
}
});
}
See JSFiddle
(for some reason the code doesn't format properly)
I would suggest to try username "jack".
In fact none of suggested methods work for this.
I tried with max_id, min_id, it does not work either.
So it is exact flaw in API, and there is no such documentation on Instagram API to help to solve this.
So finding exact user id by it's username is quite a problem for popular names.
The only one solution for today I found is parsing user's Instagram HTML page and get it's id from there. This is very stupid, but this is only one solution which works in all cases right now :(
It's simple:
https://www.instagram.com/{username}/?__a=1

QuickBooks SyncStatus Issue

we are using QuickBooks desktop edition, facing a strange issue with QuickBooks Sales Receipt - Syncronised status and State code wrireBack Messages, Problem detail is as below in steps,
First we are fetching QuickBooks Sales Receipts with provided idSet
Dim salesReceiptQuery = New Intuit.Ipp.Data.Qbd.SalesReceiptQuery() With {.Item1 = idset, _
.Item1ElementName = Item1ChoiceType4.TransactionIdSet, _
.IncludeTagElements = New String() {"SalesReceipt/Synchronized"}}
Dim salesReceipts As System.Collections.ObjectModel.ReadOnlyCollection(Of Intuit.Ipp.Data.Qbd.SalesReceipt) = Nothing
Try
salesReceipts = salesReceiptQuery.ExecuteQuery(Of Intuit.Ipp.Data.Qbd.SalesReceipt)(QBContext)
Catch ex As Exception
Trace.WriteLine("SyncWatchDog Task - Exception: " & ex.Message)
End Try
then we loop withe result to check "salesReceipt.Synchronized = True", here we are getting some Sales Recepipt with "salesReceipt.Synchronized = False".
Second step is we take all Sales Recept Id with "salesReceipt.Synchronized = False", and query Quickbooks with below code,
Dim syncStatusRequest As New Intuit.Ipp.Data.Qbd.SyncStatusRequest() With {.NgIdSet = list.GetNgIdSetArray}
Dim syncStatusResponse = DataServices.GetSyncStatus(syncStatusRequest)
Here when we loop over syncStatusResponce to get "syncStatus.StateCode", we are getting
STATECODE =1 ,
STATEDESC=Synchronized,
DESCRIPTION=(successful). Object created in QuickBooks. Equivalent to StateCode 8 (for object created in Data Services)
and
MESSAGECODE=40,
MESSAGEDESC=WRTB success,
DESCRIPTION:The requests sent from Data Services to the QuickBooks company file were successfully synched into the company file.
we are not able to understand if Sales Receipt is salesReceipt.Synchronized = False, what is meaning of StateCode 1 and MessageCode 40.
Please suggest the solution,
Thanks & Regards,
Reshma D.
You can try to retrieve objects in a sync error state, by specifying the ErroredObjectsOnly="true" attribute.
If you get any object in the response, then try to see the sync status of those error-ed objects using status API,otherwise(success) call GetAll API on SalesReceipt to see if you are getting all those objects(as by default it returns objects which were successfully created).
Ref - https://developer.intuit.com/docs/0025_quickbooksapi/0050_data_services/v2/0500_quickbooks_windows/0600_object_reference/syncstatus
You can ApiExplorer tool to test this use case.
Link - https://developer.intuit.com/apiexplorer?apiname=V2QBD
Can you query some other retrieved records too retrieved from salesReceipt.Synchronized = False?
Check if they also have StateCode 1.
It might be an issue with the Synchronized filter not working and retrieving all data.

Resources