reading messages from fb - c#

I successfully login to facebook but while trying to read the mailbox I got the following error: {"(OAuthException - #298) (#298) Requires extended permission: read_mailbox"}
If I add that scope in the URL;
var destinationUrl =
String.Format(
"https://www.facebook.com/dialog/oauth?client_id={0}&scope={1}&display=popup&redirect_uri=http://www.facebook.com/connect/login_success.html&response_type=token",
AppID, //client_id
"user_posts" //scope
);
and try to get mails:
private void FaceBookScrapper()
{
var client = new FacebookClient(_fbToken);
var input = new List<FbMesseage>();
if (client != null)
{
dynamic result = client.Get("me/inbox", null);
foreach (var item in result.inbox.data)
{
if (item.unread > 0 || item.unseen > 0)
{
foreach (var message in item.comments.data)
{
input.Add(new FbMesseage
{
Id = message.id,
FromName = message.from.name,
FromId = message.from.id,
Text = message.message,
CreatedDate = message.created_time
});
}
FbMesseageCollectionViewModelIns.LoadData(input);
}
}
}
}
}
}

That permission doesn't exist any more - it has been removed, together with the /user/inbox endpoint.
https://developers.facebook.com/docs/apps/changelog#v2_4_deprecations mentions this, and https://developers.facebook.com/docs/graph-api/reference/v2.5/user/inbox as well.
Under the latter URL, it says it right on the very top of the page:
This document refers to a feature that was removed after Graph API v2.4.
There is no way any more to access a user's inbox via API.

Related

gmail api returning null for a specific history id. History id received from Cloud Pub/Sub push subscription

From Cloud pub/sub push service i got a history id. Using that history id i am trying to read the recent mail's but It returns null.
I have configured cloud pub/sub push subscription and add a watch to "Unread" label.
Scenario 1:
I have received a push notification. From that push notification i have taken history id to get the recent messages. it's returning me null value.
Scenario 2:
I have logged into that configured mail id and then the message loaded in inbox. After that if i try to read i am getting the history list.
static string[] Scopes = { GmailService.Scope.MailGoogleCom };
static void Main(string[] args)
{
string UserId = "####.gmail.com";
UserCredential credential;
using (var stream =
new FileStream("client_secret_#####.json", FileMode.Open, FileAccess.Read))
{
string credPath = "token.json";
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
GoogleClientSecrets.Load(stream).Secrets,
Scopes,
UserId,
CancellationToken.None,
new FileDataStore(credPath, true)).Result;
Console.WriteLine("Credential file saved to: " + credPath);
}
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
List<History> result = new List<History>();
UsersResource.HistoryResource.ListRequest request = service.Users.History.List(UserId);
//history id received from cloud pub/sub push subscription.
request.StartHistoryId = Convert.ToUInt64("269871");
do
{
try
{
ListHistoryResponse response = request.Execute();
if (response.History != null)
{
result.AddRange(response.History);
}
request.PageToken = response.NextPageToken;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
} while (!String.IsNullOrEmpty(request.PageToken));
foreach (var vHistory in result)
{
foreach (var vMsg in vHistory.Messages)
{
string date = string.Empty;
string from = string.Empty;
string subject = string.Empty;
string body = string.Empty;
var emailInfoRequest = service.Users.Messages.Get(UserId, vMsg.Id);
var emailInfoResponse = emailInfoRequest.Execute();
if(emailInfoResponse!= null)
{
foreach (var mParts in emailInfoResponse.Payload.Headers)
{
if (mParts.Name == "Date")
{
date = mParts.Value;
}
else if (mParts.Name == "From")
{
from = mParts.Value;
}
else if (mParts.Name == "Subject")
{
subject = mParts.Value;
}
if (date != "" && from != "")
{
if (emailInfoResponse.Payload.Parts != null)
{
foreach (MessagePart p in emailInfoResponse.Payload.Parts)
{
if (p.MimeType == "text/html")
{
byte[] data = FromBase64ForUrlString(p.Body.Data);
body = Encoding.UTF8.GetString(data);
}
else if(p.Filename!=null && p.Filename.Length>0)
{
string attId = p.Body.AttachmentId;
string outputDir = #"D:\#####\";
MessagePartBody attachPart = service.Users.Messages.Attachments.Get(UserId, vMsg.Id, attId).Execute();
String attachData = attachPart.Data.Replace('-', '+');
attachData = attachData.Replace('_', '/');
byte[] data = Convert.FromBase64String(attachData);
File.WriteAllBytes(Path.Combine(outputDir, p.Filename), data);
}
}
}
else
{
byte[] data = FromBase64ForUrlString(emailInfoResponse.Payload.Body.Data);
body = Encoding.UTF8.GetString(data);
}
}
}
}
}
}
public static byte[] FromBase64ForUrlString(string base64ForUrlInput)
{
int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
result.Append(String.Empty.PadRight(padChars, '='));
result.Replace('-', '+');
result.Replace('_', '/');
return Convert.FromBase64String(result.ToString());
}
}
Please let me know how to read the full message using history id. when i receive push notification.
The Gmail Api documentation states that the Users.history:list method requires startHistoryId as a parameter to be executed, rather than giving you this parameter as a response. This is confusing, since it states as an optional parameter, but it is also specifies that it is required. The documentation also specifies:
The supplied startHistoryId should be obtained from the historyId of a
message, thread, or previous list response.
I suggest you to test the methods you use first with "Try this API" and OAuth 2.0 Playground. This makes it easier to understand which parameters you need to supply and which responses you can obtain from each method.
I have dealt with this. The point is that the history_id you are receiving is to be interpreted like the "latest moment when something happened". So, in order to make this work, you MUST use a history_id coming from a previous execution (that, don't forget, in GMail Push API means that you have to implement the initial full sync, or at the very least you should be executing a second run of your partial sync), which will return the events that span from the previous history_id to the one you just received.
I have just published an article on medium, since the detail of the history_id, in my opinion, can be a little sneaky. Article is here.

TweetSharp send message to followers?

Does anybody know if by using tweetsharp, one can send a message to a persons follow list? I have made the following code that allows me to message a single person via userid, but not to a list.
Any ideas?
var service = new
TweetSharp.TwitterService("ConsumerKey","ConsumerSecret","TokenKey","TokenSec
retKey");
var twitterStatus = service.SendTweet(new SendTweetOptions() { Status ="Hello World" });
if (twitterStatus != null)
{
MessageBox.Show("It worked");
}
You can start off by getting the TwitterService object to obtain followers, then follow up with the SendMessage function.
TwitterService service = new TwitterService("key", "secret");
service.AuthenticateWith(userToken, userSecret);
var friendship =
service.GetFriendshipInfo(new GetFriendshipInfoOptions
{
SourceScreenName = "handle",
TargetScreenName = "handle"
});
if (friendship.Relationship.Source.FollowedBy)
{
yield return handle;
}
Then on return do something like:
foreach (string handle in client.ReturnFollowingUsers(handles).Distinct()))
{
TwitterDirectMessage dm = client.SendMessage(handle, message);
}

Google Merchant Product Feed not Accepting my Feed

I am working with the GData api to import products to my merchant feed. The code is as follows:
List<ProductEntry> newEntries = new List<ProductEntry>();
foreach (Product prod in ent.Products.Where(i => !i.IsDeleted && i.IsDisplayed && i.Price > 0))
{
newEntries.Add(prod.GetNewEntry());
}
string GoogleUsername = "nope#gmail.com";
string GooglePassword = "*****";
ContentForShoppingService service = new ContentForShoppingService("MY STORE");
service.setUserCredentials(GoogleUsername, GooglePassword);
service.AccountId = "*******";
service.ShowWarnings = true;
ProductFeed pf = service.InsertProducts(newEntries);
r.Write(pf.Entries.Count.ToString());
This code is returning to me 1 entry, rather than the 400+ it should, and that 1 entry is empty with no error or warning info. Nothing shows on my merchant center dash. Any ideas on what might be occurring here?
OR - how can I get more details on what is going on?
First of all create a service account on Google Developers
Console if you don't have one already.
NuGet package Google.Apis.ShoppingContent.v2
after you do whats mentioned on the link you'll get
a ClientId
a ClientSecret
those we will be using to authenticate.
var credentials = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets() {
ClientId = "yourclientid",
ClientSecret = "yourclientsecret" },
new string[] { ShoppingContentService.Scope.Content },
"user",
CancellationToken.None).Result;
//make this a global variable or just make sure you pass it to InsertProductBatch or any function that needs to use it
service = new ShoppingContentService(new BaseClientService.Initializer()
{
HttpClientInitializer = credentials,
ApplicationName = "Your-app-name"
});
Now for the insert part:
private async Task<List<Product>> InsertProductBatch(IEnumerable<Product> products, ulong merchantaccountid)
{
// Create a batch request.
BatchRequest request = new BatchRequest(service);
List<Product> responseproducts = new List<Product>();
foreach (var p in products)
{
ProductsResource.InsertRequest insertRequest =
service.Products.Insert(p, merchantaccountid);
request.Queue<Product>(
insertRequest,
(content, error, index, message) =>
{
responseproducts.Add(content);
//ResponseProducts.Add(content);
if (content != null)
{
//product inserted successfully
}
AppendLine(String.Format("Product inserted with id {0}", ((Product)content).Id));
if (error != null)
{
//there is an error you can access the error message though error.Message
}
});
}
await request.ExecuteAsync(CancellationToken.None);
return responseproducts;
}
And thats all to it.

how to get user's event list from Adobe Connect API?

I'm trying to get list of events, a particular user has signed up for. Note: i can get my-events, but then i need to login as user :(
Adobe Connect API user guide says this:
Given a user’s login or principal-id, this action returns the list of events that the user attended
Now do I get list of Events User is going to attend - is signed up for?
...
main()
{
//login as adiminstrator
ConnectAPI connectApi = new ConnectAPI(#"http://domain.adobeconnect.com","user#domain.com", "Password", "");
var listOfEventsJson = getUsersAttendedEvents("someUser#email.com", "someAccountId");
Console.WriteLine( listOfEventsJson );
}
I get an empty Json list when I use
private String getUsersAttendedEvents(string login, string accountId)
{
if (_bzsession == "")
Login();
string queryString = "login=" + login +
"&account-id=" + accountId;
var result = Request("events-attendance", queryString);
return JsonConvert.SerializeXmlNode(result, Newtonsoft.Json.Formatting.Indented);
}
response result is this:
{
"results": {
"?xml": {
"#version": "1.0",
"#encoding": "utf-8"
},
"results": {
"status": {
"#code": "no-data"
}
}
}
}
thanks in advance
my solution is to run thrue all events and after run thrue events users and compare users, do you have better one!? Couse this takes time to run thrue all thouse loops:
here is my own solution:
public List<String> getUserAtendedEvents(String userEmail)
{
// get all upcoming Events Sco ID's
var scoIds = getAllEventsDataToClass().ScoIds;
List<String> userEvents = new List<string>();
// request Connect for Event info
// action=report-event-participants-complete-information&sco-id=1418245799
for (int i = 0; i < scoIds.Count; i++)
{
XDocument req = RequestXDoc("report-event-participants-complete-information", "sco-id=" + scoIds[i]);
var emails = req.Descendants().Attributes("login"); // ---- login emails
foreach (var email in emails)
{
if (email.Value.Equals(userEmail))
{
userEvents.Add(scoIds[i]);
}
}
}
return userEvents;
}

C# Google drive sdk. How to get a list of google drive folders?

I'm writing a program to allow a user to upload files to their Google Drive account. I have the upload part working and am using OAuth2. The issue I'm currently having is getting a list of folders from the users Drive account.
I found some code that is supposed to do this using the .setUserCredentials method, but it doesn't work:
DocumentsService service1 = new DocumentsService("project");
service1.setUserCredentials("user","pass");
FolderQuery query1 = new FolderQuery();
// Make a request to the API and get all documents.
DocumentsFeed feed = service1.Query(query1);
// Iterate through all of the documents returned
foreach (DocumentEntry entry in feed.Entries)
{
var blech = entry.Title.Text;
}
Nothing is returned. Ideally, I want to use OAuth2 to do this. I've been trying with the following code, trying to set the authentication token, but I always get denied access:
String CLIENT_ID = "clientid";
String CLIENT_SECRET = "secretid";
var docprovider = new NativeApplicationClient(GoogleAuthenticationServer.Description, CLIENT_ID, CLIENT_SECRET);
var docstate = GetDocAuthentication(docprovider);
DocumentsService service1 = new DocumentsService("project");
service1.SetAuthenticationToken(docstate.RefreshToken);
FolderQuery query1 = new FolderQuery();
DocumentsFeed feed = service1.Query(query1); //get error here
// Iterate through all of the documents returned
foreach (DocumentEntry entry in feed.Entries)
{
// Print the title of this document to the screen
var blech = entry.Title.Text;
}
..
private static IAuthorizationState GetDocAuthentication(NativeApplicationClient client)
{
const string STORAGE = "storagestring";
const string KEY = "keystring";
string scope = "https://docs.google.com/feeds/default/private/full/-/folder";
// Check if there is a cached refresh token available.
IAuthorizationState state = AuthorizationMgr.GetCachedRefreshToken(STORAGE, KEY);
if (state != null)
{
try
{
client.RefreshToken(state);
return state; // Yes - we are done.
}
catch (DotNetOpenAuth.Messaging.ProtocolException ex)
{
}
}
// Retrieve the authorization from the user.
state = AuthorizationMgr.RequestNativeAuthorization(client, scope);
AuthorizationMgr.SetCachedRefreshToken(STORAGE, KEY, state);
return state;
}
Specifically, I get "Execution of request failed: https://docs.google.com/feeds/default/private/full/-/folder - The remote server returned an error: (401) Unauthorized".
I've also tried:
var docauth = new OAuth2Authenticator<NativeApplicationClient>(docprovider, GetDocAuthentication);
DocumentsService service1 = new DocumentsService("project");
service1.SetAuthenticationToken(docauth.State.AccessToken);
but "State" is always null, so I get a null object error. What am I doing wrong and how is this done?
You should use the Drive SDK, not the Documents List API, which allows you to list folders. You can use "root" as a folderId if you want to list the root directory.
I actually implemented the v3 version of the GDrive SDK for .NET and needed to search for folders as well.
I prefer requesting uniquely all folders instead of getting all files and then performing a LinQ query to keep just the folders.
This is my implementation:
private async Task<bool> FolderExistsAsync(string folderName)
{
var response = await GetAllFoldersAsync();
return response.Files
.Where(x => x.Name.ToLower() == folderName.ToLower())
.Any();
}
private async Task<Google.Apis.Drive.v3.Data.FileList> GetAllFoldersAsync()
{
var request = _service.Files.List();
request.Q = "mimeType = 'application/vnd.google-apps.folder'";
var response = await request.ExecuteAsync();
return response;
}
You could request the name on the Q this way as well:
request.Q = $"mimeType = 'application/vnd.google-apps.folder' and name = '{folderName}'";
Which would lead and simplify things to (obviating null checking):
private async Task<bool> FolderExistsAsync(string folderName)
{
var response = await GetDesiredFolder(folderName);
return response.Files.Any();
}
private async Task<FileList> GetDesiredFolder(string folderName)
{
var request = _service.Files.List();
request.Q = $"mimeType = 'application/vnd.google-apps.folder' and name = '{folderName}'";
var response = await request.ExecuteAsync();
return response;
}
private IEnumerable<DocumentEntry> GetFolders(string id) {
if (IsLogged) {
var query = new FolderQuery(id)
{
ShowFolders = true
};
var feed = GoogleDocumentsService.Query(query);
return feed.Entries.Cast<DocumentEntry>().Where(x => x.IsFolder).OrderBy(x => x.Title.Text);
}
return null;
}
...
var rootFolders = GetFolders("root");
if (rootFolders != null){
foreach(var folder in rootFolders){
var subFolders = GetFolders(folder.ResourceId);
...
}
}
where GoogleDocumentsService is a instance of DocumentsService and IsLogged is a success logged flag.
I got this way to get list of folders from google drive
FilesResource.ListRequest filelist= service.Files.List();
filelist.Execute().Items.ToList().Where(x => x.MimeType == "application/vnd.google-apps.folder").ToList()

Categories

Resources