I am looking for a way to use Campaign Monitor's API in my ASP.NET/VB Web application.
I have not used any API before, thus reading their documentation is very difficult to understand.
If anyone has used it and is able to provide some instructions I would appreciate it; or if someone has some general usage instructions (if applied on any APi), be my guest! :)
I know this is not the typical "I have a problem and this is my problem and here's my effort so far" but any help would be much appreciated.
You can also use the Campaign Monitor API client library which is available on Nuget:
AuthenticationDetails auth = new ApiKeyAuthenticationDetails(apiKey);
var fields = new List<SubscriberCustomField>() {
new SubscriberCustomField() { Key = "MyCustomField", Value = myVal }
};
var subscriber = new Subscriber(auth, listId);
subscriber.Add(email, fullName, fields, false);
I use campaign monitor for populating subscriber lists.
There are two methods to post your subscribers to lists. I'm going to stick to the simplest one. Let's round up somethings you need first.
You'll need an API key (which I am sure you have).
You'll need to create a subscribers list and after you create this
list you'll need the list ID. To get the ID (which is wierd).You'll
need to click into your subscriber list. This look for this towards
the top. Single opt-in list (change name/type) Note: You are not
going to change the name or edit anything but you have to click in
here to get the ID. On the third section you will see this: API
Subscriber List ID. If you're using the API, you'll need this ID to
access this list. 000x0000xx0x0xx00x00xx (just an example.)
You'll need a form to capture Name and Email. You'll need your listid which
you got in the previous point.
Then you'll need to code a communication object.
If you are doing a straight forward call you'll need the name, email, and listid.
ListID ="000x0000xx0x0xx00x00xx";
Email ="JoeM#somethingemail.com";
Name = "Joe Middle";
APIKey = yourAPIKey;
APIURL = "http://api.createsend.com/";
ApiCall = variables.APIURL;
ApiCall &= "api/api.asmx/Subscriber.Add?ApiKey=" & variables.APIKey;
ApiCall &= "&ListID=" & URLEncodedFormat(arguments.ListID);
ApiCall &= "&Email=" & URLEncodedFormat(arguments.Email);
ApiCall &= "&Name=" & URLEncodedFormat(arguments.Name);
Once you have your url build you use whatever method .net uses to post http.
Then you'll want to code for success or fail and do something with that info. post to http and call the result. apiResult.
apiResult = xmlParse(apiResult.fileContent);
try {intCount = ArrayLen(apiResult.Result.XMLChildren);}
catch(Any e){intCount = 0;}
if (intCount gt 0){apiResult = apiResult.Result.xmlChildren;}
// Error handling
if ( apiResult[1].xmlName eq "Code" and apiResult[2].xmlName eq "Message" ){
returnStruct['blnSuccess'] = 0;
returnStruct['errorCode'] = apiResult[1].xmlText;
returnStruct['errorMessage'] = apiResult[2].xmlText;
}
// Success
else {
// Return str
returnStruct['blnSuccess'] = 1;
returnStruct['returnString'] = apiResult.Result.xmlText;
}
The code above was adapted from coldfusion and I didn't build it but it is cfscript which is not CFML and you can kind of interpret what is happening.
If you adapt this to .NET then all you are missing is your HTTP call stuff method.
To check log into Campaign Monitor and click on your list. You should see additions showing up, if not it is either you API key (not usually the case), your listID (could be the case), your code (most likely culprit).
This was hammered out in a hurry so apologies if the flow is weird.
Good luck!
Related
Custom Search UI will be populated when user selects Complex asset in the Advance search screen drop down(apart from Folders,Contents) where 12 fields will be displayed .So when user clicks search button ,need to read those values and redirect to the alfresco repo files(org/alfresco/slingshot/search/search.get.js).We have already customized these files(search.get.js,search.lib.js) existed in the repository to suit out logic and working fine in 4.2.2;As we are migrating to 511,so we need to change this logic in customized faceted-search.get.js to read these values.How to write this logic in customized facted-search.get.js?
It's not actually possible to read those URL hash attributes in the faceted-search.get.js file because the JavaScript controller of the WebScript does not have access to that part of the URL (it only has information about the URL and the request parameters, not the hash parameters).
The hash parameters are actually handled on the client-side by the AlfSearchList widget.
Maybe you could explain what you're trying to achieve so that I can suggest an alternative - i.e. the end goal for the user, not the specifics of the coding you're trying to achieve.
We will be reading the querystring values something like below in the .get.js file.
function getNodeRef(){
var queryString = page.url.getQueryString();
var nodeRef = "NOT FOUND";
var stringArray = queryString.split("&");
for (var t = 0; t < stringArray.length; t++) {
if (stringArray[t].indexOf('nodeRef=') > -1) {
nodeRef = stringArray[t].split('=')[1];
break;
}
}
if (nodeRef !== "NOT FOUND") {
nodeRef = nodeRef.replace("://", "/");
return nodeRef;
}
else {
throw new Error("Node Reference is not found.");
}
}
It may be help you and we will wait for Dave Drapper suggestion also.
I am attempting to create a DocuSign envelope from a template document using the CreateEnvelopeFromTemplates method, available within their v3 SOAP API web service. This is being instantiated from a asp.NET v4.0 web site.
Upon calling the method armed with the required parameter objects being passed in. I am recieving an exception from the web service, basically telling me that the Template ID is not a valid GUID.
669393: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
Line 14889:
Line 14890: public DocuSignDSAPI.EnvelopeStatus CreateEnvelopeFromTemplates(DocuSignDSAPI.TemplateReference[] TemplateReferences, DocuSignDSAPI.Recipient[] Recipients, DocuSignDSAPI.EnvelopeInformation EnvelopeInformation, bool ActivateEnvelope) {
Line 14891: return base.Channel.CreateEnvelopeFromTemplates(TemplateReferences, Recipients, EnvelopeInformation, ActivateEnvelope);
Line 14892: }
Line 14893:
The template reference, a guid. Must be specified as the "Template" string property against TemplateReference object. This is then added to a dynamic array of TemplateReferences, which is one of the input parameters of the CreateEnvelopeFromTemplates method.
Actual template GUID: f37b4d64-54e3-4723-a6f1-a4120f0e9695
I am building up my template reference object using the following function that i wrote to try and make the functionality reusable:
Private Function GetTemplateReference(ByVal TemplateID As String) As TemplateReference
Dim templateReference As New TemplateReference
Dim guidTemplateID As Guid
With TemplateReference
.TemplateLocation = TemplateLocationCode.Server
If Guid.TryParse(TemplateID, guidTemplateID) Then
.Template = guidTemplateID.ToString
End If
End With
Return TemplateReference
End Function
The TemplateID is being passed in from a appSetting configuration value at the time of the TemplateReferences array instantiation like so...
templateReferences = New TemplateReference() {GetTemplateReference(ConfigurationManager.AppSettings("DocuSignTemplate_Reference"))}
recipients = New Recipient() {AddRecipient("myself#work.email", "My Name")}
envelopeInformation = CreateEnvelopeInformation()
envelopeStatus = client.CreateEnvelopeFromTemplates(templateReferences, recipients, envelopeInformation, True)
As you can see from my GetTemplateReference function I am also parsing the GUID before setting it back as a string so i know its valid. The template is managed and stored at the DocuSign end, hence specifying the document location.
I am referring to their own documentation:
CreateEnvelopeFromTemplates
Why oh why is the method not liking my Template ID? I can successfully use their REST API to call the same method, using their own code samples. Worst case I can make use of this but would rather interact with the web service as I would need to construct all the relevent requests in either XML or JSON.
I would really appreciate if someone could perhaps shed some light on this problem.
Thanks for taking the time to read my question!
Andrew might be spot on with the AccountId mention - are you setting the AccountId in the envelope information object? Also, have you seen the DocuSign SOAP SDK up on Github? That has 5 sample SOAP projects including one MS.NET project. The .NET project is in C# not Visual Basic, but still I think it will be helpful to you. Check out the SOAP SDK here:
https://github.com/docusign/DocuSign-eSignature-SDK
For instance, here is the test function for the CreateEnvelopeFromTemplates() function:
public void CreateEnvelopeFromTemplatesTest()
{
// Construct all the recipient information
DocuSignWeb.Recipient[] recipients = HeartbeatTests.CreateOneSigner();
DocuSignWeb.TemplateReferenceRoleAssignment[] finalRoleAssignments = new DocuSignWeb.TemplateReferenceRoleAssignment[1];
finalRoleAssignments[0] = new DocuSignWeb.TemplateReferenceRoleAssignment();
finalRoleAssignments[0].RoleName = recipients[0].RoleName;
finalRoleAssignments[0].RecipientID = recipients[0].ID;
// Use a server-side template -- you could make more than one of these
DocuSignWeb.TemplateReference templateReference = new DocuSignWeb.TemplateReference();
templateReference.TemplateLocation = DocuSignWeb.TemplateLocationCode.Server;
// TODO: replace with template ID from your account
templateReference.Template = "server template ID";
templateReference.RoleAssignments = finalRoleAssignments;
// Construct the envelope information
DocuSignWeb.EnvelopeInformation envelopeInfo = new DocuSignWeb.EnvelopeInformation();
envelopeInfo.AccountId = _accountId;
envelopeInfo.Subject = "create envelope from templates test";
envelopeInfo.EmailBlurb = "testing docusign creation services";
// Create draft with all the template information
DocuSignWeb.EnvelopeStatus status = _apiClient.CreateEnvelopeFromTemplates(new DocuSignWeb.TemplateReference[] { templateReference },
recipients, envelopeInfo, false);
// Confirm that the envelope has been assigned an ID
Assert.IsNotNullOrEmpty(status.EnvelopeID);
Console.WriteLine("Status for envelope {0} is {1}", status.EnvelopeID, status.Status);
}
This code calls other sample functions in the SDK which I have not included, but hopefully this helps shed some light on what you're doing wrong...
This problem arises when you don't set up the field AccountId. This field can be retrieved from your account. In Docusign's console go to Preferences / API and look here
Where to find AccountID Guid in Docusign's Console
Use API Account ID (which is in GUID format) and you should be OK.
i developed CMS to one of my customers and he wants that when a user fill in the contact form, it will automatically generate lead in his CRM.
what is the easiest way to do that?
by the way, the contact form is ajax and the data is transfered to asmx, so it will be easy to call to CRM webservice or something like that, because i'm already in the server side.
can someone point me to tutorial or some code example?
thanks!
Your best start will be with the SDK available here, which contains example code and the sdk dlls etc...
Here is a page with a quick reference to all the web service endpoints available in the different flavors of CRM 2011.
From the SDK samplepcode\cs\quickstart creating account, but very similar for lead:
// Connect to the Organization service.
// The using statement assures that the service proxy will be properly disposed.
using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri,
serverConfig.HomeRealmUri,
serverConfig.Credentials,
serverConfig.DeviceCredentials))
{
// This statement is required to enable early-bound type support.
_serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior());
// Instaniate an account object.
// See the Entity Metadata topic in the SDK documentation to determine
// which attributes must be set for each entity.
Account account = new Account { Name = "Fourth Coffee" };
// Create an account record named Fourth Coffee.
_accountId = _serviceProxy.Create(account);
Console.Write("{0} {1} created, ", account.LogicalName, account.Name);
// Retrieve the account containing several of its attributes.
ColumnSet cols = new ColumnSet(
new String[] { "name", "address1_postalcode", "lastusedincampaign" });
Account retrievedAccount = (Account)_serviceProxy.Retrieve("account", _accountId, cols);
Console.Write("retrieved, ");
// Update the postal code attribute.
retrievedAccount.Address1_PostalCode = "98052";
// The address 2 postal code was set accidentally, so set it to null.
retrievedAccount.Address2_PostalCode = null;
// Shows use of a Money value.
retrievedAccount.Revenue = new Money(5000000);
// Shows use of a boolean value.
retrievedAccount.CreditOnHold = false;
// Update the account record.
_serviceProxy.Update(retrievedAccount);
Console.WriteLine("and updated.");
I want to send an alert in Ax, when any field in the vendor table changes (and on create/delete of a record).
In the alert, I would like to include the previous and current value.
But, it appears that you can't set alerts for when any field in a table changes, but need to set one up for EVERY FIELD?! I hope I am mistaken.
And how can I send this notification to a group of people
I have created a new class with a static method that I can easily call from any .update() method to alert me when a record changes, and what changed in the record.
It uses the built in email templates of Ax as well.
static void CompareAndEmail(str emailTemplateName, str nameField, str recipient, Common original, Common modified)
{
UserInfo userInfo;
Map emailParameterMap = new Map(Types::String, Types::String);
str changes;
int i, fieldId;
DictTable dictTable = new DictTable(original.TableId);
DictField dictField;
;
for (i=1; i<=dictTable.fieldCnt(); i++)
{
fieldId = dictTable.fieldCnt2Id(i);
dictField = dictTable.fieldObject(fieldId);
if (dictField.isSystem())
continue;
if (original.(fieldId) != modified.(fieldId))
{
changes += strfmt("%1: %2 -> %3 \n\r",
dictField.name(),
original.(fieldId),
modified.(fieldId)
);
}
}
//Send Notification Email
select Name from UserInfo where userInfo.id == curUserId();
emailParameterMap.insert("modifiedBy", userInfo.Name);
emailParameterMap.insert("tableName", dictTable.name());
emailParameterMap.insert("recordName", original.(dictTable.fieldName2Id(nameField)));
emailParameterMap.insert("recordChanges", changes);
SysEmailTable::sendMail(emailTemplateName, "en-us", recipient, emailParameterMap);
}
Then in the .update() method I just add this one line
//Compare and email differences
RecordChangeNotification::CompareAndEmail(
"RecChange", //Template to use
"Name", //Name field of the record (MUST BE VALID)
"user#domain.com", //Recipient email
this_Orig, //Original record
this //Modified record
);
The only things I want to improve upon are:
moving the template name and recipient into a table, for easier maintenance
better formatting for the change list, I don't know how to template that (see: here)
As you have observed the alert system is not designed for "any" field changes, only specific field changes.
This is a bogus request anyway as it would generate many alarts. The right thing to do is to enable database logging of the VendTable table, then send a daily report (in batch) to those interested.
This is done in Administration\Setup\Database logging. There is a report in Administration\Reports. You will need to know the table number to select the table.
This solution requires a "Database logging" license key.
If you really need this feature, then you can create a class that sends a message/email with the footprint of the old record vs the new record. Then simply add some code in the table method "write"/"update"/"save" to make sure you class is run whenever vendtable gets edited.
But I have to agree with Jan. This will generate a lot of alerts. I'd spend some energy checking if the modifications done in vendtable are according to the business needs, and prohibit illegal modifications. That includes making sure only the right people have enough access.
Good luck!
I do agree with suggestion of Skaue.you just write and class to send the mail of changes in vend table.
and execute this class on update method of vendtable.
thanks and Regards,
Deepak Kumar
I don't know much about Flash but we are working on a site that has a flash form and when the users pick an option, like selecting a value from a drop down list, we need the value to be passed to asp.net server-side code. What's the easiest way to do this?
Flash can invoke server side service. So use GET or POST to pass data
You could explore these options:
1) Communicate between the SWF and the containing page through JavaScript
2) Communicate via asp.net webservices from the SWF directly to the webservice.
3) Not sure but could probably do a POST to a processing aspx page?
HTH
I think a good option is to use the XML class so consider this:
var xmlRequest = new XML();
xmlRequest.onLoad = parseXMLResponse;
xmlRequest.load("http://yourpathtoyourserver/file.aspx?listselectedvalue=something");
function parseXMLRequest(loaded)
{
trace("hi");
}
You can also have the page give you data back this way so it's not just one way communication.
Assuming you are using Action Script 2.
Read the important notes at the bottom of each codes pertain to sending and retrieving data from flash to .net page. Explanation of the code is in the comment inside the code.
Flash Part (Action Script 2)
//function to send collected form data to asp.net page
//use other control/button to call this function
//important: in order for the 'onLoad' event to work correctly, this function has to be 'Void'
function sendForm():Void
{
//create LoadVars object
var lv_in:LoadVars = new LoadVars();
var lv_out:LoadVars = new LoadVars();
//set onLoad event
lv_in.onLoad = function(success:Boolean)
{
//if success, meaning data has received from .net page, run this code
if (success)
{
//lv_in.status is use to get the posted data from .Net page
statusMsg.text = "Thank you for filling up the form!" + lv_in.status;
}
//if fail, run this code
else
{
statusMsg.text = "The form you are trying to fill up has an error!";
}
}
//this is the collected data from the form
lv_out.userName = txtUserName.text;
lv_out.userAddress = txtUserAddress.text;
lv_out.userBirthday = txtUserBirthday.text;
//begin invoke .net page
lv_out.sendAndLoad("ProcessDataForm.aspx", lv_in, "POST");
}
Important note:
The function that contain onLoad event, in this case sendForm function, has to be Void function, meaning it's not returning value. If this function return value, what happen is the function will be executed all the way without waiting for the returned data from .net page, thus the onLoad event will not be set properly.
.Net Part
public void ProcessData
{
//process the data here
Response.Write("status=processed&");
}
Important note:
To send data/message back to flash, you can use Response.Write. However, if you want Action Script to parse the posted message/data from .Net page keep in mind you have to include & symbol at the end of the message. When parsing data/message, Action Script will stop at & symbol, thus leave the rest of the message alone and only get the message under sent variable.