Using .NET c# I need to programmatically manage / add subscribers to my lists in aWeber using the API. The process that I am tasked with will be a Windows Service that runs x # of times a day and updates the subscribers at aWeber and the lists that they are in.
So .. all of my research using the aWeber API with .NET has shown me that a signon page at aWeber must be completed in order to receive the oauth_verifier back in the callback URL.
So in summary here are my questions:
Any recommendations on how to accomplish this task using an unattended service?
Has anyone does this?
Any help is greatly appreciated.
Thanks
Emma
1) How to use Aweber .NET SDK to connect with Aweber account [Regular Account - (i.e.) Not the developer's one].
Download .NET SDK for Aweber from https://aweber.codeplex.com/
Ans :- 1) Create a developer account - Visit https://labs.aweber.com/
2) As you have successfully created the account you would see ConsumerKey, ConsumerSecret, & an AppId in your Application.
3) Then for the fist time add the following code.
string ConsumerKey = ConfigurationManager.AppSettings["AWeberConsumerKey"];
string ConsumerSecret= ConfigurationManager.AppSettings["AWeberConsumerSecret"];
Aweber.API api = new Aweber.API(ConsumerKey, ConsumerSecret);
api.CallbackUrl = "http://" + Request.Url.Host + ":" + Request.Url.Port + "/Authorize/Index";
api.get_request_token();
Response.Cookies["oauth_token"].Value = api.OAuthToken;
Response.Cookies["oauth_token_secret"].Value = api.OAuthTokenSecret;
api.authorize();
**Now create An Authorize controller in case of MVC or Authorize.aspx**
string ConsumerKey = ConfigurationManager.AppSettings["AWeberConsumerKey"];
string ConsumerSecret= ConfigurationManager.AppSettings["AWeberConsumerSecret"];
API api = new API(ConsumerKey, ConsumerSecret);
api.OAuthVerifier = Request["oauth_verifier"];
Response.Cookies["access_token"].Value = api.get_access_token();
Account account = api.getAccount();
**Now you can apply your code to create, delete... subscribers to/from the list**
When you run this code first the authorize page will appear where you need to add your Aweber regular account credentials.
Once it's verified then you'll get access to the aweber's(Customer) account.
**But you would not like the authorize page appear always whenever you run your application so you can omit it by doing the following steps.**
1. Use the PHP script provided in http://stackoverflow.com/questions/15378034/how-to-create-an-app-in-aweber
2. Run the above PHP script & you'll get the pair of accesskey & accesssecret.Copy them to your C# code (these are the permanent keys).
3. Initialize the API with this code:
string ConsumerKey = ConfigurationManager.AppSettings["AWeberConsumerKey"];
string ConsumerSecret = ConfigurationManager.AppSettings["AWeberConsumerSecret"];
string accessKey = ConfigurationManager.AppSettings["accessKey"];
string accessSecret = ConfigurationManager.AppSettings["accessSecret"];
Aweber.API api = new Aweber.API(ConsumerKey, ConsumerSecret);
api.OAuthToken = accessKey;
api.OAuthTokenSecret = accessSecret;
Account account = api.getAccount();
**Now we'll code to create subscriber to a particular list**
int listid = int.Parse(ConfigurationManager.AppSettings["ListId"]);
foreach (List list in account.lists().entries)
{
if (list.id == listid) Your List's ID **(Mylist - xxxxxxx)**
{
foreach (Subscriber subscriber in list.subscribers().entries)
{
if (subscriber.email.Equals(objRegModel.EmailID))
{
flag = false;
break;
**Checks whether the similar subscriber exists on the list**
}
else
{
flag = true;
}
}
if (flag == true)
{
BaseCollection<Subscriber> target = list.subscribers();
SortedList<string, object> parameters = new SortedList<string, object>();
parameters.Add("email", objRegModel.EmailID);
parameters.Add("name", objRegModel.FirstName + " " + objRegModel.LastName);
Subscriber subscriber = target.create(parameters);
**This will add the subscriber to the specified list only if does not exist on that list.**
}
}
}
**To Delete a particluar subscriber from the list**
Apply the same logic till Account account = api.getAccount();
To get the EmailID,IP Address etc of the subscribers on the
list.Refer to this link https://labs.aweber.com/docs/permissions
int listid = int.Parse(ConfigurationManager.AppSettings["ListId"]);
foreach (List list in account.lists().entries)
{
if (list.id == listid)
{
foreach (Subscriber subscriber in list.subscribers().entries)
{
We Perform the check whether the email of the subscriber exists on the list or not & accordingly delete it from the list.
if (subscriber.email == eid && subscriber.status != "unconfirmed")
{
try
{
if (subscriber.delete())
{
//Response.Write("Subscriber Successfully Deleted");
}
}
catch (Exception ex)
{
}
}
}
}
}
}
Related
I want to implement Authorize .net payment gateway in my website using asp.net. I am a beginner in this. Can someone give me a sample code from where I can be redirected to the Authorize.net page to complete payment process.
I have created a sandbox account.
Redirection URL - https://test.authorize.net/gateway/transact.dll but I get an error
(13) The merchant login ID or password is invalid or the account is inactive.
My account is active and in test mode.
My Code:
protected void Button_pay_Click(object sender, EventArgs e)
{
string value = TextBox_amt.Text;
decimal d = decimal.Parse(value);
Run("abc", "abcq234", d);
}
public static ANetApiResponse Run(String ApiLoginID, String ApiTransactionKey, decimal amount)
{
Console.WriteLine("Create an Accept Payment Transaction Sample");
ApiOperationBase<ANetApiRequest, ANetApiResponse>.RunEnvironment = AuthorizeNet.Environment.SANDBOX;
// define the merchant information (authentication / transaction id)
ApiOperationBase<ANetApiRequest, ANetApiResponse>.MerchantAuthentication = new merchantAuthenticationType()
{
name = ApiLoginID,
ItemElementName = ItemChoiceType.transactionKey,
Item = ApiTransactionKey,
};
var opaqueData = new opaqueDataType
{
dataDescriptor = "COMMON.ACCEPT.INAPP.PAYMENT",
dataValue = "119eyJjb2RlIjoiNTBfMl8wNjAwMDUyN0JEODE4RjQxOUEyRjhGQkIxMkY0MzdGQjAxQUIwRTY2NjhFNEFCN0VENzE4NTUwMjlGRUU0M0JFMENERUIwQzM2M0ExOUEwMDAzNzlGRDNFMjBCODJEMDFCQjkyNEJDIiwidG9rZW4iOiI5NDkwMjMyMTAyOTQwOTk5NDA0NjAzIiwidiI6IjEuMSJ9"
};
var billingAddress = new customerAddressType
{
firstName = "John",
lastName = "Doe",
address = "123 My St",
city = "OurTown",
zip = "98004"
};
//standard api call to retrieve response
var paymentType = new paymentType { Item = opaqueData };
// Add line Items
var lineItems = new lineItemType[2];
lineItems[0] = new lineItemType { itemId = "1", name = "t-shirt", quantity = 2, unitPrice = new Decimal(15.00) };
lineItems[1] = new lineItemType { itemId = "2", name = "snowboard", quantity = 1, unitPrice = new Decimal(450.00) };
var transactionRequest = new transactionRequestType
{
transactionType = transactionTypeEnum.authCaptureTransaction.ToString(), // charge the card
amount = amount,
payment = paymentType,
billTo = billingAddress,
lineItems = lineItems
};
var request = new createTransactionRequest { transactionRequest = transactionRequest };
// instantiate the contoller that will call the service
var controller = new createTransactionController(request);
controller.Execute();
// get the response from the service (errors contained if any)
var response = controller.GetApiResponse();
//validate
if (response != null)
{
if (response.messages.resultCode == messageTypeEnum.Ok)
{
if (response.transactionResponse.messages != null)
{
Console.WriteLine("Successfully created transaction with Transaction ID: " + response.transactionResponse.transId);
Console.WriteLine("Response Code: " + response.transactionResponse.responseCode);
Console.WriteLine("Message Code: " + response.transactionResponse.messages[0].code);
Console.WriteLine("Description: " + response.transactionResponse.messages[0].description);
Console.WriteLine("Success, Auth Code : " + response.transactionResponse.authCode);
}
else
{
Console.WriteLine("Failed Transaction.");
if (response.transactionResponse.errors != null)
{
Console.WriteLine("Error Code: " + response.transactionResponse.errors[0].errorCode);
Console.WriteLine("Error message: " + response.transactionResponse.errors[0].errorText);
}
}
}
else
{
Console.WriteLine("Failed Transaction.");
if (response.transactionResponse != null && response.transactionResponse.errors != null)
{
Console.WriteLine("Error Code: " + response.transactionResponse.errors[0].errorCode);
Console.WriteLine("Error message: " + response.transactionResponse.errors[0].errorText);
}
else
{
Console.WriteLine("Error Code: " + response.messages.message[0].code);
Console.WriteLine("Error message: " + response.messages.message[0].text);
}
}
}
else
{
Console.WriteLine("Null Response.");
}
return response;
}
Aparajita you must check with the API credentials for sandbox in Authorize.Net account
This comes up often and the reasons are always the same:
You are using your production credentials but hitting the sandbox endpoints
You are using your sandbox credentials but are hitting the production endpoints
The credentials you are using are incorrect
Verifying which endpoint you are actually hitting.
If you are testing against the production environment, verify that the URL you have in your code is the actual production URL (or if you are using a framework, the configuration is set to production).
The correct URL for production is https://api2.authorize.net/xml/v1/request.api.
The correct URL for testing is https://apitest.authorize.net/xml/v1/request.api
Verify your credentials
If you are sure that you are hitting the correct endpoint you then need to verify that you are using the correct credentials for that environment.
Make sure you are using the API login and transaction key and not the console login and password. They are not the same thing. Only the API login and transaction key will work when accessing the APIs. You can get these after logging in to the console.
Double check that the API login is correct in the console.
If the API login is correct, from within the customer console generate a new transaction key to verify that you have the correct one.
Make sure that the credentials are not accidentally entered incorrectly in your code. Make sure all of the characters are there. Also, the credentials are case sensitive. Make sure you did not capitalize or lowercase those values.
If you need to verify your login credentials work set up a MVCE that hits the endpoint you are trying to reach with your API credentials. It should be a simple script that makes a basic API call. This will make it easy to debug why you are getting this error.
Test mode is not the sandbox
It is common to confuse test mode with the sandbox environment. Test mode in production uses the production environment and production credentials. Using the sandbox credentials or URLs will not work.
I used this sample project to solve my problem. This is in TEST Mode.
https://github.com/AuthorizeNet/sdk-dotnet/tree/master/CoffeeShopWebApp
I know about using the class MessageListRequest to ask for a list of SMS messages from the Twilio server. There is no Subaccount filter as a parameter when defining the request. Does anyone know how to get the message list for only those messages associated with a specific subaccount? Thanks.
I have used the subaccount credentials to get the list of messages but the result of the Twilio request is a list object with zero entries . I know there are messages in the sub account because I can see them in the Twilio dashboard for the subaccount. Can you please tell me what I am doing wrong in this code?
var aRequest = new MessageListRequest();
aRequest.From = null;
aRequest.To = null;
aRequest.DateSent = null;
GetSubAccounts();
if (mySubAccountSid != null)
{
TwilioRestClient aTwilio = new TwilioRestClient(mySubAccountSid,
mySubAccountToken);
var aResult = aTwilio.ListMessages(aRequest);
if (aResult != null)
{
foreach (var aMessage in aResult.Messages)
{
mySQLManager.UpdateSMSLogTable(aMessage, myVesselID);
Methods.WriteLog(aMessage.Sid + " " + aMessage.To + " " + aMessage.Body);
}
}
return aList;
}
The simple way, which is likely what you mean, is even if you use
your master credentials for auth, but a subaccount SID in the URL
provided for Message List Resource,
/2010-04-01/Accounts/{AccountSid}/Messages, you get the resources
for that subaccount.
The C# library has a GetAccount method that takes an account
SID and returns the Account object (representing the subaccount) for
which you should then be able to make API calls as normal.
var account = twilio.GetAccount("SUBACCOUNT_SID");
Eventually if you want to track things in a more sophisticated
manner, you may decide to use UsageRecords.
Using UsageRecords combined with Subaccounts will allow you
to build usage reports and set triggers based upon some behavior.
The two links provided above will show you how to work with each in
more detail but an example of grabbing a list of all-time usage for
sms would like this in C#:
// Download the twilio-csharp library from twilio.com/docs/csharp/install
using System;
using Twilio;
class Example
{
static void Main(string[] args)
{
// Find your Account Sid and Auth Token at twilio.com/user/account
string AccountSid = "ACCOUNT_SID";
string AuthToken = "AUTH_TOKEN";
var twilio = new TwilioRestClient(AccountSid, AuthToken);
var records = twilio.ListUsage("sms", null, null, null, null, null);
foreach (var record in records.UsageRecords)
{
Console.WriteLine(record.Count);
}
}
}
I want to add 3D secure authentication to credit card payments taken through a website. I am using Sitefinity 8, the e-commerce plug-in and SagePay as the payment processor.
I have created a custom payment provider and can successfully redirect users to the 3D secure page. I am able to perform the second authentication call to SagePay using the SagePay integration kit (i.e. externally from the e-commerce plugin). However, I am struggling to find a way to complete the payment due the way the internal e-commerce classes function.
The difficulty is that the order processor treats the payment as declined if 3D secure authentication is required, but there does not seem to be a way to process the order correctly without using the inbuilt functionality. From my inspections of the ecommerce libraries, there seems to be no way to extend or modify these classes due to internal modifiers and concrete implementations.
How can I process the order once I have completed authentiation? Has anyone successfully implemented 3D secure with ecommerce? Or know if it is possible?
This is my custom payment provider at the moment.
public class CustomSagePayProvider : SagePayProvider
{
// Rest of code...
protected override IPaymentResponse ParseReponse(string uniqueTransactionCode, string responseXml)
{
var paymentResponse = base.ParseReponse(uniqueTransactionCode, responseXml);
if (Requires3DSecure(paymentResponse))
{
var responseFields = GetResponseAsDictionary(responseXml);
Set3DSecureFields(responseFields, paymentResponse);
}
return paymentResponse;
}
private bool Requires3DSecure(IPaymentResponse paymentResponse)
{
return paymentResponse.GatewayCSCResponse == "OK";
}
private void Set3DSecureFields(Dictionary<string, string> responseFields, IPaymentResponse paymentResponse)
{
var postValues = new NameValueCollection();
postValues.Add("MD", responseFields.ContainsKey("MD") ? responseFields["MD"] : string.Empty);
postValues.Add("PAReq", responseFields.ContainsKey("PAReq") ? responseFields["PAReq"] : string.Empty);
paymentResponse.GatewayRedirectUrlPostValues = postValues;
paymentResponse.GatewayRedirectUrl = responseFields.ContainsKey("ACSURL") ? responseFields["ACSURL"] : string.Empty;
}
}
And this is the 3D secure payment process using the .NET SagePay integration kit
using SagePay.IntegrationKit;
using SagePay.IntegrationKit.Messages;
// Rest of code
var sagePay = new SagePayIntegration();
IThreeDAuthRequest request = new DataObject();
request.Md = Request.Form["MD"];
request.PaRes = Request.Form["PaRes"];
sagePay.RequestQueryString = sagePay.BuildQueryString(request, ProtocolMessage.THREE_D_AUTH_REQUEST, ProtocolVersion.V_223);
sagePay.ResponseQueryString = sagePay.ProcessWebRequestToSagePay("https://test.sagepay.com/gateway/service/direct3dcallback.vsp", sagePay.RequestQueryString);
var result = sagePay.GetDirectPaymentResult(sagePay.ResponseQueryString);
if (result.Status == ResponseStatus.OK)
{
// Process order
}
I was able to add 3D secure authentication by treating the 2nd authentication call as an offsite payment and adding the IOffsitePaymentProcessorProvider interface to my payment provider class
public class CustomSagePayProvider : SagePayProvider, IOffsitePaymentProcessorProvider
{
// Triggered after payments that have been 3D Secure authenticated
public IPaymentResponse HandleOffsiteNotification(int orderNumber, HttpRequest request, PaymentMethod paymentMethod)
{
var paymentResponse = new PaymentResponse() { IsOffsitePayment = true };
var sagePay = new SagePayIntegration();
var result = sagePay.GetDirectPaymentResult(request.Params.ToString());
if (result.ThreeDSecureStatus == ThreeDSecureStatus.OK)
{
paymentResponse.IsSuccess = true;
paymentResponse.GatewayTransactionID = result.TxAuthNo.ToString();
}
return paymentResponse;
}
public IPaymentResponse HandleOffsiteReturn(int orderNumber, HttpRequest request, PaymentMethod paymentMethod)
{
throw new NotImplementedException();
}
I pass the notification url as a query string parameter in the termUrl value posted to SagePay when first requesting the authentication
(The url must be /Ecommerce/offsite-payment-notification/ to use the inbuilt offside payment notification handler).
var notificationUrl = request.Url.GetLeftPart(UriPartial.Authority) + "/Ecommerce/offsite-payment-notification/";
In the callback from SagePay after the user completes authentication, I use the SagePay integration kit to process the result of the authentication.
var sagePay = new SagePayIntegration();
IThreeDAuthRequest request = new DataObject();
request.Md = md;
request.PaRes = paRes;
sagePay.RequestQueryString = sagePay.BuildQueryString(request, ProtocolMessage.THREE_D_AUTH_REQUEST, ProtocolVersion.V_223);
sagePay.ResponseQueryString = sagePay.ProcessWebRequestToSagePay("https://test.sagepay.com/gateway/service/direct3dcallback.vsp", sagePay.RequestQueryString);
return sagePay.GetDirectPaymentResult(sagePay.ResponseQueryString);
Finally, I trigger the HandleOffsiteNotification event by posting to the url www.mysite.com/Ecommerce/offsite-payment-notification/. This marks the order as complete, updates stock levels and cleans up the user's basket. For simplicity in this example, I am using the SagePay integration kit object to build the query string and post to the url.
var sagePay = new SagePayIntegration();
var ordersManager = OrdersManager.GetManager();
var query = sagePay.ConvertSagePayMessageToNameValueCollection(ProtocolMessage.DIRECT_PAYMENT_RESULT, typeof(IDirectPaymentResult), result, ProtocolVersion.V_223);
// Required Sitefinity fields to trigger HandleOffsiteNotification in IOffsitePaymentProcessorProvider
query.Add("invoice", orderNumber.ToString());
query.Add("provider", ordersManager.Provider.Name);
var queryString = sagePay.BuildQueryString(query);
// Post 3d secure details to this site simulate an offsite payment processor response
sagePay.ProcessWebRequestToSagePay(notificationUrl, queryString);
I am trying to build a registration section for a website (internal to my dept). Now to get new users registered, I built a form where user enters his employee id i.e. AD account name and then clicks a button to fetch his details. Which are later saved in database where registration requests are queued. Once those requests are approved by admin then only those users can use the application. Now the problem is that user is not logged in, so is it possible for non logged in user to fetch details from AD server. if it is then how.? Because when I tried the below listed code I am getting bad username or password error using FindOne function.
public string getProperties(string StaffCode, string property)
{
try
{
string result = "";
using (var de = new DirectoryEntry(_path))
using (var ds = new DirectorySearcher(de))
{
ds.Filter = string.Format("(sAMAccountName={0})", StaffCode);
ds.PropertiesToLoad.AddRange(new[] {
"sn", // last name
"givenName", // first name
"mail", // email
"telephoneNumber", // phone number
// etc - add other properties you need
});
var res = ds.FindOne();
if (res == null)
{
result = "noUserFound";
}
else
{
foreach (string propName in res.Properties.PropertyNames)
{
ResultPropertyValueCollection valueCollection = res.Properties[propName];
foreach (Object propertyValue in valueCollection)
{
if (propName == property)
{
result = propertyValue.ToString();
}
}
}
}
}
return result;
}
catch (Exception ex)
{
return "someErrorOccurred";
}
Please help me in overcoming this issue.
Thanks in advance
My guess is that the identity of the application pool you run this code under doesn't have enough priviledges to query the AD without authentication.
Specifically, start with replacing this constructor
using ( var de = new DirectoryEntry( _path ) )
with the one that takes admin's username/password in an explicit way
using ( var de = new DirectoryEntry( _path, username, password ) )
and make sure the username has enough priviledges to query the catalog.
If this works, you could possibly try to go back to the original version but you'd have to make sure the identity of the asp.net application pool has enough priviledges to query the AD but also, that the asp.net server is a part of the domain (if it is not, authentication without providing username/password in an explicit way will most likely not work).
Good day all.
Does anyone has a working example how to make Google Plus post through .NET (C#).
I have already tried google and stackoverflow search, but did not manage to find the solution.
I successfully get posts:
public void Post(string text)
{
PlusService plus = new PlusService {Key = "MYVERYSECRETKEY"};
ActivitiesResource ar = new ActivitiesResource(plus, null);
ActivitiesResource.ListRequest list = ar.List("108055870103885325249", new ActivitiesResource.Collection());
ActivityFeed feed = list.Fetch();
string activityKey = "";
foreach (var a in feed.Items)
if (a.Url == "https://plus.google.com/108055870103885325249/posts/EtvvUgn8eKz")
{
activityKey = a.Id;
break;
}
ActivitiesResource.GetRequest get = ar.Get(activityKey);
Activity act = get.Fetch();
var sb = new System.Text.StringBuilder();
sb.AppendLine("Title: " + act.Title);
sb.AppendLine("URL:" + act.Url);
sb.AppendLine("Published:" + act.Published);
sb.AppendLine("By:" + act.Actor.DisplayName);
sb.AppendLine("Annotation:" + act.Annotation);
sb.AppendLine("Content:" + act.Object.Content);
sb.AppendLine("Type:" + act.Object.ObjectType);
sb.AppendLine("# of +1s:" + act.Object.Plusoners.TotalItems);
sb.AppendLine("# of reshares:" + act.Object.Resharers.TotalItems);
}
But I cannot find any method for making posts.
Thanks in advance.
Currently, the Google+ API does not allow writing of posts to a user's activity stream. You can use the moments.insert method in the Google+ REST API to write App Activities to the user's profile, which the user can choose whether to share publicly or to their circles.
You would work with the REST API in a similar manner to other REST APIs in .NET by POSTing to the moments.insert end-point.
This feature is now available to apps that request the https://www.googleapis.com/auth/plus.login scope and specify the type of moments that the app wants to write in the request_visible_actions parameter either in the Google+ Sign-In button or directly in the OAuth query parameters.