I'm using this Mailchimp 2.0 PHP wrapper:
https://github.com/drewm/mailchimp-api
To send data to my list via the Mailchimp 2.0 API.
I can get email, firstname, and lastname to send successfully from my form to mailchimp.
I set those up as required fields in mailchimp(EMAIL, FNAME, LNAME).
Here is the PHP for that:
$MailChimp = new MailChimp('xxxxxxx');
$result = $MailChimp->call('lists/subscribe', array(
'id' => 'xxxxxx',
//required fields
'email' => array( 'email' => $_POST['email']),
'merge_vars' => array('FNAME' => $_POST['fname'], 'LNAME' => $_POST['lname']),
//mailchimp options
'double_optin' => false,
'update_existing' => true,
'replace_interests' => false
));
But I also have 12 checkboxes for stuff like engine size, type, gas type, color, etc. that are optional.
How can send these to the mailchimp API? I'm hoping someone with experience with Mailchimp API could help out.
Any help would be appreciated.
Thanks!
Here is a clarification to the structure of the groupings that is not in the docs' example. I.e. you supply only the names of the groups that have been selected by the user:
"merge_vars": {
"groupings": [
{
"groups": [
"selection 3",
"selection 7"
],
"id": <group_id>// or "name": <group_name>
}
]
},
In the merge_vars array, define "groupings" which points to an array. This 'groupings' array will then consist of individual arrays that point to a particular grouping of groups. Ex. if you have a grouping of groups titled "gas type" with group options "diesel", "unleaded", etc. this level of the array points to "gas type".
THEN, you define a "groups" array inside of this array to denote membership into the actual subgroups ("diesel", "unleaded").
Here's a code example from the list subscribe MailChimp API 2.0 documentation:
"merge_vars": {
"groupings": [
{
"id": 42,
"name": "example name",
"groups": [
"..."
]
}
]
lists/subscribe: http://apidocs.mailchimp.com/api/2.0/lists/subscribe.php
My personal suggestion: create groups in the web app if you haven't already. Then, use the lists/interest-groupings method to see how the interest groups are formatted and returned to you. This gives you a sense of how to structure it in your own code.
lists/interest-groupings: http://apidocs.mailchimp.com/api/2.0/lists/interest-groupings.php
Related
I have a call to Companies House API and response I get from API is an array of hashes.
companies = {
"total_results" => 2,
"items" => [{
"title" => "First company",
"date_of_creation" => "2016-11-09",
"company_type" => "ltd",
"company_number" => "10471071323",
"company_status" => "active"
},
{
"title" => "Second company",
"date_of_creation" => "2016-11-09",
"company_type" => "ltd",
"company_number" => "1047107132",
"company_status" => "active"
}]
}
How I can iterate over companies and get a result similar to:
[{
title: "First company",
company_number: "10471071323"
},
{
title: "Second company",
company_number: "1047107132"
}]
You can use map which will iterate through the elements in an array and return a new array:
companies["items"].map do |c|
{
title: c['title'],
company_number: c['company_number']
}
end
=> [
{:title=>"First company", :company_number=>"10471071323"},
{:title=>"Second company", :company_number=>"1047107132"}
]
companies.map { |company| company.slice('title', 'company_number').symbolize_keys }
This should do the trick.
If you're not using Rails (or, more specifically, ActiveSupport), then symbolize_keys won't be available. In this case, you'd have to go for a more standard-Ruby approach:
companies.map do |company|
{ title: company["title"], company_number: company["company_number"] }
end
The answers are totally correct; but you should be made aware that what you’re looking at from companies house is not just an array of hashes - it’s a valid JsonApi response.
You might find your job easier if you’re using a gem which is aware of JsonApi specs, or if you’re just approaching it as that kind of data.
Have a look at the ruby implementations of https://jsonapi.org/implementations/
Or ActiveModelSerializer for ways to not only reform your hashes but deserialise this very structured data into ruby objects.
But like I say, if all you’re looking for is a quick way to reform the data as you describe. The above answers are perfect.
Assume you have a GraphQL type and it includes many fields.
How to query all the fields without writing down a long query that includes the names of all the fields?
For example, If I have these fields :
public function fields()
{
return [
'id' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The id of the user'
],
'username' => [
'type' => Type::string(),
'description' => 'The email of user'
],
'count' => [
'type' => Type::int(),
'description' => 'login count for the user'
]
];
}
To query all the fields usually the query is something like this:
FetchUsers{users(id:"2"){id,username,count}}
But I want a way to have the same results without writing all the fields, something like this:
FetchUsers{users(id:"2"){*}}
//or
FetchUsers{users(id:"2")}
Is there a way to do this in GraphQL ??
I'm using Folkloreatelier/laravel-graphql library.
Unfortunately what you'd like to do is not possible. GraphQL requires you to be explicit about specifying which fields you would like returned from your query.
Yes, you can do this using introspection. Make a GraphQL query like (for type UserType)
{
__type(name:"UserType") {
fields {
name
description
}
}
}
and you'll get a response like (actual field names will depend on your actual schema/type definition)
{
"data": {
"__type": {
"fields": [
{
"name": "id",
"description": ""
},
{
"name": "username",
"description": "Required. 150 characters or fewer. Letters, digits, and #/./+/-/_ only."
},
{
"name": "firstName",
"description": ""
},
{
"name": "lastName",
"description": ""
},
{
"name": "email",
"description": ""
},
( etc. etc. ...)
]
}
}
}
You can then read this list of fields in your client and dynamically build a second GraphQL query to get the values of these fields.
This relies on you knowing the name of the type that you want to get the fields for -- if you don't know the type, you could get all the types and fields together using introspection like
{
__schema {
types {
name
fields {
name
description
}
}
}
}
NOTE: This is the over-the-wire GraphQL data -- you're on your own to figure out how to read and write with your actual client. Your GraphQL javascript library may already employ introspection in some capacity. For example, the apollo codegen command uses introspection to generate types.
2022 Update
Since this answer was originally written, it is now a recommended security practice to TURN OFF introspection in production. Reference: Why you should disable GraphQL introspection in production.
For an environment where introspection is off in production, you could use it in development as a way to assist in creating a static query that was used in production; you wouldn't actually be able to create a query dynamically in production.
I guess the only way to do this is by utilizing reusable fragments:
fragment UserFragment on Users {
id
username
count
}
FetchUsers {
users(id: "2") {
...UserFragment
}
}
I faced this same issue when I needed to load location data that I had serialized into the database from the google places API. Generally I would want the whole thing so it works with maps but I didn't want to have to specify all of the fields every time.
I was working in Ruby so I can't give you the PHP implementation but the principle should be the same.
I defined a custom scalar type called JSON which just returns a literal JSON object.
The ruby implementation was like so (using graphql-ruby)
module Graph
module Types
JsonType = GraphQL::ScalarType.define do
name "JSON"
coerce_input -> (x) { x }
coerce_result -> (x) { x }
end
end
end
Then I used it for our objects like so
field :location, Types::JsonType
I would use this very sparingly though, using it only where you know you always need the whole JSON object (as I did in my case). Otherwise it is defeating the object of GraphQL more generally speaking.
GraphQL query format was designed in order to allow:
Both query and result shape be exactly the same.
The server knows exactly the requested fields, thus the client downloads only essential data.
However, according to GraphQL documentation, you may create fragments in order to make selection sets more reusable:
# Only most used selection properties
fragment UserDetails on User {
id,
username
}
Then you could query all user details by:
FetchUsers {
users() {
...UserDetails
}
}
You can also add additional fields alongside your fragment:
FetchUserById($id: ID!) {
users(id: $id) {
...UserDetails
count
}
}
Package graphql-type-json supports custom-scalars type JSON.
Use it can show all the field of your json objects.
Here is the link of the example in ApolloGraphql Server.
https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#custom-scalars
Assume you have a GraphQL type and it includes many fields.
How to query all the fields without writing down a long query that includes the names of all the fields?
For example, If I have these fields :
public function fields()
{
return [
'id' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The id of the user'
],
'username' => [
'type' => Type::string(),
'description' => 'The email of user'
],
'count' => [
'type' => Type::int(),
'description' => 'login count for the user'
]
];
}
To query all the fields usually the query is something like this:
FetchUsers{users(id:"2"){id,username,count}}
But I want a way to have the same results without writing all the fields, something like this:
FetchUsers{users(id:"2"){*}}
//or
FetchUsers{users(id:"2")}
Is there a way to do this in GraphQL ??
I'm using Folkloreatelier/laravel-graphql library.
Unfortunately what you'd like to do is not possible. GraphQL requires you to be explicit about specifying which fields you would like returned from your query.
Yes, you can do this using introspection. Make a GraphQL query like (for type UserType)
{
__type(name:"UserType") {
fields {
name
description
}
}
}
and you'll get a response like (actual field names will depend on your actual schema/type definition)
{
"data": {
"__type": {
"fields": [
{
"name": "id",
"description": ""
},
{
"name": "username",
"description": "Required. 150 characters or fewer. Letters, digits, and #/./+/-/_ only."
},
{
"name": "firstName",
"description": ""
},
{
"name": "lastName",
"description": ""
},
{
"name": "email",
"description": ""
},
( etc. etc. ...)
]
}
}
}
You can then read this list of fields in your client and dynamically build a second GraphQL query to get the values of these fields.
This relies on you knowing the name of the type that you want to get the fields for -- if you don't know the type, you could get all the types and fields together using introspection like
{
__schema {
types {
name
fields {
name
description
}
}
}
}
NOTE: This is the over-the-wire GraphQL data -- you're on your own to figure out how to read and write with your actual client. Your GraphQL javascript library may already employ introspection in some capacity. For example, the apollo codegen command uses introspection to generate types.
2022 Update
Since this answer was originally written, it is now a recommended security practice to TURN OFF introspection in production. Reference: Why you should disable GraphQL introspection in production.
For an environment where introspection is off in production, you could use it in development as a way to assist in creating a static query that was used in production; you wouldn't actually be able to create a query dynamically in production.
I guess the only way to do this is by utilizing reusable fragments:
fragment UserFragment on Users {
id
username
count
}
FetchUsers {
users(id: "2") {
...UserFragment
}
}
I faced this same issue when I needed to load location data that I had serialized into the database from the google places API. Generally I would want the whole thing so it works with maps but I didn't want to have to specify all of the fields every time.
I was working in Ruby so I can't give you the PHP implementation but the principle should be the same.
I defined a custom scalar type called JSON which just returns a literal JSON object.
The ruby implementation was like so (using graphql-ruby)
module Graph
module Types
JsonType = GraphQL::ScalarType.define do
name "JSON"
coerce_input -> (x) { x }
coerce_result -> (x) { x }
end
end
end
Then I used it for our objects like so
field :location, Types::JsonType
I would use this very sparingly though, using it only where you know you always need the whole JSON object (as I did in my case). Otherwise it is defeating the object of GraphQL more generally speaking.
GraphQL query format was designed in order to allow:
Both query and result shape be exactly the same.
The server knows exactly the requested fields, thus the client downloads only essential data.
However, according to GraphQL documentation, you may create fragments in order to make selection sets more reusable:
# Only most used selection properties
fragment UserDetails on User {
id,
username
}
Then you could query all user details by:
FetchUsers {
users() {
...UserDetails
}
}
You can also add additional fields alongside your fragment:
FetchUserById($id: ID!) {
users(id: $id) {
...UserDetails
count
}
}
Package graphql-type-json supports custom-scalars type JSON.
Use it can show all the field of your json objects.
Here is the link of the example in ApolloGraphql Server.
https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#custom-scalars
I have been trying to figure out how to automatically add recipients to a Draft email that is created using the Gmail API through their Ruby library. I can create the draft without any issues but setting the recipients is causing me troubles and I haven't been able to find any good examples showing the best way to add email specific things.
Using the Google API playground and pulling in drafts that have already been created, it looks like the structure should be something similar to what is shown below, but whenever the draft is created, there are no recipients.
#result = client.execute(
:api_method => gmail.users.drafts.create,
:parameters => {
'userId' => "me"
},
:body_object => {
'message' => {
'raw' => Base64.urlsafe_encode64('Test Email Message'),
'payload' => {
'headers' =>
[
{
'name' => "To",
'value' => "John Smith <john_smith.fake#gmail.com>"
}
]
}
}
}
)
'raw' should contain the entire (RFC822) email, complete with body and headers. Do not use the 'payload.headers' structure, that parsed format is only used for returning during message.get() presently.
so for 'raw' you'd want to Base64.urlsafe_encode64() a string like:
"To: someguy#example.com\r\nFrom: myself#example.com\r\nSubject: my subject\r\n\r\nBody goes here"
I use Mandrill plugin for Codeigniter.
I created HTML template through Mandrill account, named fess1 with merge tag FNAME, after I published it.
Example:
...
<p>
<span>Hi *|FNAME|*,<br></span>
</p>
....
Now I try to send mail from codeigniter like:
private function sendMailMandrill($owner_name,$business_name,$owner_email){
$message = array('dest_mail' => $owner_email);
$message['to'] = array(array('email' => 'mim#wefi.com'));
$mergeVars[] = array(
'rcpt' => array(array('email' => 'mim#wefi.com')),
'vars' => array(
array(
'name' => 'FNAME',
'content' => 'Fessy'
)
)
);
$message['merge'] = true;
$template_name = 'fess1';
$template_content = array( // I don't know what I need to provide here, left it empty
array(
'name' => 'example name',
'content' => 'example content'
)
);
$message['merge_vars'] = $mergeVars;
return $this->mandrill->messages_send_template($template_name, $template_content, $message);
}
The result:
I get the mail, based on fess1 template, but with the tag *|FNAME|*.
Sounds like Mandrill didn't recognize the merge tag.
I used mandrill->messages_send_template but since my template stored into Mandrill account I have no clue what I need to provide for $template_content.
So I wrote dummy info there.
Did I miss something?
Thank you,
[EDIT]
From logs this is what I send:
{
"template_name": "fess1",
"template_content": [
{
"name": "example name",
"content": "example content"
}
],
"message": {
"owner_name": "עידו",
"business_name": "פלאפל מוסקו",
"dest_mail": "maxim#wifi.com",
"to": [
{
"email": "maxim#wifi.com"
}
],
"merge": "true",
"merge_vars": [
{
"rcpt": [
{
"email": "maxim#wifi.com"
}
],
"vars": [
{
"name": "FNAME",
"content": "Fessy"
}
]
}
]
},
"key": "xxxxxxxxxxxxxxxx"
}
You can provide blank information for the template_content parameter. That parameter allows you to use mc:edit regions in your template. It is a required parameter, but a blank array will suffice if all of the content is in your template in Mandrill.
As for whether the merge_vars were recognized, the first thing we recommend is inspecting the API Logs for your account (Settings > API Logs) since that will show you the JSON that Mandrill received. You can then compare that to the expected JSON format from the Mandrill API docs: https://mandrillapp.com/api/docs/messages.JSON.html#method=send-template
It looks like your arrays may not be nested as expected. Once you view the JSON that's being generated as compared with the expected format, you can also view the PHP documentation for the Mandrill PHP client. It may not be identical to the CodeIgniter plugin, but should give you an idea of how the merge_vars parameter would be structured in PHP: https://mandrillapp.com/api/docs/messages.php.html
In mergeVars you created array instead key:value. Change it to:
'rcpt' => 'mim#wefi.com',