I have been able so far to create a new civi Mailing object and populate it, but confusingly I can't see a parameter in that to specify the mail destination group.
For context, I am dealing with Civi using pure REST api from a remote server. I have a solution to getting a custom template onto the server; the new problem is setting a schedule and delivery group, and initiating the send. I am using the python-civicrm library from github as the intermediary on the client.
I presume send happens as a result of setting the schedule -- i.e. I don't need an API call to say 'send mailing'? Is setting 'sheduled date' == 'now' safe or should I set a date of 'now + 1min' or similar?
So that leaves setting the delivery group. We already have groups defined in the DB, and I want to specify the group by name (and preferably be able to verify in advance that a group name is a valid destination, perhaps by doing a group name -> id lookup).
I think there might be a parameter to Mailing create 'groups' which can have keys 'include' and 'exclude'; at least, that's what the web form seems to do. However it's not mentioned in the REST api implementation.
Can anyone offer pointers?
I think you will find all you need in the following link :
Example of api call that is using the group include/exclude : https://gist.github.com/xurizaemon/6775471
Discussion about implementing mailing as an api - http://forum.civicrm.org/index.php?topic=24075.0
Otherwise, if it doesn't work, i suggest that you :
help adding this api in the CiviCRM Core - you could have some help on this on irc #civicrm (and have a look at https://issues.civicrm.org/jira/browse/CRM-11023)
OR create an extension with the api you need. It will be automatically available for REST. If you haven't created an extension yet, i suggest you go to the page http://wiki.civicrm.org/confluence/display/CRMDOC/Create+a+Module+Extension. It's quite straightforward with civix installed.
The table you need to check in the database is civicrm_mailing_group
To confirm, the problem was that (a) I needed to use groups[include]=array(ids) as mentioned by samuelsov, but also (b) I needed to use the json={...} form of request through REST, because the HTTP params syntax doesn't support nested data.
Related
How can one set the allowed values for a Rally attribute (e.g. "Package") using Rally's web services API (2.0)?
I know how to retrieve the allowed values, and the WSAPI documentation says one should be able to POST new ones, or PUT to existing ones to rename them. But in actuality, POSTing new ones returns an error saying that POST isn't supported, and PUTting to existing ones isn't possible because they don't have _refs to PUT to.
Clearly there must be some way to do this — after all, the GUI can do it — but I haven't managed to figure it out. Anyone have the answer?
Ah, the package field... 'Twas a simpler time when this field was created. Unfortunately it is implemented differently than almost all other dropdowns in Rally and as such is not able to be updated via WSAPI as you have found. Other field allowed values (including custom fields) have _refs and operate as you expect above.
I'm struggling to find an answer to this (perhaps because I'm not asking the question properly) ...
I'm building API to expose resources for a basic social networking service I'm creating.
My understanding is that the structure of URLs in an API is essentially a hierarchy, directory like structure. I think that means I can have multiple endpoints to reach the same resources or collections of resource links.
For example:
I have an endpoint
www.domain.api.org/users/{:uid}/posts
Which will return all posts sent by the user or that the user is tagged in. Seems ok, but what if I have an endpoint such as:
www.domain.api.org/posts
Which when hit with a http GET will return all public posts (i.e. all users' posts plus his friends' and public posts).
The difference is that the first URL points to user owned resources whereas the second to public ones (of which the users posts are included of course)
Are these okay or am I doing it the wrong / less sensible way?
To reiterate, can I have multiple endpoints which point to different contexts/views of the same resource?
Basically multiple endpoints for the same resources should be avoided. However in this particular case it does make sense.
What you can do is to introduce optional query param userId to the following endpoint:
www.domain.api.org/posts/?userId=<userId>
If this substitutes the first endpoint you mentioned that's the way to go.
I would like to add ontop of #Opal's answer.
Are these okay or am I doing it the wrong / less sensible way?
Ideally, like Opal mentioned, you would use queryParams in your url. For many applications I have build, I don't know the uids returned from the api beforehand, so selecting an item and passing it inside my url as a query parameter makes sense. But it also has the added benefit of having your key inside your url, allowing you to bookmark it, pass the url to another user and they will automatically see the same data you want them to see.
To iterate: Is your current implementation wrong? No, but ideally you would use a combination of both route parameters are query parameters to achieve this
To create an endpoints, you have to be sure that you have these information at once:
Name of the endpoint
Status: activate or not (required) - is the endpoint activated or disable
Service profile (required) - ID of the Service Profile assigned to the endpoint.
Tariff profile (required) - ID of the tariff Profile assigned to the endpoint.
You can add another optional informations, and be sure of the structure of your endpoint.
Hope this helps you.
This is a classic RESTful way of creating resources I have in the application:
# This creates user. Client is responsible to create UUID, which is simple
PUT /users/CLIENT_GENERATED_UUID
# Access user by uuid
GET /users/UUID
When we touch the field of data storage performance it turns out that randomly generated UUIDs do not serve well by many reasons like data locality.
Server-generated IDs are good for performance but they don't really match REST:
If you use POST to create resources, you lose idempotency: PUT, GET, DELETE idempotency is implied by REST, while POST is not.
You may ask server to provide you with a nice ID before doing PUT. Despite it feels quite heavy and non-obvious, it also does not protect from dummy client that uses own random id instead of asking for it.
Could somebody give me a hint in this architecture matter?
Creating a resource using is not meant to be idempotent. If the server assigns the ID, it must choose a different ID for every resource to be created. Such an operation must not be idempotent, repeating it must create a different resource.
Using POST against a collecton resource as in
POST /users
is totally RESTful if the server assigns the ID. This request can be repeated and it will create a different resource.
Using an idempotent operation like PUT for creating a resource only makes sense if the problem domain allows the client to control the ID. I think that is ist not true for most domains.
My advice: use POST and let the server assign the ID.
Actually when you read RESTful Best Practices you can find that:
The POST verb is most-often utilized for creation of new resources.
in addtion to:
PUT can also be used to create a resource in the case where the resource ID is chosen by the client instead of by the server.
In REST environment you send POST to create resources and can return the server generated ID to send the values after with PUT or PATCH.
POST /users
PUT /users/id
Also, people create resources with PUT using client generated IDs
PUT /users
But I think the best aproach is use server generated IDs with POST.
Here are a clear explanation: http://www.restapitutorial.com/lessons/httpmethods.html
I don't quite grok how to sensibly structure a REST (or REST-like) API.
Imagine an API for creating and sending out newsletter emails. You might have the following nouns/resources: newsletters (subject, body, etc.), mailing lists (collections of recipients), and recipients (email addresses and associated data).
So you could use PUT to create a resource and be returned its ID:
/newsletter
/list
/user
You could obtain information on a resource using GET:
/newsletter/[id]
/list/[id]
/user/[id]
You can update an existing resource using PATCH (or should this be POST?):
/newsletter/[id]
/list/[id]
/user/[id]
You can delete a resource using DELETE:
/newsletter/[id]
/list/[id]
/user/[id]
Is the above correct?
What endpoints are sensible for actions like sending a newsletter to a list, adding a user to a list?
Does the following make sense, and is it RESTfull?
/newsletter/[newsletter_id]/send/[mailinglist_id]
/list/[list_id]/add/[user_id]
/list/[list_id]/remove/[user_id]
Is it redundant or unhelpful to have list/[id]/add/[id] and list/[id]/remove/[id] endpoints for lists, when users could be added or removed via PATCH at /list/[id] ?
What about searching for a users' ID via a property like email address or name? Or getting a list via an identifier like its name or when it was created?
You pretty much nailed it, except with the /list/[list_id]/add/[user_id] and /list/[list_id]/remove[user_id], because you have verbs in the URL - that is the purpose of the HTTP methods. Change them to, for example:
PUT (or POST) to /list/[list_id]/users/ for adding a user to the list
and
DELETE to /list/[list_id]/users/[user_id]
For search, I'd go with parameterized url for the list of resources, like:
/newsletter/?name=dfjkhskdfh
These verbs are often confused:
To create an entity you use POST
To update - PUT
These things could be treated in the following way:
POST /newsletters/[newsletter_id]/mailinglists/[mailinglist_id]/mailingfacts - performs sending the letters, it's like adding a fact of mailing to the collection
/lists/[list_id]/[user_id] - adds a user to the list
/lists/[list_id]/[user_id] - deletes the user from the list.
Is it redundant or unhelpful to have list/[id]/add/[id] and list/[id]/remove/[id] endpoints for lists, when users could be added or removed via PATCH at /list/[id] ?
It is bad/unhelpful. One of the ideas of REST is that the end points are resources and not a Remote Procedure Call (RPC). add or remove is suggesting a procedure to call.
Further GET requests should be side-effect free, that is, they don't do any updates. Further Roy Fielding explains GET as:
retrieval of information that should be a representation of some resource
So GET is only for retrieval, not for sending data (i.e. which user to add/remove).
The other very dangerous problem with list/[id]/remove/[id] is that if a spider or your test framework is going around your site it could start deleting items.
Hi I'm am trying to get the list of issues from a JIRA server using the SOAP API provided by JIRA.
I'm trying to filter the issues based on a custom field (and latter I will want to set that custom field).
If I get the list of issue it returns the custom fields for those issues along with them (I get customfieldId, key, values for each custom field) and I can get the custom field with getCustomFields methods provided by the API (to look for the ID of the field with a given name).
The issue I have is that if I login with an account that is not an admin (using the API) I can't call the getCustomFields method (it throws an exception saying I have to be an admin to do that).
My question is: Is there any other way to know which is the ID of the custom field I desire that can be done using a normal user account?
Also if you know how to set a custom field for an issue, it would also be very helpful :) (I would also like to be able to do it with a regular user account).
You have to be an admin to get a list of custom fields. Any 'normal' account can act on the custom fields via the API provided the user knows the customfield ID.
You can set the value of a custom field too, even with a 'normal' account. Again, the user needs the appropriate permissions to do this. Example provided here.
More here and here.
You can also use getFieldsForEdit(token, issueKey), which will return RemoteField[] for all fields available for edit on that issue (even if it has not yet been defined on the issue). It does not require admin permissions, but because it has the word "Edit" in the method, it does require that you have permission to edit the issue (which means, e.g., if the issue is status=Closed, it will raise an exception unless you allow editing closed issues. Unfortunately, I have yet to find a way to retrieve the RemoteField[] list (in order to map id to name), so getCustomFields() and getFieldsForEdit() appear to be the only options.
Have you tried getting a list of issues from the project, picking one, zeroing out the data, and using that as a template? That might work.
SOAP is being deprecated in favor of the REST API, which also has a better method to get this information