Extract a UID from a QR code
Before creating a lead, you must first retrieve the guest's unique identifier, or UID.
This UID is included in the guest's QR code. Eventmaker QR codes contain a MeCard that may include guest data such as:
Name (
N)Email address (
EMAIL)Company name (
ORG)Job title (
TITLE)Phone number (
TEL)Guest unique identifier (
UID)
⚠️ Only the UID field is mandatory in the MeCard. All other fields are included at the event organizer's discretion.
Create one or more leads
Once you have retrieved the UID, you can create the lead in Eventmaker.
Use the batch_create API endpoint to create one or more leads for an exhibitor.
The exhibitor is authenticated using their access_token.
Example
curl -X POST \
-H "Content-Type: application/json" \
https://app.eventmaker.io/api/v1/devices/<access_token>/connections/batch_create.json \
-d @payload.json
Replace <access_token> with the exhibitor's access token.
payload.json
{
"connections": [
{
"guest_uid": "<guest_uid>",
"author": "Robin"
},
{
"guest_uid": "<guest_uid>",
"author": "Robin"
}
]
}Replace <guest_uid> with the UID extracted from the MeCard.
Each lead in the payload must include at least:
guest_uidauthor
Example response
[
{
"_id": "5c6c0c0af897748ba97644f2",
"guest_uid": "guest uid",
"exhibitor_id": "5c66dfdcf89774219591baa6",
"updated_at": "2019-02-19T14:00:42.711Z",
"created_at": "2019-02-19T14:00:42.672Z",
"author": "Robin",
"comments": [],
"exhibitor_products": []
},
{
// Additional lead
}
]
The comments and exhibitor_products fields can be ignored.
Retrieve lead details
Creating a lead only returns a limited amount of information.
To retrieve additional guest data, use the lead_guests API endpoint.
This endpoint returns a list of fields associated with the event. These fields are whitelisted by the event organizer, meaning the organizer determines which guest information is returned by the API.
Example
curl -X GET \
-H "Content-Type: application/json" \
"https://app.eventmaker.io/api/v1/lead_guests/<guest_uid>.json?access_token=<access_token>"
Replace <guest_uid> and <access_token> with the corresponding values.
Example response
{
"email": "maria.hamilton@gmail.com",
"first_name": "Maria",
"last_name": "Hamilton",
"company_name": "Apple",
"uid": "S61LMJY"
}Using encrypted QR codes 🔐
Some events require encrypted QR codes.
For these events, your application must retrieve an encryption key and an initialization vector, or IV, before decrypting the QR code and continuing with the process described above.
When QR code encryption is enabled for an event, retrieve the encryption key and IV using the following API endpoint.
Request
curl -X PUT \
-H "Content-Type: application/json" \
-d '{ "signature": "<signature>" }' \ "https://app.eventmaker.io/api/v1/events/<event_id>/exhibitors/<access_token>/activate_license.json"
Replace the values between angle brackets with the corresponding values.
Example response when encryption is disabled
{ "qr_code_ciphering_enabled": false, "qr_code_ciphering_key": null, "qr_code_ciphering_iv": null, "app": "Leads Android" }Example response when encryption is enabled
{
"qr_code_ciphering_enabled": true,
"qr_code_ciphering_key": kHxOFKTAq7xutc8MnAlmrUrQNAW/xXM8V1X5VgB444Q=",
"qr_code_ciphering_iv": "JWEVPt7lhlNcnfNNyVtnOQ==",
"app": "Leads Android"
}If the signature is invalid, the API returns:
401 Unauthorized
If the signature is valid, the API returns:
200 OK
Calculate the signature 🔏
Your application must first be registered with Eventmaker. Please contact us to register it and receive a signing secret.
The signing key is created by concatenating the signing secret with the event ID:
<secret><event_id>
Then sign the exhibitor's access token using HMAC-SHA256 and the signing key:
signing_key = <secret><event_id>
signature = HmacSha256(access_token, signing_key)
The resulting signature must be represented as a lowercase hexadecimal string.
iOS example using Objective-C
#import <CommonCrypto/CommonHMAC.h>
[...]
NSString *key = [NSString stringWithFormat:@"%@%@", kSigningSecret, eventId];
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [toSign cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(
kCCHmacAlgSHA256,
cKey,
strlen(cKey),
cData,
strlen(cData),
cHMAC
);
NSData *HMACData = [
NSData dataWithBytes:cHMAC
length:sizeof(cHMAC)
];
const unsigned char *buffer =
(const unsigned char *)[HMACData bytes];
NSMutableString *signature = [
NSMutableString stringWithCapacity:HMACData.length * 2 ];
for (NSUInteger i = 0; i < HMACData.length; ++i) {
[signature appendFormat:@"%02x", buffer[i]];
}
In this example, toSign must contain the exhibitor's access token.
Android example using Java
import java.nio.charset.StandardCharsets;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
String signingKey = signingSecret + eventId;
String toSign = accessToken;
Mac hmacSHA256 = Mac.getInstance("HmacSHA256");
hmacSHA256.init(
new SecretKeySpec(
signingKey.getBytes(StandardCharsets.UTF_8),
"HmacSHA256"
)
);
byte[] result = hmacSHA256.doFinal(
toSign.getBytes(StandardCharsets.UTF_8)
);
StringBuilder signatureBuilder = new StringBuilder(result.length * 2);
for (byte value : result) {
signatureBuilder.append(String.format("%02x", value & 0xff));
}
String signature = signatureBuilder.toString();
Decrypt a QR code
When Eventmaker QR codes are encrypted, their content has the following format:
E:somecipheredunreadablestuff
Whenever your application scans a QR code, it must check whether the content starts with the E: prefix.
If this prefix is present, remove it and decrypt the remaining content.
The QR code content is encrypted using:
AES-256
CBC block cipher mode
PKCS padding
The following values are Base64-encoded:
The encryption key
The initialization vector
The encrypted QR code content after the
E:prefix
They must therefore be Base64-decoded before the decryption process.
⚠️ Make sure your application supports both encrypted and unencrypted QR codes.
iOS example using Objective-C
#import <CommonCrypto/CommonCryptor.h>
NSString *contentWithoutPrefix = [
content substringFromIndex:[@"E:" length]
];
NSData *data = [
[NSData alloc]
initWithBase64EncodedString:contentWithoutPrefix
options:NSDataBase64DecodingIgnoreUnknownCharacters
];
NSData *keyData = [
[NSData alloc]
initWithBase64EncodedString:key
options:0
];
NSData *ivData = [
[NSData alloc]
initWithBase64EncodedString:iv
options:0
];
CCCryptorRef cryptor = NULL;
CCCryptorStatus status = CCCryptorCreateWithMode(
kCCDecrypt,
kCCModeCBC,
kCCAlgorithmAES,
ccPKCS7Padding,
ivData.bytes,
keyData.bytes,
kCCKeySizeAES256,
NULL,
0,
0,
0,
&cryptor
);
if (status != kCCSuccess) {
// Handle cryptor creation error
}
size_t bufferSize = CCCryptorGetOutputLength(
cryptor,
(size_t)data.length,
true
);
void *buffer = malloc(bufferSize);
if (buffer == NULL) {
CCCryptorRelease(cryptor);
// Handle memory allocation error
}
size_t bytesWritten = 0;
size_t totalBytesWritten = 0;
status = CCCryptorUpdate(
cryptor,
data.bytes,
(size_t)data.length,
buffer,
bufferSize,
&bytesWritten
);
if (status != kCCSuccess) {
free(buffer);
CCCryptorRelease(cryptor);
// Handle decryption error
}
totalBytesWritten += bytesWritten;
status = CCCryptorFinal(
cryptor,
buffer + totalBytesWritten,
bufferSize - totalBytesWritten,
&bytesWritten
);
if (status != kCCSuccess) {
free(buffer);
CCCryptorRelease(cryptor);
// Handle finalization error
}
totalBytesWritten += bytesWritten;
NSData *decryptedData = [
NSData dataWithBytes:buffer
length:totalBytesWritten
];
free(buffer);
CCCryptorRelease(cryptor);
NSString *decryptedContent = [
[NSString alloc]
initWithData:decryptedData
encoding:NSUTF8StringEncoding
];
Android example using Java
import android.util.Base64;
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
String encryptedPrefix = "E:";
if (!content.startsWith(encryptedPrefix)) {
// The QR code is not encrypted.
String decodedContent = content;
} else {
String contentWithoutPrefix =
content.substring(encryptedPrefix.length());
byte[] key = Base64.decode(
qrCodeCipheringKey,
Base64.DEFAULT
);
byte[] iv = Base64.decode(
qrCodeCipheringIv,
Base64.DEFAULT
);
byte[] encryptedContent = Base64.decode(
contentWithoutPrefix,
Base64.DEFAULT
);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(
Cipher.DECRYPT_MODE,
keySpec,
ivSpec
);
byte[] decryptedContent = cipher.doFinal(encryptedContent);
String decodedContent = new String(
decryptedContent,
StandardCharsets.UTF_8
);
}
