Hi Stack Overflow Community,
I am a marketer by trait, with some technical skills, but not a developer by nature; so I wanted to reach out to a developer community to help me. I am currently setting up a process to run a pre-launch email referral campaign through viral loops (https://viral-loops.com/templates/startup-prelaunch) and am using Zapier to connect it to the ESP we are using, SendGrid, since there is no direct integration.
I am trying to pass over the following information
First Name
Last Name
Participant URL (the URL the user can share to refer people)
Added to a specific list (Early Access Waitlist)
I have set up the zap successfully so that it is passing through the first name, last name, and adding contacts to our ESP. However, I cannot figure out, why I cannot get it to add to the specific audience list or add the participant URL.
For the list id, I thought I have followed this step properly -- https://docs.sendgrid.com/api-reference/contacts/add-or-update-a-contact#body
For the participant URL, I created a custom field in SendGrid and then use the above doc. and thought it should pull in.
I have attached the current Zap setup in this link:
Thanks in advance for the help!
A few things here, the shape of your JSON isn't exactly right, I'll show you that in a bit. Your participant_URL field is a custom field, so it needs to go in the custom_fields property of a contact and use the ID of the custom field. And your list IDs should be IDs and not names.
For the custom field ID, the easiest way to get the ID is by calling the API to get the field definitions. You could likely do this with another Zap to the API. Or the following curl command in your terminal:
curl -X GET https://api.sendgrid.com/v3/marketing/field_definitions \
--header "Authorization: Bearer <<YOUR_API_KEY_HERE>>"
The List ID is easier to get. Just go to your lists in the Marketing Campaigns section of the SendGrid dashboard and click on the list. The ID is in the URL: https://mc.sendgrid.com/contacts/lists/<<YOUR_LIST_ID>>.
For the JSON, it should look like this:
{
"list_ids": ["YOUR_LIST_ID"],
"contacts": [{
"email": "email#example.com",
"first_name": "Alice",
"last_name": "Franks",
"custom_fields": [{
"CUSTOM_FIELD_ID_FOR_URL": "https://vrips.co/XXXXX"
}]
}]
}
Related
I am trying to figure out the best way of adding multiple users to a group via a REST API.
Right now, I am thinking this is the best way of adding a single user at a time:
PUT /groups/123/{userID}
Then, to remove the user from the group:
DELETE /groups/123/{userID}
But how would I add multiple users to the group at the same time? Would this be the best way?
PUT /groups/123
Content body as an array:
[
"user1",
"user2",
"user3"
]
...and to remove the users from the group, I would do the same thing via a DELETE request.
Is there anything "wrong" with this setup, or would there be a better, more "industry standard" way of doing this?
How to PUT multiple resources via a REST API
You don't do that - each request in HTTP has one-and-exactly-one target resource; the semantics of the PUT request are that the message body of the request is a replacement representation for the resource.
Resources are generalizations of documents.
It's entirely reasonable to have a document that is a representation of the members of some group.
PUT /groups/123
[
"user1",
"user2",
"user3"
]
What this request means is "replace your copy of /groups/123 with this copy". It's purely a document editing command.
The useful work - like actually making changes to the master group membership list, is a side effect of making your copy of the document look like the provided copy. See Webber 2011.
In this style, "removing" a user from the group would look like another edit to the /groups/123 document
PUT /groups/123
[
"user1",
"user3"
]
Of course, remote authoring semantics aren't required; you could instead do:
POST /groups/123
Please remove user1
or
POST /groups/123
action=addUser&id=user4
to remove the users from the group, I would do the same thing via a DELETE request
Careful - DELETE (like PUT) means something specific in HTTP, and that may not be what you mean.
Relatively few resources allow the DELETE method
The semantics of DELETE belong firmly in the transfer documents over a network domain, not in the "manage users and groups" domain.
In Google Apps Script I am calling the G Suite Admin SDK Directory API using the command AdminDirectory.Groups.insert(group). Is this considered to be a POST request? I’m wondering because I know there are implicit ways of making POST requests where POST is not specified explicitly such as urlfetch(). In the project that I am working on, I am trying to avoid using HTTP requests for security reasons.
I did some research online, but I am having some difficulty finding the answer to this question. I'm thinking that since a JavaScript object rather than a JSON object was passed into insert(), it would not be considered a POST request since JSON notation is typically used when sending data to a server or retrieving data from a server. Because group is a JavaScript object and not a JSON object, I am thinking the command AdminDirectory.Groups.insert(group) would not be a POST request. Am I on the right track here?
For some context, here is the function I wrote to create a group:
function createAGroup() {
var group = {
email: "test-group#test.com",
name: "Test Group",
description: "This is a test group."
};
group = AdminDirectory.Groups.insert(group);
Logger.log('Group %s created.', group);
}
The function createAGroup() created a group successfully. However, was the command AdminDirectory.Groups.insert(group) using a POST request to create the group or not?
If you are not sure which kind of request you are looking at - you can find it out in the Google Developers Reference.
In your case:
If you go to the Apps Script Reference for the admin directory:
https://developers.google.com/apps-script/advanced/admin-sdk-directory
It will link you to the reference documentation for the specific methods for the Admin SDK Directory API where you can find the reference for the specific method Groups:insert
https://developers.google.com/admin-sdk/directory/v1/reference/groups/insert
It tells you:
HTTP request
POST https://www.googleapis.com/admin/directory/v1/groups
This syntax is translated one to one into Apps Script, which you can prove as following:
If you test the method in “Try this API” with your request body, the outcome will be:
200
{
"kind": "admin#directory#group",
"id": "03oy7u293zlw6l7m",
"etag": "\"zPBZh0mDALCYqI567HUiXii8qQjpg/VckrVGnV8Hs56iDrqRt7j4XT5eRyM\"",
"email": "test-group#test.com",
"name": "Test Group",
"description": "This is a test group",
"adminCreated": true
}
Now if you run it in Apps Script your Looger.lo output will be:
Group {kind=admin#directory#group, name=Test Group, description=This is a test group., etag="zPBZh0mDALCYqI7HMkUiXii8qQjpg/gIcr9tsZMDRRrDJECvLtNT66KBc", id=00ha3apch11zp6hh, adminCreated=true, email=test-group#test.com} created.
You can see that in both cases the response retrieves the data in the same way and gives you an equivalent feedback. Thus, it is safe to say that the method used in App Script, uses indeed the POST request.
As a general rule:
Anything that is creating a new object at the backend (like inserting users or groups) is a POST request, anything that is updating existing objects (e.g. change personal data of a user) is a PUT request, anything that retrieves data (e.g. listing users) is a GET request and DELETE is pretty self-explaining.
App Script is a “tool” that takes away the need to implement the request manually. But always check the reference how to implement a specific method.
If you do want to make an explicit JSON request - you can convert the JavaScript notation into a JSON string with JSON.stringify() as explained here:
https://developers.google.com/apps-script/guides/services/external#work_with_json
I am currently pulling data from Twitter's API through a Node.js connection running on my computer. Here's the heart of my search:
///
var param = {q: "Futbol -filter:retweets -filter:replies", lang: "en", result_type: "popular", count: 10}
client.get('search/tweets',param,function(error,tweets,response){// MY SEARCH GOES HERE}
The git repo is here: https://github.com/KingOfCramers/Twitter-Stream-JSON-in-Node
I have a few questions because I am confused about the twitter syntax for Node.js.
First, I pass it to "q" any information relating to a search. What are those parameters called? What page on the Twitter API lists all of them?
Secondly, I am currently passing other arguments as well, such as lang and result_type. I want to tailor my search to specific accounts. Is there a parameter to search by username or the id of the user on Twitter? Eventually I want to stream twitter JSON data from specific groups, like Congresspeople (a different request, client.stream()).
Thanks!
You are using standard search operators, which are explained here. If you want to filter your search by specific accounts, you need to use from: query parameter described in that page.
I'm adding a new REST service to our API, and wanted to canvas a few opinions on the best REST API. The service is used to retrieve the user's email address in case they have forgotten what their username is. The service requires three parameters:
Account number (this is a number that is on their printed statement)
Surname
Date of birth
If we find a match for these three pieces of info, the service returns JSON contained a masked version of the user's registered email address (eg. jo******#gmail.com) so that the UI can present a message something like "We are going to send your username to j******#g******.com. Is that OK?"
Note that the service doesn't actually change anything within their account or send an email (it is purely fetching info so that the user can confirm the next step), so it seems to me that a GET request is the way to go. The question is how to represent it? It strikes me that /users is a reasonable place to start(?), but then what? Using the URL path, I might end up with something like:
/users/accountEmail/accountNumber/123456/surname/Smith/dateOfBirth/25-12-1970
This seems icky as, ordinarily, our /users URLs contain the username (eg. /users/john/transactions), but clearly for this API call we don't actually know who the user is yet. I'm also not sure it really indicates what the service actually does. Alternatively, I could use URL query params:
/users/accountEmail?accountNumber=123456&surname=Smith&dateOfBirth=25-12-1970
This feels a bit more natural, but I'm unsure that stringing all those input parameters into the URL is a good idea. Then again, maybe /users is the wrong noun. Maybe it should be like:
/accountEmail/...
Having said all that, maybe given the service's idempotence, I could actually use a PUT request and encode the parameters into the HTTP body. Not sure about using PUT for read-only requests though... it seems a bit like heading down the RPC path. The one nice thing about the PUT approach though is that it doesn't log this relatively sensitive user input into any web server logs.
I'd be interested in opinions or hearing what other API developers did in a similar situation. Thanks.
First of all, don't use method GET with sensitive information in URL parameters or in a URL path, because that information can be stored in web server access log files, browser's history, HTTP proxy log files, etc.
Security wise you need to use method POST in this case. In regard of URL to use, I'm not that sure, probably something like /accounts and put all parameters to the request body.
Your second approach is what I would use. Logically, the URLS are build following these steps.
Collection Resource of Users
The URL
GET /users
returns a list of all users including all user properties.
[
12345: {
"surname": "Smith",
"firstname": "John",
"dateOfBirth": "1970-12-25",
"accountEmail": "john.smith#example.com"
},
6789 : {
"surname": "Hallow",
"firstname": "Jane",
"dateOfBirth": "1981-02-15",
"accountEmail": "jane.hallowh#example.com"
}
]
Sub-Collection Resource of User Emails
The URL
GET /users/accountEmail
returns al list alf all emails for all users.
[
12345: {
"accountEmail": "john.smith#example.com"
},
"accountEmail": "jane.hallowh#example.com"
}
]
Filter this Resource
The URL
GET /users/accountEmail?accountNumber=123456&surname=Smith&dateOfBirth=25-12-1970
returns a filtered list of emails for the users that match the query parameters.
[
12345: {
"accountEmail": "john.smith#example.com"
}
]
The example on the Brightcove site provides the JSON needed to update tags for a particular video in my library:
{"method":"update_video","params":{"video":{"id":"123456",
"shortDescription":"vidDesc","Name":"vidName","startDate":1392912992000,
"endDate":null,"tags":["tag1","tag2","tag3"]},"token":"someToken.."}}
I've tried this, and it works.
But when I try to post something similar but with an updated reference ID, like this:
{"method":"update_video","params":{"video":{"id":"123456",
"shortDescription":"vidDesc","Name":"vidName","startDate":1392912992000,
"endDate":null,"referenceId":"newReferenceId","token":"someToken.."}}
I get this error back from the service:
{"error": {"name":"MissingJSONError","message":"Could not find JSON-RPC.",
"code":211}, "result": null, "id": null}
I've tried passing it as ref as well - no dice. Does anyone know if it's possible to update this value via any means other than Brightcove's web portal?
Make sure you're sending the JSON as form data rather than in the post body.
e.g. with curl,
curl -F 'json={"method":"update_video","params":{"video":{"id":"123456789","referenceId":"newrefid"},"token":"myToken"}}' https://api.brightcove.com/services/post