Mailgun Get Bounces - mailgun

Can I use to get bounces for the current date, based on the date?
GET /domain/bounces/date or GET /domain/bounces/created_at
Is this possible?
public static IRestResponse GetBounces() {
RestClient client = new RestClient();
client.BaseUrl = "https://api.mailgun.net/v2";
client.Authenticator = new HttpBasicAuthenticator("api","key-3ax6xnjp29jd6fds4gc373sgvjxteol0");
RestRequest request = new RestRequest();
request.AddParameter("domain", "samples.mailgun.org", ParameterType.UrlSegment);
request.Resource = "{domain}/bounces/{created_at}";
return client.Execute(request);
}
Thank you

Not directly, you need to get the whole object which returns time-date of bounce within its body and then extract it iteratively
GET /<domain>/bounces
Related: http://documentation.mailgun.com/api-bounces.html#bounces

For the newest, use the events API. You really only need the suppressions API for things older than 30 days.

Related

Adding a cookie to DocumentRequest

Using AngleSharp v 0.9.9, I'm loading a page with OpenAsync which sets a bunch of cookies, something like:
var configuration = Configuration.Default.WithHttpClientRequester().WithCookies();
var currentContext = BrowsingContext.New(configuration);
// ....
var doc = context.OpenAsync(url, token);
This works fine and I can see the cookies have been set. For example, I can do this:
var cookieProvider = currentContext.Configuration.Services.OfType<ICookieProvider>().First() as MemoryCookieProvider;
And examine it in the debugger and see the cookies in there (for domain=.share.state.nm.us)
Then I need to submit a post:
var request = new DocumentRequest(postUrl);
request.Method = HttpMethod.Post;
request.Headers["Content-Type"] = "application/x-www-form-urlencoded";
request.Headers["User-Agent"] = userAgent;
//...
Which eventually gets submitted:
var download = loader.DownloadAsync(request);
And I can see (using Fiddler) that it's submitting the cookies from the cookieProvider.
However, I need to add a cookie (and possible change the value in another) and no matter what I try, it doesn't seem to include it. For example, I do this:
cookieProvider.Container.Add(new System.Net.Cookie()
{
Domain = ".share.state.nm.us",
Name = "psback",
Value = "somevalue",
Path = "/"
});
And again I can examine the cookieProvider in the debugger and see the cookie I set. But when I actually submit the request and look in fiddler, the new cookie isn't included.
This seems like it should be really simple, what is the correct way to set a new cookie and have it included in subsequent requests?
I think there are two potential ways to solve this.
either use document.Cookie for setting a new cookie (would require an active document that already is at the desired domain) or
Use a Filter for getting / manipulating the request before its send. This let's you really just change the used cookie container before actually submitting.
The Filter is set in the DefaultLoader configuration. See https://github.com/AngleSharp/AngleSharp/blob/master/src/AngleSharp/ConfigurationExtensions.cs#L152.

Epicor ERP can you call an Epicor Function within a Customization

Epicor ERP 10.2.500 has been recently released with the addition of Epicor Functions. They can be called from within Method and Data Directives.
Do anybody has been able to do so with a Form Customization within Epicor?
This is possible via a REST call to your function API. In this case, I had a function that sent an email from some inputs.
private void epiButtonC1_Click(object sender, System.EventArgs args)
{
//API Key is included in the query param in this example.
var request = (HttpWebRequest)WebRequest.Create("https://{appserver}/{EpicorInstance}/api/v2/efx/{CompanyID}/{LibraryID}/{functionName}/?api-key={yourAPIKey}");
request.Method = "POST";
//All REST v2 requests also sent with authentication method (Token, Basic)
//This should be Base64 encoded
string username = "userName";
string password = "passWord";
string encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
request.Headers.Add("Authorization", "Basic " + encoded);
//Add body to correspond to request signature
request.ContentType = "application/json";
using(var writer = new StreamWriter(request.GetRequestStream()))
 {
    var values = new Dictionary<string, string>;
      {
        {"toEmailAddress", "someEmail#email.com"},
        {"fromEmailAddress","someOtherEmail#email.com"}, 
        {"body","This is the body"},   
{"subject","Hello from Client Code!"}
    };
    string json = JsonConvert.SerializeObject(values);
    writer.Write(json);
}
using (var response = request.GetResponse()) 
using (var reader = new StreamReader(response.GetResponseStream()))
{
  var result = reader.ReadToEnd();
  epiTextBoxC1.Text = result.ToString();
}
}
Haven't done it myself personally, but looking into the first post release notes about it here leads me to believe there is no out of the box solution, yet in this version/initial release.
However I'm sure you could do a HTTP request from within the Epicor customization if you have the REST API enabled in your environment.
If you create your own dll that calls the EpicorFunction you can use it within the customization. Still looking for a way to call them directly.
REST endpoint is the recommended way to perform the function call as pointed out by a-moreng.
If for some reason you cannot use this, you can use a passthrough method to any server-side BO via a customization Adapter. For instance, create an updatable BAQ which you can call from a customization using the DynamicQueryAdapter.
Pick an arbitrary table and field to save the BAQ.
Create three string parameters to store the Function library name, the function name, and a delimited list of parameters.
On the GetList method, create a Base Processing Directive.
Split your delimited parameter list and convert them to the appropriate datatypes.
Use the resulting variables to call your function.
If desired, you can pass return variables into the ttResults of the BAQ

Instagram ?__a=1 not working anymore

I've been using Instagram's undocumented API https://www.instagram.com/<user>/?__a=1 to get a public user feed on a website. Since a while now, this is not working anymore, probably because Facebook removed it. Is there an other way to get the data of an instagram account in a easy way?
I built a small server which does that transformation. You'll receive the instagram data as before with ?__a=1 (as JSON ) - have fun 😊
https://www.instapi.io/u/<username>
https://www.instapi.io/u/appwithus
EDIT 12/2020: Unfortunately the service is no longer available
Edit 15/03 NOT WORKING ANYMORE Seems like instagram changed again their API, now it gives a CORS error.
As of 2 february 2021, I have found a solution
Instead of using https://www.instagram.com/username/?__a=1 which it asks for a login.
Justing adding a /channel seems to make it work, like so:
https://www.instagram.com/username/channel/?__a=1
There is a JSON data in https://www.instagram.com/<user>/.
You can use regexp to find what you need.
Sample
// This regexp gets widest possible dict around "profile_pic_url"
// but inside tag <script type="text/javascript">...</script>
let r = new RegExp('<script type="text\/javascript">' +
'([^{]+?({.*profile_pic_url.*})[^}]+?)' +
'<\/script>');
let source = document.documentElement.outerHTML;
let jsonStr = source.match(r)[2];
let data = JSON.parse(jsonStr);
console.log('data', data);
let oldVariantOfData = data['entry_data']['ProfilePage'][0];
console.log('oldVariantOfData', oldVariantOfData);
The same response is attached in the html response of the profile url, I perform this temporal solution (when I can't use the API) in python:
url_recent_media = 'https://www.instagram.com/%s/' % instagram_id
response = urllib2.urlopen(url_recent_media)
insta_html = response.read()
insta_html_split = insta_html.split('"ProfilePage":[')
if len(insta_html_split) > 1:
insta_html_split_2 = insta_html_split[1].split(']},"gatekeepers"')
if len(insta_html_split_2) > 1:
json_dict = json.loads(insta_html_split_2[0])
I hope this help you.
you can try without using instagram API.
import json, urllib2
img_dicts = []
url = 'https://www.instagram.com/{}/'.format(instagram_username)
try:
r = urllib2.urlopen(url, timeout=10.0)
instagram_html = r.read()
instagram_html_data = instagram_html.split('"ProfilePage":[')
if len(instagram_html_data) > 1:
instagram_html_final_data = instagram_html_data[1].split(']},"gatekeepers"')
if len(instagram_html_final_data) > 1:
json_dict = json.loads(instagram_html_final_data[0])
media = json_dict['graphql']['user']['edge_owner_to_timeline_media']['edges']
for obj in media:
img_dicts.append({
'id': obj['node']['id'],
'caption': obj['node']['edge_media_to_caption']['edges'][0]['node']['text'],
'imgurl_standard': obj['node']['display_url'],
'imgurl_lower': obj['node']['thumbnail_resources'][4]['src'],
'imgurl_thumb': obj['node']['thumbnail_resources'][3]['src']
})
img_dicts will give you images in different quality and caption of instagram post.

EXM subscribe to list C#

I'm working on converting my old Sitecore (< 8) code to work with Sitecore EXM. I'm having a hard time adding users to Recipient Lists from code. The answers in this post: Sitecore 8 EXM add a contact to list from listmanager don't answer my questions completely, and since I cannot comment, I've decided to start a new topic.
My first problem is that my EcmFactory.GetDefaultFactory().Bl.RecipientCollectionRepository.GetEditableRecipientCollection(recipientListId) gives a compilation error on the RecipientCollectionRepository, it says it does not exist. So I've used slightly different code. My code now, is as follows:
var contactRepository = new ContactRepository();
var contactName = this.Email.Text;
var contact = contactRepository.LoadContactReadOnly(contactName);
contact = contactRepository.CreateContact(Sitecore.Data.ID.NewID);
contact.Identifiers.AuthenticationLevel = Sitecore.Analytics.Model.AuthenticationLevel.None;
contact.System.Classification = 0;
contact.ContactSaveMode = ContactSaveMode.AlwaysSave;
contact.Identifiers.Identifier = contactName;
contact.System.OverrideClassification = 0;
contact.System.Value = 0;
contact.System.VisitCount = 0;
var contactPreferences = contact.GetFacet<IContactPreferences>("Preferences");
contactPreferences.Language = "nl-NL";
var contactEmailAddresses = contact.GetFacet<IContactEmailAddresses>("Emails");
contactEmailAddresses.Entries.Create("test").SmtpAddress = this.Email.Text;
contactEmailAddresses.Preferred = "test";
var contactPersonalInfo = contact.GetFacet<IContactPersonalInfo>("Personal");
contactPersonalInfo.FirstName = contactName;
contactPersonalInfo.Surname = "recipient";
if (recipientList != null)
{
var xdbContact = new XdbContactId(contact.ContactId);
if (!recipientList.Contains(xdbContact, true).Value)
{
recipientList.AddRecipient(xdbContact);
}
contactRepository.SaveContact(contact, new ContactSaveOptions(true, null));
}
So the recipientList is found, and the first time I add a contact to it, it increases the "Recipients" to 1 (checked using the /sitecore/system/List Manager/All Lists/E-mail Campaign Manager/Custom/RecipientList).
I also have a message which has this Opt-in recipient list, but when I check that message, it says it will be sent to 0 subscribers.
Any thoughts on this?
See this article listing known issues in Sitecore EXM:
https://kb.sitecore.net/articles/149565
"The recipient list shows "0" total recipients after recipients have been subscribed to the list. (62217)"
I got around this in a sandbox environment by adding a simple list (from csv, one contact) to the message. This upped the total recipient count from 0 to 1 which allows the message to be activated. All recipients in the composite list were sent a message.
Do you have a distributed environment? If so the RecipientCollectionRepository will not work as it is only available on a Content Management server. You could try using the ClientApi:
ClientApi.UpdateSubscriptions(RecipientId recipientId, string[] listsToSubscribe, string[] listsToUnsubscribe, string managerRootId, bool confirmSubscription)
and just add the id of the list you want to subscribe people to in the first string array.
Just a quick note with this option, listToUnsubscribe does not actually remove a contact from a list. You are meant to pass through the ID of the opt out list. This basically excludes them from any future emails. One draw back is that you will no longer be able to resubscribe them.
If this does not work for you you will need to create your own API between your CD server and your CM server where the CM server uses the recipientCollectionRepository to subscribe and unsubscribe

How to get Expiration Date of access token in Facebook SDK for Unity

I am using parse sdk for backend management for my game. For user signup/login parse api ask for parameter tokenExpiration. I have no idea how to get it from facebook unity sdk.
https://www.parse.com/docs/unity_guide#fbusers-signup
Task<ParseUser> logInTask = ParseFacebookUtils.LogInAsync(accessToken, userId, tokenExpiration);
Got this problem solved by myself using debug_token. Here is the right code on how to do it.
FB.API("/debug_token?input_token="+FB.AccessToken+"&access_token="+FB.AccessToken,Facebook.HttpMethod.GET, AccessTokenCallback);
function AccessTokenCallback(response:String){
Debug.Log(response);
var access = JSON.Parse(response);
Debug.Log("Token Expiration is: "+access["data"]["expires_at"].Value);
}
If you will print the response it will give you a JSON with all information about the access token and you can take whatever info you need about an access token.
Open FacebookAccessTokenEditor.cs and replace original line 81:
formData["batch"] = "[{\"method\":\"GET\", \"relative_url\":\"me?fields=id\"},{\"method\":\"GET\", \"relative_url\":\"app?fields=id\"}]";
by these two:
string getExpiresAt = ",{\"method\":\"GET\", \"relative_url\":\"debug_token?input_token="+accessToken+"\"}";
formData["batch"] = "[{\"method\":\"GET\", \"relative_url\":\"me?fields=id\"},{\"method\":\"GET\", \"relative_url\":\"app?fields=id\"}"+getExpiresAt+"]";
Then open FacebookEditor.cs and in method MockLoginCallback, just before line 220:
isLoggedIn = true;
insert the following lines:
var tokenData = (Dictionary<string, object>)MiniJSON.Json.Deserialize(responses[2]);
var expiresAt = (long)((Dictionary<string, object>)tokenData["data"])["expires_at"];
accessTokenExpiresAt = FromTimestamp((int)expiresAt);
also, add the missing function FromTimestamp which you can copy from AndroidFacebook.cs or IOSFacebook.cs or jus copy from here:
private DateTime FromTimestamp(int timestamp)
{
return new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(timestamp);
}
Finally, you can call the parse method like you do on IOS or Android or Web:
Task<ParseUser> logInTask = ParseFacebookUtils.LogInAsync(FB.UserId, FB.AccessToken, FB.AccessTokenExpiresAt);
Note: As I have worked on the code, I am not sure of the original line numbers, but I think they are correct. Also, this does not reflect the best coding practices, but since it is used only in a debug context, they're good enough for me.