I'm upgrading a C# application used at work to gather client satisfaction stats using Survey Monkey. The upgrade is to make it use the Survey Monkey API V3 instead of V2 (since V2 gets turned off soon). Both versions of our code make use of Ben Emmett's excellent .NET wrapper(https://github.com/bcemmett/SurveyMonkeyApi) extended with appropriate methods to support creating new surveys and sending invitations.
In version 2 we used the Create_Flow API method to generate new surveys based on an existing one (we have a couple of existing base surveys and choose the appropriate one based on the type of project we're surveying about). It's important that the title of the new survey reflect the name of the relevant project. The relevant part of our V2 code looks like this:
var data = new CreateFlowSettings();
data.survey.survey_title = legislationTitle;
data.survey.from_survey_id = fromSurveyId;
data.collector.recipients = recipients;
data.email_message.subject = subject;
data.email_message.body_text = bodyText;
data.email_message.reply_email = replyEmail;
var serializedData = JsonConvert.SerializeObject(data);
const string endPoint = "/batch/create_flow";
var response = MakeApiRequest(endPoint, serializedData);
var createFlowResponse =
JsonConvert.DeserializeObject<CreateFlowResponseObjects.CreateFlowResponse>(response.ToString());
return createFlowResponse;
In V3 we create our surveys using the /surveys endpoint like so (the term 'template' used in the code below is not a reference to the Survey Monkey concept of template surveys):
public Survey CreateSurvey(string templateSurveyid, string newSurveyTitle)
{
const string endpoint = "/surveys";
var requestData = new RequestData {{"from_survey_id", templateSurveyid}, {"title", newSurveyTitle}};
var result = MakeApiRequest(endpoint, Verb.POST, requestData);
return result.ToObject<Survey>();
}
In V2 the title of the survey displayed at the top of each page in our new surveys would reflect the 'survey_title' data we sent with the API request. In V3 however the 'title' value is NOT replacing the text appearing at the top of each page. It IS correctly determining the name of the survey on the site but at the top of each page we see the title of the survey on which the new one was based (the survey with the id passed to the API as 'from_survey_id').
I think I've googled this pretty extensively and can't find anybody else describing this problem. Any ideas what I am doing wrong? Do I need to code modifying the survey after creation to achieve this in V3?
So it turns out this is a bug in API v3. Only part of the survey title is being updated on copy survey.
This has been resolved - expect a fix out (likely sometime this week) and it will start working without any changes on your side.
Note: PATCH on the survey should be working properly (but I wouldn't recommend coding around the issue unless necessary)
Related
Hey all the last time I used IGDB was when it was in version 3 and it was easy to search for a game depending on the platform chosen:
string url = "https://api-v3.igdb.com/games/?search=" + gameNameHere +
"&fields=name,genres,involved_companies,first_release_date,cover";
HttpWebRequest gameRequest = (HttpWebRequest)WebRequest.Create(url);
However, this version 4 is quite compilated since they tie in Twitch Oauth for some reason in order to call the API.
Besides the Oauth issue I am unable to find a simple search for a game using the IGDB-DOTNET wrapper for V4...
Now for this wrapper I start out (like it says on the website) with the following:
var igdb = new IGDBClient(
// Found in Twitch Developer portal for your app
Environment.GetEnvironmentVariable("IGDB_CLIENT_ID"),
Environment.GetEnvironmentVariable("IGDB_CLIENT_SECRET")
);
I place both my Client ID and Secret into the proper spots above. Ok, easy enough.
But now it continues to this - calling it "simple":
// Simple fields
var games = await igdb.QueryAsync<Game>(IGDBClient.Endpoints.Games,
query: "fields id,name; where id = 4;");
var game = games.First();
game.Id; // 4
game.Name; // Thief
So where did this Thief game ID of 4 come from? How do I search for the game "Thief" and get that ID in order to call the above to get the needed name, cover, artwork, etc...?
The other 3 examples below that also do not show how to search for a game.
So is this below what its looking for me to do in order to search?
var games = await igdb.QueryAsync<Game>(IGDBClient.Endpoints.Games,
query: "search \"Thief\"; fields id,name,cover;");
If not then how does one do that for V4?
Yes, you are right,
var r = await IGDBClient.QueryAsync<Game>(IGDBClient.Endpoints.Games,
$"search \"{query}\"; fields id, name,first_release_date,total_rating,summary,cover.*;");
where query = "Thief";
using .NET IPP QBOV3 SDK
I have been working (struggling) on a small integration project all week.
The purpose of the project is to be able to have some accounts integration between a windows desktop client application, to quickbooks online.
I want to be able to -
Create new customers/suppliers (can do this)
Add sales invoices (cannot do this)
Return credit balances (not even tried this yet)
After reading a few forums, and articles to come to the understanding the QBOV3 .NET SDK was the one to use, for two reasons.
I'm going to use C# .net, as a winforms application to code the
functionality I need (this allows me to have the functionality integrated in the
current system, a this is also written in c# .net winforms)
It seems intuit say this is the way to go, as all over APIs are
going to be depreciated.
So, my first hurdle was the OAuth - which eventually I managed to figure out. I can now authorise and connect to my QBO sandbox account - great!
I can also create customers from the winforms application, and they appear in QBO - also great!
The next step, which has stumped me for the last 2 or so, is to be able to create an invoice for a customer - I just cant seem to figure out what to do. I am constantly getting a 'Bad request' error.
I have found next to no examples online on how to do this from a c# winforms application. It cant be that hard - so I'm really kicking myself at the moment.
Any help, or sample to set me in the right direction would be appreciated.
I cant believe no simple examples exist of this already - I guess not many are doing this via a desktop winforms application, or I am just looking in the wrong places - or have missed something obvious!
Reading through the API documentation is confusing, and doesn't really offer any sample code. I would of thought adding a sales invoice would be a pretty big thing to cover.
Here is the code I am currently using to gain some simple functionality - creating the customer works fine (if the customer doesn't exist in qbo - this is something I need to check before adding - so any steer on that would be great also)
Here is the code I cobbled together so far..
private void button2_Click(object sender, EventArgs e)
{
string consumerKey = "consumerKey";
string consumerSecret = "consumerSecret";
string accessToken = "accessToken";
string accessTokenSecret = "accessTokenSecret";
string appToken = "appToken";
string companyID = "companyID"; //realmID
OAuthRequestValidator oauthValidator = new OAuthRequestValidator(accessToken, accessTokenSecret, consumerKey, consumerSecret);
ServiceContext context = new ServiceContext(appToken, companyID, IntuitServicesType.QBO, oauthValidator);
//uses production as default, which is https://quickbooks.api.intuit.com
context.IppConfiguration.BaseUrl.Qbo = "https://sandbox-quickbooks.api.intuit.com/";
//If not set, the default base URL, https://quickbooks.api.intuit.com, is used
DataService service = new DataService(context);
//add customer
Customer customer = new Customer();
customer.CompanyName = "Jims Junk";
customer.GivenName = "Jim";
customer.FamilyName = "Little";
customer.PrimaryEmailAddr = new EmailAddress() { Address = "test#test.com", Default = true };
customer.DisplayName = "Jims Junk Ltd"
Customer resultCustomer = service.Add(customer) as Customer;
//invoice
//-An invoice must have at least one Line that describes an item.
//- An invoice must have CustomerRef populated.
//- The DocNumber attribute is populated automatically by the data service if not supplied.
//- If ShipAddr, BillAddr, or both are not provided, the appropriate customer address from Customer is used to fill those values.
//-DocNumber, if supplied, must be unique.
Invoice invoice = new Invoice();
invoice.DocNumber = "uniqueNumber";
invoice.TxnDate = DateTime.Today.Date;
invoice.TxnDateSpecified = true;
invoice.CustomerRef = new ReferenceType()
{
name = customer.DisplayName,
Value = resultCustomer.Id
};
Line invLine = new Line();
invLine.Amount = 10000;
invLine.DetailType = LineDetailTypeEnum.SalesItemLineDetail;
invLine.Description = "Test Product";
invoice.Line = new Line[] { invLine };
Invoice resultInvoice = service.Add(invoice) as Invoice;
}
Sods Law, after a few days of not finding anything - Just now I find a code sample that has helped.
I have now managed to get an invoice posted into QBO.
Here is the linked that helped - http://developer.qbapi.com/Create-Invoice-Error---Bad-Request.aspx
ill just leave it here, so that others may benefit if struggling.
Thanks for reading.
I was using the Facebook Public API Feed for the longest time and since they deprecated it I've been trying to find a replacement method in C#.
I am able to get my page posts but any post that contains images I only get the message and no images. After spending the past weekend trying to find a way I am desperate to know if anyone has had any success in getting full page post content from the Facebook C# SDK library.
Here is what I have and it works for getting the posts but they do not contain any images.
var fb = new FacebookClient
{
AppId = ConfigurationManager.AppSettings.Get("FacebookAppID"),
AppSecret = ConfigurationManager.AppSettings.Get("FacebookAppSecret"),
AccessToken = ConfigurationManager.AppSettings.Get("FacebookAccessToken")
};
var pageFeed = string.Format("/v2.4/{0}/feed", _facebookPageId);
dynamic response = fb.Get(pageFeed);
Since the upgrade in Graph API v2.4. Only a limited set of data is sent via FB unless specifically requested. You should pass the fields parameter with the keyword of data which you would like to retrieve.
A list of keyword is available here
In your case, the request statement would be:
var pageFeed = string.Format("/v2.4/{0}/feed?fields=id,message,picture", _facebookPageId);
To get all pictures from a post: replace picture with attachments, as picture will return the very first picture linked to the post.
var pageFeed = string.Format("/v2.4/{0}/feed?fields=id,message,attachments", _facebookPageId);
How can i get the country name from latitude and longtitude using c#?
Im using the Bing.Map API
Location location12 = new Location(location.Latitude, location.Longitude);
MapLayer.SetPosition(pin, location12);
Map.Children.Add(pin);
string placeName = GetPlaceNameForCoordinates(location.Latitude, location.Longitude);
You'll want to use a reverse geocoding API of some kind. For example:
The Bing Maps API (the webservice)
The Google Geocoding API
The Geonames API
If you're already using the Bing.Maps SDK, you should use the Map.SearchManager property to get a SearchManager, and then use the ReverseGeocodeAsync method. In particular, as noted in comments, mixing and matching which API you use to show data via other SDKs may well violate the terms and conditions of both: be careful which technologies you use within a single application. (Even though this question gives sample code using the Bing Maps SDK, I've kept the list above in order to help others who may come with a slightly different context.)
For example:
var manager = map.SearchManager;
var request = new ReverseGeocodeRequestOptions(location) {
IncludeEntityTypeFlags = ReverseGeocodeEntityType.CountryRegion
};
var response = await manager.ReverseGeocodeAsync(
new ReverseGeocodeRequestOptions(location) { );
// Use the response
If you decide to use the Geonames API, the data can be downloaded for offline use too.
I've created a github project with sample code that does this without api calls
see here
Very simple country name and id returned
Right now I have an app that allows a user to schedule/post a Facebook post and then monitor the likes/comments. One of the problems I foresee is that currently I am pulling every single comment/like whether it's been processed or not. What I would like to do instead is be able to say 'Give me all the NEW comments since XYZdate/XYZcomment.' Is this currently possible?
var accessToken = existingUserNode.Attributes["accessToken"].Value;
var facebookAPIMgr = new FacebookWrapper.FacebookAPIManager();
var msg = new FacebookWrapper.FacebookMessage()
{
AccessToken = accessToken,
FacebookMessageId = facebookPost.FacebookMessageId
};
//Get Facebook Message Comments
// Need to find a way to limit this to only new comments/likes
var comments = facebookAPIMgr.RetrieveComments(msg);
You can do time-based pagination as part of your graph API query. If you keep a unix timestamp of when you polled things last, you can simply do https://graph.facebook.com/{whatever}?since={last run}.
This worked when I was working heavily with the Graph API earlier this year, and is still around on the documentation, but considering how much Facebook loves to change stuff without telling anyone you may still encounter problems. So just a warning, YMMV.