MBS FileMaker Advent calendar - Door 15 - vCard QR
Day 15 - vCard QR |
Today we want to create QR codes that contain the contact details of one of our giftee. If we scan this contact with our cell phone, it can be transferred directly to the phone's address book. To do this, we first have to write a so-called vcf file. The ending vcf stands for Virtual Contact File. We can see how such a file is structured if we export a contact from the Apple calendar and open it in a text editor. It may look like this:
BEGIN:VCARD VERSION:3.0 PRODID:-//Apple Inc.//macOS 13.4.1//EN N:Mustermann;Max;;; FN:Max Mustermann ORG:Mustermann AG; EMAIL;type=INTERNET;type=WORK;type=pref:xyz@abc.de TEL;type=CELL;type=VOICE;type=pref:012346789 TEL;type=IPHONE;type=CELL;type=VOICE:1011121314 TEL;type=HOME;type=FAX:15161718 ADR;type=HOME;type=pref:;;Musterstraße 3;Musterstadt;;1234;Germany NOTE:Conference item1.URL;type=pref:www.xyz.com item1.X-ABLabel:_$!<HomePage>!$_ BDAY:2000-04-01 END:VCARD
We have different key and value pairs here that are separated from each other with a colon.
There is information that must be entered in a VCard and there is information that is optional. One piece of information that you must always include in your QR code are the tags that enclose our content. This type of text always starts with BEGIN:VCARD and ends with END:VCARD.
In addition, we need the version we are using. There are several versions in which the data structure is slightly different and which have different support. Today we use version 3.0 as this is also used by Apple as the export version. For this reason, the next line in our data is already fixed: VERSION:3.0.
Now it's time for the actual data. Here we start with the name, first we have the key N in which we first enter the last name and then the first name separated by a semicolon. If the person has other first names, these can be entered separated by another semicolon. Any titles, such as a doctorate, can also be entered with a semicolon. We also need the key FN. This is the representation of the name as we would write it. For example, we can write the Dr. title of a person in front of it. For Dr. Manuel Müller, for example, these two lines look like this:
N:Miller;Michael;Dr. FN:Dr. Michael Miller
This would already fulfill the minimum amount of data that a vCard must have. But we would still like to include the rest of the information we have about our client in the vCard.
Now we come to a part that can be repeated several times in a vCard, the telephone number. The key to the phone number is TEL. Here we can specify additional types. These can be e.g. text, voice, fax, cell, video or pager. If we want to assign several of these types to a number, we can either specify a comma-separated list or write several times e.g. Type="voice";Type="fax". In this example we see a pref as the type for the first telephone number we have entered. This pref means that it is the preferred telephone number.
TEL;type=CELL;type=VOICE;type=pref:012346789
In our example, we have a cell phone number that is used and preferred for making calls. The telephone number is then placed after a colon.
The whole thing works in a similar way for email addresses. Here the key is EMAIL.
EMAIL;type=INTERNET;type=WORK;type=pref:xyz@abc.de
Now we come to a somewhat more complicated but very important part, the address. Here, too, we can enter a type, as we have just seen with the telephone number. The address itself consists of various components that are separated by semicolons. The order of these components is very important and must be respected. If we omit a component, we leave the area between the separating semicolons empty. First we can specify a mailbox. This is followed by a possible address extension separated by a semicolon, then the street, city, region, zip code and finally the country. This can then look like this, for example:
ADR;type=HOME;type=pref:;;Musterstraße 3;Musterstadt;NRW;1234;Germany
We do not need the post box and the address extension in the example, but the values would be entered between the semicolons if required.
Another interesting value to enter in a QR code is the date of birth. This has the key BDAY. The value is composed as follows YYYYMMDD. If you do not know the YEAR, it is replaced with two -: - -MMDD
In our example, the person was born on April 1, 2000: BDAY:20000401 Here, the specification differs from the Apple way.
Now that we know what this information should look like, we can put it together in our script and then write it in a QR code.
We first compose the content of the QR code by connecting the fixed text modules with the variable values.
# Start VCard Set Variable [ $Content ; Value: "BEGIN:VCARD" & Char(13) & "VERSION:3.0" & Char(13) ] # Name Set Variable [ $Content ; Value: $Content & "N:" & Giftee::last_name & ";" & Giftee::first_name & ";;;" & Char(13) ] Set Variable [ $Content ; Value: $Content & "FN:" & Giftee::first_name & " " & Giftee::last_name & Char(13) ]
For the portals, we first go to the portal with Go to Object and run through the individual entries with a loop. With Go to Portal Row we move forward through the individual entries. We check whether the most important information in the portals here, the email address and the telephone number, are not empty, otherwise we do not need to create this entry. In the telephone part, you can also see that we make the distinction whether it is the first telephone number in the portal, because we then give it the label pref to mark it as a preferred telephone number. We make this distinction as to whether it is the first non-empty entry with a variable that we set to 1 before starting the loop and as soon as we have run through the branch of the condition that gives us a telephone number as the preferred telephone number, we set the value of the variable to 0. As a result, this path is no longer run through the next time and we only ever have one telephone number with the label pref.
# EMail Go to Object [ Object Name: "EmailPortal" ] Go to Portal Row [ Select: On ; First ] Loop [ Flush: Always ] If [ Email::Emailaddress ≠ "" ] Set Variable [ $Content ; Value: $Content & "EMAIL;type=" & Upper ( Email::Typ ) & ":" & Email::Emailaddress & Char(13) ] End If Go to Portal Row [ Select: On ; Next ; Exit after last: On ] End Loop # # Telephone Go to Object [ Object Name: "Telephoneportal" ] Go to Portal Row [ Select: On ; First ] Set Variable [ $L1 ; Value: 1 ] Loop [ Flush: Always ] If [ Telephone::Number ≠ "" ] If [ $L1=1 ] Set Variable [ $Content ; Value: $Content & "TEL;type=" & Telephone::Type & ",pref:" & Telephone::Number & Char(13) ] Set Variable [ $L1 ; Value: $L1=0 ] Else Set Variable [ $Content ; Value: $Content & "TEL;type=" & Telephone::Type & ":" & Telephone::Number & Char(13) ] End If End If Go to Portal Row [ Select: On ; Next ; Exit after last: On ] End Loop
We have to include a lot of fields for the address, but this is simple text as usual.
# Address If [ Giftee::Street ≠ "" or Giftee::City ≠ "" or Giftee::Postcode ≠ "" or Giftee::Country ≠ "" or Giftee::State ≠ "" ] Set Variable [ $Content ; Value: $Content & "ADR;type=HOME;type=pref:;;" & Giftee::Street & ";" & Giftee::City & ";" & "" & ";" & Giftee::Postcode & ";" & Giftee::Country & Char(13) ] End If
We have to include a lot of fields for the address, but this is simple text as usual. The birthday is more interesting. First we check whether the birthday is entered, as it is one of the optional values and can also be omitted. The year that we get back from the Year function is always 4 digits, unless it is necessarily a historical birthday before the year 1000. We can therefore adopt this. For the month, however, the months January to September are single digits when we call the Month function. The date format that we have in the vCard always requires two digits. For this reason, we query the length of the text that the Month function returns from the birth date and if this is not 2, we add a 0 to the front. The month then has the required two digits again. We do the same for the days in the date. Last but not least, we put the date together in the form YYYYMMDD and then append it to the content. Now only the END tag is missing, which we also append.
# Birthday If [ Giftee::Birthday ≠ "" ] Set Variable [ $Year ; Value: Year ( Giftee::Birthday ) ] # If [ Length ( Month ( Giftee::Birthday ) ) ≠ 2 ] Set Variable [ $Month ; Value: "0" & Month ( Giftee::Birthday ) ] Else Set Variable [ $Month ; Value: Month ( Giftee::Birthday ) ] End If # If [ Length ( Day ( Giftee::Birthday ) ) ≠ 2 ] Set Variable [ $Day ; Value: "0" & Day ( Giftee::Birthday ) ] Else Set Variable [ $Day ; Value: Day ( Giftee::Birthday ) ] End If Set Variable [ $BDay ; Value: $Year & $Month & $Day ] Set Variable [ $Content ; Value: $Content & "BDAY:" & $BDay & Char(13) ] End If # End VCard Set Variable [ $Content ; Value: $Content & "END:VCARD" ]
We have built the content of the QR code and we can now generate the QR code. We want to use the Barcode.GenerateJSON function to do this. The function name already contains the word JSON. We have to pass this function a JSON that contains the settings for the desired barcode. We have already explained how the JSON functions work in more detail in one of the previous doors. So let's take a look at the information we need to set in this JSON. First of all, we have to specify which barcode we want to generate exactly, because in addition to the QR code, the MBS FileMaker Plugin can generate more than 80 other different barcode types. So we enter the value QRCode in the Symbology key. Then, of course, we want to transfer the QR code content that we have created, so we enter this under the key Text. Next comes the Scale factor. The scale factor should have at least the value 4 when printing a barcode with a high resolution. The barcodes in the plugin can have barcode-specific options, which can have different meanings for the individual barcodes. Option1 is such a value that can set something completely different for different barcodes. In the case of the QR code, it defines the ECC level. The ECC level specifies how often the information within the QR code is repeated. This has the advantage that a QR code can still be read even if it has been damaged or, for example, a small logo has been positioned in the middle. ECC 4 is the highest level we can set.
Since all settings have been made we can generate the QR code in the Barcode.GenerateJSON function by specifying our JSON. We get a GraphicsMagick reference as the return value. GraphicsMagick is another topic from the plugin that deals with graphical functions.
Set Variable [ $QR_JSON ; Value: MBS( "JSON.CreateObject" ) ] Set Variable [ $QR_JSON ; Value: MBS( "JSON.AddStringToObject"; $QR_JSON; "Symbology"; "QRCode") ] Set Variable [ $QR_JSON ; Value: MBS( "JSON.AddStringToObject"; $QR_JSON; "Text"; $Content) ] Set Variable [ $QR_JSON ; Value: MBS( "JSON.AddNumberToObject"; $QR_JSON; "Scale"; 4) ] Set Variable [ $QR_JSON ; Value: MBS( "JSON.AddNumberToObject"; $QR_JSON; "Option1"; 4) ] Set Variable [ $QRRef ; Value: MBS( "Barcode.GenerateJSON"; $QR_JSON ) ]
So that we can save the QR code in a file on the disk, we assemble the path. The file should be stored on the desktop under the name QR_lastName_ firstName.png. We then use GMImage.WriteToFile to write this GMImage reference as an image file to the correct path. If you want to save the QR code in a container, you can instead use the GMImage.WriteToContainer function. As GMImage is also a reference, we release it in memory. From a previous door we already know the Files.LaunchFile function, which opens a file for us directly with the standard program provided to do this.
Set Variable [ $Path ; Value: MBS("Path.AddPathComponent"; MBS("Folders.UserDesktop"); "QR_" & Giftee::last_name & "_" & Giftee::first_name & ".png") ] Set Variable [ $r ; Value: MBS("GMImage.WriteToFile"; $QRRef; $Path) ] Set Variable [ $r ; Value: MBS( "GMImage.FreeAll" ) ] Set Variable [ $r ; Value: MBS("Files.LaunchFile"; $Path) ]
We are now finished with our script and can generate the barcode.
I hope you enjoyed today's door and we'll see again tomorrow.
14 👈 | 15 of 24 | 👉 16 |